wok-next view linux/stuff/linux-header.u @ rev 16392
dbus: ensure /var/run exists...
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Tue Apr 15 14:04:51 2014 +0000 (2014-04-15) |
parents | 667706522605 |
children | 98da7130169f |
line source
1 --- linux-3.2.14/arch/x86/boot/header.S
2 +++ linux-3.2.14/arch/x86/boot/header.S
3 @@ -7,12 +7,14 @@
4 * modified by more people than can be counted
5 *
6 * Rewritten as a common file by H. Peter Anvin (Apr 2007)
7 + * Rewritten Pascal Bellard (Nov 2009)
8 *
9 * BIG FAT NOTE: We're in real mode using 64k segments. Therefore segment
10 * addresses must be multiplied by 16 to obtain their respective linear
11 * addresses. To avoid confusion, linear addresses are written using leading
12 * hex while segment addresses are written as segment:offset.
13 *
14 + * Assume protocol 2.00+ (kernel >= 1.3.73)
15 */
17 #include <asm/segment.h>
18 @@ -27,6 +29,8 @@
20 BOOTSEG = 0x07C0 /* original address of boot-sector */
21 SYSSEG = 0x1000 /* historical load address >> 4 */
22 +INITSEG = 0x9000 /* boot address >> 4 */
23 +SETUPSEG = 0x9020 /* setup address >> 4 */
25 #ifndef SVGA_MODE
26 #define SVGA_MODE ASK_VGA
27 @@ -40,53 +44,480 @@
28 #define ROOT_RDONLY 1
29 #endif
31 +setup_sects = 497
32 +syssize = 500
33 +cmd_line_ptr = 0x228
34 +
35 +/* some extra features */
36 +#define EXE_SUPPORT real mode dos .exe file support (no himem.sys)
37 +#define CMDLINE kernel >= 2.4
38 +#define OLDCMDLINE kernel < 2.4
39 +#define HELP display version for ? argument
40 +#define MORETHAN16M up to 4Gb RAM, not 16Mb
41 +#define KEYBOARDLESS_SUPPORT scan floppy swap each 5 seconds
42 +#define FULL_ZIMAGE Up to 512K system zImage
43 +
44 +/* some limitations to reduce code size */
45 +//#define FLOPPY_1440K_ONLY 1.44M floppies support only
46 +
47 .code16
48 .section ".bstext", "ax"
50 .global bootsect_start
51 bootsect_start:
53 - # Normalize the start address
54 - ljmp $BOOTSEG, $start2
55 +#ifdef EXE_SUPPORT
56 +#define CODESZ 0x8000
57 +#define EXEADRS(x) x+0xE0
58 +stacktop = 0x9E00 # in 0x8000 .. 0xA000
59 + decw %bp // Magic number: MZ
60 + popw %dx
61 + jmp fdstart // Bytes on last page of file
62 + .word (CODESZ+511)/512 // Pages in file
63 + .word 0 // Relocations
64 + .word 2 // Size of header in paragraphs
65 + .word 4096 // Minimum extra paragraphs needed
66 + .word -1 // Maximum extra paragraphs needed
67 + .word (CODESZ+15)/16 // Initial (relative) SS value
68 + .word stacktop // Initial SP value
69 + .word 0 // Checksum
70 + .word EXEADRS(comstart) // Initial IP value
71 + .word 0xFFF0 // Initial (relative) CS value
72 +// .word 0x001C // File address of relocation table
73 +// .word 0,0,0 // Overlay number
74 +swap_floppy:
75 + .ascii "Next!"
76 + .byte 7,13,0 # swap detection needs 13, 0
77 +#ifdef OLDCMDLINE
78 + .word 0xA33F
79 + .word stacktop
80 +#endif
81 +fdstart:
82 + pushw %dx
83 +#endif
85 -start2:
86 - movw %cs, %ax
87 - movw %ax, %ds
88 - movw %ax, %es
89 - movw %ax, %ss
90 - xorw %sp, %sp
91 - sti
92 - cld
93 +#ifdef FULL_ZIMAGE
94 +#define LOADSEG 0x8800 // Up to 512K zImage
95 +#else
96 +#define LOADSEG 0x8000 // 0x1000 multiple, up to 480K zImage
97 +#endif
98 +#define LOADSZ 0x8000
100 - movw $bugger_off_msg, %si
101 +oldstart:
102 + cld # assume nothing
103 +stacktop = 0x9E00 # in 0x8000 .. 0xA000
104 +zeroed = 48+12 # gdt + zeroed registers
105 + movw $stacktop-12-zeroed, %di # stacktop is an arbitrary value >=
106 + # length of bootsect + length of
107 + # setup + room for stack;
108 + # 12 is disk parm size.
109 + pushw $INITSEG
110 + popw %ss # %ss contain INITSEG
111 + movw %di, %sp # put stack at INITSEG:stacktop-...
112 +
113 +# Many BIOS's default disk parameter tables will not recognize
114 +# multi-sector reads beyond the maximum sector number specified
115 +# in the default diskette parameter tables - this may mean 7
116 +# sectors in some cases.
117 +#
118 +# Since single sector reads are slow and out of the question,
119 +# we must take care of this by creating new parameter tables
120 +# (for the first disk) in RAM. We can set the maximum sector
121 +# count to 36 - the most we will encounter on an ED 2.88.
122 +#
123 +# High doesn't hurt. Low does. Let's use the max: 63
124 +
125 + pushw %ss
126 + popw %es # %es = %ss = INITSEG
127 + xorw %ax, %ax # %ax = 0
128 +#ifdef EXE_SUPPORT
129 + cwd # floppy = head = 0
130 +#endif
131 + movw $zeroed/2, %cx # clear gdt + offset, %ds, limits
132 + rep # don't worry about cld
133 + stosw # already done above
134 + popw %bx # offset = 0
135 + popw %ds # %ds = 0
136 + popw %fs # %fs = 0
137 +
138 + movb setup_sects+0x7C00, %al # read bootsector + setup (%ds = 0)
139 + incw %ax
140 +
141 + ldsw 0x78(%bx), %si # %ds:%bx+0x78 is parameter table address
142 + pushw %es
143 + pushw %di
144 + movb $6, %cl # copy 12 bytes
145 + rep # don't worry about cld
146 + movsw # already done above
147 + pushw %ss
148 + popw %ds # now %ds = %es = %ss = INITSEG
149 + popl %fs:0x78(%bx) # update parameter table address
150 + movb $63, 0x4-12(%di) # patch sector count, %di = stacktop
151 + cli
152 +
153 + xchg %ax, %di # sector count
154 + popw %ax # limits = 0
155 + incw %cx # cylinder 0, sector 1, clear Z
156 + call read_first_sectors # read setup
157 +loadsys:
158 + movw $0x200,%si
159 +type_of_loader = 0x10
160 +loadflags = 0x11
161 +heap_end_ptr = 0x24
162 + orw $0x8020, type_of_loader(%si) # loader type = 0x20 = bootsect-loader
163 + movb $(stacktop-0x300)/256, heap_end_ptr+1(%si)
164 + call puts_version # show which kernel we are loading
165 +
166 +# This routine loads the system at address LOADSEG, making sure
167 +# no 64kB boundaries are crossed. We try to load it as fast as
168 +# possible, loading whole tracks whenever we can.
169 +
170 +ramdisk_image = 0x0218
171 +ramdisk_size = 0x021C
172 +bootsect_src_limit = 16
173 +bootsect_dst_limit = 24
174 +bootsect_src_base = 18
175 +bootsect_dst_base = 26 # bits 0..23
176 +bootsect_dst_base_hi = 31 # bits 24..31
177 + popw %bx # clear %bx
178 + movw %sp, %si # for bootsect_gdt
179 +init_gdt:
180 + decw bootsect_src_limit(%bx,%si) # max 64Kb
181 +#if LOADSEG % 0x1000 == 0
182 + movw $0x9300+(LOADSEG/0x1000), bootsect_src_base+2(%bx,%si)
183 +#else
184 + movl $0x93000000+(LOADSEG*0x10), bootsect_src_base(%bx,%si)
185 +#endif
186 + xorb $bootsect_dst_limit-bootsect_src_limit, %bl
187 + jne init_gdt
188 +code32_start = 0x214
189 +#ifdef MORETHAN16M
190 + movb code32_start+3, %al # destination = 0x00100000 or 0x00010000
191 + movb %al, bootsect_dst_base_hi(%si) # load high (> 16M) ?
192 +#endif
193 + movw code32_start+1, %ax # destination = 0x00100000 or 0x00010000
194 + movl syssize, %ebx
195 + decl %ebx
196 + shrl $5, %ebx
197 + incl %ebx
198 +syslp:
199 + movw %ax, bootsect_dst_base+1(%si)
200 + movw $LOADSZ/512, %di # size in sectors
201 + subl $LOADSZ/512, %ebx
202 + pushf
203 + jnc not_last
204 + addw %bx, %di
205 +not_last:
206 + pushw %ax
207 + pushw %si
208 + pushw %bx
209 + xorw %bx,%bx
210 + pushw $LOADSEG
211 + popw %es
212 +patchcall:
213 + call read_sectors # update %bp
214 + popw %bx
215 + popw %si
216 + movw $LOADSZ/2, %cx # word count
217 + movb $0x87, %ah
218 + pushw %ss
219 + popw %es # restore es
220 + int $0x15 # max 16M, maybe more...
221 + popw %ax
222 + addw $LOADSZ/256, %ax # next dest
223 +#ifdef MORETHAN16M
224 + adcb %cl, bootsect_dst_base_hi(%si) # breaks 16M limit ?
225 +#endif
226 + popf
227 + ja syslp
229 -msg_loop:
230 - lodsb
231 - andb %al, %al
232 - jz bs_die
233 - movb $0xe, %ah
234 - movw $7, %bx
235 - int $0x10
236 - jmp msg_loop
237 -
238 -bs_die:
239 - # Allow the user to press a key, then reboot
240 - xorw %ax, %ax
241 +# This procedure turns off the floppy drive motor, so
242 +# that we enter the kernel in a known state, and
243 +# don't have to worry about it later.
244 +
245 +kill_motor:
246 + xchgw %ax, %di # reset FDC (%di < 128)
247 + int $0x13
248 +
249 +# After that (everything loaded), we jump to the setup-routine
250 +# loaded directly after the bootblock:
251 +# Segments are as follows: %ds = %ss = INITSEG
252 +
253 + ljmp $SETUPSEG, $0
254 +
255 +# read_sectors reads %di sectors into %es:0 buffer.
256 +# %es:0 is updated to the next memory location.
257 +# First, sectors are read sector by sector until
258 +# sector per track count is known. Then they are
259 +# read track by track.
260 +# Assume no error on first track.
261 +
262 +#define FLOPPY_CYLINDERS 80 /* 80 cylinders minimum */
263 +#define FLOPPY_HEADS 2 /* 2 heads minimum */
264 +#define FLOPPY_SECTORS 18 /* 18 sectors minimum */
265 +
266 +check_limits:
267 +#ifndef FLOPPY_1440K_ONLY
268 + popw %dx
269 + cmpb $FLOPPY_SECTORS+1, %cl # 18 sectors minimum
270 + jb check_head
271 + cmpb %al, %cl # max sector known ?
272 + ja next_head # no -> store it
273 +check_head:
274 + cmpb $FLOPPY_HEADS, %dh # 2 heads minimum
275 + jb check_cylinder
276 + cmpb %ah, %dh # max head known ?
277 + ja next_cylinder # no -> store it
278 +check_cylinder:
279 +#endif
280 + pushaw
281 +#ifndef FLOPPY_1440K_ONLY
282 + cbw # %ah = 0
283 +#endif
284 + int $0x13 # reset controler
285 + stc
286 + call putcdot # print '-'
287 +read_sectorslp:
288 + popaw
289 +bdendlp:
290 + pushw %dx # some bios break dx...
291 +#ifndef FLOPPY_1440K_ONLY
292 + pushw %ax # limits
293 + subb %cl, %al # sectors remaining in track
294 + ja tolastsect
295 + movb $1, %al # 1 sector mini
296 +tolastsect:
297 +#else
298 + mov $FLOPPY_SECTORS+1, %al
299 + subb %cl, %al # sectors remaining in track
300 +#endif
301 + cbw
302 + cmpw %di, %ax
303 + jb more1trk
304 + movw %di, %ax # sectors to read
305 +more1trk:
306 + pushw %ax # save context
307 + movb $2, %ah # cmd: read chs
308 + int $0x13
309 +#ifndef FLOPPY_1440K_ONLY
310 + popw %dx # save %ax
311 + popw %ax # limits
312 +#else
313 + popw %ax # restore context
314 + popw %dx
315 +#endif
316 + jc check_limits
317 +#ifndef FLOPPY_1440K_ONLY
318 + xchgw %ax, %bp
319 + addw %dx,%cx # next sector
320 + movw %cx, %gs
321 + addb %dl,%bh
322 + addb %dl,%bh # next location
323 + subw %dx,%di # update sector counter
324 + popw %dx
325 + jz putcdot
326 +#else
327 + addw %ax,%cx # next sector
328 + movw %cx, %gs
329 + addb %al,%bh
330 + addb %al,%bh # next location
331 + subw %ax,%di # update sector counter
332 + jz putcdot
333 +#endif
334 +read_sectors:
335 + movw %gs, %cx
336 +#ifndef FLOPPY_1440K_ONLY
337 +# al is last sector+1
338 +# ah is last cylinder+1
339 + xchgw %ax, %bp
340 +#endif
341 +#ifndef FLOPPY_1440K_ONLY
342 + cmpb %al,%cl # reach sector limit ?
343 + jne bdendlp
344 +next_head:
345 + movb %cl,%al
346 +#else
347 + cmpb $FLOPPY_SECTORS+1,%cl # reach sector limit ?
348 + jne bdendlp
349 +#endif
350 + incb %dh # next head
351 + movb $1,%cl # first sector
352 +#ifndef FLOPPY_1440K_ONLY
353 + cmpb %ah, %dh # reach head limit ?
354 + jne bdendlp
355 +next_cylinder:
356 + movb %dh,%ah
357 +#else
358 + cmpb %cl,%dh # reach head limit ?
359 + je bdendlp
360 +#endif
361 +# NOTE : support 256 cylinders max
362 + incb %ch # next cylinder
363 +read_first_sectors:
364 + cmpb $FLOPPY_CYLINDERS,%ch # reach cylinder limit ?
365 + movb $0,%dh # first head
366 + jne bdendlp
367 +next_floppy:
368 + movb $0,%ch # first cylinder
369 + pushaw
370 + movw $swap_floppy,%si
371 +#ifdef KEYBOARDLESS_SUPPORT
372 + pushw %bx
373 + call puts
374 + popw %bx
375 +waitfloppy:
376 + call wait
377 + jne waitfloppydone
378 + pushw %dx # some bios break dx...
379 + cbw
380 + int $0x13 # reset FDC
381 + movw $0x201,%ax
382 + int $0x13 # read first sector
383 + popw %dx
384 + rclb $1,%ah # floppy changed 06=>0D no error 00
385 + cmpb -2(%si), %ah # 0D then 00
386 + jne waitfloppy # no => try again
387 + incw %si
388 + decw %ax # was 0001 ?
389 + jne waitfloppy
390 +waitfloppydone:
391 +#else
392 + call puts
393 + cbw # %ah = 0, get keyboard character
394 int $0x16
395 - int $0x19
396 +#endif
397 + jmp read_sectorslp
398 +
399 +#ifdef EXE_SUPPORT
400 +read_sectors_dos:
401 + pushw %es
402 + popw %ds
403 + movb $0x3F, %ah // read
404 + cwd // write to %ds:%dx, not %es:%bx
405 + movw %di, %cx
406 + shlw $9, %cx // byte count
407 + movw %bp, %bx
408 + int $0x21
409 + pushw %ss
410 + popw %ds
411 +#endif
413 - # int 0x19 should never return. In case it does anyway,
414 - # invoke the BIOS reset code...
415 - ljmp $0xf000,$0xfff0
416 -
417 - .section ".bsdata", "a"
418 -bugger_off_msg:
419 - .ascii "Direct booting from floppy is no longer supported.\r\n"
420 - .ascii "Please use a boot loader program instead.\r\n"
421 - .ascii "\n"
422 - .ascii "Remove disk and press any key to reboot . . .\r\n"
423 - .byte 0
424 +putcdot:
425 + movb $'.'+3, %al // . = success, - = failure
426 +putclf:
427 + sbbb $3, %al
428 +putc:
429 + movb $0xe, %ah
430 + movw $7, %bx # one dot each 64k
431 + int $0x10
432 + cmp $0xd, %al # CR ?
433 + je putclf
434 + ret
435 +
436 +#ifdef KEYBOARDLESS_SUPPORT
437 +clock = 0x46C
438 +wait:
439 +wait4key:
440 + movw $clock, %di
441 +#define DELAY 5
442 + movb $257-(DELAY*182)/10, %fs:(%di)
443 +waitkbd:
444 + movw $0x10D, %ax # test keyboard, timeout => CR
445 + cmpb %fs:(%di),%ah
446 + je waitdone
447 + int $0x16
448 + jz waitkbd
449 + cbw
450 + int $0x16 # eat char
451 + movw %di, %fs # disable timeout
452 + incw %di # clear Z
453 +waitdone:
454 + ret
455 +#endif
457 +#ifdef EXE_SUPPORT
458 +comstart:
459 + cld # assume nothing
460 + pushw $INITSEG
461 + popw %es
462 + pushw %es
463 + popw %ss
464 +#ifdef CMDLINE
465 + movw %sp, %di
466 + movw $0x80, %si
467 + lodsb
468 + cbw
469 + xchgw %ax, %cx
470 + rep
471 + movsb
472 + movb $(48+2)/2, %cl
473 + xorw %bx, %bx
474 +clearstacklp:
475 + pushw %bx
476 + loop clearstacklp
477 +# ifdef HELP
478 + cmpb $'?', -1(%si)
479 + movw $EXEADRS(0x200), %si
480 + movw setup_sects-0x200(%si), %di // bits 0..6
481 + je puts_version
482 + smsww %ax
483 + andb $1, %al
484 + jne puts_version // real mode only...
485 +# endif
486 +#else
487 + movw $(48+2)/2, %cx
488 + xorw %bx, %bx
489 +clearstacklp:
490 + pushw %bx
491 + loop clearstacklp
492 +#endif
493 +#if !defined(CMDLINE) || !defined(HELP)
494 + movw EXEADRS(setup_sects), %di // bits 0..6
495 + movb $0, %al // access = RO
496 +#endif
497 + movw 0x2C(%bx), %ds // DOS 3.0+
498 +loop1:
499 + incw %bx
500 + cmpw %cx, (%bx)
501 + jne loop1
502 + leaw 4(%bx), %dx // %ds:%dx filename
503 + movb $0x3D, %ah // open, access = RO
504 + int $0x21
505 + jc dosexit
506 + xchgw %ax, %bp // fd
507 + incw %di
508 + call read_sectors_dos // update %ds
509 + addb $read_sectors_dos-read_sectors, patchcall+1
510 +#ifdef CMDLINE
511 +# ifdef OLDCMDLINE
512 + movw $0x202, %bx
513 + cmpw %bx, 0x206-0x202(%bx)
514 + jb oldcmdline
515 + movw $INITSEG/16+stacktop/256, cmd_line_ptr+1-0x202(%bx)
516 +oldcmdline:
517 +# else
518 + movw $INITSEG/16+stacktop/256, cmd_line_ptr+1
519 +# endif
520 +#endif
521 + ljmp $INITSEG, $loadsys
522 +#else
523 +swap_floppy:
524 + .ascii "Next!"
525 + .byte 7,13,0 # swap detection needs 13, 0
526 +#endif
527 +
528 +#define kernel_version_offset 0xE
529 +puts_version:
530 + addw kernel_version_offset(%si),%si # starting protocol 2.00, Kernel 1.3.73
531 +puts:
532 + movb $0xd, %al # CR
533 +putcs:
534 + call putc
535 + lodsb
536 + cmpb $0, %al # end of string is any byte <= 0
537 + jg putcs
538 +dosexit:
539 + ret
541 # Kernel attributes; used by setup. This is part 1 of the
542 # header, from the old boot sector.