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

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