wok-tiny view linux/stuff/bootloader.S @ rev 97

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