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

linux/boot: fix cmdline tail
author Pascal Bellard <pascal.bellard@slitaz.org>
date Mon Nov 23 11:01:54 2009 +0100 (2009-11-23)
parents aa65a927a2f3
children b1b311195e79
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,391 @@
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 + xchg %ax, %di # sector count
108 + cbw # limits = 0
109 + incw %cx # cylinder 0, sector 1
110 + xorw %bx, %bx
111 + call read_first_sectors # read setup
112 +
113 +#define version_offset 0xE
114 +#define loadflags_offset 0x11
115 +#define heap_end_ptr_offset 0x24
116 +
117 + movw $_start,%si
118 + orb $0x80, loadflags_offset(%si)
119 + movw $stacktop-0x200, heap_end_ptr_offset(%si)
120 +
121 + addw version_offset(%si),%si # starting protocol 2.00, Kernel 1.3.73
122 + call puts # show which kernel we are loading
123 +
124 +#ifdef EDIT_CMDLINE
125 +# The cmdline can be entered and modifed on hot key.
126 +# Only characters before the cursor are passed to the kernel.
127 + movw $cmd_line_ptr, %si
128 + cmpw %bx,(%si) # %bx = 7
129 + jb nocmdline
130 + incw %di # read 1 sector
131 + movw (%si), %bx
132 + pushw %si
133 + call read_sectors
134 + popw %di
135 + movw (%di), %si
136 + call puts
137 +cmdlp:
138 + movb $32, %al # clear end of line
139 + int $0x10 # with Space
140 + movb $8, %al # and BackSpace
141 int $0x10
142 - jmp msg_loop
143 + decw %si
144 +cmdget:
145 + cbw # %ah = 0, get keyboard character
146 + int $0x16
147 + cmpb $8, %al # BackSpace ?
148 + je cmdbs
149 + cbw
150 + movw %ax, (%si) # store end of string too
151 + lodsw # %si += 2
152 +cmdbs:
153 + cmpw (%di), %si # lower limit is checked
154 + je cmdget # but upper limit not
155 + call putc # set %ah and %bx
156 + cmpb $10, %al # Enter ?
157 + jne cmdlp
158 + movb %bh,-2(%si) # remove CR
159 +endcmdline:
160 +
161 +nocmdline:
162 +#endif
164 -bs_die:
165 - # Allow the user to press a key, then reboot
166 - xorw %ax, %ax
167 +# This routine loads the system at address SYSSEG, making sure
168 +# no 64kB boundaries are crossed. We try to load it as fast as
169 +# possible, loading whole tracks whenever we can.
170 +
171 + movw $24, %cx # allocate 48 bytes in stack
172 +init_gdt:
173 + push $0 # initialized with 0
174 + loop init_gdt
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 + pushw %es # print %es (named EX)
276 + pushw %dx # print %dx
277 + pushw %cx # print %cx
278 + pushw %bx # print %bx
279 +#ifndef FLOPPY_1440K_ONLY
280 + xchgw %ax, %si
281 +#endif
282 + movb $2,%ah
283 + pushw %ax # print %ax
284 + movw $6,%cx
285 +print_all:
286 + pushw %cx # save count remaining
287 + movb $4, %cl # 4 hex digits
288 +print_digit:
289 + rolw $4, %bp # rotate to use low 4 bits
290 + movb $0x0f, %al
291 + andw %bp, %ax # %al = mask for nybble
292 + addb $0x90, %al # convert %al to ascii hex
293 + daa # in only four instructions!
294 + adcb $0x40, %al
295 + daa
296 + call putc # set %ah and %bx
297 + loop print_digit
298 + movb $0x20, %al # SPACE
299 + int $0x10
300 + popw %cx
301 + loop print_loop
302 +#endif
303 + cbw # %ah = 0
304 + int $0x13 # reset controler
305 + popaw
306 +read_sectorslp:
307 + xorw %si, %si
308 + lodsw
309 + xchgw %ax,%cx # restore disk state
310 + lodsw
311 + xchgw %ax,%dx
312 +#ifndef FLOPPY_1440K_ONLY
313 +# al is last sector+1
314 +# ah is last cylinder+1
315 + lodsw
316 +#endif
317 +#ifndef FLOPPY_1440K_ONLY
318 + pushw %ax # limits
319 + subb %cl, %al # sectors remaining in track
320 + ja tolastsect
321 + movb $1, %al # 1 sector mini
322 +tolastsect:
323 +#else
324 + mov $FLOPPY_SECTORS+1, %al
325 + subb %cl, %al # sectors remaining in track
326 +#endif
327 + cbw
328 + cmpw %di, %ax
329 + jb more1trk
330 + movw %di, %ax # sectors to read
331 +more1trk:
332 + pushw %ax # save context
333 + pushw %dx # some bios break dx...
334 + movb $2, %ah # cmd: read chs
335 + int $0x13
336 + popw %dx
337 + xchgw %ax, %bp # status
338 +#ifndef FLOPPY_1440K_ONLY
339 + popw %si # save %ax
340 + popw %ax # limits
341 +#else
342 + popw %ax # restore context
343 +#endif
344 + jc check_limits
345 +#ifndef FLOPPY_1440K_ONLY
346 + subw %si,%di # update sector counter
347 + addw %si,%cx # next sector
348 + shlw $9,%si
349 + addw %si,%bx # next location
350 +#else
351 + subw %ax,%di # update sector counter
352 + addw %ax,%cx # next sector
353 + addw %ax,%ax
354 + addb %al,%bh # next location
355 +#endif
356 +#ifndef FLOPPY_1440K_ONLY
357 + cmpb %al,%cl # reach sector limit ?
358 + jne bdendlp
359 +next_head:
360 + movb %cl,%al
361 +#else
362 + cmpb $FLOPPY_SECTORS+1,%cl # reach sector limit ?
363 + jne bdendlp
364 +#endif
365 + incb %dh # next head
366 + movb $1,%cl # first sector
367 +#ifndef FLOPPY_1440K_ONLY
368 + cmpb %ah, %dh # reach head limit ?
369 + jne bdendlp
370 +next_cylinder:
371 + movb %dh,%ah
372 +#else
373 + cmpb %cl,%dh # reach head limit ?
374 + je bdendlp
375 +#endif
376 +# NOTE : support 256 cylinders max
377 + incb %ch # next cylinder
378 +read_first_sectors:
379 + movb $0,%dh # first head
380 +#ifndef FLOPPY_1440K_ONLY
381 + cmpb $FLOPPY_SECTORS+1,%al # 1.44M floppy ?
382 + jne bdendlp
383 +#endif
384 + cmpb $FLOPPY_CYLINDERS,%ch # reach cylinder limit ?
385 + jb bdendlp
386 +next_floppy:
387 + movb $0,%ch # first cylinder
388 + pushaw
389 + movw $swap_floppy,%si
390 + call puts
391 + cbw # %ah = 0, get keyboard character
392 int $0x16
393 - int $0x19
394 + popaw
395 +bdendlp:
396 +#ifndef FLOPPY_1440K_ONLY
397 + movw %ax, limits
398 +#endif
399 + pushw %dx
400 + pushw %cx
401 + popl curcx # save disk state
402 +read_sectors:
403 + orw %di,%di
404 + jne read_sectorslp
405 + pushw %ss
406 + popw %es # restore es
407 + movb $0x2e+3, %al # 2e = .
408 +putclf:
409 + subb $3, %al
410 +putc:
411 + movb $0xe, %ah
412 + movw $7, %bx # one dot each 64k
413 + int $0x10
414 + cmp $0xd, %al # CR ?
415 + je putclf
416 + ret
418 - # int 0x19 should never return. In case it does anyway,
419 - # invoke the BIOS reset code...
420 - ljmp $0xf000,$0xfff0
421 +puts:
422 + movb $0xd, %al # CR
423 +putcs:
424 + call putc
425 + lodsb
426 + orb %al,%al # end of string is \0
427 + jnz putcs
428 + ret
430 - .section ".bsdata", "a"
431 -bugger_off_msg:
432 - .ascii "Direct booting from floppy is no longer supported.\r\n"
433 - .ascii "Please use a boot loader program instead.\r\n"
434 - .ascii "\n"
435 - .ascii "Remove disk and press any key to reboot . . .\r\n"
436 - .byte 0
437 +regs: .asciz "X:"
439 +swap_floppy:
440 + .ascii "Insert next floppy and press any key to continue."
441 + .byte 7,13,0
443 # Kernel attributes; used by setup. This is part 1 of the
444 # header, from the old boot sector.