mirror of
https://github.com/ipxe/ipxe
synced 2025-12-07 18:00:28 +03:00
Access to the gpxe.org and etherboot.org domains and associated resources has been revoked by the registrant of the domain. Work around this problem by renaming project from gPXE to iPXE, and updating URLs to match. Also update README, LOG and COPYRIGHTS to remove obsolete information. Signed-off-by: Michael Brown <mcb30@ipxe.org>
217 lines
4.9 KiB
ArmAsm
217 lines
4.9 KiB
ArmAsm
/*
|
|
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_ipxe
|
|
|
|
|
|
.org PREFIXSIZE
|
|
/*
|
|
We're now at the beginning of the kernel proper.
|
|
*/
|
|
run_ipxe:
|
|
/* Set up stack just below 0x7c00 */
|
|
xorw %ax, %ax
|
|
movw %ax, %ss
|
|
movw $0x7c00, %sp
|
|
|
|
/* Install iPXE */
|
|
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 iPXE */
|
|
call uninstall
|
|
|
|
/* Boot next device */
|
|
int $0x18
|