wok-tiny diff linux/stuff/bootloader.S @ rev 95
linux: add bootloader
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Tue Oct 06 21:04:42 2015 +0200 (2015-10-06) |
parents | |
children | 2c3b4f47fbf5 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/linux/stuff/bootloader.S Tue Oct 06 21:04:42 2015 +0200 1.3 @@ -0,0 +1,824 @@ 1.4 +BOOTSEG = 0x07C0 /* original address of boot-sector */ 1.5 +SYSSEG = 0x1000 /* historical load address >> 4 */ 1.6 +INITSEG = 0x9000 /* boot address >> 4 */ 1.7 +SETUPSEG = 0x9020 /* setup address >> 4 */ 1.8 +ASK_VGA = -3 1.9 + 1.10 +#ifndef SVGA_MODE 1.11 +#define SVGA_MODE ASK_VGA 1.12 +#endif 1.13 + 1.14 +#ifndef RAMDISK 1.15 +#define RAMDISK 0 1.16 +#endif 1.17 + 1.18 +#ifndef ROOT_RDONLY 1.19 +#define ROOT_RDONLY 1 1.20 +#endif 1.21 + 1.22 +/* Assume protocol 2.00+ (kernel >= 1.3.73) */ 1.23 +/* feature set */ 1.24 +#define EXE_SUPPORT real mode dos .exe file support 1.25 +// #define EXE_ONLY remove floppy code 1.26 +#define EXE_CMDLINE kernel >= 2.4 1.27 +// #define FLOPPY_CMDLINE kernel >= 2.4 1.28 +// #define OLDCMDLINE kernel < 2.4 1.29 +#define MORETHAN16M up to 4Gb RAM, not 16Mb 1.30 +#define KEYBOARDLESS_SUPPORT scan floppy swap each 5 seconds 1.31 +// #define FAT12_SUPPORT will format the floppy free space in FAT 12 1.32 +// #define REALMODE_NOT_CHECKED exe crash when started in vm86 1.33 +// #define SINGLE_FLOPPY Everytihng fit in a single floppy 1.34 +// #define EDIT_CMDLINE 1.35 +// #define MOVE_CMDLINE 1.36 +#define INITRD_SUPPORT 1.37 +// #define INITRD_AUTOADDR Hole in 16Mb..32Mb 1.38 +// #define MULTI_INITRD Russian dolls 1.39 +// #define README_SUPPORT 1.40 +// #define COUNTER Show floppy number 1.41 +#define LABEL "SliTaz" 1.42 + 1.43 + .code16 1.44 + .org 0 1.45 + 1.46 +bootsect_start: 1.47 + 1.48 +cur_initrd_size_ofs = 494 1.49 +ramdisk_image_ofs = 0x218 1.50 +ramdisk_image = bootsect_start+ramdisk_image_ofs 1.51 +ramdisk_size_ofs = 0x21C 1.52 +ramdisk_size = bootsect_start+ramdisk_size_ofs 1.53 +cmd_line_ptr_ofs = 0x228 1.54 +cmd_line_ptr = bootsect_start+cmd_line_ptr_ofs 1.55 +setup_sects = bootsect_start+497 1.56 +syssize = bootsect_start+500 1.57 +boot_flag_ofs = 510 1.58 +boot_flag = bootsect_start+boot_flag_ofs 1.59 + 1.60 + 1.61 +stacktop = 0x9E00 # in 0x8000 .. 0xA000 1.62 +zeroed = 48+10 # gdt + zeroed registers 1.63 +.macro INIT_REGS 1.64 + movw $stacktop-zeroed, %di # stacktop is an arbitrary value >= 1.65 + # length of bootsect + length of 1.66 + # setup + room for stack; 1.67 + # 12 is disk parm size. 1.68 + pushw $INITSEG 1.69 + popw %ss # %ss contain INITSEG 1.70 + movw %di, %sp # put stack at INITSEG:stacktop-... 1.71 + pushw %ss 1.72 + popw %es # %es = %ss = INITSEG 1.73 + xorw %ax, %ax # %ax = 0 1.74 +#if defined(EXE_CMDLINE) 1.75 + movw $zeroed+1, %cx # clear gdt + offset, %ds, limits, cmdline="" 1.76 + rep # don't worry about cld 1.77 + stosb # already done above 1.78 + decw %di 1.79 +#else 1.80 + movw $zeroed/2, %cx # clear gdt + offset, %ds, limits 1.81 + rep # don't worry about cld 1.82 + stosw # already done above 1.83 +#endif 1.84 + popw %bx # offset = 0 1.85 +.endm 1.86 + 1.87 +#ifdef FAT12_SUPPORT 1.88 + jmp fdstart 1.89 + nop 1.90 + .ascii "SLITAZ " 1.91 + .word 512 // 0B: bytes per sector 1.92 + .byte 1 // 0D: sectors per cluster 1.93 + .word 2880 // 0E: reserved seectors 1.94 + .byte 2 // 10: FAT number 1.95 + .word 64 // 11: root entries 4x 16 1.96 + .word 2880 // 13: total sectors 1.97 + .byte 0xF0 // 15: media id (or F9) 1.98 +#endif 1.99 + 1.100 +#ifdef EXE_SUPPORT 1.101 +#define CODESZ 0x8000 1.102 +#define EXEADRS(x) x+0xE0 1.103 + decw %bp // Magic number: MZ 1.104 + popw %dx 1.105 +#ifdef EXE_ONLY 1.106 + .word 512 // Bytes on last page of file 1.107 +#else 1.108 + jmp fdstart // Bytes on last page of file 1.109 +#endif 1.110 + .word (CODESZ+511)/512 // Pages in file 1.111 + .word 0 // Relocations 1.112 + .word 2 // Size of header in paragraphs 1.113 + .word 4096 // Minimum extra paragraphs needed 1.114 + .word -1 // Maximum extra paragraphs needed 1.115 + .word (CODESZ+15)/16 // Initial (relative) SS value 1.116 + .word stacktop+4 // Initial SP value (+callf) 1.117 + .word 0 // Checksum 1.118 + .word EXEADRS(comstart) // Initial IP value 1.119 + .word 0xFFF0 // Initial (relative) CS value 1.120 +#if defined(EXE_ONLY) || defined(SINGLE_FLOPPY) || defined(COUNTER) 1.121 +// .word 0x001C // File address of relocation table 1.122 +// .word 0,0,0 // Overlay number 1.123 + .ascii "(SliTaz)" 1.124 +#else 1.125 +swap_floppy: 1.126 + .ascii "Next!" 1.127 + .byte 7,13,0 # swap detection needs 13, 0 1.128 +#endif 1.129 +#ifdef OLDCMDLINE 1.130 +# ifdef FLOPPY_CMDLINE 1.131 + .word 0 # 0xA33F 1.132 + .word 0 # stacktop 1.133 +# else 1.134 + .word 0xA33F 1.135 + .word stacktop 1.136 +# endif 1.137 +#endif 1.138 +#ifndef EXE_ONLY 1.139 +fdstart: 1.140 + pushw %dx 1.141 +#endif 1.142 +#endif 1.143 + 1.144 +LOADSEG = 0x8000 # 0x1000 multiple, up to 512K zImage 1.145 +LOADSZ = 0x10000 1.146 + 1.147 +#if defined(EXE_SUPPORT) || defined(EXE_ONLY) 1.148 +A20BUFFER = 0x68000 # a20 gate / himem.sys support 1.149 +#define USEA20BUFFER 1.150 +#endif 1.151 + 1.152 +#ifndef EXE_ONLY 1.153 +# bootsect_start: 1.154 +#ifdef EXE_SUPPORT 1.155 + call initregs 1.156 + cwd # floppy = head = 0 1.157 +#else 1.158 + INIT_REGS 1.159 +#endif 1.160 + popw %ds # %ds = 0 1.161 + movb setup_sects+0x7C00, %al # read bootsector + setup 1.162 + incw %ax # %ax = setup_sects+bootsect 1.163 + popw %fs # %fs = 0 1.164 + 1.165 +# Many BIOS's default disk parameter tables will not recognize 1.166 +# multi-sector reads beyond the maximum sector number specified 1.167 +# in the default diskette parameter tables - this may mean 7 1.168 +# sectors in some cases. 1.169 +# 1.170 +# Since single sector reads are slow and out of the question, 1.171 +# we must take care of this by creating new parameter tables 1.172 +# (for the first disk) in RAM. We can set the maximum sector 1.173 +# count to 36 - the most we will encounter on an ED 2.88. 1.174 +# 1.175 +# High doesn't hurt. Low does. Let's use the max: 63 1.176 + 1.177 + cli 1.178 + ldsw 0x78(%bx), %si # %ds:%bx+0x78 is parameter table address 1.179 + popw %di 1.180 + pushw %es 1.181 + pushw %di 1.182 +#ifdef FLOPPY_CMDLINE 1.183 + movw $0, %bp # patched by installer (7C22) 1.184 +skipcmdline: 1.185 +#define cmd_line_ptr 0x22 1.186 +#endif 1.187 + movb $6, %cl # copy 12 bytes 1.188 + rep # don't worry about cld 1.189 + movsw # already done above 1.190 + pushw %ss 1.191 + popw %ds # now %ds = %es = %ss = INITSEG 1.192 + popl %fs:0x78(%bx) # update parameter table address 1.193 + movb $63, 0x4-12(%di) # patch sector count, %di = stacktop 1.194 + 1.195 + xchg %ax, %di # sector count 1.196 + popw %ax # limits = 0 1.197 + incw %cx # cylinder 0, sector 1, clear Z 1.198 + call read_first_sectors # read setup 1.199 +#ifdef README_SUPPORT 1.200 + xorw %si, %si 1.201 + orw readme, %si 1.202 + jz readmeend 1.203 +readmeloop: 1.204 + call puts 1.205 + jz readmeend 1.206 + call wait4key 1.207 + cmpb $27, %al 1.208 + jne readmeloop 1.209 +readmeend: 1.210 +#endif 1.211 +#endif 1.212 +loadsys: 1.213 + movw $0x200,%si 1.214 +type_of_loader = 0x10 1.215 +loadflags = 0x11 1.216 +heap_end_ptr = 0x24 1.217 + orw $0x8020, type_of_loader(%si) # loader type = 0x20 = bootsect-loader 1.218 + movb $(stacktop-0x300)/256, heap_end_ptr+1(%si) 1.219 + call puts_version # show which kernel we are loading 1.220 + 1.221 +#ifdef FLOPPY_CMDLINE 1.222 +# The cmdline can be entered and modifed at boot time. 1.223 +# Only characters before the cursor are passed to the kernel. 1.224 + 1.225 + xorw %si, %si 1.226 + orw cmd_line_ptr-7(%bx), %si 1.227 + jz nocmdline 1.228 +#ifdef OLDCMDLINE 1.229 + movw $0xA33F, cmd_line_ptr-2-7(%bx) 1.230 +#endif 1.231 + call puts 1.232 +#ifdef EDIT_CMDLINE 1.233 +cmdlp: 1.234 + movb $0x20, %al # clear end of line 1.235 +cmdlpz: 1.236 + call putc # with Space 1.237 + subb $0x18, %al # and BackSpace 1.238 + jnc cmdlpz 1.239 + decw %si 1.240 +cmdget: 1.241 +#ifdef KEYBOARDLESS_SUPPORT 1.242 + call wait4key 1.243 +#else 1.244 + int $0x16 1.245 +#endif 1.246 + cbw # %ah = 0, get keyboard character 1.247 + cmpb $8, %al # BackSpace ? 1.248 + je cmdbs 1.249 + movb %al, (%si) # store char 1.250 + lodsw # %si += 2 1.251 +cmdbs: 1.252 + cmpw %si, cmd_line_ptr-7(%bx) 1.253 + je cmdget 1.254 + call putc 1.255 + cmpb $10, %al # Enter/linefeed ? 1.256 + jne cmdlp 1.257 + movb %bh,-2(%si) # set end of string and remove CR 1.258 +endcmdline: 1.259 +#endif 1.260 +#ifdef MOVE_CMDLINE 1.261 + pushw %ss 1.262 + popw %es 1.263 + movw $0x8000, %di 1.264 + movw %di, %si 1.265 + xchgw %si, cmd_line_ptr-7(%bx) 1.266 + movb $0x2, %ch 1.267 + rep 1.268 + movsb 1.269 +#endif 1.270 +nocmdline: 1.271 +#endif 1.272 + 1.273 +# This routine loads the system at address LOADSEG, making sure 1.274 +# no 64kB boundaries are crossed. We try to load it as fast as 1.275 +# possible, loading whole tracks whenever we can. 1.276 + 1.277 +.macro autoaddr base 1.278 +#ifdef INITRD_AUTOADDR 1.279 + movb $0x88, %ah 1.280 + int $0x15 1.281 + //jc NeedMoreRAM # error code 80 or 86 1.282 + cmpw $0xB000, %ax # more than 45M ? 1.283 + jb NeedMoreRAM 1.284 + movb %ch, bootsect_dst_base_hi(%si) # initramfs @ 32M 1.285 + movb %ch, ramdisk_image_ofs+3-\base 1.286 +NeedMoreRAM: 1.287 +#endif 1.288 +.endm 1.289 + 1.290 +bootsect_src_limit = 16 1.291 +bootsect_dst_limit = 24 1.292 +bootsect_src_base = 18 1.293 +bootsect_dst_base = 26 # bits 0..23 1.294 +bootsect_dst_base_hi = 31 # bits 24..31 1.295 + popw %bx # clear %bx 1.296 + movw %sp, %si # for bootsect_gdt 1.297 +init_gdt: 1.298 + decw bootsect_src_limit(%bx,%si) # max 64Kb 1.299 + movw $0x9300+(LOADSEG/0x1000), bootsect_src_base+2(%bx,%si) 1.300 + xorb $bootsect_dst_limit-bootsect_src_limit, %bl 1.301 + jne init_gdt 1.302 +#ifdef INITRD_SUPPORT 1.303 + movw $syssize, %bx 1.304 + movb $5, %cl 1.305 +code32_start = 0x214 1.306 + movw code32_start+1, %ax # destination = 0x00100000 or 0x00010000 1.307 +initrdlp: 1.308 + movl (%bx), %ebx 1.309 + decl %ebx 1.310 + shrl %cl, %ebx 1.311 +#else 1.312 +code32_start = 0x214 1.313 + movw code32_start+1, %ax # destination = 0x00100000 or 0x00010000 1.314 + movl syssize, %ebx 1.315 + decl %ebx 1.316 + shrl $5, %ebx 1.317 +#endif 1.318 +#ifdef MORETHAN16M 1.319 + incl %ebx 1.320 +#else 1.321 + incw %bx 1.322 +#endif 1.323 +#ifdef USEA20BUFFER 1.324 + movw $0x00100000>>8, %di 1.325 +#endif 1.326 +syslp: 1.327 +#ifdef USEA20BUFFER 1.328 + cmpw %ax, %di 1.329 + jne nota20 1.330 + xorw $(0x00100000+A20BUFFER)>>8, %ax 1.331 +nota20: 1.332 +#endif 1.333 + movw %ax, bootsect_dst_base+1(%si) 1.334 +#ifdef MORETHAN16M 1.335 + movl $LOADSZ/512, %edi # size in sectors 1.336 + subl %edi, %ebx 1.337 +#else 1.338 + movw $LOADSZ/512, %di # size in sectors 1.339 + subw %di, %bx 1.340 +#endif 1.341 + pushf 1.342 + jnc not_last 1.343 + addw %bx, %di 1.344 +not_last: 1.345 +#ifdef MULTI_INITRD 1.346 + pushw %di 1.347 +#endif 1.348 + pushw %ax 1.349 + pushw %bx 1.350 + pushw %si 1.351 + xorw %bx,%bx 1.352 + pushw $LOADSEG 1.353 + popw %es 1.354 +#ifdef EXE_ONLY 1.355 + call read_sectors_dos 1.356 +#else 1.357 +patchcall: 1.358 + call read_sectors # update %bp 1.359 +#endif 1.360 + popw %si 1.361 + popw %bx 1.362 + movw %es, %cx # word count = LOADSZ/2 (= LOADSEG) 1.363 + movb $0x87, %ah 1.364 + pushw %ss 1.365 + popw %es # restore es 1.366 + int $0x15 # max 16M, maybe more... 1.367 + popw %ax 1.368 +#ifdef MULTI_INITRD 1.369 + popw %di 1.370 + shlw $1,%di # sectors to pages 1.371 + addw %di, %ax 1.372 +#ifdef MORETHAN16M 1.373 + adcb %cl, bootsect_dst_base_hi(%si) # breaks 16M limit ? 1.374 +#endif 1.375 +#else 1.376 +#ifdef MORETHAN16M 1.377 + addw $0x100, %ax # next dest (ax+=LOADSZ/256) 1.378 + adcb %cl, bootsect_dst_base_hi(%si) # breaks 16M limit ? 1.379 +#else 1.380 + incb %ah # next dest (ax+=LOADSZ/256) 1.381 +#endif 1.382 +#endif 1.383 +#ifdef USEA20BUFFER 1.384 + movw $(LOADSZ+A20BUFFER)>>8, %di 1.385 +#endif 1.386 + popf 1.387 + ja syslp 1.388 +#ifdef INITRD_SUPPORT 1.389 +initrdlp2: 1.390 +#ifdef INITRD_AUTOADDR 1.391 + movw $0x209, %cx 1.392 +#else 1.393 + movb $9, %cl 1.394 +#endif 1.395 +#ifdef MULTI_INITRD 1.396 + movw $cur_initrd_size_ofs, %di 1.397 + movw (%di), %bx 1.398 + addw $4, (%di) 1.399 + shrw %cl, boot_flag_ofs-cur_initrd_size_ofs(%di) 1.400 + je nextInitrd 1.401 + orw %bx, %bx 1.402 + je bootit # no initrd 1.403 + autoaddr cur_initrd_size_ofs(%di) 1.404 + movw ramdisk_image+1,%ax 1.405 + jmp initrdlp 1.406 +nextInitrd: 1.407 + pushw %bx 1.408 + movl -4(%bx), %ebx 1.409 + addl %ebx, ramdisk_size_ofs-cur_initrd_size_ofs(%di) 1.410 + movb $swap_floppy2-0x100, %cs:dpy_swap_floppy-2+0x7C00 1.411 + popw %bx 1.412 + cmpb 2(%di), %bl 1.413 + jb initrdlp 1.414 +#else 1.415 + movw $ramdisk_size, %bx 1.416 +#ifdef MORETHAN16M 1.417 + cmpb %cl, ramdisk_image+2-ramdisk_size(%bx) 1.418 + jb bootit 1.419 + autoaddr ramdisk_size_ofs(%bx) 1.420 + movw ramdisk_image+1,%ax 1.421 + shrw %cl, boot_flag-ramdisk_size(%bx) 1.422 + jne initrdlp 1.423 +#else 1.424 + movw ramdisk_image+1,%ax 1.425 + cmpw %ax, bootsect_dst_base+1(%si) 1.426 + jb initrdlp 1.427 +#endif 1.428 +#endif 1.429 +bootit: 1.430 +#ifdef USEA20BUFFER 1.431 +#ifdef MORETHAN16M 1.432 +#ifdef INITRD_SUPPORT 1.433 + movb %al, bootsect_dst_base_hi(%si) // assume @initrd 64k aligned 1.434 + //movb $0, bootsect_dst_base_hi(%si) 1.435 +#else 1.436 + movb %cl, bootsect_dst_base_hi(%si) 1.437 +#endif 1.438 +#endif 1.439 + movb $0x10, bootsect_dst_base+2(%si) // assume @initrd 64k aligned 1.440 + //movw $0x1000, bootsect_dst_base+1(%si) // assume @initrd page aligned 1.441 + movw $A20BUFFER/0x100, bootsect_src_base+1(%si) 1.442 + movb $0x87, %ah 1.443 + int $0x15 1.444 +#endif 1.445 +#endif 1.446 +#ifdef MULTI_INITRD 1.447 + jcxz read_sectorslp 1.448 +#endif 1.449 + 1.450 +# This procedure turns off the floppy drive motor, so 1.451 +# that we enter the kernel in a known state, and 1.452 +# don't have to worry about it later. 1.453 + 1.454 +kill_motor: 1.455 +#ifdef USEA20BUFFER 1.456 + cwd 1.457 +#else 1.458 + xchgw %ax, %di # reset FDC (%di < 128) 1.459 +#endif 1.460 + int $0x13 1.461 + 1.462 +# After that (everything loaded), we jump to the setup-routine 1.463 +# loaded directly after the bootblock: 1.464 +# Segments are as follows: %ds = %ss = INITSEG 1.465 + 1.466 + ljmp $SETUPSEG, $0 1.467 + 1.468 +# read_sectors reads %di sectors into %es:0 buffer. 1.469 +# %es:0 is updated to the next memory location. 1.470 +# First, sectors are read sector by sector until 1.471 +# sector per track count is known. Then they are 1.472 +# read track by track. 1.473 +# Assume no error on first track. 1.474 + 1.475 +#ifndef EXE_ONLY 1.476 + 1.477 +#define FLOPPY_CYLINDERS 80 1.478 +#define FLOPPY_HEADS 2 1.479 + 1.480 +.macro putsmsg 1.481 +#if !defined(SINGLE_FLOPPY) && defined(COUNTER) 1.482 + movw $msgdigit+1-msg, %bx 1.483 +nextdigit: 1.484 + andb $0xF0, (%bx,%si) 1.485 + decw %bx 1.486 + incb (%bx,%si) 1.487 + cmpb $'9', (%bx,%si) 1.488 + ja nextdigit 1.489 +#endif 1.490 + call puts 1.491 +.endm 1.492 + 1.493 +check_limits: 1.494 + popw %dx 1.495 + cmpb %al, %cl # max sector known ? 1.496 + ja next_head # no -> store it 1.497 + pushaw 1.498 + int $0x13 # reset controler 1.499 + stc 1.500 + call putcdot # print '-' 1.501 +read_sectorslp: 1.502 + popaw 1.503 +bdendlp: 1.504 + pushw %dx # some bios break dx... 1.505 + pushw %ax # limits 1.506 + subb %cl, %al # sectors remaining in track 1.507 + ja tolastsect 1.508 + movb $1, %al # 1 sector mini 1.509 +tolastsect: 1.510 + cmpw %di, %ax 1.511 + jb more1trk 1.512 + movw %di, %ax # sectors to read 1.513 +more1trk: 1.514 + pushw %ax # save context 1.515 + movb $2, %ah # cmd: read chs 1.516 + int $0x13 1.517 + popw %dx # save %ax 1.518 + popw %ax # limits 1.519 + jc check_limits 1.520 + xchgw %ax, %bp 1.521 + addw %dx,%cx # next sector 1.522 + movw %cx, %gs 1.523 + addb %dl,%bh 1.524 + addb %dl,%bh # next location 1.525 + subw %dx,%di # update sector counter 1.526 + popw %dx 1.527 + jz putcdot 1.528 +read_sectors: 1.529 + movw %gs, %cx 1.530 +# al is last sector+1 1.531 +# ah is 0 1.532 + xchgw %ax, %bp 1.533 + cmpb %al,%cl # reach sector limit ? 1.534 + jne bdendlp 1.535 +next_head: 1.536 + movb %cl,%al 1.537 + movb $1, %cl # first sector 1.538 +inc_head: 1.539 + xorb %cl, %dh # next head 1.540 + jne bdendlp # reach head limit ? 1.541 + incb %ch # next cylinder 1.542 +read_first_sectors: 1.543 +#ifdef SINGLE_FLOPPY 1.544 + jmp bdendlp 1.545 +#else 1.546 + cmpb $FLOPPY_CYLINDERS,%ch # reach cylinder limit ? 1.547 + jne bdendlp 1.548 +next_floppy: 1.549 + movb $0,%ch # first cylinder 1.550 + pushaw 1.551 + movw $swap_floppy,%si 1.552 +dpy_swap_floppy: 1.553 +#ifdef KEYBOARDLESS_SUPPORT 1.554 + pushw %bx 1.555 + putsmsg 1.556 + popw %bx 1.557 + movw %si, %bp 1.558 +waitfloppy: 1.559 + call wait 1.560 + jne waitfloppydone 1.561 +#ifdef MULTI_INITRD 1.562 + decb (%si) # max_timeouts 1.563 +gobootit: 1.564 + //movw ramdisk_size+2-max_timeouts(%si), %cx 1.565 + .byte 0x8B, 0x4C, ramdisk_size+2-max_timeouts 1.566 + jz bootit 1.567 +#endif 1.568 + pushw %dx # some bios break dx... 1.569 + cbw 1.570 + int $0x13 # reset FDC 1.571 + movw $0x201,%ax 1.572 + int $0x13 # read first sector 1.573 + popw %dx 1.574 + rclb $1,%ah # floppy changed 06=>0D no error 00 1.575 + cmpb -2(%bp), %ah # 0D then 00 1.576 + jne waitfloppy # no => try again 1.577 + incw %bp 1.578 + decw %ax # was 0001 ? 1.579 + jne waitfloppy 1.580 +waitfloppydone: 1.581 +#else 1.582 + putsmsg 1.583 + cbw # %ah = 0, get keyboard character 1.584 + int $0x16 1.585 +#endif 1.586 +#ifdef MULTI_INITRD 1.587 + orb $0x20, %al 1.588 + cmp $'b', %al 1.589 + jz gobootit 1.590 +#endif 1.591 + jmp read_sectorslp 1.592 +#endif 1.593 +#endif 1.594 + 1.595 +#ifdef EXE_SUPPORT 1.596 +read_sectors_dos: 1.597 + xorw %dx, %dx // write to %ds:%dx, not %es:%bx 1.598 + call read_sectors_dosz 1.599 +read_sectors_dosz: 1.600 + pushw %es 1.601 + popw %ds 1.602 + movb $0x3F, %ah // read 1.603 + movw %di, %cx 1.604 + shlw $8, %cx // byte count / 2 1.605 + movw %bp, %bx 1.606 + int $0x21 1.607 + xchgw %ax, %dx 1.608 + pushw %ss 1.609 + popw %ds 1.610 +#endif 1.611 + 1.612 +putcdot: 1.613 + movb $'.'+3, %al // . = success, - = failure 1.614 +putclf: 1.615 + sbbb $3, %al 1.616 +putc: 1.617 + movb $0xe, %ah 1.618 + movw $7, %bx # one dot each 64k 1.619 + int $0x10 1.620 + cmp $0xd, %al # CR ? 1.621 + je putclf 1.622 + ret 1.623 + 1.624 +#ifdef KEYBOARDLESS_SUPPORT 1.625 +clock = 0x46C 1.626 +wait: 1.627 +wait4key: 1.628 + movw $clock, %di 1.629 +#define DELAY 5 1.630 + movb $257-(DELAY*182)/10, %fs:(%di) 1.631 +waitkbd: 1.632 + movw $0x10D, %ax # test keyboard, timeout => CR 1.633 + cmpb %fs:(%di),%ah 1.634 + je waitdone 1.635 + int $0x16 1.636 + jz waitkbd 1.637 + cbw 1.638 + int $0x16 # eat char 1.639 + movw %di, %fs # disable timeout 1.640 + incw %di # clear Z 1.641 +waitdone: 1.642 + ret 1.643 +#endif 1.644 + 1.645 +#ifdef EXE_SUPPORT 1.646 +comstart: 1.647 +#ifndef EXE_ONLY 1.648 + call initregs 1.649 +#else 1.650 + INIT_REGS 1.651 +#endif 1.652 + movb EXEADRS(setup_sects), %al # read bootsector + setup 1.653 + incw %ax 1.654 +#ifdef EXE_CMDLINE 1.655 + movw $0x80, %si 1.656 + movb (%si), %cl 1.657 + incw %si 1.658 +# ifdef OLDCMDLINE 1.659 +# ifdef FLOPPY_CMDLINE 1.660 + jcxz nocmdline 1.661 + movw %di, EXEADRS(0x22) 1.662 + movw $0xA33F, 0x7F(%si) 1.663 +# endif 1.664 +# endif 1.665 + rep 1.666 + movsb 1.667 +nocmdline: 1.668 + xchgw %ax, %di 1.669 +# ifdef HELP 1.670 + cmpb $'?', -1(%si) 1.671 + movw $EXEADRS(0x200), %si 1.672 + je puts_version 1.673 +# ifndef REALMODE_NOT_CHECKED 1.674 + smsww %ax 1.675 + andb $1, %al 1.676 + jne puts_version // real mode only... 1.677 +# endif 1.678 +# endif 1.679 +#else 1.680 + xchgw %ax, %di 1.681 +#endif 1.682 + movw 0x2C(%bx), %ds // DOS 3.0+ 1.683 +loop1: 1.684 + incw %bx 1.685 + cmpw %cx, (%bx) 1.686 + jne loop1 1.687 + leaw 4(%bx), %dx // %ds:%dx filename 1.688 +#if !defined(REALMODE_NOT_CHECKED) && defined(EXE_CMDLINE) && defined(HELP) 1.689 + movb $0x3D, %ah // open, access = RO 1.690 +#else 1.691 + movw $0x3D00, %ax // open, access = RO 1.692 +#endif 1.693 + int $0x21 1.694 + jc dosexit 1.695 + xchgw %ax, %bp // fd 1.696 + call read_sectors_dos // update %ds 1.697 +#ifndef EXE_ONLY 1.698 + addb $read_sectors_dos-read_sectors, patchcall+1 1.699 +#endif 1.700 +#ifdef EXE_CMDLINE 1.701 +# ifdef OLDCMDLINE 1.702 + movw $0x202, %bx 1.703 + cmpw %bx, 0x206-0x202(%bx) # new cmdline for version >= 0x202 1.704 + jb oldcmdline 1.705 + movw $INITSEG/16+stacktop/256, cmd_line_ptr+1-0x202(%bx) 1.706 +# else 1.707 + movw $INITSEG/16+stacktop/256, cmd_line_ptr+1 1.708 +# endif 1.709 +oldcmdline: 1.710 +#endif 1.711 +// ljmp $INITSEG, $loadsys 1.712 + pushw %ds 1.713 + .byte 0x6A, loadsys-bootsect_start 1.714 + lretw 1.715 +#endif 1.716 +#define kernel_version_offset 0xE 1.717 +puts_version: 1.718 + addw kernel_version_offset(%si),%si # starting protocol 2.00, Kernel 1.3.73 1.719 +puts: 1.720 + movb $0xd, %al # CR 1.721 +putcs: 1.722 + call putc 1.723 + lodsb 1.724 + cmpb $0, %al # end of string is any byte <= 0 1.725 + jg putcs 1.726 +dosexit: 1.727 + ret 1.728 + 1.729 +#if !defined(FLOPPY_ONLY) && !defined(EXE_ONLY) 1.730 +initregs: 1.731 + popw %si 1.732 + INIT_REGS 1.733 + pushw %si # use new stack 1.734 + ret 1.735 +#endif 1.736 + 1.737 + 1.738 +#if !defined(SINGLE_FLOPPY) && !defined(EXE_SUPPORT) 1.739 +#ifdef MULTI_INITRD 1.740 +swap_floppy2: 1.741 + .ascii "B or " 1.742 +#endif 1.743 +swap_floppy: 1.744 +#ifdef COUNTER 1.745 +msg: 1.746 + .ascii "Put disk 00" 1.747 +msgdigit: 1.748 + .ascii "1, press Enter." 1.749 +#else 1.750 + .ascii "Next!" 1.751 +#endif 1.752 + .byte 7,13,0 # swap detection needs 13, 0 1.753 +#ifdef MULTI_INITRD 1.754 +max_timeouts: 1.755 + .byte 20 1.756 +table: 1.757 + .org cur_initrd_size_ofs 1.758 +cur_initrd_size: 1.759 + .word table 1.760 + .byte table+4-256 1.761 +#endif 1.762 +#endif 1.763 +#ifdef README_SUPPORT 1.764 + .org 0x1EF 1.765 +readme: 1.766 + .word 0 1.767 +#endif 1.768 +#ifdef LABEL 1.769 + .ascii LABEL 1.770 +#endif 1.771 + .org 0x1F1 1.772 + 1.773 +#ifdef MULTI_INITRD 1.774 + .org 0x400 1.775 + 1.776 + orw $0x8020, type_of_loader(%si) # loader type = 0x20 = bootsect-loader 1.777 + pushal 1.778 + 1.779 + movw $10+16, %cx 1.780 +fillbuf: 1.781 + pushw $0 1.782 + loop fillbuf 1.783 + popal // clear regiters 1.784 +maploop: 1.785 + movw %sp, %di // %es = %ss 1.786 + movb $20, %cl 1.787 + movw $0xE820, %ax 1.788 + movl $0x534d4150, %edx 1.789 + int $0x15 1.790 + sbbl %eax, %edx 1.791 + jne mapdone 1.792 + decw 16(%di) 1.793 + jne notram 1.794 + addw 8+2(%di), %bp 1.795 +notram: 1.796 + orw %bx, %bx 1.797 + jnz maploop 1.798 +mapdone: 1.799 + addw $20, %sp 1.800 + shrw $20-16,%bp 1.801 + jnz mapdone2 1.802 + movb $0x88, %ah 1.803 + int $0x15 1.804 + xchgw %ax, %bp 1.805 + shrw $10, %bp 1.806 +mapdone2: 1.807 + incw %bp 1.808 +// %bp : nb Mb 1.809 + call here 1.810 +here: 1.811 + popw %di 1.812 + movw $0x1EE, %si 1.813 + lodsw 1.814 +sizeloop: 1.815 + scasw // %di += 2 1.816 + addw $4, %ax 1.817 + cmpb %al, (%si) 1.818 + jbe sizedone 1.819 + cmpw %bp, sizes-here(%di) 1.820 + jbe sizeloop 1.821 + movb %al, (%si) 1.822 +sizedone: 1.823 + popal 1.824 + lret // need %si 1.825 +sizes: 1.826 + 1.827 +#endif