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
-/*
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
 FILE_LICENCE ( GPL_ANY )
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
 	.text
6
 	.text
48
-	.code16
49
 	.arch i386
7
 	.arch i386
50
-	.org	0
8
+	.code16
51
 	.section ".prefix", "ax", @progbits
9
 	.section ".prefix", "ax", @progbits
52
 	.globl	_lkrn_start
10
 	.globl	_lkrn_start
53
 _lkrn_start:
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
 	.word	0
35
 	.word	0
98
-syssize: 
99
-	.long	-PREFIXPGH
100
-
36
+syssize:
37
+	.long	0
101
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
38
 	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
102
-	.ascii	"ADDL"
39
+	.ascii	"ADPL"
103
 	.long	syssize
40
 	.long	syssize
104
 	.long	16
41
 	.long	16
105
 	.long	0
42
 	.long	0
106
 	.previous
43
 	.previous
107
-	
108
-ram_size: 
44
+ram_size:
109
 	.word	0
45
 	.word	0
110
-vid_mode: 
46
+vid_mode:
111
 	.word	0
47
 	.word	0
112
-root_dev: 
48
+root_dev:
113
 	.word	0
49
 	.word	0
114
-boot_flag: 
115
-	.word	0xAA55
50
+boot_flag:
51
+	.word	0xaa55
116
 jump:
52
 jump:
117
 	/* Manually specify a two-byte jmp instruction here rather
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
 header:
57
 header:
122
 	.byte	'H', 'd', 'r', 'S'
58
 	.byte	'H', 'd', 'r', 'S'
123
 version:
59
 version:
125
 realmode_swtch:
61
 realmode_swtch:
126
 	.long	0
62
 	.long	0
127
 start_sys:
63
 start_sys:
128
-	.word	0
64
+	.word	BZI_RM_SEGMENT
129
 kernel_version:
65
 kernel_version:
130
 	.word	version_string - 0x200
66
 	.word	version_string - 0x200
131
 type_of_loader:
67
 type_of_loader:
132
 	.byte	0
68
 	.byte	0
133
 loadflags:
69
 loadflags:
134
-	.byte	0
70
+	.byte	0x01 /* LOADED_HIGH */
135
 setup_move_size:
71
 setup_move_size:
136
 	.word	0
72
 	.word	0
137
 code32_start:
73
 code32_start:
144
 	.long	0
80
 	.long	0
145
 heap_end_ptr:
81
 heap_end_ptr:
146
 	.word	0
82
 	.word	0
147
-pad1:
148
-	.word	0
83
+ext_loader_ver:
84
+	.byte	0
85
+ext_loader_type:
86
+	.byte	0
149
 cmd_line_ptr:
87
 cmd_line_ptr:
150
 	.long	0
88
 	.long	0
151
 initrd_addr_max:
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
 kernel_alignment:
91
 kernel_alignment:
157
 	.long	0
92
 	.long	0
158
 relocatable_kernel:
93
 relocatable_kernel:
159
 	.byte	0
94
 	.byte	0
160
-pad2:
161
-	.byte	0, 0, 0
95
+min_alignment:
96
+	.byte	0
97
+xloadflags:
98
+	.word	0
162
 cmdline_size:
99
 cmdline_size:
163
 	.long	0x7ff
100
 	.long	0x7ff
164
 hardware_subarch:
101
 hardware_subarch:
169
 version_string:
106
 version_string:
170
 	.asciz	VERSION
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
 	/* Set up stack just below 0x7c00 and clear direction flag */
119
 	/* Set up stack just below 0x7c00 and clear direction flag */
195
 	xorw	%ax, %ax
120
 	xorw	%ax, %ax
196
 	movw	%ax, %ss
121
 	movw	%ax, %ss
198
 	cld
123
 	cld
199
 
124
 
200
 	/* Retrieve command-line pointer */
125
 	/* Retrieve command-line pointer */
201
-	movl	%ds:cmd_line_ptr, %edx
126
+	movl	cmd_line_ptr, %edx
202
 	testl	%edx, %edx
127
 	testl	%edx, %edx
203
 	jz	no_cmd_line
128
 	jz	no_cmd_line
204
 
129
 
240
 	jnz	1f
165
 	jnz	1f
241
 	orl	$0xffffffff, %ebp /* Allow arbitrary relocation if no initrd */
166
 	orl	$0xffffffff, %ebp /* Allow arbitrary relocation if no initrd */
242
 1:
167
 1:
243
-
244
 	/* Install iPXE */
168
 	/* Install iPXE */
245
 	call	alloc_basemem
169
 	call	alloc_basemem
246
 	xorl	%esi, %esi
170
 	xorl	%esi, %esi
282
 
206
 
283
 	/* Boot next device */
207
 	/* Boot next device */
284
 	int $0x18
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