wok-stable view gpxe/stuff/prefix.u @ rev 7674

Fixed linux. Need to make folder PWD/_pkg before adding bzImage to it. Also i'm force copying kernel config file now so we have the right config. It is copyed twice so its needed and doesn't hunt anything i think.
author Christopher Rogers <slaxemulator@gmail.com>
date Thu Dec 16 17:16:06 2010 +0000 (2010-12-16)
parents a9ff8c135e36
children
line source
1 --- gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S
2 +++ gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S
3 @@ -3,6 +3,7 @@
5 Authors: Gary Byers (gb@thinguin.org)
6 Marty Connor (mdc@thinguin.org)
7 + Pascal Bellard (pascal.bellard@slitaz.org)
9 This software may be used and distributed according to the terms
10 of the GNU Public License (GPL), incorporated herein by reference.
11 @@ -50,40 +51,351 @@
12 .arch i386
13 .org 0
14 .section ".prefix", "ax", @progbits
15 -/*
16 - This is a minimal boot sector. If anyone tries to execute it (e.g., if
17 - a .lilo file is dd'ed to a floppy), print an error message.
18 -*/
20 -bootsector:
21 - jmp $BOOTSEG, $1f /* reload cs:ip to match relocation addr */
22 -1:
23 - movw $0x2000, %di /* 0x2000 is arbitrary value >= length
24 - of bootsect + room for stack */
25 + call here
26 +here:
27 + pop %ax
28 + cmpw $0x103, %ax /* COM entry point is cs:0x100 */
29 + jne bootsector
30 +
31 +/* We need a real mode stack that won't be stomped on by Etherboot
32 + which starts at 0x20000. Choose something that's sufficiently high,
33 + but not in DOC territory. Note that we couldn't do this in a real
34 + .com program since stack variables are in the same segment as the
35 + code and data, but this isn't really a .com program, it just looks
36 + like one to make DOS load it into memory. It still has the 64kB
37 + limitation of .com files though. */
38 +#define STACK_SEG 0x7000
39 +#define STACK_SIZE 0x4000
40 + /* Set up temporary stack */
41 + movw $STACK_SEG, %ax
42 + movw %ax, %ss
43 + movw $STACK_SIZE, %sp
44 +
45 + /* Calculate segment address of image start */
46 + pushw %cs
47 + popw %ax
48 + addw $(0x100/16), %ax /* Adjust cs */
49 + pushw %ax
50 + jmp go_setup_code
51 +
52 +bootsector:
53 + jmp $BOOTSEG, $go /* reload cs:ip to match relocation addr */
54 +go:
55 + movw $0x2000-12, %di /* 0x2000 is arbitrary value >= length */
56 + /* of bootsect + room for stack + 12 for */
57 + /* saved disk parm block */
59 movw $BOOTSEG, %ax
60 movw %ax,%ds
61 movw %ax,%es
62 -
63 - cli
64 - movw %ax, %ss /* put stack at BOOTSEG:0x2000. */
65 + movw %ax,%ss /* put stack at initial position */
66 movw %di,%sp
67 - sti
69 - movw $why_end-why, %cx
70 - movw $why, %si
71 +/* Many BIOS's default disk parameter tables will not recognize multi-sector
72 + * reads beyond the maximum sector number specified in the default diskette
73 + * parameter tables - this may mean 7 sectors in some cases.
74 + *
75 + * Since single sector reads are slow and out of the question, we must take care
76 + * of this by creating new parameter tables (for the first disk) in RAM. We
77 + * will set the maximum sector count to 36 - the most we will encounter on an
78 + * ED 2.88. High doesn't hurt. Low does.
79 + *
80 + * Segments are as follows: ds=es=ss=cs - BOOTSEG
81 + */
82 +
83 + xorw %cx,%cx
84 + movw %cx,%es /* access segment 0 */
85 + movw $0x78, %bx /* 0:bx is parameter table address */
86 + pushw %ds /* save ds */
87 +/* 0:bx is parameter table address */
88 + ldsw %es:(%bx),%si /* loads ds and si */
89 +
90 + movw %ax,%es /* ax is BOOTSECT (loaded above) */
91 + movb $6, %cl /* copy 12 bytes */
92 + cld
93 + pushw %di /* keep a copy for later */
94 + rep
95 + movsw /* ds:si is source, es:di is dest */
96 + popw %di
97 +
98 + movb $36,%es:4(%di)
99 +
100 + movw %cx,%ds /* access segment 0 */
101 + xchgw %di,(%bx)
102 + movw %es,%si
103 + xchgw %si,2(%bx)
104 + popw %ds /* restore ds */
105 + movw %di, dpoff /* save old parameters */
106 + movw %si, dpseg /* to restore just before finishing */
107 + pushw %ds
108 + popw %es /* reload es */
109 +
110 +/* Note that es is already set up. Also cx is 0 from rep movsw above. */
111 +
112 + xorb %ah,%ah /* reset FDC */
113 + xorb %dl,%dl
114 + int $0x13
115 +
116 +/* Get disk drive parameters, specifically number of sectors/track.
117 + *
118 + * It seems that there is no BIOS call to get the number of sectors. Guess
119 + * 36 sectors if sector 36 can be read, 18 sectors if sector 18 can be read,
120 + * 15 if sector 15 can be read. Otherwise guess 9.
121 + */
123 - movw $0x0007, %bx /* page 0, attribute 7 (normal) */
124 - movb $0x0e, %ah /* write char, tty mode */
125 -prloop:
126 + movw $disksizes, %si /* table of sizes to try */
127 +
128 +probe_loop:
129 lodsb
130 + orb %al, %al
131 + je got_sectors /* if all else fails, try 9 */
132 + cbtw /* extend to word */
133 + movw %ax, sectors
134 + xchgw %cx,%ax /* cx = track and sector */
135 + xorw %dx,%dx /* drive 0, head 0 */
136 + movw $0x0200, %bx /* address after boot sector */
137 + /* (512 bytes from origin, es = cs) */
138 + movw $0x0201, %ax /* service 2, 1 sector */
139 + int $0x13
140 + jc probe_loop /* try next value */
141 +
142 +got_sectors:
143 + movw $msg1end-msg1, %cx
144 + movw $msg1, %si
145 + call print_str
146 +
147 +/* ok, we've written the Loading... message, now we want to load the system */
148 +
149 + movw $SYSSEG, %ax
150 + movw %ax,%es /* segment of SYSSEG<<4 */
151 + pushw %es
152 + call read_it
153 +
154 +/* This turns off the floppy drive motor, so that we enter the kernel in a
155 + * known state, and don't have to worry about it later.
156 + */
157 + movw $0x3f2, %dx
158 + xorb %al,%al
159 + outb %al,%dx
160 +
161 + call print_nl
162 + pop %es /* = SYSSEG */
163 +sigok:
164 +
165 +/* Restore original disk parameters */
166 + movw $0x78, %bx
167 + movw dpoff, %di
168 + movw dpseg, %si
169 + xorw %ax,%ax
170 + movw %ax,%ds
171 + movw %di,(%bx)
172 + movw %si,2(%bx)
173 +
174 + /* Everything now loaded. %es = SYSSEG, so %es:0000 points to
175 + * start of loaded image.
176 + */
177 +
178 + /* Jump to loaded copy */
179 + ljmp $SYSSEG, $run_etherboot
180 +
181 +endseg: .word SYSSEG + _load_size_pgh
182 + .section ".zinfo.fixup", "a" /* Compressor fixup information */
183 + .ascii "SUBW"
184 + .long endseg
185 + .long 16
186 + .long 0
187 + .previous
188 +
189 +/* This routine loads the system at address SYSSEG<<4, making sure no 64kB
190 + * boundaries are crossed. We try to load it as fast as possible, loading whole
191 + * tracks whenever we can.
192 + *
193 + * in: es - starting address segment (normally SYSSEG)
194 + */
195 +read_it:
196 + movw $0,sread /* read whole image incl boot sector */
197 + movw %es,%ax
198 + testw $0x0fff, %ax
199 +die: jne die /* es must be at 64kB boundary */
200 + xorw %bx,%bx /* bx is starting address within segment */
201 +rp_read:
202 + movw %es,%ax
203 + movw %bx,%dx
204 + movb $4, %cl
205 + shrw %cl,%dx /* bx is always divisible by 16 */
206 + addw %dx,%ax
207 + cmpw syssize, %ax /* have we loaded all yet? */
208 + jb ok1_read
209 + ret
210 +ok1_read:
211 + movw sectors, %ax
212 + subw sread, %ax
213 + movw %ax,%cx
214 + shlw $9, %cx /* 80186 opcode */
215 + addw %bx,%cx
216 + jnc ok2_read
217 + je ok2_read
218 + xorw %ax,%ax
219 + subw %bx,%ax
220 + shrw $9, %ax /* 80186 opcode */
221 +ok2_read:
222 + call read_track
223 + movw %ax,%cx
224 + addw sread, %ax
225 + cmpw sectors, %ax
226 + jne ok3_read
227 + movw $1, %ax
228 + subw head, %ax
229 + jne ok4_read
230 + incw track
231 +ok4_read:
232 + movw %ax, head
233 + xorw %ax,%ax
234 +ok3_read:
235 + movw %ax, sread
236 + shlw $9, %cx /* 80186 opcode */
237 + addw %cx,%bx
238 + jnc rp_read
239 + movw %es,%ax
240 + addb $0x10, %ah
241 + movw %ax,%es
242 + xorw %bx,%bx
243 + jmp rp_read
244 +
245 +read_track:
246 + pusha /* 80186 opcode */
247 + pushw %ax
248 + pushw %bx
249 + pushw %bp /* just in case the BIOS is buggy */
250 + movb $0x2e, %al /* 0x2e = . */
251 + call print_char
252 + popw %bp
253 + popw %bx
254 + popw %ax
255 +
256 + movw sread, %cx
257 + incw %cx
258 + movb track, %ch
259 + movw $0x0100, %dx
260 + andb head, %dh
261 + movb $2, %ah
262 +
263 + pushw %dx /* save for error dump */
264 + pushw %cx
265 + pushw %bx
266 + pushw %ax
267 +
268 + int $0x13
269 + jc bad_rt
270 + addw $8, %sp
271 + popa /* 80186 opcode */
272 + ret
273 +
274 +bad_rt: pushw %ax /* save error code */
275 + call print_all /* ah = error, al = read */
276 +
277 + xorb %ah,%ah
278 + xorb %dl,%dl
279 + int $0x13
280 +
281 + addw $10, %sp
282 + popa /* 80186 opcode */
283 + jmp read_track
284 +
285 +/* print_all is for debugging purposes. It will print out all of the registers.
286 + * The assumption is that this is called from a routine, with a stack frame like
287 + * dx
288 + * cx
289 + * bx
290 + * ax
291 + * error
292 + * ret <- sp
293 + */
294 +
295 +print_all:
296 + call print_nl /* nl for readability */
297 + /* print_nl update ah and bx */
298 + movw $5, %cx /* error code + 4 registers */
299 + movw %sp,%bp
300 +
301 +print_loop:
302 + pushw %cx /* save count left */
303 +
304 + cmpb $5, %cl
305 + jae no_reg /* see if register name is needed */
306 +
307 + movb $0x5+0x41-1, %al
308 + subb %cl,%al
309 + int $0x10
310 +
311 + movb $0x58, %al /* 'X' */
312 int $0x10
313 +
314 + movb $0x3A, %al /* ':' */
315 + int $0x10
316 +
317 +no_reg:
318 + addw $2, %bp /* next register */
319 + call print_hex /* print it */
320 + movb $0x20, %al /* print a space */
321 + int $0x10
322 + popw %cx
323 + loop print_loop
324 + /* nl for readability */
325 +print_nl:
326 + movb $0xd, %al /* CR */
327 + call print_char
328 + movb $0xa, %al /* LF */
329 + jmp print_char
330 +
331 +
332 +print_str:
333 +prloop:
334 + lodsb
335 + call print_char
336 loop prloop
337 -freeze: jmp freeze
338 + ret
340 -why: .ascii "This image cannot be loaded from a floppy disk.\r\n"
341 -why_end:
342 +/* print_hex prints the word pointed to by ss:bp in hexadecimal. */
344 +print_hex:
345 + movw (%bp),%dx /* load word into dx */
346 + movb $4, %cl
347 + call print_2digits
348 +print_2digits:
349 + call print_digit
350 +/* fall through */
351 +print_digit:
352 + rol %cl,%dx /* rotate to use lowest 4 bits */
353 + movb $0x0f, %al /* mask for nybble */
354 + andb %dl,%al
355 + addb $0x90, %al /* convert al to ascii hex */
356 + daa /* (four instructions) */
357 + adcb $0x40, %al
358 + daa
359 +print_char:
360 + movb $0x0e, %ah /* write char, tty mode */
361 + movw $0x0007, %bx /* page 0, attribute 7 (normal) */
362 + int $0x10
363 + ret
364 +
365 +sread: .word 0 /* sectors read of current track */
366 +head: .word 0 /* current head */
367 +track: .word 0 /* current track */
368 +
369 +sectors:
370 + .word 0
371 +
372 +dpseg: .word 0
373 +dpoff: .word 0
374 +
375 +disksizes:
376 + .byte 36,18,15,9,0
377 +
378 +msg1:
379 + .ascii "Loading ROM image"
380 +msg1end:
382 .org 497
383 setup_sects:
384 @@ -106,13 +418,6 @@
386 .org 512
388 - .section ".zinfo.fixup", "a" /* Compressor fixup information */
389 - .ascii "SUBW"
390 - .long syssize
391 - .long 16
392 - .long 0
393 - .previous
394 -
395 /*
396 We're now at the beginning of the second sector of the image -
397 where the setup code goes.
398 @@ -123,14 +428,18 @@
399 executing the Etherboot image that's loaded at SYSSEG:0 and
400 whose entry point is SYSSEG:0.
401 */
402 -setup_code:
403 +setup_code:
404 + pushw $(SYSSEG-(PREFIXSIZE/16))
405 /* Etherboot expects to be contiguous in memory once loaded.
406 * LILO doesn't do this, but since we don't need any
407 * information that's left in the prefix, it doesn't matter:
408 * we just have to ensure that %cs:0000 is where the start of
409 * the Etherboot image *would* be.
410 */
411 - ljmp $(SYSSEG-(PREFIXSIZE/16)), $run_etherboot
412 +go_setup_code:
413 + pushw $run_etherboot
414 + /* Calculated lcall to _start with %cs:0000 = image start */
415 + lret
418 .org PREFIXSIZE
419 @@ -140,6 +449,10 @@
420 run_etherboot:
421 call install
423 + /* Set up real-mode stack */
424 + movw %bx, %ss
425 + movw $_estack16, %sp
426 +
427 /* Jump to .text16 segment */
428 pushw %ax
429 pushw $1f