|  | @@ -1,123 +1,59 @@
 | 
		
	
		
			
			| 1 |  | -/*
 | 
		
	
		
			
			| 2 |  | -	Copyright (C) 2000, Entity Cyber, Inc.
 | 
		
	
		
			
			| 3 |  | -
 | 
		
	
		
			
			| 4 |  | -	Authors: Gary Byers (gb@thinguin.org)
 | 
		
	
		
			
			| 5 |  | -		 Marty Connor (mdc@thinguin.org)
 | 
		
	
		
			
			| 6 |  | -
 | 
		
	
		
			
			| 7 |  | -	This software may be used and distributed according to the terms
 | 
		
	
		
			
			| 8 |  | -	of the GNU Public License (GPL), incorporated herein by reference.
 | 
		
	
		
			
			| 9 |  | -
 | 
		
	
		
			
			| 10 |  | -	Description:	
 | 
		
	
		
			
			| 11 |  | -
 | 
		
	
		
			
			| 12 |  | -	This is just a little bit of code and data that can get prepended
 | 
		
	
		
			
			| 13 |  | -	to a ROM image in order to allow bootloaders to load the result
 | 
		
	
		
			
			| 14 |  | -	as if it were a Linux kernel image.
 | 
		
	
		
			
			| 15 |  | -
 | 
		
	
		
			
			| 16 |  | -	A real Linux kernel image consists of a one-sector boot loader
 | 
		
	
		
			
			| 17 |  | -	(to load the image from a floppy disk), followed a few sectors
 | 
		
	
		
			
			| 18 |  | -	of setup code, followed by the kernel code itself.  There's
 | 
		
	
		
			
			| 19 |  | -	a table in the first sector (starting at offset 497) that indicates
 | 
		
	
		
			
			| 20 |  | -	how many sectors of setup code follow the first sector and which
 | 
		
	
		
			
			| 21 |  | -	contains some other parameters that aren't interesting in this
 | 
		
	
		
			
			| 22 |  | -	case.
 | 
		
	
		
			
			| 23 |  | -
 | 
		
	
		
			
			| 24 |  | -	When a bootloader loads the sectors that comprise a kernel image,
 | 
		
	
		
			
			| 25 |  | -	it doesn't execute the code in the first sector (since that code
 | 
		
	
		
			
			| 26 |  | -	would try to load the image from a floppy disk.)  The code in the
 | 
		
	
		
			
			| 27 |  | -	first sector below doesn't expect to get executed (and prints an
 | 
		
	
		
			
			| 28 |  | -	error message if it ever -is- executed.)
 | 
		
	
		
			
			| 29 |  | -
 | 
		
	
		
			
			| 30 |  | -	We don't require much in the way of setup code.  Historically, the
 | 
		
	
		
			
			| 31 |  | -	Linux kernel required at least 4 sectors of setup code.
 | 
		
	
		
			
			| 32 |  | -	Therefore, at least 4 sectors must be present even though we don't
 | 
		
	
		
			
			| 33 |  | -	use them.
 | 
		
	
		
			
			| 34 |  | -
 | 
		
	
		
			
			| 35 |  | -*/
 | 
		
	
		
			
			| 36 |  | -
 | 
		
	
		
			
			| 37 | 1 |  FILE_LICENCE ( GPL_ANY )
 | 
		
	
		
			
			| 38 | 2 |  
 | 
		
	
		
			
			| 39 |  | -#define	SETUPSECS 4		/* Minimal nr of setup-sectors */
 | 
		
	
		
			
			| 40 |  | -#define PREFIXSIZE ((SETUPSECS+1)*512)
 | 
		
	
		
			
			| 41 |  | -#define PREFIXPGH (PREFIXSIZE / 16 )
 | 
		
	
		
			
			| 42 |  | -#define	BOOTSEG  0x07C0		/* original address of boot-sector */
 | 
		
	
		
			
			| 43 |  | -#define	INITSEG  0x9000		/* we move boot here - out of the way */
 | 
		
	
		
			
			| 44 |  | -#define	SETUPSEG 0x9020		/* setup starts here */
 | 
		
	
		
			
			| 45 |  | -#define SYSSEG   0x1000		/* system loaded at 0x10000 (65536). */
 | 
		
	
		
			
			|  | 3 | +#define BZI_RM_SEGMENT 0x1000
 | 
		
	
		
			
			|  | 4 | +#define BZI_LOAD_HIGH_ADDR 0x100000
 | 
		
	
		
			
			| 46 | 5 |  
 | 
		
	
		
			
			| 47 | 6 |  	.text
 | 
		
	
		
			
			| 48 |  | -	.code16
 | 
		
	
		
			
			| 49 | 7 |  	.arch i386
 | 
		
	
		
			
			| 50 |  | -	.org	0
 | 
		
	
		
			
			|  | 8 | +	.code16
 | 
		
	
		
			
			| 51 | 9 |  	.section ".prefix", "ax", @progbits
 | 
		
	
		
			
			| 52 | 10 |  	.globl	_lkrn_start
 | 
		
	
		
			
			| 53 | 11 |  _lkrn_start:
 | 
		
	
		
			
			| 54 |  | -/* 
 | 
		
	
		
			
			| 55 |  | -	This is a minimal boot sector.	If anyone tries to execute it (e.g., if
 | 
		
	
		
			
			| 56 |  | -	a .lilo file is dd'ed to a floppy), print an error message. 
 | 
		
	
		
			
			| 57 |  | -*/
 | 
		
	
		
			
			| 58 |  | -
 | 
		
	
		
			
			| 59 |  | -bootsector: 
 | 
		
	
		
			
			| 60 |  | -	jmp	$BOOTSEG, $1f	/* reload cs:ip to match relocation addr */
 | 
		
	
		
			
			| 61 |  | -1:
 | 
		
	
		
			
			| 62 |  | -	movw	$0x2000, %di		/*  0x2000 is arbitrary value >= length
 | 
		
	
		
			
			| 63 |  | -					    of bootsect + room for stack */
 | 
		
	
		
			
			| 64 |  | -
 | 
		
	
		
			
			| 65 |  | -	movw	$BOOTSEG, %ax
 | 
		
	
		
			
			| 66 |  | -	movw	%ax,%ds
 | 
		
	
		
			
			| 67 |  | -	movw	%ax,%es
 | 
		
	
		
			
			| 68 |  | -
 | 
		
	
		
			
			| 69 |  | -	cli
 | 
		
	
		
			
			| 70 |  | -	movw	%ax, %ss		/* put stack at BOOTSEG:0x2000. */
 | 
		
	
		
			
			| 71 |  | -	movw	%di,%sp
 | 
		
	
		
			
			| 72 |  | -	sti
 | 
		
	
		
			
			| 73 |  | -
 | 
		
	
		
			
			| 74 |  | -	movw	$why_end-why, %cx
 | 
		
	
		
			
			| 75 |  | -	movw	$why, %si
 | 
		
	
		
			
			| 76 |  | -
 | 
		
	
		
			
			| 77 |  | -	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
 | 
		
	
		
			
			| 78 |  | -	movb	$0x0e, %ah		/* write char, tty mode */
 | 
		
	
		
			
			| 79 |  | -prloop: 
 | 
		
	
		
			
			| 80 |  | -	lodsb
 | 
		
	
		
			
			| 81 |  | -	int	$0x10
 | 
		
	
		
			
			| 82 |  | -	loop	prloop
 | 
		
	
		
			
			| 83 |  | -freeze: jmp	freeze
 | 
		
	
		
			
			| 84 |  | -
 | 
		
	
		
			
			| 85 |  | -why:	.ascii	"This image cannot be loaded from a floppy disk.\r\n"
 | 
		
	
		
			
			| 86 |  | -why_end: 
 | 
		
	
		
			
			| 87 | 12 |  
 | 
		
	
		
			
			|  | 13 | +/*****************************************************************************
 | 
		
	
		
			
			|  | 14 | + *
 | 
		
	
		
			
			|  | 15 | + * Kernel header
 | 
		
	
		
			
			|  | 16 | + *
 | 
		
	
		
			
			|  | 17 | + * We place our prefix (i.e. our .prefix and .text16.early sections)
 | 
		
	
		
			
			|  | 18 | + * within the bzImage real-mode portion which gets loaded at
 | 
		
	
		
			
			|  | 19 | + * 1000:0000, and our payload (i.e. everything else) within the
 | 
		
	
		
			
			|  | 20 | + * bzImage protected-mode portion which gets loaded at 0x100000
 | 
		
	
		
			
			|  | 21 | + * upwards.
 | 
		
	
		
			
			|  | 22 | + *
 | 
		
	
		
			
			|  | 23 | + */
 | 
		
	
		
			
			| 88 | 24 |  
 | 
		
	
		
			
			| 89 |  | -/*
 | 
		
	
		
			
			| 90 |  | -	The following header is documented in the Linux source code at
 | 
		
	
		
			
			| 91 |  | -	Documentation/x86/boot.txt
 | 
		
	
		
			
			| 92 |  | -*/
 | 
		
	
		
			
			| 93 |  | -	.org	497
 | 
		
	
		
			
			| 94 |  | -setup_sects: 
 | 
		
	
		
			
			| 95 |  | -	.byte	SETUPSECS
 | 
		
	
		
			
			| 96 |  | -root_flags: 
 | 
		
	
		
			
			|  | 25 | +	.org	0x1f1
 | 
		
	
		
			
			|  | 26 | +setup_sects:
 | 
		
	
		
			
			|  | 27 | +	.byte	-1 /* Allow for initial "boot sector" */
 | 
		
	
		
			
			|  | 28 | +	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
 | 
		
	
		
			
			|  | 29 | +	.ascii	"ADHL"
 | 
		
	
		
			
			|  | 30 | +	.long	setup_sects
 | 
		
	
		
			
			|  | 31 | +	.long	512
 | 
		
	
		
			
			|  | 32 | +	.long	0
 | 
		
	
		
			
			|  | 33 | +	.previous
 | 
		
	
		
			
			|  | 34 | +root_flags:
 | 
		
	
		
			
			| 97 | 35 |  	.word	0
 | 
		
	
		
			
			| 98 |  | -syssize: 
 | 
		
	
		
			
			| 99 |  | -	.long	-PREFIXPGH
 | 
		
	
		
			
			| 100 |  | -
 | 
		
	
		
			
			|  | 36 | +syssize:
 | 
		
	
		
			
			|  | 37 | +	.long	0
 | 
		
	
		
			
			| 101 | 38 |  	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
 | 
		
	
		
			
			| 102 |  | -	.ascii	"ADDL"
 | 
		
	
		
			
			|  | 39 | +	.ascii	"ADPL"
 | 
		
	
		
			
			| 103 | 40 |  	.long	syssize
 | 
		
	
		
			
			| 104 | 41 |  	.long	16
 | 
		
	
		
			
			| 105 | 42 |  	.long	0
 | 
		
	
		
			
			| 106 | 43 |  	.previous
 | 
		
	
		
			
			| 107 |  | -	
 | 
		
	
		
			
			| 108 |  | -ram_size: 
 | 
		
	
		
			
			|  | 44 | +ram_size:
 | 
		
	
		
			
			| 109 | 45 |  	.word	0
 | 
		
	
		
			
			| 110 |  | -vid_mode: 
 | 
		
	
		
			
			|  | 46 | +vid_mode:
 | 
		
	
		
			
			| 111 | 47 |  	.word	0
 | 
		
	
		
			
			| 112 |  | -root_dev: 
 | 
		
	
		
			
			|  | 48 | +root_dev:
 | 
		
	
		
			
			| 113 | 49 |  	.word	0
 | 
		
	
		
			
			| 114 |  | -boot_flag: 
 | 
		
	
		
			
			| 115 |  | -	.word	0xAA55
 | 
		
	
		
			
			|  | 50 | +boot_flag:
 | 
		
	
		
			
			|  | 51 | +	.word	0xaa55
 | 
		
	
		
			
			| 116 | 52 |  jump:
 | 
		
	
		
			
			| 117 | 53 |  	/* Manually specify a two-byte jmp instruction here rather
 | 
		
	
		
			
			| 118 |  | -	 * than leaving it up to the assembler. */
 | 
		
	
		
			
			| 119 |  | -	.byte	0xeb
 | 
		
	
		
			
			| 120 |  | -	.byte	setup_code - header
 | 
		
	
		
			
			|  | 54 | +	 * than leaving it up to the assembler.
 | 
		
	
		
			
			|  | 55 | +	 */
 | 
		
	
		
			
			|  | 56 | +	.byte	0xeb, ( setup - header )
 | 
		
	
		
			
			| 121 | 57 |  header:
 | 
		
	
		
			
			| 122 | 58 |  	.byte	'H', 'd', 'r', 'S'
 | 
		
	
		
			
			| 123 | 59 |  version:
 | 
		
	
	
		
			
			|  | @@ -125,13 +61,13 @@ version:
 | 
		
	
		
			
			| 125 | 61 |  realmode_swtch:
 | 
		
	
		
			
			| 126 | 62 |  	.long	0
 | 
		
	
		
			
			| 127 | 63 |  start_sys:
 | 
		
	
		
			
			| 128 |  | -	.word	0
 | 
		
	
		
			
			|  | 64 | +	.word	BZI_RM_SEGMENT
 | 
		
	
		
			
			| 129 | 65 |  kernel_version:
 | 
		
	
		
			
			| 130 | 66 |  	.word	version_string - 0x200
 | 
		
	
		
			
			| 131 | 67 |  type_of_loader:
 | 
		
	
		
			
			| 132 | 68 |  	.byte	0
 | 
		
	
		
			
			| 133 | 69 |  loadflags:
 | 
		
	
		
			
			| 134 |  | -	.byte	0
 | 
		
	
		
			
			|  | 70 | +	.byte	0x01 /* LOADED_HIGH */
 | 
		
	
		
			
			| 135 | 71 |  setup_move_size:
 | 
		
	
		
			
			| 136 | 72 |  	.word	0
 | 
		
	
		
			
			| 137 | 73 |  code32_start:
 | 
		
	
	
		
			
			|  | @@ -144,21 +80,22 @@ bootsect_kludge:
 | 
		
	
		
			
			| 144 | 80 |  	.long	0
 | 
		
	
		
			
			| 145 | 81 |  heap_end_ptr:
 | 
		
	
		
			
			| 146 | 82 |  	.word	0
 | 
		
	
		
			
			| 147 |  | -pad1:
 | 
		
	
		
			
			| 148 |  | -	.word	0
 | 
		
	
		
			
			|  | 83 | +ext_loader_ver:
 | 
		
	
		
			
			|  | 84 | +	.byte	0
 | 
		
	
		
			
			|  | 85 | +ext_loader_type:
 | 
		
	
		
			
			|  | 86 | +	.byte	0
 | 
		
	
		
			
			| 149 | 87 |  cmd_line_ptr:
 | 
		
	
		
			
			| 150 | 88 |  	.long	0
 | 
		
	
		
			
			| 151 | 89 |  initrd_addr_max:
 | 
		
	
		
			
			| 152 |  | -	/* We don't use an initrd but some bootloaders (e.g. SYSLINUX) have
 | 
		
	
		
			
			| 153 |  | -	 * been known to require this field.  Set the value to 2 GB.  This
 | 
		
	
		
			
			| 154 |  | -	 * value is also used by the Linux kernel. */
 | 
		
	
		
			
			| 155 |  | -	.long	0x7fffffff
 | 
		
	
		
			
			|  | 90 | +	.long	0xffffffff
 | 
		
	
		
			
			| 156 | 91 |  kernel_alignment:
 | 
		
	
		
			
			| 157 | 92 |  	.long	0
 | 
		
	
		
			
			| 158 | 93 |  relocatable_kernel:
 | 
		
	
		
			
			| 159 | 94 |  	.byte	0
 | 
		
	
		
			
			| 160 |  | -pad2:
 | 
		
	
		
			
			| 161 |  | -	.byte	0, 0, 0
 | 
		
	
		
			
			|  | 95 | +min_alignment:
 | 
		
	
		
			
			|  | 96 | +	.byte	0
 | 
		
	
		
			
			|  | 97 | +xloadflags:
 | 
		
	
		
			
			|  | 98 | +	.word	0
 | 
		
	
		
			
			| 162 | 99 |  cmdline_size:
 | 
		
	
		
			
			| 163 | 100 |  	.long	0x7ff
 | 
		
	
		
			
			| 164 | 101 |  hardware_subarch:
 | 
		
	
	
		
			
			|  | @@ -169,28 +106,16 @@ hardware_subarch_data:
 | 
		
	
		
			
			| 169 | 106 |  version_string:
 | 
		
	
		
			
			| 170 | 107 |  	.asciz	VERSION
 | 
		
	
		
			
			| 171 | 108 |  
 | 
		
	
		
			
			| 172 |  | -/*
 | 
		
	
		
			
			| 173 |  | -	We don't need to do too much setup.
 | 
		
	
		
			
			| 174 |  | -
 | 
		
	
		
			
			| 175 |  | -	This code gets loaded at SETUPSEG:0.  It wants to start
 | 
		
	
		
			
			| 176 |  | -	executing the image that's loaded at SYSSEG:0 and
 | 
		
	
		
			
			| 177 |  | -	whose entry point is SYSSEG:0.
 | 
		
	
		
			
			| 178 |  | -*/
 | 
		
	
		
			
			| 179 |  | -setup_code:
 | 
		
	
		
			
			| 180 |  | -	/* We expect to be contiguous in memory once loaded.  The Linux image
 | 
		
	
		
			
			| 181 |  | -	 * boot process requires that setup code is loaded separately from
 | 
		
	
		
			
			| 182 |  | -	 * "non-real code".  Since we don't need any information that's left
 | 
		
	
		
			
			| 183 |  | -	 * in the prefix, it doesn't matter: we just have to ensure that
 | 
		
	
		
			
			| 184 |  | -	 * %cs:0000 is where the start of the image *would* be.
 | 
		
	
		
			
			| 185 |  | -	 */
 | 
		
	
		
			
			| 186 |  | -	ljmp	$(SYSSEG-(PREFIXSIZE/16)), $run_ipxe
 | 
		
	
		
			
			| 187 |  | -
 | 
		
	
		
			
			| 188 |  | -
 | 
		
	
		
			
			| 189 |  | -	.org	PREFIXSIZE
 | 
		
	
		
			
			| 190 |  | -/*
 | 
		
	
		
			
			| 191 |  | -	We're now at the beginning of the kernel proper.
 | 
		
	
		
			
			|  | 109 | +/*****************************************************************************
 | 
		
	
		
			
			|  | 110 | + *
 | 
		
	
		
			
			|  | 111 | + * Setup code
 | 
		
	
		
			
			|  | 112 | + *
 | 
		
	
		
			
			| 192 | 113 |   */
 | 
		
	
		
			
			| 193 |  | -run_ipxe:
 | 
		
	
		
			
			|  | 114 | +
 | 
		
	
		
			
			|  | 115 | +setup:
 | 
		
	
		
			
			|  | 116 | +	/* Fix up code segment */
 | 
		
	
		
			
			|  | 117 | +	ljmp	$BZI_RM_SEGMENT, $1f
 | 
		
	
		
			
			|  | 118 | +1:
 | 
		
	
		
			
			| 194 | 119 |  	/* Set up stack just below 0x7c00 and clear direction flag */
 | 
		
	
		
			
			| 195 | 120 |  	xorw	%ax, %ax
 | 
		
	
		
			
			| 196 | 121 |  	movw	%ax, %ss
 | 
		
	
	
		
			
			|  | @@ -198,7 +123,7 @@ run_ipxe:
 | 
		
	
		
			
			| 198 | 123 |  	cld
 | 
		
	
		
			
			| 199 | 124 |  
 | 
		
	
		
			
			| 200 | 125 |  	/* Retrieve command-line pointer */
 | 
		
	
		
			
			| 201 |  | -	movl	%ds:cmd_line_ptr, %edx
 | 
		
	
		
			
			|  | 126 | +	movl	cmd_line_ptr, %edx
 | 
		
	
		
			
			| 202 | 127 |  	testl	%edx, %edx
 | 
		
	
		
			
			| 203 | 128 |  	jz	no_cmd_line
 | 
		
	
		
			
			| 204 | 129 |  
 | 
		
	
	
		
			
			|  | @@ -240,7 +165,6 @@ no_cmd_line:
 | 
		
	
		
			
			| 240 | 165 |  	jnz	1f
 | 
		
	
		
			
			| 241 | 166 |  	orl	$0xffffffff, %ebp /* Allow arbitrary relocation if no initrd */
 | 
		
	
		
			
			| 242 | 167 |  1:
 | 
		
	
		
			
			| 243 |  | -
 | 
		
	
		
			
			| 244 | 168 |  	/* Install iPXE */
 | 
		
	
		
			
			| 245 | 169 |  	call	alloc_basemem
 | 
		
	
		
			
			| 246 | 170 |  	xorl	%esi, %esi
 | 
		
	
	
		
			
			|  | @@ -282,3 +206,30 @@ no_cmd_line:
 | 
		
	
		
			
			| 282 | 206 |  
 | 
		
	
		
			
			| 283 | 207 |  	/* Boot next device */
 | 
		
	
		
			
			| 284 | 208 |  	int $0x18
 | 
		
	
		
			
			|  | 209 | +
 | 
		
	
		
			
			|  | 210 | +/*****************************************************************************
 | 
		
	
		
			
			|  | 211 | + *
 | 
		
	
		
			
			|  | 212 | + * Open payload (called by libprefix)
 | 
		
	
		
			
			|  | 213 | + *
 | 
		
	
		
			
			|  | 214 | + * Parameters:
 | 
		
	
		
			
			|  | 215 | + *   %ds:0000 : Prefix
 | 
		
	
		
			
			|  | 216 | + *   %esi : Buffer for copy of image source (or zero if no buffer available)
 | 
		
	
		
			
			|  | 217 | + *   %ecx : Expected offset within buffer of first payload block
 | 
		
	
		
			
			|  | 218 | + * Returns:
 | 
		
	
		
			
			|  | 219 | + *   %esi : Valid image source address (buffered or unbuffered)
 | 
		
	
		
			
			|  | 220 | + *   %ecx : Actual offset within buffer of first payload block
 | 
		
	
		
			
			|  | 221 | + *   CF set on error
 | 
		
	
		
			
			|  | 222 | + */
 | 
		
	
		
			
			|  | 223 | +
 | 
		
	
		
			
			|  | 224 | +	.section ".text16.early", "awx", @progbits
 | 
		
	
		
			
			|  | 225 | +	.globl	open_payload
 | 
		
	
		
			
			|  | 226 | +open_payload:
 | 
		
	
		
			
			|  | 227 | +
 | 
		
	
		
			
			|  | 228 | +	/* Our payload will always end up at BZI_LOAD_HIGH_ADDR */
 | 
		
	
		
			
			|  | 229 | +	movl	$BZI_LOAD_HIGH_ADDR, %esi
 | 
		
	
		
			
			|  | 230 | +	xorl	%ecx, %ecx
 | 
		
	
		
			
			|  | 231 | +	lret
 | 
		
	
		
			
			|  | 232 | +
 | 
		
	
		
			
			|  | 233 | +	/* Payload must be aligned to a whole number of setup sectors */
 | 
		
	
		
			
			|  | 234 | +	.globl	_payload_align
 | 
		
	
		
			
			|  | 235 | +	.equ	_payload_align, 512
 |