diff options
Diffstat (limited to 'contrib/syslinux/latest/gpxe/src/arch/i386/prefix/lkrnprefix.S')
-rw-r--r-- | contrib/syslinux/latest/gpxe/src/arch/i386/prefix/lkrnprefix.S | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/contrib/syslinux/latest/gpxe/src/arch/i386/prefix/lkrnprefix.S b/contrib/syslinux/latest/gpxe/src/arch/i386/prefix/lkrnprefix.S new file mode 100644 index 0000000..101d038 --- /dev/null +++ b/contrib/syslinux/latest/gpxe/src/arch/i386/prefix/lkrnprefix.S @@ -0,0 +1,216 @@ +/* + Copyright (C) 2000, Entity Cyber, Inc. + + Authors: Gary Byers (gb@thinguin.org) + Marty Connor (mdc@thinguin.org) + + This software may be used and distributed according to the terms + of the GNU Public License (GPL), incorporated herein by reference. + + Description: + + This is just a little bit of code and data that can get prepended + to a ROM image in order to allow bootloaders to load the result + as if it were a Linux kernel image. + + A real Linux kernel image consists of a one-sector boot loader + (to load the image from a floppy disk), followed a few sectors + of setup code, followed by the kernel code itself. There's + a table in the first sector (starting at offset 497) that indicates + how many sectors of setup code follow the first sector and which + contains some other parameters that aren't interesting in this + case. + + When a bootloader loads the sectors that comprise a kernel image, + it doesn't execute the code in the first sector (since that code + would try to load the image from a floppy disk.) The code in the + first sector below doesn't expect to get executed (and prints an + error message if it ever -is- executed.) + + We don't require much in the way of setup code. Historically, the + Linux kernel required at least 4 sectors of setup code. + Therefore, at least 4 sectors must be present even though we don't + use them. + +*/ + +FILE_LICENCE ( GPL_ANY ) + +#define SETUPSECS 4 /* Minimal nr of setup-sectors */ +#define PREFIXSIZE ((SETUPSECS+1)*512) +#define PREFIXPGH (PREFIXSIZE / 16 ) +#define BOOTSEG 0x07C0 /* original address of boot-sector */ +#define INITSEG 0x9000 /* we move boot here - out of the way */ +#define SETUPSEG 0x9020 /* setup starts here */ +#define SYSSEG 0x1000 /* system loaded at 0x10000 (65536). */ + + .text + .code16 + .arch i386 + .org 0 + .section ".prefix", "ax", @progbits +/* + This is a minimal boot sector. If anyone tries to execute it (e.g., if + a .lilo file is dd'ed to a floppy), print an error message. +*/ + +bootsector: + jmp $BOOTSEG, $1f /* reload cs:ip to match relocation addr */ +1: + movw $0x2000, %di /* 0x2000 is arbitrary value >= length + of bootsect + room for stack */ + + movw $BOOTSEG, %ax + movw %ax,%ds + movw %ax,%es + + cli + movw %ax, %ss /* put stack at BOOTSEG:0x2000. */ + movw %di,%sp + sti + + movw $why_end-why, %cx + movw $why, %si + + movw $0x0007, %bx /* page 0, attribute 7 (normal) */ + movb $0x0e, %ah /* write char, tty mode */ +prloop: + lodsb + int $0x10 + loop prloop +freeze: jmp freeze + +why: .ascii "This image cannot be loaded from a floppy disk.\r\n" +why_end: + + +/* + The following header is documented in the Linux source code at + Documentation/i386/boot.txt +*/ + .org 497 +setup_sects: + .byte SETUPSECS +root_flags: + .word 0 +syssize: + .long -PREFIXPGH + + .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ + .ascii "ADDL" + .long syssize + .long 16 + .long 0 + .previous + +ram_size: + .word 0 +vid_mode: + .word 0 +root_dev: + .word 0 +boot_flag: + .word 0xAA55 +jump: + /* Manually specify a two-byte jmp instruction here rather + * than leaving it up to the assembler. */ + .byte 0xeb + .byte setup_code - header +header: + .byte 'H', 'd', 'r', 'S' +version: + .word 0x0207 /* 2.07 */ +realmode_swtch: + .long 0 +start_sys: + .word 0 +kernel_version: + .word 0 +type_of_loader: + .byte 0 +loadflags: + .byte 0 +setup_move_size: + .word 0 +code32_start: + .long 0 +ramdisk_image: + .long 0 +ramdisk_size: + .long 0 +bootsect_kludge: + .long 0 +heap_end_ptr: + .word 0 +pad1: + .word 0 +cmd_line_ptr: + .long 0 +initrd_addr_max: + /* We don't use an initrd but some bootloaders (e.g. SYSLINUX) have + * been known to require this field. Set the value to 2 GB. This + * value is also used by the Linux kernel. */ + .long 0x7fffffff +kernel_alignment: + .long 0 +relocatable_kernel: + .byte 0 +pad2: + .byte 0, 0, 0 +cmdline_size: + .long 0 +hardware_subarch: + .long 0 +hardware_subarch_data: + .byte 0, 0, 0, 0, 0, 0, 0, 0 + +/* + We don't need to do too much setup. + + This code gets loaded at SETUPSEG:0. It wants to start + executing the image that's loaded at SYSSEG:0 and + whose entry point is SYSSEG:0. +*/ +setup_code: + /* We expect to be contiguous in memory once loaded. The Linux image + * boot process requires that setup code is loaded separately from + * "non-real code". Since we don't need any information that's left + * in the prefix, it doesn't matter: we just have to ensure that + * %cs:0000 is where the start of the image *would* be. + */ + ljmp $(SYSSEG-(PREFIXSIZE/16)), $run_gpxe + + + .org PREFIXSIZE +/* + We're now at the beginning of the kernel proper. + */ +run_gpxe: + /* Set up stack just below 0x7c00 */ + xorw %ax, %ax + movw %ax, %ss + movw $0x7c00, %sp + + /* Install gPXE */ + call install + + /* Set up real-mode stack */ + movw %bx, %ss + movw $_estack16, %sp + + /* Jump to .text16 segment */ + pushw %ax + pushw $1f + lret + .section ".text16", "awx", @progbits +1: + pushl $main + pushw %cs + call prot_call + popl %ecx /* discard */ + + /* Uninstall gPXE */ + call uninstall + + /* Boot next device */ + int $0x18 |