wok-next diff gpxe/stuff/patches/prefix.u @ rev 20661
Unification of the patch system
author | Aleksej Bobylev <al.bobylev@gmail.com> |
---|---|
date | Thu May 10 21:12:00 2018 +0300 (2018-05-10) |
parents | gpxe/stuff/prefix.u@0ebb1ed44fed |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gpxe/stuff/patches/prefix.u Thu May 10 21:12:00 2018 +0300 1.3 @@ -0,0 +1,429 @@ 1.4 +--- gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S 1.5 ++++ gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S 1.6 +@@ -3,6 +3,7 @@ 1.7 + 1.8 + Authors: Gary Byers (gb@thinguin.org) 1.9 + Marty Connor (mdc@thinguin.org) 1.10 ++ Pascal Bellard (pascal.bellard@slitaz.org) 1.11 + 1.12 + This software may be used and distributed according to the terms 1.13 + of the GNU Public License (GPL), incorporated herein by reference. 1.14 +@@ -50,40 +51,351 @@ 1.15 + .arch i386 1.16 + .org 0 1.17 + .section ".prefix", "ax", @progbits 1.18 +-/* 1.19 +- This is a minimal boot sector. If anyone tries to execute it (e.g., if 1.20 +- a .lilo file is dd'ed to a floppy), print an error message. 1.21 +-*/ 1.22 + 1.23 +-bootsector: 1.24 +- jmp $BOOTSEG, $1f /* reload cs:ip to match relocation addr */ 1.25 +-1: 1.26 +- movw $0x2000, %di /* 0x2000 is arbitrary value >= length 1.27 +- of bootsect + room for stack */ 1.28 ++ call here 1.29 ++here: 1.30 ++ pop %ax 1.31 ++ cmpw $0x103, %ax /* COM entry point is cs:0x100 */ 1.32 ++ jne bootsector 1.33 ++ 1.34 ++/* We need a real mode stack that won't be stomped on by Etherboot 1.35 ++ which starts at 0x20000. Choose something that's sufficiently high, 1.36 ++ but not in DOC territory. Note that we couldn't do this in a real 1.37 ++ .com program since stack variables are in the same segment as the 1.38 ++ code and data, but this isn't really a .com program, it just looks 1.39 ++ like one to make DOS load it into memory. It still has the 64kB 1.40 ++ limitation of .com files though. */ 1.41 ++#define STACK_SEG 0x7000 1.42 ++#define STACK_SIZE 0x4000 1.43 ++ /* Set up temporary stack */ 1.44 ++ movw $STACK_SEG, %ax 1.45 ++ movw %ax, %ss 1.46 ++ movw $STACK_SIZE, %sp 1.47 ++ 1.48 ++ /* Calculate segment address of image start */ 1.49 ++ pushw %cs 1.50 ++ popw %ax 1.51 ++ addw $(0x100/16), %ax /* Adjust cs */ 1.52 ++ pushw %ax 1.53 ++ jmp go_setup_code 1.54 ++ 1.55 ++bootsector: 1.56 ++ jmp $BOOTSEG, $go /* reload cs:ip to match relocation addr */ 1.57 ++go: 1.58 ++ movw $0x2000-12, %di /* 0x2000 is arbitrary value >= length */ 1.59 ++ /* of bootsect + room for stack + 12 for */ 1.60 ++ /* saved disk parm block */ 1.61 + 1.62 + movw $BOOTSEG, %ax 1.63 + movw %ax,%ds 1.64 + movw %ax,%es 1.65 +- 1.66 +- cli 1.67 +- movw %ax, %ss /* put stack at BOOTSEG:0x2000. */ 1.68 ++ movw %ax,%ss /* put stack at initial position */ 1.69 + movw %di,%sp 1.70 +- sti 1.71 + 1.72 +- movw $why_end-why, %cx 1.73 +- movw $why, %si 1.74 ++/* Many BIOS's default disk parameter tables will not recognize multi-sector 1.75 ++ * reads beyond the maximum sector number specified in the default diskette 1.76 ++ * parameter tables - this may mean 7 sectors in some cases. 1.77 ++ * 1.78 ++ * Since single sector reads are slow and out of the question, we must take care 1.79 ++ * of this by creating new parameter tables (for the first disk) in RAM. We 1.80 ++ * will set the maximum sector count to 36 - the most we will encounter on an 1.81 ++ * ED 2.88. High doesn't hurt. Low does. 1.82 ++ * 1.83 ++ * Segments are as follows: ds=es=ss=cs - BOOTSEG 1.84 ++ */ 1.85 ++ 1.86 ++ xorw %cx,%cx 1.87 ++ movw %cx,%es /* access segment 0 */ 1.88 ++ movw $0x78, %bx /* 0:bx is parameter table address */ 1.89 ++ pushw %ds /* save ds */ 1.90 ++/* 0:bx is parameter table address */ 1.91 ++ ldsw %es:(%bx),%si /* loads ds and si */ 1.92 ++ 1.93 ++ movw %ax,%es /* ax is BOOTSECT (loaded above) */ 1.94 ++ movb $6, %cl /* copy 12 bytes */ 1.95 ++ cld 1.96 ++ pushw %di /* keep a copy for later */ 1.97 ++ rep 1.98 ++ movsw /* ds:si is source, es:di is dest */ 1.99 ++ popw %di 1.100 ++ 1.101 ++ movb $36,%es:4(%di) 1.102 ++ 1.103 ++ movw %cx,%ds /* access segment 0 */ 1.104 ++ xchgw %di,(%bx) 1.105 ++ movw %es,%si 1.106 ++ xchgw %si,2(%bx) 1.107 ++ popw %ds /* restore ds */ 1.108 ++ movw %di, dpoff /* save old parameters */ 1.109 ++ movw %si, dpseg /* to restore just before finishing */ 1.110 ++ pushw %ds 1.111 ++ popw %es /* reload es */ 1.112 ++ 1.113 ++/* Note that es is already set up. Also cx is 0 from rep movsw above. */ 1.114 ++ 1.115 ++ xorb %ah,%ah /* reset FDC */ 1.116 ++ xorb %dl,%dl 1.117 ++ int $0x13 1.118 ++ 1.119 ++/* Get disk drive parameters, specifically number of sectors/track. 1.120 ++ * 1.121 ++ * It seems that there is no BIOS call to get the number of sectors. Guess 1.122 ++ * 36 sectors if sector 36 can be read, 18 sectors if sector 18 can be read, 1.123 ++ * 15 if sector 15 can be read. Otherwise guess 9. 1.124 ++ */ 1.125 + 1.126 +- movw $0x0007, %bx /* page 0, attribute 7 (normal) */ 1.127 +- movb $0x0e, %ah /* write char, tty mode */ 1.128 +-prloop: 1.129 ++ movw $disksizes, %si /* table of sizes to try */ 1.130 ++ 1.131 ++probe_loop: 1.132 + lodsb 1.133 ++ orb %al, %al 1.134 ++ je got_sectors /* if all else fails, try 9 */ 1.135 ++ cbtw /* extend to word */ 1.136 ++ movw %ax, sectors 1.137 ++ xchgw %cx,%ax /* cx = track and sector */ 1.138 ++ xorw %dx,%dx /* drive 0, head 0 */ 1.139 ++ movw $0x0200, %bx /* address after boot sector */ 1.140 ++ /* (512 bytes from origin, es = cs) */ 1.141 ++ movw $0x0201, %ax /* service 2, 1 sector */ 1.142 ++ int $0x13 1.143 ++ jc probe_loop /* try next value */ 1.144 ++ 1.145 ++got_sectors: 1.146 ++ movw $msg1end-msg1, %cx 1.147 ++ movw $msg1, %si 1.148 ++ call print_str 1.149 ++ 1.150 ++/* ok, we've written the Loading... message, now we want to load the system */ 1.151 ++ 1.152 ++ movw $SYSSEG, %ax 1.153 ++ movw %ax,%es /* segment of SYSSEG<<4 */ 1.154 ++ pushw %es 1.155 ++ call read_it 1.156 ++ 1.157 ++/* This turns off the floppy drive motor, so that we enter the kernel in a 1.158 ++ * known state, and don't have to worry about it later. 1.159 ++ */ 1.160 ++ movw $0x3f2, %dx 1.161 ++ xorb %al,%al 1.162 ++ outb %al,%dx 1.163 ++ 1.164 ++ call print_nl 1.165 ++ pop %es /* = SYSSEG */ 1.166 ++sigok: 1.167 ++ 1.168 ++/* Restore original disk parameters */ 1.169 ++ movw $0x78, %bx 1.170 ++ movw dpoff, %di 1.171 ++ movw dpseg, %si 1.172 ++ xorw %ax,%ax 1.173 ++ movw %ax,%ds 1.174 ++ movw %di,(%bx) 1.175 ++ movw %si,2(%bx) 1.176 ++ 1.177 ++ /* Everything now loaded. %es = SYSSEG, so %es:0000 points to 1.178 ++ * start of loaded image. 1.179 ++ */ 1.180 ++ 1.181 ++ /* Jump to loaded copy */ 1.182 ++ ljmp $SYSSEG, $run_etherboot 1.183 ++ 1.184 ++endseg: .word SYSSEG + _load_size_pgh 1.185 ++ .section ".zinfo.fixup", "a" /* Compressor fixup information */ 1.186 ++ .ascii "SUBW" 1.187 ++ .long endseg 1.188 ++ .long 16 1.189 ++ .long 0 1.190 ++ .previous 1.191 ++ 1.192 ++/* This routine loads the system at address SYSSEG<<4, making sure no 64kB 1.193 ++ * boundaries are crossed. We try to load it as fast as possible, loading whole 1.194 ++ * tracks whenever we can. 1.195 ++ * 1.196 ++ * in: es - starting address segment (normally SYSSEG) 1.197 ++ */ 1.198 ++read_it: 1.199 ++ movw $0,sread /* read whole image incl boot sector */ 1.200 ++ movw %es,%ax 1.201 ++ testw $0x0fff, %ax 1.202 ++die: jne die /* es must be at 64kB boundary */ 1.203 ++ xorw %bx,%bx /* bx is starting address within segment */ 1.204 ++rp_read: 1.205 ++ movw %es,%ax 1.206 ++ movw %bx,%dx 1.207 ++ movb $4, %cl 1.208 ++ shrw %cl,%dx /* bx is always divisible by 16 */ 1.209 ++ addw %dx,%ax 1.210 ++ cmpw syssize, %ax /* have we loaded all yet? */ 1.211 ++ jb ok1_read 1.212 ++ ret 1.213 ++ok1_read: 1.214 ++ movw sectors, %ax 1.215 ++ subw sread, %ax 1.216 ++ movw %ax,%cx 1.217 ++ shlw $9, %cx /* 80186 opcode */ 1.218 ++ addw %bx,%cx 1.219 ++ jnc ok2_read 1.220 ++ je ok2_read 1.221 ++ xorw %ax,%ax 1.222 ++ subw %bx,%ax 1.223 ++ shrw $9, %ax /* 80186 opcode */ 1.224 ++ok2_read: 1.225 ++ call read_track 1.226 ++ movw %ax,%cx 1.227 ++ addw sread, %ax 1.228 ++ cmpw sectors, %ax 1.229 ++ jne ok3_read 1.230 ++ movw $1, %ax 1.231 ++ subw head, %ax 1.232 ++ jne ok4_read 1.233 ++ incw track 1.234 ++ok4_read: 1.235 ++ movw %ax, head 1.236 ++ xorw %ax,%ax 1.237 ++ok3_read: 1.238 ++ movw %ax, sread 1.239 ++ shlw $9, %cx /* 80186 opcode */ 1.240 ++ addw %cx,%bx 1.241 ++ jnc rp_read 1.242 ++ movw %es,%ax 1.243 ++ addb $0x10, %ah 1.244 ++ movw %ax,%es 1.245 ++ xorw %bx,%bx 1.246 ++ jmp rp_read 1.247 ++ 1.248 ++read_track: 1.249 ++ pusha /* 80186 opcode */ 1.250 ++ pushw %ax 1.251 ++ pushw %bx 1.252 ++ pushw %bp /* just in case the BIOS is buggy */ 1.253 ++ movb $0x2e, %al /* 0x2e = . */ 1.254 ++ call print_char 1.255 ++ popw %bp 1.256 ++ popw %bx 1.257 ++ popw %ax 1.258 ++ 1.259 ++ movw sread, %cx 1.260 ++ incw %cx 1.261 ++ movb track, %ch 1.262 ++ movw $0x0100, %dx 1.263 ++ andb head, %dh 1.264 ++ movb $2, %ah 1.265 ++ 1.266 ++ pushw %dx /* save for error dump */ 1.267 ++ pushw %cx 1.268 ++ pushw %bx 1.269 ++ pushw %ax 1.270 ++ 1.271 ++ int $0x13 1.272 ++ jc bad_rt 1.273 ++ addw $8, %sp 1.274 ++ popa /* 80186 opcode */ 1.275 ++ ret 1.276 ++ 1.277 ++bad_rt: pushw %ax /* save error code */ 1.278 ++ call print_all /* ah = error, al = read */ 1.279 ++ 1.280 ++ xorb %ah,%ah 1.281 ++ xorb %dl,%dl 1.282 ++ int $0x13 1.283 ++ 1.284 ++ addw $10, %sp 1.285 ++ popa /* 80186 opcode */ 1.286 ++ jmp read_track 1.287 ++ 1.288 ++/* print_all is for debugging purposes. It will print out all of the registers. 1.289 ++ * The assumption is that this is called from a routine, with a stack frame like 1.290 ++ * dx 1.291 ++ * cx 1.292 ++ * bx 1.293 ++ * ax 1.294 ++ * error 1.295 ++ * ret <- sp 1.296 ++ */ 1.297 ++ 1.298 ++print_all: 1.299 ++ call print_nl /* nl for readability */ 1.300 ++ /* print_nl update ah and bx */ 1.301 ++ movw $5, %cx /* error code + 4 registers */ 1.302 ++ movw %sp,%bp 1.303 ++ 1.304 ++print_loop: 1.305 ++ pushw %cx /* save count left */ 1.306 ++ 1.307 ++ cmpb $5, %cl 1.308 ++ jae no_reg /* see if register name is needed */ 1.309 ++ 1.310 ++ movb $0x5+0x41-1, %al 1.311 ++ subb %cl,%al 1.312 ++ int $0x10 1.313 ++ 1.314 ++ movb $0x58, %al /* 'X' */ 1.315 + int $0x10 1.316 ++ 1.317 ++ movb $0x3A, %al /* ':' */ 1.318 ++ int $0x10 1.319 ++ 1.320 ++no_reg: 1.321 ++ addw $2, %bp /* next register */ 1.322 ++ call print_hex /* print it */ 1.323 ++ movb $0x20, %al /* print a space */ 1.324 ++ int $0x10 1.325 ++ popw %cx 1.326 ++ loop print_loop 1.327 ++ /* nl for readability */ 1.328 ++print_nl: 1.329 ++ movb $0xd, %al /* CR */ 1.330 ++ call print_char 1.331 ++ movb $0xa, %al /* LF */ 1.332 ++ jmp print_char 1.333 ++ 1.334 ++ 1.335 ++print_str: 1.336 ++prloop: 1.337 ++ lodsb 1.338 ++ call print_char 1.339 + loop prloop 1.340 +-freeze: jmp freeze 1.341 ++ ret 1.342 + 1.343 +-why: .ascii "This image cannot be loaded from a floppy disk.\r\n" 1.344 +-why_end: 1.345 ++/* print_hex prints the word pointed to by ss:bp in hexadecimal. */ 1.346 + 1.347 ++print_hex: 1.348 ++ movw (%bp),%dx /* load word into dx */ 1.349 ++ movb $4, %cl 1.350 ++ call print_2digits 1.351 ++print_2digits: 1.352 ++ call print_digit 1.353 ++/* fall through */ 1.354 ++print_digit: 1.355 ++ rol %cl,%dx /* rotate to use lowest 4 bits */ 1.356 ++ movb $0x0f, %al /* mask for nybble */ 1.357 ++ andb %dl,%al 1.358 ++ addb $0x90, %al /* convert al to ascii hex */ 1.359 ++ daa /* (four instructions) */ 1.360 ++ adcb $0x40, %al 1.361 ++ daa 1.362 ++print_char: 1.363 ++ movb $0x0e, %ah /* write char, tty mode */ 1.364 ++ movw $0x0007, %bx /* page 0, attribute 7 (normal) */ 1.365 ++ int $0x10 1.366 ++ ret 1.367 ++ 1.368 ++sread: .word 0 /* sectors read of current track */ 1.369 ++head: .word 0 /* current head */ 1.370 ++track: .word 0 /* current track */ 1.371 ++ 1.372 ++sectors: 1.373 ++ .word 0 1.374 ++ 1.375 ++dpseg: .word 0 1.376 ++dpoff: .word 0 1.377 ++ 1.378 ++disksizes: 1.379 ++ .byte 36,18,15,9,0 1.380 ++ 1.381 ++msg1: 1.382 ++ .ascii "Loading ROM image" 1.383 ++msg1end: 1.384 + 1.385 + .org 497 1.386 + setup_sects: 1.387 +@@ -106,13 +418,6 @@ 1.388 + 1.389 + .org 512 1.390 + 1.391 +- .section ".zinfo.fixup", "a" /* Compressor fixup information */ 1.392 +- .ascii "SUBW" 1.393 +- .long syssize 1.394 +- .long 16 1.395 +- .long 0 1.396 +- .previous 1.397 +- 1.398 + /* 1.399 + We're now at the beginning of the second sector of the image - 1.400 + where the setup code goes. 1.401 +@@ -123,14 +428,18 @@ 1.402 + executing the Etherboot image that's loaded at SYSSEG:0 and 1.403 + whose entry point is SYSSEG:0. 1.404 + */ 1.405 +-setup_code: 1.406 ++setup_code: 1.407 ++ pushw $(SYSSEG-(PREFIXSIZE/16)) 1.408 + /* Etherboot expects to be contiguous in memory once loaded. 1.409 + * LILO doesn't do this, but since we don't need any 1.410 + * information that's left in the prefix, it doesn't matter: 1.411 + * we just have to ensure that %cs:0000 is where the start of 1.412 + * the Etherboot image *would* be. 1.413 + */ 1.414 +- ljmp $(SYSSEG-(PREFIXSIZE/16)), $run_etherboot 1.415 ++go_setup_code: 1.416 ++ pushw $run_etherboot 1.417 ++ /* Calculated lcall to _start with %cs:0000 = image start */ 1.418 ++ lret 1.419 + 1.420 + 1.421 + .org PREFIXSIZE 1.422 +@@ -140,6 +449,10 @@ 1.423 + run_etherboot: 1.424 + call install 1.425 + 1.426 ++ /* Set up real-mode stack */ 1.427 ++ movw %bx, %ss 1.428 ++ movw $_estack16, %sp 1.429 ++ 1.430 + /* Jump to .text16 segment */ 1.431 + pushw %ax 1.432 + pushw $1f