wok-next rev 12556
linux/embedded loader: needs 256 bytes alignements, not 64k
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Sat Apr 28 13:23:21 2012 +0200 (2012-04-28) |
parents | a619433464a8 |
children | 4caf2c7f24c8 |
files | linux/stuff/linux-header.u |
line diff
1.1 --- a/linux/stuff/linux-header.u Sat Apr 28 13:11:36 2012 +0200 1.2 +++ b/linux/stuff/linux-header.u Sat Apr 28 13:23:21 2012 +0200 1.3 @@ -1,50 +1,43 @@ 1.4 ---- linux-2.6.30.6/arch/x86/boot/header.S 1.5 -+++ linux-2.6.30.6/arch/x86/boot/header.S 1.6 -@@ -6,7 +6,7 @@ 1.7 - * Based on bootsect.S and setup.S 1.8 +--- linux-3.2.14/arch/x86/boot/header.S 1.9 ++++ linux-3.2.14/arch/x86/boot/header.S 1.10 +@@ -7,6 +7,7 @@ 1.11 * modified by more people than can be counted 1.12 * 1.13 -- * Rewritten as a common file by H. Peter Anvin (Apr 2007) 1.14 + * Rewritten as a common file by H. Peter Anvin (Apr 2007) 1.15 + * Rewritten Pascal Bellard (Nov 2009) 1.16 * 1.17 * BIG FAT NOTE: We're in real mode using 64k segments. Therefore segment 1.18 * addresses must be multiplied by 16 to obtain their respective linear 1.19 -@@ -27,6 +27,8 @@ 1.20 +@@ -27,7 +28,12 @@ 1.21 1.22 BOOTSEG = 0x07C0 /* original address of boot-sector */ 1.23 SYSSEG = 0x1000 /* historical load address >> 4 */ 1.24 +INITSEG = 0x9000 /* boot address >> 4 */ 1.25 +SETUPSEG = 0x9020 /* setup address >> 4 */ 1.26 1.27 ++#define LOADSEG 0x0800 1.28 ++#define LOADSZ (LOADSEG*0x10) 1.29 ++ 1.30 #ifndef SVGA_MODE 1.31 #define SVGA_MODE ASK_VGA 1.32 -@@ -40,53 +42,412 @@ 1.33 - #define ROOT_RDONLY 1 1.34 #endif 1.35 - 1.36 -+/* some extra features */ 1.37 -+#define EDIT_CMDLINE on hotkey 1.38 -+#define SHOW_REGS show int13 status & parameters 1.39 -+ 1.40 - .code16 1.41 - .section ".bstext", "ax" 1.42 +@@ -45,48 +51,366 @@ 1.43 1.44 .global bootsect_start 1.45 bootsect_start: 1.46 + cld # assume nothing 1.47 +stacktop = 0x9E00 # in 0x8000 .. 0xA000 1.48 -+zeroed = 48+10 # gdt + zeroed registers 1.49 ++zeroed = 48+12 # gdt + zeroed registers 1.50 + movw $stacktop-12-zeroed, %di # stacktop is an arbitrary value >= 1.51 + # length of bootsect + length of 1.52 + # setup + room for stack; 1.53 + # 12 is disk parm size. 1.54 + pushw $INITSEG 1.55 -+ popw %es # %es = INITSEG 1.56 -+ 1.57 -+ pushw %es 1.58 -+ popw %ss # %ss and %es already contain INITSEG 1.59 ++ popw %ss # %ss contain INITSEG 1.60 + movw %di, %sp # put stack at INITSEG:stacktop-... 1.61 -+ 1.62 + 1.63 +- # Normalize the start address 1.64 +- ljmp $BOOTSEG, $start2 1.65 +# Many BIOS's default disk parameter tables will not recognize 1.66 +# multi-sector reads beyond the maximum sector number specified 1.67 +# in the default diskette parameter tables - this may mean 7 1.68 @@ -56,41 +49,61 @@ 1.69 +# count to 36 - the most we will encounter on an ED 2.88. 1.70 +# 1.71 +# High doesn't hurt. Low does. Let's use the max: 63 1.72 -+# 1.73 -+# Segments are as follows: %es = %ss = INITSEG, 1.74 -+ 1.75 + 1.76 +-start2: 1.77 +- movw %cs, %ax 1.78 +- movw %ax, %ds 1.79 +- movw %ax, %es 1.80 +- movw %ax, %ss 1.81 +- xorw %sp, %sp 1.82 +- sti 1.83 +- cld 1.84 ++ pushw %ss 1.85 ++ popw %es # %es = %ss = INITSEG 1.86 + xorw %ax, %ax # %ax = 0 1.87 + movw $zeroed/2, %cx # clear gdt + offset, %ds, limits 1.88 + rep # don't worry about cld 1.89 + stosw # already done above 1.90 + popw %bx # offset = 0 1.91 + popw %ds # %ds = 0 1.92 -+ popw %gs # %gs = 0 1.93 -+ 1.94 ++ popw %fs # %fs = 0 1.95 + 1.96 +- movw $bugger_off_msg, %si 1.97 + movb setup_sects+0x7C00, %al # read bootsector + setup (%ds = 0) 1.98 + incw %ax 1.99 -+ 1.100 + 1.101 +-msg_loop: 1.102 +- lodsb 1.103 +- andb %al, %al 1.104 +- jz bs_die 1.105 +- movb $0xe, %ah 1.106 +- movw $7, %bx 1.107 ++ ldsw 0x78(%bx), %si # %ds:%bx+0x78 is parameter table address 1.108 + pushw %es 1.109 -+ pushw %di # %ds:%bx+0x78 is parameter table address 1.110 -+ ldsw 0x78(%bx), %si # %ds:%si is source 1.111 ++ pushw %di 1.112 + movb $6, %cl # copy 12 bytes 1.113 + rep # don't worry about cld 1.114 + movsw # already done above 1.115 -+ popl %gs:0x78(%bx) # update parameter table address 1.116 -+ pushw %es 1.117 ++ pushw %ss 1.118 + popw %ds # now %ds = %es = %ss = INITSEG 1.119 ++ popl %fs:0x78(%bx) # update parameter table address 1.120 + movb $63, 0x4-12(%di) # patch sector count, %di = stacktop 1.121 + cli 1.122 + 1.123 + xchg %ax, %di # sector count 1.124 + popw %ax # limits = 0 1.125 -+ incw %cx # cylinder 0, sector 1 1.126 ++ incw %cx # cylinder 0, sector 1, clear Z 1.127 + call read_first_sectors # read setup 1.128 + 1.129 -+offset_version = 0xE 1.130 + movw $0x200,%si 1.131 -+ addw offset_version(%si),%si # starting protocol 2.00, Kernel 1.3.73 1.132 -+ call putstr # show which kernel we are loading 1.133 ++#define kernel_version 0xE 1.134 ++type_of_loader = 0x10 1.135 ++loadflags = 0x11 1.136 ++heap_end_ptr = 0x24 1.137 ++ orw $0x8020, type_of_loader(%si) # loader type = 0x20 = bootsect-loader 1.138 ++ movb $(stacktop-0x300)/256, heap_end_ptr+1(%si) 1.139 ++ addw kernel_version(%si),%si # starting protocol 2.00, Kernel 1.3.73 1.140 ++ call puts # show which kernel we are loading 1.141 + 1.142 +# The cmdline can be entered and modifed at boot time. 1.143 +# Only characters before the cursor are passed to the kernel. 1.144 @@ -101,13 +114,13 @@ 1.145 + incw %di 1.146 + call read_sectors 1.147 + popw %si 1.148 -+ call putstr 1.149 -+#ifdef EDIT_CMDLINE 1.150 ++ call puts 1.151 +cmdlp: 1.152 + movb $0x20, %al # clear end of line 1.153 + int $0x10 # with Space 1.154 + movb $8, %al # and BackSpace 1.155 -+ int $0x10 1.156 + int $0x10 1.157 +- jmp msg_loop 1.158 + decw %si 1.159 +cmdget: 1.160 + call wait4key 1.161 @@ -116,113 +129,100 @@ 1.162 + movb %al, (%si) # store char 1.163 + lodsw # %si += 2 1.164 +cmdbs: 1.165 -+#if 1 1.166 + cmpw %si,cmd_line_ptr 1.167 + je cmdget 1.168 -+#endif 1.169 + call putc # set %ah and %bx 1.170 + cmpb $10, %al # Enter ? 1.171 + jne cmdlp 1.172 + movb %bh,-2(%si) # set end of string and remove CR 1.173 +endcmdline: 1.174 -+#endif 1.175 +nocmdline: 1.176 1.177 -- # Normalize the start address 1.178 -- ljmp $BOOTSEG, $start2 1.179 -- 1.180 --start2: 1.181 -- movw %cs, %ax 1.182 -- movw %ax, %ds 1.183 -- movw %ax, %es 1.184 -- movw %ax, %ss 1.185 -- xorw %sp, %sp 1.186 -- sti 1.187 -- cld 1.188 -- 1.189 -- movw $bugger_off_msg, %si 1.190 -+# This routine loads the system at address SYSSEG, making sure 1.191 +-bs_die: 1.192 +- # Allow the user to press a key, then reboot 1.193 +- xorw %ax, %ax 1.194 +- int $0x16 1.195 +- int $0x19 1.196 ++# This routine loads the system at address LOADSEG, making sure 1.197 +# no 64kB boundaries are crossed. We try to load it as fast as 1.198 +# possible, loading whole tracks whenever we can. 1.199 -+ 1.200 + 1.201 +- # int 0x19 should never return. In case it does anyway, 1.202 +- # invoke the BIOS reset code... 1.203 +- ljmp $0xf000,$0xfff0 1.204 +ramdisk_image = 0x0218 1.205 +ramdisk_size = 0x021C 1.206 ++bootsect_src_limit = 16 1.207 ++bootsect_dst_limit = 24 1.208 ++bootsect_src_base = 18 1.209 ++bootsect_dst_base = 26 1.210 ++ popw %bx # clear %bx 1.211 + movw %sp, %si # for bootsect_gdt 1.212 -+ decw 16(%si) # bootsect_src = 64Kb 1.213 -+ decw 24(%si) # bootsect_dst = 64Kb 1.214 -+ movw $syssize, %di 1.215 -+type_of_loader = 0x210 1.216 -+loadflags = 0x211 1.217 -+heap_end_ptr = 0x224 1.218 -+ksyssize = 500 1.219 -+ orw $0x80FF, type_of_loader-ksyssize(%di) # loader type = 0xFF 1.220 -+ movw $stacktop-0x200, heap_end_ptr-ksyssize(%di) 1.221 -+ movb $0x10, %al # destination = 0x100000 1.222 ++init_gdt: 1.223 ++ decw bootsect_src_limit(%bx,%si) # max 64Kb 1.224 ++ movb $0x93, bootsect_src_base+3(%bx,%si) 1.225 ++ xorb $bootsect_dst_limit-bootsect_src_limit, %bl 1.226 ++ jne init_gdt 1.227 ++ movw $syssize, %bx 1.228 ++code32_start = 0x214 1.229 ++ movw code32_start+1, %ax # destination = 0x00100000 or 0x00010000 1.230 + movb $5, %cl 1.231 +initrdlp: 1.232 -+ decw %ax 1.233 -+ movb $0x93,%ah 1.234 -+ movw %ax, 28(%si) # bootsect_dst_base+2 1.235 -+ movb $(SYSSEG/4096), %al # source = SYSSEG 1.236 -+ movw %ax, 20(%si) # bootsect_src_base+2 1.237 -+ cbw 1.238 -+ cwde 1.239 -+ shlw %cl, %ax 1.240 -+ decw %ax 1.241 -+ addl (%di),%eax 1.242 -+ shrl %cl, %eax 1.243 ++ movl (%bx),%ebx 1.244 ++ decl %ebx 1.245 ++ shrl %cl, %ebx 1.246 ++ incw %bx 1.247 +syslp: 1.248 -+ pushw $SYSSEG 1.249 ++ pushw $LOADSEG 1.250 + popw %es 1.251 -+ movw $128,%di # 64Kb 1.252 -+ subw %di, %ax # max 32M > int 15 limit 1.253 ++ movw $LOADSZ/256,%di # size in pages 1.254 ++ movw %di, bootsect_src_base+1(%si) # assume LOADSZ == LOADSEG*16 1.255 ++ movw %ax, bootsect_dst_base+1(%si) 1.256 ++ addw %di, %ax # next dest 1.257 ++ shrw $1, %di # pages to sectors 1.258 ++ subw %di, %bx # max 32M > int 15 limit 1.259 + pushf 1.260 + jnc not_last 1.261 -+ addw %ax, %di 1.262 ++ addw %bx, %di 1.263 +not_last: 1.264 -+ xorw %bx, %bx # clear %bx 1.265 + pushw %ax 1.266 -+#if defined(SHOW_REGS) 1.267 ++ pushw %di 1.268 + pushw %si 1.269 -+ call read_sectors 1.270 ++ pushw %bx 1.271 ++ xorw %bx,%bx 1.272 ++ call read_sectors # update %bp 1.273 ++ popw %bx 1.274 + popw %si 1.275 -+#else 1.276 -+ call read_sectors 1.277 -+#endif 1.278 -+ movw $0x8000, %cx # full 64K 1.279 ++ popw %cx # sectors to word count: 1.280 ++ xchgb %cl, %ch # %cx <<= 8 1.281 + movb $0x87, %ah 1.282 -+ incb 28(%si) # bootsect_dst_base+2 1.283 ++ pushw %ss 1.284 ++ popw %es # restore es 1.285 + int $0x15 # max 16M 1.286 + popw %ax 1.287 + popf 1.288 + ja syslp 1.289 -+ movw ramdisk_image+2,%ax 1.290 -+ movw $ramdisk_size,%di 1.291 ++ movw ramdisk_image+1,%ax 1.292 ++ movw $ramdisk_size,%bx 1.293 + movb $9, %cl 1.294 -+ cmpb %al,28(%si) 1.295 ++ cmpw %ax, bootsect_dst_base+1(%si) 1.296 + jb initrdlp 1.297 -+ 1.298 + 1.299 +- .section ".bsdata", "a" 1.300 +-bugger_off_msg: 1.301 +- .ascii "Direct booting from floppy is no longer supported.\r\n" 1.302 +- .ascii "Please use a boot loader program instead.\r\n" 1.303 +- .ascii "\n" 1.304 +- .ascii "Remove disk and press any key to reboot . . .\r\n" 1.305 +- .byte 0 1.306 +# This procedure turns off the floppy drive motor, so 1.307 +# that we enter the kernel in a known state, and 1.308 +# don't have to worry about it later. 1.309 + 1.310 ++kill_motor: 1.311 ++ xchgw %ax, %di # reset FDC (%di < 128) 1.312 ++ int $0x13 1.313 + 1.314 -+#if 1 1.315 -+kill_motor: 1.316 -+ xchgw %ax, %bx # reset FDC 1.317 -+ int $0x13 1.318 -+#else 1.319 -+kill_motor: 1.320 -+ movw $0x3f2, %dx 1.321 -+ xchgw %ax, %bx 1.322 -+ outb %al, %dx 1.323 -+#endif 1.324 - 1.325 --msg_loop: 1.326 -- lodsb 1.327 -- andb %al, %al 1.328 -- jz bs_die 1.329 -- movb $0xe, %ah 1.330 -- movw $7, %bx 1.331 +# After that (everything loaded), we jump to the setup-routine 1.332 +# loaded directly after the bootblock: 1.333 +# Segments are as follows: %ds = %ss = INITSEG 1.334 @@ -240,20 +240,15 @@ 1.335 +#define FLOPPY_HEADS 2 /* 2 heads minimum */ 1.336 +#define FLOPPY_SECTORS 18 /* 18 sectors minimum */ 1.337 + 1.338 -+#ifdef SHOW_REGS 1.339 +print_loop: 1.340 + movb $0x6 + 'A' - 1, %al 1.341 + subb %cl, %al 1.342 + movw $regs, %si # caller %si is saved 1.343 -+ call putcs # putc(%al) + putstr(%si) 1.344 ++ call putcs # putc(%al) + puts(%si) 1.345 +# it will print out all of the registers. 1.346 + popw %bp # load word into %si 1.347 + jmp print_all # print %bp (status) 1.348 -+#endif 1.349 +check_limits: 1.350 -+#ifndef SHOW_REGS 1.351 -+ popw %dx 1.352 -+#endif 1.353 + cmpb $FLOPPY_SECTORS+1, %cl # 18 sectors minimum 1.354 + jb check_head 1.355 + cmpb %al, %cl # max sector known ? 1.356 @@ -265,7 +260,6 @@ 1.357 + ja next_cylinder # no -> store it 1.358 +check_cylinder: 1.359 + pushaw 1.360 -+#ifdef SHOW_REGS 1.361 + cmpw $0x600,%bp # disk changed ? 1.362 + je reset_floppy 1.363 + pushw %es # print %es (named EX) 1.364 @@ -290,19 +284,11 @@ 1.365 + decb %ch 1.366 + jnz print_digit 1.367 + movb $0x20, %al # SPACE 1.368 - int $0x10 1.369 -- jmp msg_loop 1.370 -- 1.371 --bs_die: 1.372 -- # Allow the user to press a key, then reboot 1.373 -- xorw %ax, %ax 1.374 ++ int $0x10 1.375 + loop print_loop 1.376 + call wait 1.377 + cbw # %ah = 0 1.378 +reset_floppy: 1.379 -+#else 1.380 -+ cbw # %ah = 0 1.381 -+#endif 1.382 + int $0x13 # reset controler 1.383 + popaw 1.384 +read_sectorslp: 1.385 @@ -320,38 +306,24 @@ 1.386 + pushw %ax # save context 1.387 + movb $2, %ah # cmd: read chs 1.388 + int $0x13 1.389 -+#ifdef SHOW_REGS 1.390 + xchgw %ax, %bp # status 1.391 -+#endif 1.392 -+# ifdef SHOW_REGS 1.393 + popw %si # save %ax 1.394 + popw %ax # limits 1.395 + popw %dx 1.396 -+# else 1.397 -+ popw %dx # save %ax 1.398 -+ popw %ax # limits 1.399 -+# endif 1.400 + jc check_limits 1.401 + xchgw %ax, %bp 1.402 -+# ifdef SHOW_REGS 1.403 +update_regs: 1.404 + incw %cx # next sector 1.405 -+ movw %cx, %fs 1.406 ++ movw %cx, %gs 1.407 + addb $2,%bh # next location 1.408 + decw %di # update sector counter 1.409 + jz putcdot 1.410 + decw %si 1.411 + jnz update_regs 1.412 -+# else 1.413 -+ addw %dx,%cx # next sector 1.414 -+ addb %dl,%bh 1.415 -+ addb %dl,%bh # next location 1.416 -+ subw %dx,%di # update sector counter 1.417 -+ popw %dx 1.418 -+ jz putcdot 1.419 -+# endif 1.420 +read_sectors: 1.421 -+ movw %fs, %cx 1.422 ++ movw %gs, %cx 1.423 ++# al is last sector+1 1.424 ++# ah is last cylinder+1 1.425 + xchgw %ax, %bp 1.426 + cmpb %al,%cl # reach sector limit ? 1.427 + jne bdendlp 1.428 @@ -365,20 +337,17 @@ 1.429 + movb %dh,%ah 1.430 +# NOTE : support 256 cylinders max 1.431 + incb %ch # next cylinder 1.432 ++ cmpb $FLOPPY_CYLINDERS, %ch # reach cylinder limit ? 1.433 +read_first_sectors: 1.434 + movb $0,%dh # first head 1.435 -+cylinder_count = 496 1.436 -+ cmpb $FLOPPY_CYLINDERS,%ch # reach cylinder limit ? 1.437 -+ jb bdendlp 1.438 -+ cmpb cylinder_count, %ch 1.439 -+ jb bdendlp 1.440 ++ jne bdendlp 1.441 +next_floppy: 1.442 + movb $0,%ch # first cylinder 1.443 + pushaw 1.444 + movw $swap_floppy,%si 1.445 + incb 12(%si) 1.446 + pushw %bx 1.447 -+ call putstr 1.448 ++ call puts 1.449 + popw %bx 1.450 +waitfloppy: 1.451 + call wait 1.452 @@ -387,8 +356,6 @@ 1.453 + cbw 1.454 + int $0x13 # reset FDC 1.455 + movw $0x201,%ax 1.456 -+# cwd 1.457 -+# movw $1,%cx 1.458 + int $0x13 # read first sector 1.459 + popw %dx 1.460 + rclb $1,%ah # floppy changed 06=>0D no error 00 1.461 @@ -403,8 +370,10 @@ 1.462 + jmp read_sectorslp 1.463 + 1.464 +putcdot: 1.465 -+ pushw %ss 1.466 -+ popw %es # restore es 1.467 ++# REMOVE ME START 1.468 ++# pushw %ss 1.469 ++# popw %es 1.470 ++# REMOVE ME STOP 1.471 + movb $0x2e+3, %al # loading... message 2e = . 1.472 +putclf: 1.473 + subb $3, %al 1.474 @@ -416,7 +385,7 @@ 1.475 + je putclf 1.476 + ret 1.477 + 1.478 -+putstr: 1.479 ++puts: 1.480 + movb $0xd, %al # CR 1.481 +putcs: 1.482 + call putc 1.483 @@ -431,38 +400,23 @@ 1.484 + movw $clock, %di 1.485 +#define DELAY 5 1.486 + movb $(DELAY*182)/10,%cl 1.487 -+ addb %gs:(%di),%cl 1.488 ++ addb %fs:(%di),%cl 1.489 +waitkbd: 1.490 + movw $0x10D, %ax # test keyboard, timeout => CR 1.491 -+ cmpb %gs:(%di),%cl 1.492 ++ cmpb %fs:(%di),%cl 1.493 + je waitdone 1.494 - int $0x16 1.495 -- int $0x19 1.496 ++ int $0x16 1.497 + jz waitkbd 1.498 + cbw 1.499 + int $0x16 # eat char 1.500 -+ movw %di, %gs # disable timeout 1.501 ++ movw %di, %fs # disable timeout 1.502 + incw %di # clear Z 1.503 +waitdone: 1.504 + ret 1.505 - 1.506 -- # int 0x19 should never return. In case it does anyway, 1.507 -- # invoke the BIOS reset code... 1.508 -- ljmp $0xf000,$0xfff0 1.509 -- 1.510 -- .section ".bsdata", "a" 1.511 --bugger_off_msg: 1.512 -- .ascii "Direct booting from floppy is no longer supported.\r\n" 1.513 -- .ascii "Please use a boot loader program instead.\r\n" 1.514 -- .ascii "\n" 1.515 -- .ascii "Remove disk and press any key to reboot . . .\r\n" 1.516 -- .byte 0 1.517 -+#ifdef SHOW_REGS 1.518 -+regs: .asciz "X:" 1.519 -+#endif 1.520 - 1.521 ++ 1.522 ++regs: .asciz "X:" 1.523 ++ 1.524 +swap_floppy: .ascii "Insert disk 1" 1.525 -+ .ascii "." 1.526 + .byte 7,13,0 1.527 1.528 # Kernel attributes; used by setup. This is part 1 of the