wok annotate memtest/stuff/bootloader.S @ rev 19159
/etc/init.d/*: use 'action' in pair with 'status'.
'action' returns translated message, so why not to add full translatable /etc/init.d/* content
'action' returns translated message, so why not to add full translatable /etc/init.d/* content
author | Aleksej Bobylev <al.bobylev@gmail.com> |
---|---|
date | Thu May 26 20:16:45 2016 +0300 (2016-05-26) |
parents | 99c5dab1a371 |
children | 2638f54b93f1 |
rev | line source |
---|---|
pascal@15188 | 1 SYSSEG = 0x1000 |
pascal@15188 | 2 INITSEG = 0x9000 |
pascal@15188 | 3 SETUPSEG = 0x9020 |
pascal@15188 | 4 |
pascal@15188 | 5 .text |
pascal@15188 | 6 .code16 |
pascal@15188 | 7 .org 0 |
pascal@15188 | 8 .globl _start |
pascal@15188 | 9 _start: |
pascal@15188 | 10 |
pascal@15188 | 11 #define CODESZ 512 |
pascal@15188 | 12 |
pascal@15188 | 13 /* some extra features */ |
pascal@15188 | 14 #define EXE_SUPPORT real mode dos .exe file support |
pascal@15188 | 15 #define CMDLINE 0x9E00 |
pascal@15188 | 16 #define HELP store help message for /? argument |
pascal@15188 | 17 #define CHECK_REALMODE does not support vm86 |
pascal@15188 | 18 |
pascal@15188 | 19 /* some contraints to reduce the size */ |
pascal@15188 | 20 //#define FLOPPY_1440K_ONLY 1.44M floppies support only |
pascal@15188 | 21 #define NO_CURSOR_DEFINITION |
pascal@15188 | 22 |
pascal@15188 | 23 #ifdef EXE_SUPPORT |
pascal@15188 | 24 #define EXEADRS(x) x+0xE0 |
pascal@15188 | 25 stacktop = 0x9E00 # in 0x8000 .. 0xA000 |
pascal@15188 | 26 decw %bp // Magic number: MZ |
pascal@15188 | 27 popw %dx |
pascal@15188 | 28 jmp start // Bytes on last page of file |
pascal@15188 | 29 .word (CODESZ+511)/512 // Pages in file |
pascal@15188 | 30 .word 0 // Relocations |
pascal@15188 | 31 .word (end_header-_start)/16 // Size of header in paragraphs |
pascal@15188 | 32 .word 4096 // Minimum extra paragraphs needed |
pascal@15188 | 33 .word -1 // Maximum extra paragraphs needed |
pascal@15188 | 34 .word (CODESZ+15)/16 // Initial (relative) SS value |
pascal@15188 | 35 .word stacktop // Initial SP value |
pascal@15188 | 36 .word 0 // Checksum |
pascal@15188 | 37 .word EXEADRS(comstart) // Initial IP value |
pascal@15188 | 38 .word 0xFFF0 // Initial (relative) CS value |
pascal@15188 | 39 // .word 0x001C // File address of relocation table |
pascal@15188 | 40 // .word 0,0,0 // Overlay number |
pascal@15188 | 41 .ascii "(SliTaz)" |
pascal@15188 | 42 end_header: |
pascal@15188 | 43 comstart: |
pascal@15470 | 44 cld # assume nothing |
pascal@15188 | 45 #ifdef CMDLINE |
pascal@15470 | 46 movw $stacktop, %di |
pascal@15471 | 47 #else |
pascal@15188 | 48 #undef HELP |
pascal@15188 | 49 #endif |
pascal@15188 | 50 pushw $INITSEG |
pascal@15188 | 51 popw %es |
pascal@15188 | 52 #ifdef CMDLINE |
pascal@15188 | 53 movw $0x80, %si |
pascal@15188 | 54 lodsb |
pascal@15188 | 55 cbw |
pascal@15188 | 56 xchgw %ax, %cx |
pascal@15188 | 57 jcxz nocmdline |
pascal@15470 | 58 movw $0xA33F, 0x7F(%si) |
pascal@15188 | 59 skipspace: |
pascal@15188 | 60 lodsb |
pascal@15188 | 61 cmpb $0x20, %al |
pascal@15188 | 62 je skipspace |
pascal@15188 | 63 decw %si |
pascal@15188 | 64 rep |
pascal@15188 | 65 movsb |
pascal@15188 | 66 # ifdef HELP |
pascal@15188 | 67 # define PUTS |
pascal@15188 | 68 movw $EXEADRS(helpmsg), %si |
pascal@15485 | 69 cmpb $'/'+1, %al |
pascal@15476 | 70 # ifdef CHECK_REALMODE |
pascal@15485 | 71 js jsputs |
pascal@15476 | 72 # else |
pascal@15485 | 73 js puts |
pascal@15476 | 74 # endif |
pascal@15188 | 75 # endif |
pascal@15188 | 76 nocmdline: |
pascal@15188 | 77 #endif |
pascal@15472 | 78 movw $SYSSEG, %ax |
pascal@15188 | 79 #ifdef CHECK_REALMODE |
pascal@15188 | 80 #define PUTS |
pascal@15188 | 81 movw $EXEADRS(realmode_expected), %si |
pascal@15188 | 82 // bits 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 |
pascal@15188 | 83 // flags 0 NT IOPL OF DF IF TF SF ZF 0 AF 0 PF 1 CF |
pascal@15472 | 84 //movb $0x10, %ah // DF = IF = TF = 0 |
pascal@15188 | 85 pushw %ax |
pascal@15188 | 86 popfw // < 286 : flags[12..15] are forced 1 |
pascal@15188 | 87 pushfw // = 286 : flags[12..15] are forced 0 |
pascal@15469 | 88 popw %dx // > 286 : only flags[15] is forced 0 |
pascal@15485 | 89 cmpb %ah, %dh // test Fx and 0x cases |
pascal@15485 | 90 jsputs: |
pascal@15485 | 91 js puts // S= not 386+ |
pascal@15472 | 92 smsww %dx |
pascal@15472 | 93 shrw $1, %dx |
pascal@15472 | 94 jc puts |
pascal@17223 | 95 //movw syssize-realmode_expected(%si), %bp |
pascal@17223 | 96 .byte 0x8B, 0x6C, syssize-realmode_expected |
pascal@17223 | 97 //movb setup_sects-realmode_expected(%si), %ch |
pascal@17223 | 98 .byte 0x8A, 0x6C, setup_sects-realmode_expected |
pascal@17223 | 99 #else |
pascal@17223 | 100 movw EXEADRS(syssize), %bp |
pascal@17223 | 101 movb EXEADRS(setup_sects), %ch |
pascal@15188 | 102 #endif |
pascal@17223 | 103 movb $(512-(end_header-_start))/2, %cl |
pascal@15188 | 104 movw $0x100, %si |
pascal@15188 | 105 movw $end_header, %di |
pascal@15188 | 106 rep |
pascal@15188 | 107 movsw |
pascal@15188 | 108 ljmp $INITSEG, $movesys |
pascal@15188 | 109 start: |
pascal@15188 | 110 pushw %dx |
pascal@15188 | 111 #else |
pascal@15188 | 112 #undef HELP |
pascal@15188 | 113 #undef CMDLINE |
pascal@15188 | 114 #undef CHECK_REALMODE |
pascal@15188 | 115 #endif |
pascal@15188 | 116 cld # assume nothing |
pascal@15188 | 117 stacktop = 0x9E00 # in 0x8000 .. 0xA000 |
pascal@15188 | 118 zeroed = 12 # zeroed registers |
pascal@15188 | 119 movw $stacktop-12-zeroed, %di # stacktop is an arbitrary value >= |
pascal@15188 | 120 # length of bootsect + length of |
pascal@15188 | 121 # setup + room for stack; |
pascal@15188 | 122 # 12 is disk parm size. |
pascal@15188 | 123 pushw $INITSEG |
pascal@15188 | 124 popw %ss # %ss contain INITSEG |
pascal@15188 | 125 movw %di, %sp # put stack at INITSEG:stacktop-... |
pascal@15188 | 126 |
pascal@15188 | 127 # Many BIOS's default disk parameter tables will not recognize |
pascal@15188 | 128 # multi-sector reads beyond the maximum sector number specified |
pascal@15188 | 129 # in the default diskette parameter tables - this may mean 7 |
pascal@15188 | 130 # sectors in some cases. |
pascal@15188 | 131 # |
pascal@15188 | 132 # Since single sector reads are slow and out of the question, |
pascal@15188 | 133 # we must take care of this by creating new parameter tables |
pascal@15188 | 134 # (for the first disk) in RAM. We can set the maximum sector |
pascal@15188 | 135 # count to 36 - the most we will encounter on an ED 2.88. |
pascal@15188 | 136 # |
pascal@15188 | 137 # High doesn't hurt. Low does. Let's use the max: 63 |
pascal@15188 | 138 |
pascal@15188 | 139 pushw %ss |
pascal@15188 | 140 popw %es # %es = %ss = INITSEG |
pascal@15188 | 141 xorw %ax, %ax # %ax = 0 |
pascal@15472 | 142 #ifdef EXE_SUPPORT |
pascal@15472 | 143 cwd # %dx = 0 |
pascal@15472 | 144 #endif |
pascal@15188 | 145 movw $zeroed/2, %cx # clear gdt + offset, %ds, limits |
pascal@15188 | 146 rep # don't worry about cld |
pascal@15188 | 147 stosw # already done above |
pascal@15188 | 148 popw %bx # offset = 0 |
pascal@15188 | 149 popw %ds # %ds = 0 |
pascal@15188 | 150 popw %fs # %fs = 0 |
pascal@15188 | 151 |
pascal@15188 | 152 movb setup_sects+0x7C00, %al # read bootsector + setup (%ds = 0) |
pascal@15188 | 153 incw %ax |
pascal@15188 | 154 |
pascal@15188 | 155 ldsw 0x78(%bx), %si # %ds:%bx+0x78 is parameter table address |
pascal@15188 | 156 pushw %es |
pascal@15188 | 157 pushw %di |
pascal@15188 | 158 movb $6, %cl # copy 12 bytes |
pascal@15188 | 159 rep # don't worry about cld |
pascal@15188 | 160 movsw # already done above |
pascal@15188 | 161 pushw %ss |
pascal@15188 | 162 popw %ds # now %ds = %es = %ss = INITSEG |
pascal@15188 | 163 popl %fs:0x78(%bx) # update parameter table address |
pascal@15188 | 164 movb $63, 0x4-12(%di) # patch sector count, %di = stacktop |
pascal@15188 | 165 cli |
pascal@15188 | 166 |
pascal@15188 | 167 xchg %ax, %di # sector count |
pascal@15188 | 168 popw %ax # limits = 0 |
pascal@15188 | 169 incw %cx # cylinder 0, sector 1, clear Z |
pascal@15188 | 170 call read_first_sectors # read setup |
pascal@15188 | 171 |
pascal@15188 | 172 # This routine loads the system at address LOADSEG, making sure |
pascal@15188 | 173 # no 64kB boundaries are crossed. We try to load it as fast as |
pascal@15188 | 174 # possible, loading whole tracks whenever we can. |
pascal@15188 | 175 |
pascal@15188 | 176 popw %bx # clear %bx |
pascal@15188 | 177 movw syssize, %di |
pascal@17223 | 178 decw %di |
pascal@15188 | 179 shrw $9-4, %di |
pascal@17223 | 180 incw %di |
pascal@15188 | 181 movw $SYSSEG, %cx |
pascal@15188 | 182 call read_sectorsCX |
pascal@15188 | 183 |
pascal@15188 | 184 # This procedure turns off the floppy drive motor, so |
pascal@15188 | 185 # that we enter the kernel in a known state, and |
pascal@15188 | 186 # don't have to worry about it later. |
pascal@15188 | 187 |
pascal@15188 | 188 kill_motor: |
pascal@15188 | 189 xchgw %ax, %di # reset FDC (%di < 128) |
pascal@15188 | 190 int $0x13 |
pascal@15188 | 191 |
pascal@15188 | 192 # After that (everything loaded), we jump to the setup-routine |
pascal@15188 | 193 # loaded directly after the bootblock: |
pascal@15188 | 194 # Segments are as follows: %ds = %ss = INITSEG |
pascal@15188 | 195 |
pascal@15188 | 196 jmp_setup: |
pascal@15188 | 197 ljmp $SETUPSEG, $0 |
pascal@15188 | 198 |
pascal@15188 | 199 #ifdef PUTS |
pascal@15188 | 200 #define PUTC |
pascal@15472 | 201 putslp: |
pascal@15472 | 202 call putc |
pascal@15188 | 203 puts: |
pascal@15188 | 204 lodsb |
pascal@15188 | 205 orb %al, %al |
pascal@15472 | 206 jne putslp |
pascal@15480 | 207 int $0x20 // dos exit |
pascal@15188 | 208 #endif |
pascal@15188 | 209 #ifdef EXE_SUPPORT |
pascal@17223 | 210 movesys: // %ax = SYSSEG |
pascal@15188 | 211 pushw %es |
pascal@15188 | 212 popw %ss |
pascal@15188 | 213 movw %ds, %bx |
pascal@17223 | 214 subw %ax, %bx |
pascal@15188 | 215 jnc forward |
pascal@15188 | 216 addw %bp, %ax |
pascal@15188 | 217 forward: |
pascal@15188 | 218 movw %ax, %es |
pascal@17223 | 219 movw %ax, %dx |
pascal@17223 | 220 addw %bx, %dx |
pascal@17223 | 221 movw %dx, %ds |
pascal@17223 | 222 sbbw %dx, %dx // %dx = 0 : -1 |
pascal@17223 | 223 cmc // C = 1 : 0 |
pascal@17223 | 224 adcw %dx, %ax |
pascal@15188 | 225 xorw %di, %di |
pascal@15188 | 226 movb $8, %cl |
pascal@15472 | 227 pushw %si |
pascal@15188 | 228 rep |
pascal@15188 | 229 movsw |
pascal@15472 | 230 popw %si |
pascal@15188 | 231 decw %bp |
pascal@15188 | 232 jns forward |
pascal@15188 | 233 #ifndef NO_CURSOR_DEFINITION |
pascal@15188 | 234 movb $1, %ah |
pascal@15188 | 235 movb $0, %bh |
pascal@15188 | 236 movb $0x20, %ch // 0x2000 |
pascal@15188 | 237 int $0x10 |
pascal@15188 | 238 #endif |
pascal@15188 | 239 pushw %ss |
pascal@15188 | 240 popw %ds |
pascal@15188 | 241 jmp jmp_setup |
pascal@15188 | 242 #endif |
pascal@15188 | 243 putcdot: |
pascal@15188 | 244 #ifdef PUTC |
pascal@15188 | 245 movb $0x2E, %al |
pascal@15188 | 246 putc: |
pascal@15188 | 247 movb $0xE, %ah |
pascal@15188 | 248 movw $7, %bx |
pascal@15188 | 249 int $0x10 |
pascal@15188 | 250 #endif |
pascal@15188 | 251 ret |
pascal@15188 | 252 |
pascal@15188 | 253 |
pascal@15188 | 254 # read_sectors reads %di sectors into %es:0 buffer. |
pascal@15188 | 255 # %es:0 is updated to the next memory location. |
pascal@15188 | 256 # First, sectors are read sector by sector until |
pascal@15188 | 257 # sector per track count is known. Then they are |
pascal@15188 | 258 # read track by track. |
pascal@15188 | 259 # Assume no error on first track. |
pascal@15188 | 260 |
pascal@15188 | 261 #ifdef FLOPPY_1440K_ONLY |
pascal@15188 | 262 #define FLOPPY_HEADS 2 /* 2 heads */ |
pascal@15188 | 263 #define FLOPPY_SECTORS 18 /* 18 sectors */ |
pascal@15188 | 264 #else |
pascal@15188 | 265 #define FLOPPY_HEADS 2 /* 2 heads minimum */ |
pascal@15188 | 266 #define FLOPPY_SECTORS 9 /* 9 sectors minimum */ |
pascal@15188 | 267 #endif |
pascal@15188 | 268 |
pascal@15188 | 269 check_limits: |
pascal@15188 | 270 #ifndef FLOPPY_1440K_ONLY |
pascal@15188 | 271 popw %dx |
pascal@15188 | 272 #ifdef FLOPPY_SECTORS |
pascal@15188 | 273 cmpb $FLOPPY_SECTORS+1, %cl # minimum sector count |
pascal@15188 | 274 jb check_head |
pascal@15188 | 275 #endif |
pascal@15188 | 276 cmpb %al, %cl # max sector known ? |
pascal@15188 | 277 ja next_head # no -> store it |
pascal@15188 | 278 check_head: |
pascal@15188 | 279 #ifdef FLOPPY_HEADS |
pascal@15188 | 280 cmpb $FLOPPY_HEADS, %dh # 2 heads minimum |
pascal@15188 | 281 jb check_cylinder |
pascal@15188 | 282 #endif |
pascal@15188 | 283 cmpb %ah, %dh # max head known ? |
pascal@15188 | 284 ja next_cylinder # no -> store it |
pascal@15188 | 285 check_cylinder: |
pascal@15188 | 286 #endif |
pascal@15188 | 287 pushaw |
pascal@15188 | 288 #ifndef FLOPPY_1440K_ONLY |
pascal@15188 | 289 cbw # %ah = 0 |
pascal@15188 | 290 #endif |
pascal@15188 | 291 int $0x13 # reset controler |
pascal@15188 | 292 popaw |
pascal@15188 | 293 movb $1, %al # sector by sector... |
pascal@15188 | 294 read_sectorslp: |
pascal@15188 | 295 pushw %dx # some bios break dx... |
pascal@15188 | 296 #ifndef FLOPPY_1440K_ONLY |
pascal@15188 | 297 pushw %ax # limits |
pascal@15188 | 298 subb %cl, %al # sectors remaining in track |
pascal@15188 | 299 ja tolastsect |
pascal@15188 | 300 movb $1, %al # 1 sector mini |
pascal@15188 | 301 tolastsect: |
pascal@15188 | 302 #else |
pascal@15188 | 303 mov $FLOPPY_SECTORS+1, %al |
pascal@15188 | 304 subb %cl, %al # sectors remaining in track |
pascal@15188 | 305 #endif |
pascal@15188 | 306 cbw |
pascal@15188 | 307 cmpw %di, %ax |
pascal@15188 | 308 jb more1trk |
pascal@15188 | 309 movw %di, %ax # sectors to read |
pascal@15188 | 310 more1trk: |
pascal@15188 | 311 pushw %ax # save context |
pascal@15188 | 312 movb $2, %ah # cmd: read chs |
pascal@15188 | 313 int $0x13 |
pascal@15188 | 314 #ifndef FLOPPY_1440K_ONLY |
pascal@15188 | 315 popw %dx # save %ax |
pascal@15188 | 316 popw %ax # limits |
pascal@15188 | 317 #else |
pascal@15188 | 318 popw %ax # restore context |
pascal@15188 | 319 popw %dx |
pascal@15188 | 320 #endif |
pascal@15188 | 321 jc check_limits |
pascal@15188 | 322 #ifndef FLOPPY_1440K_ONLY |
pascal@15188 | 323 xchgw %ax, %bp |
pascal@15188 | 324 addw %dx,%cx # next sector |
pascal@15188 | 325 movw %cx, %gs |
pascal@15188 | 326 movw %es, %cx |
pascal@15188 | 327 pushw %dx |
pascal@15188 | 328 shlw $5, %dx |
pascal@15188 | 329 addw %dx, %cx |
pascal@15188 | 330 popw %dx |
pascal@15188 | 331 subw %dx,%di # update sector counter |
pascal@15188 | 332 popw %dx |
pascal@15188 | 333 read_sectorsCX: |
pascal@15188 | 334 movw %cx, %es # next location |
pascal@15188 | 335 jz putcdot |
pascal@15188 | 336 #else |
pascal@15188 | 337 addw %ax,%cx # next sector |
pascal@15188 | 338 movw %cx, %gs |
pascal@15188 | 339 movw %es, %cx |
pascal@15188 | 340 pushw %ax |
pascal@15188 | 341 shlw $5, %ax |
pascal@15188 | 342 addw %ax, %cx |
pascal@15188 | 343 popw %ax |
pascal@15188 | 344 subw %ax,%di # update sector counter |
pascal@15188 | 345 read_sectorsCX: |
pascal@15188 | 346 movw %cx, %es # next location |
pascal@15188 | 347 jz putcdot |
pascal@15188 | 348 #endif |
pascal@15188 | 349 read_sectors: |
pascal@15188 | 350 movw %gs, %cx |
pascal@15188 | 351 #ifndef FLOPPY_1440K_ONLY |
pascal@15188 | 352 # al is last sector+1 |
pascal@15188 | 353 # ah is last cylinder+1 |
pascal@15188 | 354 xchgw %ax, %bp |
pascal@15188 | 355 #endif |
pascal@15188 | 356 #ifndef FLOPPY_1440K_ONLY |
pascal@15188 | 357 cmpb %al,%cl # reach sector limit ? |
pascal@15188 | 358 jne bdendlp |
pascal@15188 | 359 next_head: |
pascal@15188 | 360 movb %cl,%al |
pascal@15188 | 361 #else |
pascal@15188 | 362 cmpb $FLOPPY_SECTORS+1,%cl # reach sector limit ? |
pascal@15188 | 363 jne bdendlp |
pascal@15188 | 364 #endif |
pascal@15188 | 365 incb %dh # next head |
pascal@15188 | 366 movb $1,%cl # first sector |
pascal@15188 | 367 #ifndef FLOPPY_1440K_ONLY |
pascal@15188 | 368 cmpb %ah, %dh # reach head limit ? |
pascal@15188 | 369 jne bdendlp |
pascal@15188 | 370 next_cylinder: |
pascal@15188 | 371 movb %dh,%ah |
pascal@15188 | 372 #else |
pascal@15188 | 373 cmpb %cl,%dh # reach head limit ? |
pascal@15188 | 374 je bdendlp |
pascal@15188 | 375 #endif |
pascal@15188 | 376 # NOTE : support 256 cylinders max |
pascal@15188 | 377 incb %ch # next cylinder |
pascal@18880 | 378 movb $0,%dh # first head |
pascal@15188 | 379 read_first_sectors: |
pascal@15188 | 380 bdendlp: |
pascal@15188 | 381 jmp read_sectorslp |
pascal@15188 | 382 |
pascal@15188 | 383 #ifdef HELP |
pascal@15188 | 384 helpmsg: |
pascal@15188 | 385 .ascii "No help available." |
pascal@15188 | 386 .byte 13,10 |
pascal@15188 | 387 .byte 0 |
pascal@15188 | 388 #endif |
pascal@17223 | 389 #ifdef CHECK_REALMODE |
pascal@17223 | 390 .org 475 |
pascal@17223 | 391 realmode_expected: |
pascal@17223 | 392 helpend: |
pascal@17223 | 393 .ascii "386 real mode only." |
pascal@17223 | 394 .byte 13,10,0 |
pascal@17223 | 395 #endif |
pascal@15188 | 396 .org 497 |
pascal@17223 | 397 setup_sects: |
pascal@17223 | 398 .byte 0 |
pascal@17223 | 399 .org 500 |
pascal@17223 | 400 syssize: |
pascal@17223 | 401 .word 0 |
pascal@17223 | 402 |