summaryrefslogtreecommitdiffstats
path: root/contrib/syslinux-4.02/gpxe/src/arch/i386/prefix/lkrnprefix.S
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/syslinux-4.02/gpxe/src/arch/i386/prefix/lkrnprefix.S')
-rw-r--r--contrib/syslinux-4.02/gpxe/src/arch/i386/prefix/lkrnprefix.S216
1 files changed, 216 insertions, 0 deletions
diff --git a/contrib/syslinux-4.02/gpxe/src/arch/i386/prefix/lkrnprefix.S b/contrib/syslinux-4.02/gpxe/src/arch/i386/prefix/lkrnprefix.S
new file mode 100644
index 0000000..101d038
--- /dev/null
+++ b/contrib/syslinux-4.02/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