wok diff ipxe/stuff/bootloader.S @ rev 20179
ipxe: update bootloader
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Sat Jan 27 12:56:10 2018 +0100 (2018-01-27) |
parents | |
children | 1421f93cc28a |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipxe/stuff/bootloader.S Sat Jan 27 12:56:10 2018 +0100 1.3 @@ -0,0 +1,554 @@ 1.4 +// Image/zImage & tiny bzImage linux kernel boot sector, (C) SliTaz, GPL2. 1.5 + 1.6 +SYSSEG = 0x1000 1.7 +INITSEG = 0x9000 1.8 +SETUPSEG = 0x9020 1.9 +setup_sects = 497 1.10 +syssize = 500 1.11 +cmd_line_ptr = 0x228 1.12 + 1.13 + .text 1.14 + .code16 1.15 + .org 0 1.16 + .globl _start 1.17 +_start: 1.18 + 1.19 +#define CODESZ 512 /* patched by installer */ 1.20 + 1.21 +#define BZIMAGE 0x207 /* setup version ; for bzImage < 512 Kb only */ 1.22 + 1.23 +/* some extra features */ 1.24 +#define EXE_SUPPORT real mode dos .exe file support 1.25 +#define CMDLINE kernel cmdline support 1.26 +#define VCPI VCPI 4.0 support 1.27 +#define SHUTDOWNDOS shutdown DOS services 1.28 + 1.29 +/* some contraints to reduce the code size */ 1.30 +//#define FLOPPY_1440K_ONLY 1.44M floppies support only -33 1.31 +//#define FLOPPY_HAS_2_SIDES hardcoded heads count to 2 -13 1.32 +//#define NO_CMDLINE_SHRINK remove heading spaces ? -6-20 1.33 +//#define NO_CMDLINE_FILE remove @cmdline file support ? -20 1.34 +#define NO_DOTS show progression dots ? -8 1.35 +#ifndef BZIMAGE 1.36 +//#defime NO_MINSETUP default setup (dos only) ? -4 1.37 +//#define NO_CURSOR_DEFINITION -8 1.38 +#endif 1.39 + 1.40 +#ifdef EXE_SUPPORT 1.41 +#define EXEADRS(x) (x+0xE0) 1.42 +#define FLAT20(x) (x+16*INITSEG) 1.43 + 1.44 +.macro trace_int19 1.45 + pushl $4 1.46 + popw %si 1.47 + popw %ds 1.48 + pushl (%si) 1.49 + movl $step19+(INITSEG<<16), (%si) 1.50 + pushfw 1.51 + popw %ax 1.52 + incb %ah # set TF 1.53 + pushw %ax 1.54 + popfw 1.55 + ljmp *4*0x19-4(%si) 1.56 +.endm 1.57 + 1.58 +stacktop = 0x9E00 # in 0x8000 .. 0xA000 1.59 + decw %bp // Magic number: MZ 1.60 + popw %dx 1.61 + jmp start // Bytes on last page of file 1.62 + .word (CODESZ+511)/512 // Pages in file INSTALLER 1.63 + .word 0 // Relocations 1.64 + .word (end_header-_start)/16 // Size of header in paragraphs 1.65 + .word 4096 // Minimum extra paragraphs needed 1.66 + .word -1 // Maximum extra paragraphs needed 1.67 + .word (CODESZ+15)/16 // Initial (relative) SS value INSTALLER 1.68 + .word stacktop // Initial SP value 1.69 + .word 0 // Checksum INSTALLER? 1.70 + .word EXEADRS(comstart) // Initial IP value 1.71 + .word 0xFFF0 // Initial (relative) CS value 1.72 +// .word 0x001C // File address of relocation table 1.73 +// .word 0,0,0 // Overlay number 1.74 +#endif 1.75 +start: 1.76 + xorw %ax, %ax # %ax = 0 1.77 +#ifdef BZIMAGE 1.78 +zeroed = 14 # zeroed registers 1.79 +#else 1.80 +zeroed = 12 # zeroed registers 1.81 +#endif 1.82 + movw $zeroed/2, %cx # clear gdt + offset, %ds, limits 1.83 +stacktop = 0x9E00 # in 0x8000 .. 0xA000 (+zeroed+12) 1.84 + pushw $INITSEG 1.85 +end_header: 1.86 + cld # assume nothing 1.87 +#if defined(BZIMAGE) && BZIMAGE >= 0x202 1.88 + popw %es # %es contain INITSEG 1.89 + movw %es, %di 1.90 +#else 1.91 + # cmdline offset at 0x22 1.92 + movw $stacktop, %di # stacktop is an arbitrary value >= 1.93 + # length of bootsect + length of 1.94 + # setup + room for stack; 1.95 + # 12 is disk parm size. 1.96 + popw %es # %es contain INITSEG 1.97 +#endif 1.98 + pushw %es 1.99 + popw %ss # %es = %ss = INITSEG 1.100 + movw %di, %sp # put stack at INITSEG:stacktop-... 1.101 +#ifdef EXE_SUPPORT 1.102 + cwd # force %dx = 0 (floppy only) 1.103 +#endif 1.104 + 1.105 +# Many BIOS's default disk parameter tables will not recognize 1.106 +# multi-sector reads beyond the maximum sector number specified 1.107 +# in the default diskette parameter tables - this may mean 7 1.108 +# sectors in some cases. 1.109 +# 1.110 +# Since single sector reads are slow and out of the question, 1.111 +# we must take care of this by creating new parameter tables 1.112 +# (for the first disk) in RAM. We can set the maximum sector 1.113 +# count to 36 - the most we will encounter on an ED 2.88. 1.114 +# 1.115 +# High doesn't hurt. Low does. Let's use the max: 63 1.116 + 1.117 + rep # don't worry about cld 1.118 + stosw # already done above 1.119 + popw %bx # offset = 0 1.120 + popw %ds # %ds = 0 1.121 + popw %fs # %fs = 0 1.122 + 1.123 + movb setup_sects+0x7C00, %al # read bootsector + setup (%ds = 0) 1.124 + incw %ax 1.125 + 1.126 + ldsw 0x78(%bx), %si # %ds:%bx+0x78 is parameter table address 1.127 + pushw %es 1.128 + pushw %di 1.129 + movb $6, %cl # copy 12 bytes 1.130 + rep # don't worry about cld 1.131 + movsw # already done above 1.132 + pushw %ss 1.133 + popw %ds # now %ds = %es = %ss = INITSEG 1.134 + popl %fs:0x78(%bx) # update parameter table address 1.135 + movb $63, 0x4-12(%di) # patch sector count, %di = stacktop 1.136 + cli 1.137 + 1.138 + xchg %ax, %di # sector count 1.139 + popw %ax # limits = 0 1.140 + incw %cx # cylinder 0, sector 1, clear Z 1.141 + call read_first_sectors # read setup 1.142 + 1.143 +# This routine loads the system at address LOADSEG, making sure 1.144 +# no 64kB boundaries are crossed. We try to load it as fast as 1.145 +# possible, loading whole tracks whenever we can. 1.146 + 1.147 +#ifndef NO_DOTS 1.148 + popw %bx # clear %bx 1.149 +#endif 1.150 + movw syssize, %di 1.151 + decw %di 1.152 + shrw $9-4, %di 1.153 + incw %di 1.154 + movw $SYSSEG, %cx 1.155 +#ifdef BZIMAGE 1.156 + push %cx 1.157 +#endif 1.158 + call read_sectorsCX 1.159 + 1.160 +# This procedure turns off the floppy drive motor, so 1.161 +# that we enter the kernel in a known state, and 1.162 +# don't have to worry about it later. 1.163 + 1.164 +kill_motor: 1.165 + xchgw %ax, %di # reset FDC (%di < 128) 1.166 + int $0x13 1.167 + 1.168 +# After that (everything loaded), we jump to the setup-routine 1.169 +# loaded directly after the bootblock: 1.170 +# Segments are as follows: %ds = %ss = INITSEG 1.171 + 1.172 +#ifdef BZIMAGE 1.173 + popw %bx 1.174 + popw %si // SYSSEG:0 1.175 +movesys: // %bx = DS, %si 1.176 + movw $16, %ax 1.177 + mulw %bx 1.178 + addw %si, %ax 1.179 + adcw $0x9300, %dx // %dx:%ax src flat address 1.180 + movw $9, %cx 1.181 +zero1: 1.182 + pushw $0 // 2E..1E 1.183 + loop zero1 1.184 + //pushl $0x93100000 // 1A: dest 1.185 + pushw $0x9310 1.186 + pushw %cx 1.187 + pushw $-1 // 18 1.188 + pushw %cx // 16 1.189 + pushw %dx // src 1.190 + pushw %ax 1.191 + pushw $-1 // 10 1.192 + movb $8, %cl 1.193 + movw %cx, %bx // will move 8*64 = 512Kb 1.194 +zero2: 1.195 + pushw $0 // 0E..00 1.196 + loop zero2 1.197 + movw %sp, %si 1.198 + pushw %ss 1.199 + popw %es 1.200 + pushw %es 1.201 + popw %ds 1.202 +syslp: 1.203 + movb $0x80, %ch 1.204 + movb $0x87, %ah 1.205 + int $0x15 1.206 + incb 0x14(%si) 1.207 + incb 0x1C(%si) 1.208 + decw %bx 1.209 + jne syslp 1.210 +#endif 1.211 +jmp_setup: 1.212 + ljmp $SETUPSEG, $0 1.213 + 1.214 +#ifdef EXE_SUPPORT 1.215 +#ifdef SHUTDOWNDOS 1.216 +doiret: 1.217 + iret 1.218 +step19: 1.219 + pushw %si 1.220 + pushw %ds 1.221 + movw %sp, %si 1.222 + ldsw %ss:4(%si), %si 1.223 + cmpw $0x19CD, (%si) 1.224 + popw %ds 1.225 + popw %si 1.226 + jne doiret 1.227 + xorw %si, %si 1.228 + movw %si, %ds 1.229 + pushw %cs 1.230 + popw %ss 1.231 + movw $stacktop-4-16, %sp 1.232 + popl 4(%si) 1.233 + popaw 1.234 +#ifdef BZIMAGE 1.235 + jmp movesys 1.236 +#endif 1.237 +#endif 1.238 +#ifndef BZIMAGE 1.239 +movesys: // %ax = SYSSEG, %bx = DS, %si 1.240 + shrw $4, %si 1.241 + addw %si, %bx 1.242 + subw %ax, %bx 1.243 + jnc forward 1.244 + movb $0x90, %ah 1.245 + ;decw %ax 1.246 +forward: 1.247 + movw %ax, %es 1.248 + movw %ax, %di 1.249 + addw %bx, %di 1.250 + movw %di, %ds 1.251 + sbbw %di, %di // %di = 0 : -1 1.252 + cmc // C = 1 : 0 1.253 + adcw %di, %ax 1.254 + xorw %si, %si 1.255 + xorw %di, %di 1.256 + movb $0x10, %cl 1.257 + cmpb %cl, %ah // move 512k 1.258 + rep 1.259 + movsb 1.260 + jns forward 1.261 +#ifndef NO_CURSOR_DEFINITION 1.262 + movb $1, %ah 1.263 + movb $0, %bh 1.264 + movb $0x20, %ch // 0x2000 1.265 + int $0x10 1.266 +#endif 1.267 + pushw %ss 1.268 + popw %ds 1.269 + jmp jmp_setup 1.270 +#endif 1.271 +comstart: 1.272 + cld # assume nothing 1.273 + pushw $INITSEG 1.274 + popw %es 1.275 +#ifdef CMDLINE 1.276 + movw %sp, %di 1.277 + movw $0x80, %si 1.278 + lodsb 1.279 + cbw 1.280 + xchgw %ax, %cx 1.281 + jcxz nocmdline 1.282 +# if defined(BZIMAGE) && BZIMAGE >= 0x202 1.283 + movw $INITSEG/16+stacktop/256, EXEADRS(cmd_line_ptr+1) 1.284 +# else 1.285 + movw $0xA33F, 0x7F(%si) 1.286 +# endif 1.287 +# ifndef NO_CMDLINE_SHRINK 1.288 +skipspace: 1.289 + lodsb 1.290 + cmpb $0x20, %al 1.291 + je skipspace 1.292 +# ifndef NO_CMDLINE_FILE 1.293 + movw %si,%dx 1.294 + decw %si 1.295 + subb $'@',%al 1.296 + jne notafile 1.297 + movb $0x3D,%ah 1.298 + int $0x21 1.299 + jc notafile 1.300 + xchgw %ax,%bx 1.301 + //movw %si,%dx // ~320 bytes max 1.302 + movw $EXEADRS(notafile)-130,%cx 1.303 + movb $0x3F,%ah 1.304 + int $0x21 1.305 + xchgw %ax,%cx 1.306 +notafile: 1.307 +# else 1.308 + decw %si 1.309 +# endif 1.310 +# endif 1.311 + rep 1.312 + movsb 1.313 +nocmdline: 1.314 + orb EXEADRS(setup_sects), %ch 1.315 +# ifndef NO_MINSETUP 1.316 +# ifndef BZIMAGE 1.317 + jnz setupok 1.318 + mov $4, %ch 1.319 +setupok: 1.320 +# endif 1.321 +# endif 1.322 +#else 1.323 + movb EXEADRS(setup_sects), %ch 1.324 +#endif 1.325 + movb $(512-(end_header-_start))/2, %cl 1.326 + movw $0x100, %si 1.327 + movw $end_header, %di 1.328 + rep 1.329 + movsw 1.330 + movw $SYSSEG, %ax 1.331 + movw %ds, %bx 1.332 + pushw %es 1.333 + popw %ss 1.334 +#ifndef SHUTDOWNDOS 1.335 + pushw %es 1.336 + pushw $movesys 1.337 +#endif 1.338 +#ifdef VCPI 1.339 + pushaw 1.340 + smsww %ax 1.341 + andb $1, %al 1.342 + je isrm 1.343 + movw $EXEADRS(gdt_vcpi),%si 1.344 + movw $pagebuf-0x90000,%di // %es = 0x9000 1.345 + movl $pagebuf+3,%es:0x1000(%di) 1.346 +call_vcpi: 1.347 + movb $0xDE,%ah // DE01, EBX = getiface(DS:SI, ES:DI) 1.348 + int $0x67 1.349 + movl $FLAT20(sw2pm_params),%esi 1.350 + movb $0x0C,%al // DE0C switchpm(ESI) 1.351 + cli 1.352 + jmp call_vcpi 1.353 +pm_code: 1.354 + movl %cr0,%eax 1.355 + andl $0x7FFFFFFE,%eax 1.356 + movl %eax,%cr0 1.357 + movl %eax,%cr3 1.358 +isrm: 1.359 +# ifdef SHUTDOWNDOS 1.360 + trace_int19 1.361 +# else 1.362 + lssw %cs:EXEADRS(saved_ss_sp),%sp 1.363 + popaw 1.364 + retf 1.365 +# endif 1.366 +#else 1.367 +# ifdef SHUTDOWNDOS 1.368 + pushaw 1.369 + trace_int19 1.370 +# endif 1.371 + retf 1.372 +#endif 1.373 +#endif 1.374 + 1.375 +# read_sectors reads %di sectors into %es:0 buffer. 1.376 +# %es:0 is updated to the next memory location. 1.377 +# First, sectors are read sector by sector until 1.378 +# sector per track count is known. Then they are 1.379 +# read track by track. 1.380 +# Assume no error on first track. 1.381 + 1.382 +#ifdef FLOPPY_1440K_ONLY 1.383 +#define FLOPPY_HAS_2_SIDES hardcore heads count to 2 1.384 +#define FLOPPY_SECTORS 18 /* 18 sectors */ 1.385 +#else 1.386 +#define FLOPPY_HEADS 2 /* 2 heads minimum */ 1.387 +#endif 1.388 + 1.389 +return: 1.390 +#ifndef NO_DOTS 1.391 + movw $0xE2E,%ax 1.392 + movb $7,%bl 1.393 + int $0x10 1.394 +#endif 1.395 + ret 1.396 + 1.397 +check_limits: 1.398 +#ifndef FLOPPY_1440K_ONLY 1.399 + popw %dx 1.400 + cmpb %al, %cl # max sector known ? 1.401 + ja next_head # no -> store it 1.402 +#ifndef FLOPPY_HAS_2_SIDES 1.403 +#ifdef FLOPPY_HEADS 1.404 + cmpb $FLOPPY_HEADS, %dh # 2 heads minimum 1.405 + jb check_cylinder 1.406 +#endif 1.407 + cmpb %ah, %dh # max head known ? 1.408 + ja next_cylinder # no -> store it 1.409 +check_cylinder: 1.410 +#endif 1.411 +#endif 1.412 + pushaw 1.413 +#ifndef FLOPPY_1440K_ONLY 1.414 + cbw # %ah = 0 1.415 +#endif 1.416 + int $0x13 # reset controler 1.417 + popaw 1.418 + movb $1, %al # sector by sector... 1.419 +read_sectorslp: 1.420 + pushw %dx # some bios break dx... 1.421 +#ifndef FLOPPY_1440K_ONLY 1.422 + pushw %ax # limits 1.423 + subb %cl, %al # sectors remaining in track 1.424 + ja tolastsect 1.425 + movb $1, %al # 1 sector mini 1.426 +tolastsect: 1.427 +#else 1.428 + movb $FLOPPY_SECTORS+1, %al 1.429 + subb %cl, %al # sectors remaining in track 1.430 +#endif 1.431 + cbw 1.432 + cmpw %di, %ax 1.433 + jb more1trk 1.434 + movw %di, %ax # sectors to read 1.435 +more1trk: 1.436 + pushw %ax # save context 1.437 + movb $2, %ah # cmd: read chs 1.438 + int $0x13 1.439 +#ifndef FLOPPY_1440K_ONLY 1.440 + popw %dx # save %ax 1.441 + popw %ax # limits 1.442 +#else 1.443 + popw %ax # restore context 1.444 + popw %dx 1.445 +#endif 1.446 + jc check_limits 1.447 +#ifndef FLOPPY_1440K_ONLY 1.448 + xchgw %ax, %bp 1.449 + addw %dx,%cx # next sector 1.450 + movw %cx, %gs 1.451 + movw %es, %cx 1.452 + pushw %dx 1.453 + shlw $5, %dx 1.454 + addw %dx, %cx 1.455 + popw %dx 1.456 + subw %dx,%di # update sector counter 1.457 + popw %dx 1.458 +#else 1.459 + addw %ax,%cx # next sector 1.460 + movw %cx, %gs 1.461 + movw %es, %cx 1.462 + pushw %ax 1.463 + shlw $5, %ax 1.464 + addw %ax, %cx 1.465 + popw %ax 1.466 + subw %ax,%di # update sector counter 1.467 +#endif 1.468 +read_sectorsCX: 1.469 + movw %cx, %es # next location 1.470 + jz return 1.471 +read_sectors: 1.472 + movw %gs, %cx 1.473 +#ifndef FLOPPY_1440K_ONLY 1.474 +# al is last sector+1 1.475 +# ah is last cylinder+1 1.476 + xchgw %ax, %bp 1.477 +#endif 1.478 +#ifndef FLOPPY_1440K_ONLY 1.479 + cmpb %al,%cl # reach sector limit ? 1.480 + jne bdendlp 1.481 +next_head: 1.482 + movb %cl,%al 1.483 +#else 1.484 + cmpb $FLOPPY_SECTORS+1,%cl # reach sector limit ? 1.485 + jne bdendlp 1.486 +#endif 1.487 + movb $1,%cl # first sector 1.488 +#ifndef FLOPPY_HAS_2_SIDES 1.489 + incb %dh # next head 1.490 + cmpb %ah, %dh # reach head limit ? 1.491 + jne bdendlp 1.492 +next_cylinder: 1.493 + movb %dh,%ah 1.494 + movb $0,%dh # first head 1.495 +#else 1.496 + xorb %cl,%dh # next head 1.497 + jne bdendlp # reach head limit ? 1.498 +#endif 1.499 +# NOTE : support 256 cylinders max 1.500 + incb %ch # next cylinder 1.501 +read_first_sectors: 1.502 +bdendlp: 1.503 + jmp read_sectorslp 1.504 + 1.505 +#ifdef VCPI 1.506 +pagebuf = 0x98000 1.507 +tss = gdt_abs-40 1.508 +gdt = gdt_abs-32 1.509 +gdt_null = gdt_abs-32 1.510 +gdt_vcpi = gdt_abs-24 1.511 +gdt_vcpi2 = gdt_abs-16 1.512 +gdt_vcpi3 = gdt_abs-8 1.513 +gdt_abs: 1.514 + .word 0xFFFF 1.515 + .long 0x92000000 1.516 + .byte 0xCF,0 1.517 +gdt_code: 1.518 + .word 0xFFFF 1.519 +gdt_code_base: 1.520 + .long 0x9A000000+FLAT20(0) 1.521 + .byte 0x8F,0 1.522 +gdt_tss: 1.523 + .word 0x00FF 1.524 +gdt_tss_base: 1.525 + .long 0x89000000+FLAT20(tss) 1.526 + .byte 0,0 1.527 +gdtr: 1.528 +gdt_lim: 1.529 + .word 0xFFFF 1.530 +gdt_base: 1.531 + .long FLAT20(gdt) 1.532 +sw2pm_params: 1.533 +sw2pm_cr3: 1.534 + .long pagebuf+0x1000 1.535 +sw2pm_gdtr_ptr: 1.536 + .long FLAT20(gdtr) 1.537 +sw2pm_idtr_ptr: 1.538 + .long FLAT20(idtr) 1.539 +sw2pm_ldtr: 1.540 + .word 0 1.541 +sw2pm_tr: 1.542 +SEL_TSS = gdt_tss-gdt_null 1.543 + .word SEL_TSS 1.544 +sw2pm_jumpaddr: 1.545 + .long pm_code 1.546 +SEL_CODE = gdt_code-gdt_null 1.547 + .word SEL_CODE 1.548 +idtr: 1.549 +idt_lim: 1.550 + .word 0x03FF 1.551 +idt_base: 1.552 + .long 0 1.553 +# ifndef SHUTDOWNDOS 1.554 +saved_ss_sp: 1.555 + .word stacktop-4-16-4,INITSEG 1.556 +# endif 1.557 +#endif