176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Copyright (C) 2000, Entity Cyber, Inc. 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Authors: Gary Byers (gb@thinguin.org) 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Marty Connor (mdc@thinguin.org) 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman This software may be used and distributed according to the terms 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman of the GNU Public License (GPL), incorporated herein by reference. 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Description: 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman This is just a little bit of code and data that can get prepended 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman to a ROM image in order to allow bootloaders to load the result 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman as if it were a Linux kernel image. 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman A real Linux kernel image consists of a one-sector boot loader 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (to load the image from a floppy disk), followed a few sectors 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman of setup code, followed by the kernel code itself. There's 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman a table in the first sector (starting at offset 497) that indicates 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman how many sectors of setup code follow the first sector and which 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman contains some other parameters that aren't interesting in this 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case. 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman When a bootloader loads the sectors that comprise a kernel image, 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman it doesn't execute the code in the first sector (since that code 2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman would try to load the image from a floppy disk.) The code in the 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman first sector below doesn't expect to get executed (and prints an 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman error message if it ever -is- executed.) 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman We don't require much in the way of setup code. Historically, the 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Linux kernel required at least 4 sectors of setup code. 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Therefore, at least 4 sectors must be present even though we don't 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman use them. 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3776d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFILE_LICENCE ( GPL_ANY ) 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define SETUPSECS 4 /* Minimal nr of setup-sectors */ 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PREFIXSIZE ((SETUPSECS+1)*512) 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PREFIXPGH (PREFIXSIZE / 16 ) 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define BOOTSEG 0x07C0 /* original address of boot-sector */ 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define INITSEG 0x9000 /* we move boot here - out of the way */ 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define SETUPSEG 0x9020 /* setup starts here */ 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define SYSSEG 0x1000 /* system loaded at 0x10000 (65536). */ 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .text 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .code16 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .arch i386 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .org 0 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .section ".prefix", "ax", @progbits 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman This is a minimal boot sector. If anyone tries to execute it (e.g., if 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman a .lilo file is dd'ed to a floppy), print an error message. 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanbootsector: 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman jmp $BOOTSEG, $1f /* reload cs:ip to match relocation addr */ 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman1: 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw $0x2000, %di /* 0x2000 is arbitrary value >= length 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman of bootsect + room for stack */ 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw $BOOTSEG, %ax 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw %ax,%ds 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw %ax,%es 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cli 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw %ax, %ss /* put stack at BOOTSEG:0x2000. */ 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw %di,%sp 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sti 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw $why_end-why, %cx 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw $why, %si 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw $0x0007, %bx /* page 0, attribute 7 (normal) */ 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movb $0x0e, %ah /* write char, tty mode */ 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanprloop: 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lodsb 7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int $0x10 8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman loop prloop 8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanfreeze: jmp freeze 8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanwhy: .ascii "This image cannot be loaded from a floppy disk.\r\n" 8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanwhy_end: 8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman The following header is documented in the Linux source code at 8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Documentation/i386/boot.txt 9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .org 497 9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmansetup_sects: 9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .byte SETUPSECS 9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanroot_flags: 9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .word 0 9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmansyssize: 9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .long -PREFIXPGH 9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ 10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .ascii "ADDL" 10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .long syssize 10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .long 16 10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .long 0 10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .previous 10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanram_size: 10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .word 0 10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvid_mode: 10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .word 0 11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanroot_dev: 11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .word 0 11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanboot_flag: 11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .word 0xAA55 11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanjump: 11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Manually specify a two-byte jmp instruction here rather 11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * than leaving it up to the assembler. */ 11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .byte 0xeb 11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .byte setup_code - header 11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanheader: 12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .byte 'H', 'd', 'r', 'S' 12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanversion: 12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .word 0x0207 /* 2.07 */ 12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrealmode_swtch: 12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .long 0 12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstart_sys: 12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .word 0 12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmankernel_version: 12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .word 0 12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmantype_of_loader: 13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .byte 0 13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanloadflags: 13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .byte 0 13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmansetup_move_size: 13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .word 0 13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmancode32_start: 13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .long 0 13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanramdisk_image: 13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .long 0 13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanramdisk_size: 14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .long 0 14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanbootsect_kludge: 14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .long 0 14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanheap_end_ptr: 14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .word 0 14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpad1: 14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .word 0 14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmancmd_line_ptr: 14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .long 0 14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmaninitrd_addr_max: 15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* We don't use an initrd but some bootloaders (e.g. SYSLINUX) have 15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * been known to require this field. Set the value to 2 GB. This 15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * value is also used by the Linux kernel. */ 15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .long 0x7fffffff 15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmankernel_alignment: 15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .long 0 15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrelocatable_kernel: 15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .byte 0 15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpad2: 15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .byte 0, 0, 0 16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmancmdline_size: 16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .long 0 16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanhardware_subarch: 16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .long 0 16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanhardware_subarch_data: 16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .byte 0, 0, 0, 0, 0, 0, 0, 0 16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman We don't need to do too much setup. 16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman This code gets loaded at SETUPSEG:0. It wants to start 17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman executing the image that's loaded at SYSSEG:0 and 17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman whose entry point is SYSSEG:0. 17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmansetup_code: 17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* We expect to be contiguous in memory once loaded. The Linux image 17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * boot process requires that setup code is loaded separately from 17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * "non-real code". Since we don't need any information that's left 17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * in the prefix, it doesn't matter: we just have to ensure that 17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * %cs:0000 is where the start of the image *would* be. 18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ljmp $(SYSSEG-(PREFIXSIZE/16)), $run_gpxe 18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .org PREFIXSIZE 18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman We're now at the beginning of the kernel proper. 18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrun_gpxe: 18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Set up stack just below 0x7c00 */ 19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman xorw %ax, %ax 19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw %ax, %ss 19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw $0x7c00, %sp 19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Install gPXE */ 19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman call install 19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Set up real-mode stack */ 19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw %bx, %ss 19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman movw $_estack16, %sp 20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Jump to .text16 segment */ 20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pushw %ax 20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pushw $1f 20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lret 20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .section ".text16", "awx", @progbits 20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman1: 20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pushl $main 20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pushw %cs 20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman call prot_call 21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman popl %ecx /* discard */ 21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Uninstall gPXE */ 21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman call uninstall 21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Boot next device */ 21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int $0x18 217