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