wok-tiny view 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 source
1 BOOTSEG = 0x07C0 /* original address of boot-sector */
2 SYSSEG = 0x1000 /* historical load address >> 4 */
3 INITSEG = 0x9000 /* boot address >> 4 */
4 SETUPSEG = 0x9020 /* setup address >> 4 */
5 ASK_VGA = -3
7 #ifndef SVGA_MODE
8 #define SVGA_MODE ASK_VGA
9 #endif
11 #ifndef RAMDISK
12 #define RAMDISK 0
13 #endif
15 #ifndef ROOT_RDONLY
16 #define ROOT_RDONLY 1
17 #endif
19 /* Assume protocol 2.00+ (kernel >= 1.3.73) */
20 /* feature set */
21 #define EXE_SUPPORT real mode dos .exe file support
22 // #define EXE_ONLY remove floppy code
23 #define EXE_CMDLINE kernel >= 2.4
24 // #define FLOPPY_CMDLINE kernel >= 2.4
25 // #define OLDCMDLINE kernel < 2.4
26 #define MORETHAN16M up to 4Gb RAM, not 16Mb
27 #define KEYBOARDLESS_SUPPORT scan floppy swap each 5 seconds
28 // #define FAT12_SUPPORT will format the floppy free space in FAT 12
29 // #define REALMODE_NOT_CHECKED exe crash when started in vm86
30 // #define SINGLE_FLOPPY Everytihng fit in a single floppy
31 // #define EDIT_CMDLINE
32 // #define MOVE_CMDLINE
33 #define INITRD_SUPPORT
34 // #define INITRD_AUTOADDR Hole in 16Mb..32Mb
35 // #define MULTI_INITRD Russian dolls
36 // #define README_SUPPORT
37 // #define COUNTER Show floppy number
38 #define LABEL "SliTaz"
40 .code16
41 .org 0
43 bootsect_start:
45 cur_initrd_size_ofs = 494
46 ramdisk_image_ofs = 0x218
47 ramdisk_image = bootsect_start+ramdisk_image_ofs
48 ramdisk_size_ofs = 0x21C
49 ramdisk_size = bootsect_start+ramdisk_size_ofs
50 cmd_line_ptr_ofs = 0x228
51 cmd_line_ptr = bootsect_start+cmd_line_ptr_ofs
52 setup_sects = bootsect_start+497
53 syssize = bootsect_start+500
54 boot_flag_ofs = 510
55 boot_flag = bootsect_start+boot_flag_ofs
58 stacktop = 0x9E00 # in 0x8000 .. 0xA000
59 zeroed = 48+10 # gdt + zeroed registers
60 .macro INIT_REGS
61 movw $stacktop-zeroed, %di # stacktop is an arbitrary value >=
62 # length of bootsect + length of
63 # setup + room for stack;
64 # 12 is disk parm size.
65 pushw $INITSEG
66 popw %ss # %ss contain INITSEG
67 movw %di, %sp # put stack at INITSEG:stacktop-...
68 pushw %ss
69 popw %es # %es = %ss = INITSEG
70 xorw %ax, %ax # %ax = 0
71 #if defined(EXE_CMDLINE)
72 movw $zeroed+1, %cx # clear gdt + offset, %ds, limits, cmdline=""
73 rep # don't worry about cld
74 stosb # already done above
75 decw %di
76 #else
77 movw $zeroed/2, %cx # clear gdt + offset, %ds, limits
78 rep # don't worry about cld
79 stosw # already done above
80 #endif
81 popw %bx # offset = 0
82 .endm
84 #ifdef FAT12_SUPPORT
85 jmp fdstart
86 nop
87 .ascii "SLITAZ "
88 .word 512 // 0B: bytes per sector
89 .byte 1 // 0D: sectors per cluster
90 .word 2880 // 0E: reserved seectors
91 .byte 2 // 10: FAT number
92 .word 64 // 11: root entries 4x 16
93 .word 2880 // 13: total sectors
94 .byte 0xF0 // 15: media id (or F9)
95 #endif
97 #ifdef EXE_SUPPORT
98 #define CODESZ 0x8000
99 #define EXEADRS(x) x+0xE0
100 decw %bp // Magic number: MZ
101 popw %dx
102 #ifdef EXE_ONLY
103 .word 512 // Bytes on last page of file
104 #else
105 jmp fdstart // Bytes on last page of file
106 #endif
107 .word (CODESZ+511)/512 // Pages in file
108 .word 0 // Relocations
109 .word 2 // Size of header in paragraphs
110 .word 4096 // Minimum extra paragraphs needed
111 .word -1 // Maximum extra paragraphs needed
112 .word (CODESZ+15)/16 // Initial (relative) SS value
113 .word stacktop+4 // Initial SP value (+callf)
114 .word 0 // Checksum
115 .word EXEADRS(comstart) // Initial IP value
116 .word 0xFFF0 // Initial (relative) CS value
117 #if defined(EXE_ONLY) || defined(SINGLE_FLOPPY) || defined(COUNTER)
118 // .word 0x001C // File address of relocation table
119 // .word 0,0,0 // Overlay number
120 .ascii "(SliTaz)"
121 #else
122 swap_floppy:
123 .ascii "Next!"
124 .byte 7,13,0 # swap detection needs 13, 0
125 #endif
126 #ifdef OLDCMDLINE
127 # ifdef FLOPPY_CMDLINE
128 .word 0 # 0xA33F
129 .word 0 # stacktop
130 # else
131 .word 0xA33F
132 .word stacktop
133 # endif
134 #endif
135 #ifndef EXE_ONLY
136 fdstart:
137 pushw %dx
138 #endif
139 #endif
141 LOADSEG = 0x8000 # 0x1000 multiple, up to 512K zImage
142 LOADSZ = 0x10000
144 #if defined(EXE_SUPPORT) || defined(EXE_ONLY)
145 A20BUFFER = 0x68000 # a20 gate / himem.sys support
146 #define USEA20BUFFER
147 #endif
149 #ifndef EXE_ONLY
150 # bootsect_start:
151 #ifdef EXE_SUPPORT
152 call initregs
153 cwd # floppy = head = 0
154 #else
155 INIT_REGS
156 #endif
157 popw %ds # %ds = 0
158 movb setup_sects+0x7C00, %al # read bootsector + setup
159 incw %ax # %ax = setup_sects+bootsect
160 popw %fs # %fs = 0
162 # Many BIOS's default disk parameter tables will not recognize
163 # multi-sector reads beyond the maximum sector number specified
164 # in the default diskette parameter tables - this may mean 7
165 # sectors in some cases.
166 #
167 # Since single sector reads are slow and out of the question,
168 # we must take care of this by creating new parameter tables
169 # (for the first disk) in RAM. We can set the maximum sector
170 # count to 36 - the most we will encounter on an ED 2.88.
171 #
172 # High doesn't hurt. Low does. Let's use the max: 63
174 cli
175 ldsw 0x78(%bx), %si # %ds:%bx+0x78 is parameter table address
176 popw %di
177 pushw %es
178 pushw %di
179 #ifdef FLOPPY_CMDLINE
180 movw $0, %bp # patched by installer (7C22)
181 skipcmdline:
182 #define cmd_line_ptr 0x22
183 #endif
184 movb $6, %cl # copy 12 bytes
185 rep # don't worry about cld
186 movsw # already done above
187 pushw %ss
188 popw %ds # now %ds = %es = %ss = INITSEG
189 popl %fs:0x78(%bx) # update parameter table address
190 movb $63, 0x4-12(%di) # patch sector count, %di = stacktop
192 xchg %ax, %di # sector count
193 popw %ax # limits = 0
194 incw %cx # cylinder 0, sector 1, clear Z
195 call read_first_sectors # read setup
196 #ifdef README_SUPPORT
197 xorw %si, %si
198 orw readme, %si
199 jz readmeend
200 readmeloop:
201 call puts
202 jz readmeend
203 call wait4key
204 cmpb $27, %al
205 jne readmeloop
206 readmeend:
207 #endif
208 #endif
209 loadsys:
210 movw $0x200,%si
211 type_of_loader = 0x10
212 loadflags = 0x11
213 heap_end_ptr = 0x24
214 orw $0x8020, type_of_loader(%si) # loader type = 0x20 = bootsect-loader
215 movb $(stacktop-0x300)/256, heap_end_ptr+1(%si)
216 call puts_version # show which kernel we are loading
218 #ifdef FLOPPY_CMDLINE
219 # The cmdline can be entered and modifed at boot time.
220 # Only characters before the cursor are passed to the kernel.
222 xorw %si, %si
223 orw cmd_line_ptr-7(%bx), %si
224 jz nocmdline
225 #ifdef OLDCMDLINE
226 movw $0xA33F, cmd_line_ptr-2-7(%bx)
227 #endif
228 call puts
229 #ifdef EDIT_CMDLINE
230 cmdlp:
231 movb $0x20, %al # clear end of line
232 cmdlpz:
233 call putc # with Space
234 subb $0x18, %al # and BackSpace
235 jnc cmdlpz
236 decw %si
237 cmdget:
238 #ifdef KEYBOARDLESS_SUPPORT
239 call wait4key
240 #else
241 int $0x16
242 #endif
243 cbw # %ah = 0, get keyboard character
244 cmpb $8, %al # BackSpace ?
245 je cmdbs
246 movb %al, (%si) # store char
247 lodsw # %si += 2
248 cmdbs:
249 cmpw %si, cmd_line_ptr-7(%bx)
250 je cmdget
251 call putc
252 cmpb $10, %al # Enter/linefeed ?
253 jne cmdlp
254 movb %bh,-2(%si) # set end of string and remove CR
255 endcmdline:
256 #endif
257 #ifdef MOVE_CMDLINE
258 pushw %ss
259 popw %es
260 movw $0x8000, %di
261 movw %di, %si
262 xchgw %si, cmd_line_ptr-7(%bx)
263 movb $0x2, %ch
264 rep
265 movsb
266 #endif
267 nocmdline:
268 #endif
270 # This routine loads the system at address LOADSEG, making sure
271 # no 64kB boundaries are crossed. We try to load it as fast as
272 # possible, loading whole tracks whenever we can.
274 .macro autoaddr base
275 #ifdef INITRD_AUTOADDR
276 movb $0x88, %ah
277 int $0x15
278 //jc NeedMoreRAM # error code 80 or 86
279 cmpw $0xB000, %ax # more than 45M ?
280 jb NeedMoreRAM
281 movb %ch, bootsect_dst_base_hi(%si) # initramfs @ 32M
282 movb %ch, ramdisk_image_ofs+3-\base
283 NeedMoreRAM:
284 #endif
285 .endm
287 bootsect_src_limit = 16
288 bootsect_dst_limit = 24
289 bootsect_src_base = 18
290 bootsect_dst_base = 26 # bits 0..23
291 bootsect_dst_base_hi = 31 # bits 24..31
292 popw %bx # clear %bx
293 movw %sp, %si # for bootsect_gdt
294 init_gdt:
295 decw bootsect_src_limit(%bx,%si) # max 64Kb
296 movw $0x9300+(LOADSEG/0x1000), bootsect_src_base+2(%bx,%si)
297 xorb $bootsect_dst_limit-bootsect_src_limit, %bl
298 jne init_gdt
299 #ifdef INITRD_SUPPORT
300 movw $syssize, %bx
301 movb $5, %cl
302 code32_start = 0x214
303 movw code32_start+1, %ax # destination = 0x00100000 or 0x00010000
304 initrdlp:
305 movl (%bx), %ebx
306 decl %ebx
307 shrl %cl, %ebx
308 #else
309 code32_start = 0x214
310 movw code32_start+1, %ax # destination = 0x00100000 or 0x00010000
311 movl syssize, %ebx
312 decl %ebx
313 shrl $5, %ebx
314 #endif
315 #ifdef MORETHAN16M
316 incl %ebx
317 #else
318 incw %bx
319 #endif
320 #ifdef USEA20BUFFER
321 movw $0x00100000>>8, %di
322 #endif
323 syslp:
324 #ifdef USEA20BUFFER
325 cmpw %ax, %di
326 jne nota20
327 xorw $(0x00100000+A20BUFFER)>>8, %ax
328 nota20:
329 #endif
330 movw %ax, bootsect_dst_base+1(%si)
331 #ifdef MORETHAN16M
332 movl $LOADSZ/512, %edi # size in sectors
333 subl %edi, %ebx
334 #else
335 movw $LOADSZ/512, %di # size in sectors
336 subw %di, %bx
337 #endif
338 pushf
339 jnc not_last
340 addw %bx, %di
341 not_last:
342 #ifdef MULTI_INITRD
343 pushw %di
344 #endif
345 pushw %ax
346 pushw %bx
347 pushw %si
348 xorw %bx,%bx
349 pushw $LOADSEG
350 popw %es
351 #ifdef EXE_ONLY
352 call read_sectors_dos
353 #else
354 patchcall:
355 call read_sectors # update %bp
356 #endif
357 popw %si
358 popw %bx
359 movw %es, %cx # word count = LOADSZ/2 (= LOADSEG)
360 movb $0x87, %ah
361 pushw %ss
362 popw %es # restore es
363 int $0x15 # max 16M, maybe more...
364 popw %ax
365 #ifdef MULTI_INITRD
366 popw %di
367 shlw $1,%di # sectors to pages
368 addw %di, %ax
369 #ifdef MORETHAN16M
370 adcb %cl, bootsect_dst_base_hi(%si) # breaks 16M limit ?
371 #endif
372 #else
373 #ifdef MORETHAN16M
374 addw $0x100, %ax # next dest (ax+=LOADSZ/256)
375 adcb %cl, bootsect_dst_base_hi(%si) # breaks 16M limit ?
376 #else
377 incb %ah # next dest (ax+=LOADSZ/256)
378 #endif
379 #endif
380 #ifdef USEA20BUFFER
381 movw $(LOADSZ+A20BUFFER)>>8, %di
382 #endif
383 popf
384 ja syslp
385 #ifdef INITRD_SUPPORT
386 initrdlp2:
387 #ifdef INITRD_AUTOADDR
388 movw $0x209, %cx
389 #else
390 movb $9, %cl
391 #endif
392 #ifdef MULTI_INITRD
393 movw $cur_initrd_size_ofs, %di
394 movw (%di), %bx
395 addw $4, (%di)
396 shrw %cl, boot_flag_ofs-cur_initrd_size_ofs(%di)
397 je nextInitrd
398 orw %bx, %bx
399 je bootit # no initrd
400 autoaddr cur_initrd_size_ofs(%di)
401 movw ramdisk_image+1,%ax
402 jmp initrdlp
403 nextInitrd:
404 pushw %bx
405 movl -4(%bx), %ebx
406 addl %ebx, ramdisk_size_ofs-cur_initrd_size_ofs(%di)
407 movb $swap_floppy2-0x100, %cs:dpy_swap_floppy-2+0x7C00
408 popw %bx
409 cmpb 2(%di), %bl
410 jb initrdlp
411 #else
412 movw $ramdisk_size, %bx
413 #ifdef MORETHAN16M
414 cmpb %cl, ramdisk_image+2-ramdisk_size(%bx)
415 jb bootit
416 autoaddr ramdisk_size_ofs(%bx)
417 movw ramdisk_image+1,%ax
418 shrw %cl, boot_flag-ramdisk_size(%bx)
419 jne initrdlp
420 #else
421 movw ramdisk_image+1,%ax
422 cmpw %ax, bootsect_dst_base+1(%si)
423 jb initrdlp
424 #endif
425 #endif
426 bootit:
427 #ifdef USEA20BUFFER
428 #ifdef MORETHAN16M
429 #ifdef INITRD_SUPPORT
430 movb %al, bootsect_dst_base_hi(%si) // assume @initrd 64k aligned
431 //movb $0, bootsect_dst_base_hi(%si)
432 #else
433 movb %cl, bootsect_dst_base_hi(%si)
434 #endif
435 #endif
436 movb $0x10, bootsect_dst_base+2(%si) // assume @initrd 64k aligned
437 //movw $0x1000, bootsect_dst_base+1(%si) // assume @initrd page aligned
438 movw $A20BUFFER/0x100, bootsect_src_base+1(%si)
439 movb $0x87, %ah
440 int $0x15
441 #endif
442 #endif
443 #ifdef MULTI_INITRD
444 jcxz read_sectorslp
445 #endif
447 # This procedure turns off the floppy drive motor, so
448 # that we enter the kernel in a known state, and
449 # don't have to worry about it later.
451 kill_motor:
452 #ifdef USEA20BUFFER
453 cwd
454 #else
455 xchgw %ax, %di # reset FDC (%di < 128)
456 #endif
457 int $0x13
459 # After that (everything loaded), we jump to the setup-routine
460 # loaded directly after the bootblock:
461 # Segments are as follows: %ds = %ss = INITSEG
463 ljmp $SETUPSEG, $0
465 # read_sectors reads %di sectors into %es:0 buffer.
466 # %es:0 is updated to the next memory location.
467 # First, sectors are read sector by sector until
468 # sector per track count is known. Then they are
469 # read track by track.
470 # Assume no error on first track.
472 #ifndef EXE_ONLY
474 #define FLOPPY_CYLINDERS 80
475 #define FLOPPY_HEADS 2
477 .macro putsmsg
478 #if !defined(SINGLE_FLOPPY) && defined(COUNTER)
479 movw $msgdigit+1-msg, %bx
480 nextdigit:
481 andb $0xF0, (%bx,%si)
482 decw %bx
483 incb (%bx,%si)
484 cmpb $'9', (%bx,%si)
485 ja nextdigit
486 #endif
487 call puts
488 .endm
490 check_limits:
491 popw %dx
492 cmpb %al, %cl # max sector known ?
493 ja next_head # no -> store it
494 pushaw
495 int $0x13 # reset controler
496 stc
497 call putcdot # print '-'
498 read_sectorslp:
499 popaw
500 bdendlp:
501 pushw %dx # some bios break dx...
502 pushw %ax # limits
503 subb %cl, %al # sectors remaining in track
504 ja tolastsect
505 movb $1, %al # 1 sector mini
506 tolastsect:
507 cmpw %di, %ax
508 jb more1trk
509 movw %di, %ax # sectors to read
510 more1trk:
511 pushw %ax # save context
512 movb $2, %ah # cmd: read chs
513 int $0x13
514 popw %dx # save %ax
515 popw %ax # limits
516 jc check_limits
517 xchgw %ax, %bp
518 addw %dx,%cx # next sector
519 movw %cx, %gs
520 addb %dl,%bh
521 addb %dl,%bh # next location
522 subw %dx,%di # update sector counter
523 popw %dx
524 jz putcdot
525 read_sectors:
526 movw %gs, %cx
527 # al is last sector+1
528 # ah is 0
529 xchgw %ax, %bp
530 cmpb %al,%cl # reach sector limit ?
531 jne bdendlp
532 next_head:
533 movb %cl,%al
534 movb $1, %cl # first sector
535 inc_head:
536 xorb %cl, %dh # next head
537 jne bdendlp # reach head limit ?
538 incb %ch # next cylinder
539 read_first_sectors:
540 #ifdef SINGLE_FLOPPY
541 jmp bdendlp
542 #else
543 cmpb $FLOPPY_CYLINDERS,%ch # reach cylinder limit ?
544 jne bdendlp
545 next_floppy:
546 movb $0,%ch # first cylinder
547 pushaw
548 movw $swap_floppy,%si
549 dpy_swap_floppy:
550 #ifdef KEYBOARDLESS_SUPPORT
551 pushw %bx
552 putsmsg
553 popw %bx
554 movw %si, %bp
555 waitfloppy:
556 call wait
557 jne waitfloppydone
558 #ifdef MULTI_INITRD
559 decb (%si) # max_timeouts
560 gobootit:
561 //movw ramdisk_size+2-max_timeouts(%si), %cx
562 .byte 0x8B, 0x4C, ramdisk_size+2-max_timeouts
563 jz bootit
564 #endif
565 pushw %dx # some bios break dx...
566 cbw
567 int $0x13 # reset FDC
568 movw $0x201,%ax
569 int $0x13 # read first sector
570 popw %dx
571 rclb $1,%ah # floppy changed 06=>0D no error 00
572 cmpb -2(%bp), %ah # 0D then 00
573 jne waitfloppy # no => try again
574 incw %bp
575 decw %ax # was 0001 ?
576 jne waitfloppy
577 waitfloppydone:
578 #else
579 putsmsg
580 cbw # %ah = 0, get keyboard character
581 int $0x16
582 #endif
583 #ifdef MULTI_INITRD
584 orb $0x20, %al
585 cmp $'b', %al
586 jz gobootit
587 #endif
588 jmp read_sectorslp
589 #endif
590 #endif
592 #ifdef EXE_SUPPORT
593 read_sectors_dos:
594 xorw %dx, %dx // write to %ds:%dx, not %es:%bx
595 call read_sectors_dosz
596 read_sectors_dosz:
597 pushw %es
598 popw %ds
599 movb $0x3F, %ah // read
600 movw %di, %cx
601 shlw $8, %cx // byte count / 2
602 movw %bp, %bx
603 int $0x21
604 xchgw %ax, %dx
605 pushw %ss
606 popw %ds
607 #endif
609 putcdot:
610 movb $'.'+3, %al // . = success, - = failure
611 putclf:
612 sbbb $3, %al
613 putc:
614 movb $0xe, %ah
615 movw $7, %bx # one dot each 64k
616 int $0x10
617 cmp $0xd, %al # CR ?
618 je putclf
619 ret
621 #ifdef KEYBOARDLESS_SUPPORT
622 clock = 0x46C
623 wait:
624 wait4key:
625 movw $clock, %di
626 #define DELAY 5
627 movb $257-(DELAY*182)/10, %fs:(%di)
628 waitkbd:
629 movw $0x10D, %ax # test keyboard, timeout => CR
630 cmpb %fs:(%di),%ah
631 je waitdone
632 int $0x16
633 jz waitkbd
634 cbw
635 int $0x16 # eat char
636 movw %di, %fs # disable timeout
637 incw %di # clear Z
638 waitdone:
639 ret
640 #endif
642 #ifdef EXE_SUPPORT
643 comstart:
644 #ifndef EXE_ONLY
645 call initregs
646 #else
647 INIT_REGS
648 #endif
649 movb EXEADRS(setup_sects), %al # read bootsector + setup
650 incw %ax
651 #ifdef EXE_CMDLINE
652 movw $0x80, %si
653 movb (%si), %cl
654 incw %si
655 # ifdef OLDCMDLINE
656 # ifdef FLOPPY_CMDLINE
657 jcxz nocmdline
658 movw %di, EXEADRS(0x22)
659 movw $0xA33F, 0x7F(%si)
660 # endif
661 # endif
662 rep
663 movsb
664 nocmdline:
665 xchgw %ax, %di
666 # ifdef HELP
667 cmpb $'?', -1(%si)
668 movw $EXEADRS(0x200), %si
669 je puts_version
670 # ifndef REALMODE_NOT_CHECKED
671 smsww %ax
672 andb $1, %al
673 jne puts_version // real mode only...
674 # endif
675 # endif
676 #else
677 xchgw %ax, %di
678 #endif
679 movw 0x2C(%bx), %ds // DOS 3.0+
680 loop1:
681 incw %bx
682 cmpw %cx, (%bx)
683 jne loop1
684 leaw 4(%bx), %dx // %ds:%dx filename
685 #if !defined(REALMODE_NOT_CHECKED) && defined(EXE_CMDLINE) && defined(HELP)
686 movb $0x3D, %ah // open, access = RO
687 #else
688 movw $0x3D00, %ax // open, access = RO
689 #endif
690 int $0x21
691 jc dosexit
692 xchgw %ax, %bp // fd
693 call read_sectors_dos // update %ds
694 #ifndef EXE_ONLY
695 addb $read_sectors_dos-read_sectors, patchcall+1
696 #endif
697 #ifdef EXE_CMDLINE
698 # ifdef OLDCMDLINE
699 movw $0x202, %bx
700 cmpw %bx, 0x206-0x202(%bx) # new cmdline for version >= 0x202
701 jb oldcmdline
702 movw $INITSEG/16+stacktop/256, cmd_line_ptr+1-0x202(%bx)
703 # else
704 movw $INITSEG/16+stacktop/256, cmd_line_ptr+1
705 # endif
706 oldcmdline:
707 #endif
708 // ljmp $INITSEG, $loadsys
709 pushw %ds
710 .byte 0x6A, loadsys-bootsect_start
711 lretw
712 #endif
713 #define kernel_version_offset 0xE
714 puts_version:
715 addw kernel_version_offset(%si),%si # starting protocol 2.00, Kernel 1.3.73
716 puts:
717 movb $0xd, %al # CR
718 putcs:
719 call putc
720 lodsb
721 cmpb $0, %al # end of string is any byte <= 0
722 jg putcs
723 dosexit:
724 ret
726 #if !defined(FLOPPY_ONLY) && !defined(EXE_ONLY)
727 initregs:
728 popw %si
729 INIT_REGS
730 pushw %si # use new stack
731 ret
732 #endif
735 #if !defined(SINGLE_FLOPPY) && !defined(EXE_SUPPORT)
736 #ifdef MULTI_INITRD
737 swap_floppy2:
738 .ascii "B or "
739 #endif
740 swap_floppy:
741 #ifdef COUNTER
742 msg:
743 .ascii "Put disk 00"
744 msgdigit:
745 .ascii "1, press Enter."
746 #else
747 .ascii "Next!"
748 #endif
749 .byte 7,13,0 # swap detection needs 13, 0
750 #ifdef MULTI_INITRD
751 max_timeouts:
752 .byte 20
753 table:
754 .org cur_initrd_size_ofs
755 cur_initrd_size:
756 .word table
757 .byte table+4-256
758 #endif
759 #endif
760 #ifdef README_SUPPORT
761 .org 0x1EF
762 readme:
763 .word 0
764 #endif
765 #ifdef LABEL
766 .ascii LABEL
767 #endif
768 .org 0x1F1
770 #ifdef MULTI_INITRD
771 .org 0x400
773 orw $0x8020, type_of_loader(%si) # loader type = 0x20 = bootsect-loader
774 pushal
776 movw $10+16, %cx
777 fillbuf:
778 pushw $0
779 loop fillbuf
780 popal // clear regiters
781 maploop:
782 movw %sp, %di // %es = %ss
783 movb $20, %cl
784 movw $0xE820, %ax
785 movl $0x534d4150, %edx
786 int $0x15
787 sbbl %eax, %edx
788 jne mapdone
789 decw 16(%di)
790 jne notram
791 addw 8+2(%di), %bp
792 notram:
793 orw %bx, %bx
794 jnz maploop
795 mapdone:
796 addw $20, %sp
797 shrw $20-16,%bp
798 jnz mapdone2
799 movb $0x88, %ah
800 int $0x15
801 xchgw %ax, %bp
802 shrw $10, %bp
803 mapdone2:
804 incw %bp
805 // %bp : nb Mb
806 call here
807 here:
808 popw %di
809 movw $0x1EE, %si
810 lodsw
811 sizeloop:
812 scasw // %di += 2
813 addw $4, %ax
814 cmpb %al, (%si)
815 jbe sizedone
816 cmpw %bp, sizes-here(%di)
817 jbe sizeloop
818 movb %al, (%si)
819 sizedone:
820 popal
821 lret // need %si
822 sizes:
824 #endif