wok view linux/stuff/linux-header-2.6.30.6.u @ rev 4514

Up:gutenprint; Add gutenprint-dev
author Rohit Joshi <jozee@slitaz.org>
date Thu Nov 26 12:07:22 2009 +0000 (2009-11-26)
parents b5013b460117
children f163cff3c826
line source
1 --- linux-2.6.30.6/arch/x86/boot/header.S
2 +++ linux-2.6.30.6/arch/x86/boot/header.S
3 @@ -6,7 +6,7 @@
4 * Based on bootsect.S and setup.S
5 * modified by more people than can be counted
6 *
7 - * Rewritten as a common file by H. Peter Anvin (Apr 2007)
8 + * Rewritten Pascal Bellard (Nov 2009)
9 *
10 * BIG FAT NOTE: We're in real mode using 64k segments. Therefore segment
11 * addresses must be multiplied by 16 to obtain their respective linear
12 @@ -26,6 +26,8 @@
14 BOOTSEG = 0x07C0 /* original address of boot-sector */
15 SYSSEG = 0x1000 /* historical load address >> 4 */
16 +INITSEG = 0x9000 /* boot address >> 4 */
17 +SETUPSEG = 0x9020 /* setup address >> 4 */
19 #ifndef SVGA_MODE
20 #define SVGA_MODE ASK_VGA
21 @@ -39,53 +41,394 @@
22 #define ROOT_RDONLY 1
23 #endif
25 +#define SHOW_REGS show int13 status & parameters
26 +#define EDIT_CMDLINE add kernel command line support
27 +
28 .code16
29 .section ".bstext", "ax"
31 .global bootsect_start
32 bootsect_start:
33 +stacktop = 0x9E00 # in 0x8000 .. 0xA000
34 + # with 512 bytes for cmdline
35 + movw $stacktop-12, %di # stacktop is an arbitrary value >=
36 + # length of bootsect + length of
37 + # setup + room for stack;
38 + # 12 is disk parm size.
39 + # gdt will heat 48 more bytes.
40 +curcx = 0
41 +curdx = curcx+2
42 + cld # assume nothing
43 +#ifndef FLOPPY_1440K_ONLY
44 +limits = 4
45 +#endif
47 - # Normalize the start address
48 - ljmp $BOOTSEG, $start2
49 + pushw $INITSEG
50 + popw %es # %es = INITSEG
51 + xorw %cx, %cx # %cx = 0
53 -start2:
54 - movw %cs, %ax
55 - movw %ax, %ds
56 - movw %ax, %es
57 - movw %ax, %ss
58 - xorw %sp, %sp
59 - sti
60 - cld
61 + pushw %es
62 + popw %ss # %ss and %es already contain INITSEG
63 + movw %di, %sp # put stack at INITSEG:stacktop-12.
65 - movw $bugger_off_msg, %si
66 +# Many BIOS's default disk parameter tables will not recognize
67 +# multi-sector reads beyond the maximum sector number specified
68 +# in the default diskette parameter tables - this may mean 7
69 +# sectors in some cases.
70 +#
71 +# Since single sector reads are slow and out of the question,
72 +# we must take care of this by creating new parameter tables
73 +# (for the first disk) in RAM. We can set the maximum sector
74 +# count to 36 - the most we will encounter on an ED 2.88.
75 +#
76 +# High doesn't hurt. Low does. Let's use the max: 63
77 +#
78 +# Segments are as follows: %es = %ss = INITSEG,
79 +# %fs and %gs are unused.
81 -msg_loop:
82 - lodsb
83 - andb %al, %al
84 - jz bs_die
85 - movb $0xe, %ah
86 - movw $7, %bx
87 + movw $0x78, %bx # %ds:%bx is parameter table address
88 + movw %cx, %ds # %ds = 0
89 + ldsw (%bx), %si # %ds:%si is source
90 + movb $6, %cl # copy 12 bytes
91 + rep # don't worry about cld
92 + movsw # already done above
93 + movw %cx, %ds # %ds = 0
94 + movw %sp, (%bx) # %sp = stacktop-12
95 + movw %es, 2(%bx)
96 +
97 + movb setup_sects+0x7C00, %al # read bootsector + setup (%ds = 0)
98 + cbw
99 + incw %ax
100 +
101 + pushw %es
102 + popw %ds # now %ds = %es = %ss = INITSEG
103 + movb $63, 0x4-12(%di) # patch sector count, %di = stacktop
104 +
105 + cli
106 +
107 + movb $24, %bl # allocate 48 bytes in stack
108 +init_gdt:
109 + pushw %cx # initialized with 0
110 + decw %bx
111 + jnz init_gdt
112 +
113 + xchg %ax, %di # sector count
114 + cbw # limits = 0
115 + incw %cx # cylinder 0, sector 1
116 + call read_first_sectors # read setup
117 +
118 +#define version_offset 0xE
119 +#define loadflags_offset 0x11
120 +#define heap_end_ptr_offset 0x24
121 +
122 + movw $_start,%si
123 + orb $0x80, loadflags_offset(%si)
124 + movw $stacktop-0x200, heap_end_ptr_offset(%si)
125 +
126 + addw version_offset(%si),%si # starting protocol 2.00, Kernel 1.3.73
127 + call puts # show which kernel we are loading
128 +
129 +#ifdef EDIT_CMDLINE
130 +# The cmdline can be entered and modifed on hot key.
131 +# Only characters before the cursor are passed to the kernel.
132 + movw $cmd_line_ptr, %si
133 + cmpw %bx,(%si) # %bx = 7
134 + jb nocmdline
135 + incw %di # read 1 sector
136 + movw (%si), %bx
137 + pushw %si
138 + call read_sectors
139 + popw %di
140 + movw (%di), %si
141 + call puts
142 +cmdlp:
143 + movb $32, %al # clear end of line
144 + int $0x10 # with Space
145 + movb $8, %al # and BackSpace
146 int $0x10
147 - jmp msg_loop
148 + decw %si
149 +cmdget:
150 + cbw # %ah = 0, get keyboard character
151 + int $0x16
152 + cmpb $8, %al # BackSpace ?
153 + je cmdbs
154 + movb %al, (%si) # store char
155 + lodsw # %si += 2
156 +cmdbs:
157 + cmpw (%di), %si # lower limit is checked
158 + je cmdget # but upper limit not
159 + call putc # set %ah and %bx
160 + cmpb $10, %al # Enter ?
161 + jne cmdlp
162 + movb %bh,-2(%si) # set end of line, remove CR
163 +endcmdline:
164 +
165 +nocmdline:
166 +#endif
168 -bs_die:
169 - # Allow the user to press a key, then reboot
170 - xorw %ax, %ax
171 +# This routine loads the system at address SYSSEG, making sure
172 +# no 64kB boundaries are crossed. We try to load it as fast as
173 +# possible, loading whole tracks whenever we can.
174 +
175 + movw %sp, %si # for bootsect_gdt
176 + movb $0x0F, %al # destination = 0x100000
177 + movw $syssize, %di
178 +#define type_of_loader_offset 0x1C /* type_of_loader - syssize */
179 + decb type_of_loader_offset(%di) # loader type = 0xFF
180 + movb $5, %cl
181 +initrdlp:
182 + movb $0x93,%ah
183 + movw %ax, 28(%si) # bootsect_dst_base+2
184 + movb $(SYSSEG/4096), %al # source = SYSSEG
185 + movw %ax, 20(%si) # bootsect_src_base+2
186 + cwd
187 + movw %dx, 16(%si) # bootsect_src = 64Kb
188 + movw %dx, 24(%si) # bootsect_dst = 64Kb
189 + xorl %ebx, %ebx
190 + incw %bx
191 + shlw %cl,%bx
192 + decw %bx
193 + addl (%di),%ebx
194 + shrl %cl, %ebx
195 +syslp:
196 + pushw $SYSSEG
197 + popw %es
198 + movw $128,%di # 64Kb
199 + subw %di, %bx # max 32M > int 15 limit
200 + pushf
201 + jnc not_last
202 + addw %bx, %di
203 +not_last:
204 + pushw %bx
205 + pushw %si
206 + xorw %bx, %bx
207 + call read_sectors
208 + popw %si
209 + movw $0x8000, %cx # full 64K
210 + movb $0x87, %ah
211 + incb 28(%si) # bootsect_dst_base+2
212 + int $0x15 # max 16M
213 + popw %bx
214 + popf
215 + ja syslp
216 + movw ramdisk_image+2,%ax
217 + decw %ax
218 + movw $ramdisk_size,%di
219 + movb $9, %cl
220 + cmpb %al,28(%si)
221 + jb initrdlp
222 +
223 +# This procedure turns off the floppy drive motor, so
224 +# that we enter the kernel in a known state, and
225 +# don't have to worry about it later.
226 +
227 +kill_motor:
228 + xorw %ax, %ax # reset FDC
229 + int $0x13
230 +
231 +# After that (everything loaded), we jump to the setup-routine
232 +# loaded directly after the bootblock:
233 +# Segments are as follows: %ds = %ss = INITSEG
234 +
235 + ljmp $SETUPSEG, $0
236 +
237 +# read_sectors reads %di sectors into %es:0 buffer.
238 +# %es:0 is updated to the next memory location.
239 +# First, sectors are read sector by sector until
240 +# sector per track count is known. Then they are
241 +# read track by track.
242 +# Assume no error on first track.
243 +
244 +#define FLOPPY_CYLINDERS 80 /* 80 cylinders minimum */
245 +#define FLOPPY_HEADS 2 /* 2 heads minimum */
246 +#define FLOPPY_SECTORS 18 /* 18 sectors minimum */
247 +
248 +#ifdef SHOW_REGS
249 +print_loop:
250 + movb $0x6 + 'A' - 1, %al
251 + subb %cl, %al
252 + movw $regs, %si # caller %si is saved
253 + call putcs # putc(%al) + puts(%si)
254 +# it will print out all of the registers.
255 + popw %bp # load word into %bp
256 + jmp print_all # print %bp (status)
257 +#endif
258 +check_limits:
259 +#ifndef FLOPPY_1440K_ONLY
260 + cmpb $FLOPPY_SECTORS+1, %cl # 18 sectors minimum
261 + jb check_head
262 + cmpb %al, %cl # max sector known ?
263 + ja next_head # no -> store it
264 +check_head:
265 + cmpb $FLOPPY_HEADS, %dh # 2 heads minimum
266 + jb check_cylinder
267 + cmpb %ah, %dh # max head known ?
268 + ja next_cylinder # no -> store it
269 +check_cylinder:
270 + cmpb $FLOPPY_CYLINDERS, %ch # 80 cylinders minimum
271 + jae next_floppy
272 +#endif
273 + pushaw
274 +#ifdef SHOW_REGS
275 + cmpw $0x600,%bp # disk changed ?
276 + je reset_floppy
277 + pushw %es # print %es (named EX)
278 + pushw %dx # print %dx
279 + pushw %cx # print %cx
280 + pushw %bx # print %bx
281 +#ifndef FLOPPY_1440K_ONLY
282 + xchgw %ax, %si
283 +#endif
284 + movb $2,%ah
285 + pushw %ax # print %ax
286 + movw $6,%cx
287 +print_all:
288 + pushw %cx # save count remaining
289 + movb $4, %cl # 4 hex digits
290 +print_digit:
291 + rolw $4, %bp # rotate to use low 4 bits
292 + movb $0x0f, %al
293 + andw %bp, %ax # %al = mask for nybble
294 + addb $0x90, %al # convert %al to ascii hex
295 + daa # in only four instructions!
296 + adcb $0x40, %al
297 + daa
298 + call putc # set %ah and %bx
299 + loop print_digit
300 + movb $0x20, %al # SPACE
301 + int $0x10
302 + popw %cx
303 + loop print_loop
304 +reset_floppy:
305 +#endif
306 + cbw # %ah = 0
307 + int $0x13 # reset controler
308 + popaw
309 +read_sectorslp:
310 + xorw %si, %si
311 + lodsw
312 + xchgw %ax,%cx # restore disk state
313 + lodsw
314 + xchgw %ax,%dx
315 +#ifndef FLOPPY_1440K_ONLY
316 +# al is last sector+1
317 +# ah is last cylinder+1
318 + lodsw
319 +#endif
320 +#ifndef FLOPPY_1440K_ONLY
321 + pushw %ax # limits
322 + subb %cl, %al # sectors remaining in track
323 + ja tolastsect
324 + movb $1, %al # 1 sector mini
325 +tolastsect:
326 +#else
327 + mov $FLOPPY_SECTORS+1, %al
328 + subb %cl, %al # sectors remaining in track
329 +#endif
330 + cbw
331 + cmpw %di, %ax
332 + jb more1trk
333 + movw %di, %ax # sectors to read
334 +more1trk:
335 + pushw %ax # save context
336 + pushw %dx # some bios break dx...
337 + movb $2, %ah # cmd: read chs
338 + int $0x13
339 + popw %dx
340 + xchgw %ax, %bp # status
341 +#ifndef FLOPPY_1440K_ONLY
342 + popw %si # save %ax
343 + popw %ax # limits
344 +#else
345 + popw %ax # restore context
346 +#endif
347 + jc check_limits
348 +#ifndef FLOPPY_1440K_ONLY
349 + subw %si,%di # update sector counter
350 + addw %si,%cx # next sector
351 + shlw $9,%si
352 + addw %si,%bx # next location
353 +#else
354 + subw %ax,%di # update sector counter
355 + addw %ax,%cx # next sector
356 + addw %ax,%ax
357 + addb %al,%bh # next location
358 +#endif
359 +#ifndef FLOPPY_1440K_ONLY
360 + cmpb %al,%cl # reach sector limit ?
361 + jne bdendlp
362 +next_head:
363 + movb %cl,%al
364 +#else
365 + cmpb $FLOPPY_SECTORS+1,%cl # reach sector limit ?
366 + jne bdendlp
367 +#endif
368 + incb %dh # next head
369 + movb $1,%cl # first sector
370 +#ifndef FLOPPY_1440K_ONLY
371 + cmpb %ah, %dh # reach head limit ?
372 + jne bdendlp
373 +next_cylinder:
374 + movb %dh,%ah
375 +#else
376 + cmpb %cl,%dh # reach head limit ?
377 + je bdendlp
378 +#endif
379 +# NOTE : support 256 cylinders max
380 + incb %ch # next cylinder
381 +read_first_sectors:
382 + movb $0,%dh # first head
383 +#ifndef FLOPPY_1440K_ONLY
384 + cmpb $FLOPPY_SECTORS+1,%al # 1.44M floppy ?
385 + jne bdendlp
386 +#endif
387 + cmpb $FLOPPY_CYLINDERS,%ch # reach cylinder limit ?
388 + jb bdendlp
389 +next_floppy:
390 + movb $0,%ch # first cylinder
391 + pushaw
392 + movw $swap_floppy,%si
393 + call puts
394 + cbw # %ah = 0, get keyboard character
395 int $0x16
396 - int $0x19
397 + popaw
398 +bdendlp:
399 +#ifndef FLOPPY_1440K_ONLY
400 + movw %ax, limits
401 +#endif
402 + pushw %dx
403 + pushw %cx
404 + popl curcx # save disk state
405 +read_sectors:
406 + orw %di,%di
407 + jne read_sectorslp
408 + pushw %ss
409 + popw %es # restore es
410 + movb $0x2e+3, %al # 2e = .
411 +putclf:
412 + subb $3, %al
413 +putc:
414 + movb $0xe, %ah
415 + movw $7, %bx # one dot each 64k
416 + int $0x10
417 + cmp $0xd, %al # CR ?
418 + je putclf
419 + ret
421 - # int 0x19 should never return. In case it does anyway,
422 - # invoke the BIOS reset code...
423 - ljmp $0xf000,$0xfff0
424 +puts:
425 + movb $0xd, %al # CR
426 +putcs:
427 + call putc
428 + lodsb
429 + orb %al,%al # end of string is \0
430 + jnz putcs
431 + ret
433 - .section ".bsdata", "a"
434 -bugger_off_msg:
435 - .ascii "Direct booting from floppy is no longer supported.\r\n"
436 - .ascii "Please use a boot loader program instead.\r\n"
437 - .ascii "\n"
438 - .ascii "Remove disk and press any key to reboot . . .\r\n"
439 - .byte 0
440 +regs: .asciz "X:"
442 +swap_floppy:
443 + .ascii "Insert next floppy and press any key to continue."
444 + .byte 7,13,0
446 # Kernel attributes; used by setup. This is part 1 of the
447 # header, from the old boot sector.