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