Browse Source

[lkrnprefix] Function as a bzImage kernel

The .lkrn prefix currently provides a zImage kernel with unused setup
sectors and the whole iPXE binary placed within the "protected mode
kernel" portion of the zImage.

The work carried out years ago to create the .mrom format provides a
mechanism allowing the iPXE binary to be split into a small real-mode
header and a larger payload.  This neatly matches the way that a
bzImage is loaded: the "setup sectors" can contain the header and the
"protected mode kernel" can contain the payload.

This removes the size restrictions on an iPXE .lkrn image (and hence
on derived image formats such as .iso).

Also remove obsolete copyright information, since none of the original
code or functionality now remains.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 10 years ago
parent
commit
a8d1b50d8b
1 changed files with 83 additions and 132 deletions
  1. 83
    132
      src/arch/i386/prefix/lkrnprefix.S

+ 83
- 132
src/arch/i386/prefix/lkrnprefix.S View File

@@ -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

Loading…
Cancel
Save