Magellan Linux

Contents of /trunk/mkinitrd-magellan/isolinux/comboot.inc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (show annotations) (download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File size: 15973 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd

1 ;; $Id: comboot.inc,v 1.1 2007-09-01 22:44:04 niro Exp $
2 ;; -----------------------------------------------------------------------
3 ;;
4 ;; Copyright 1994-2005 H. Peter Anvin - All Rights Reserved
5 ;;
6 ;; This program is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
9 ;; Boston MA 02111-1307, USA; either version 2 of the License, or
10 ;; (at your option) any later version; incorporated herein by reference.
11 ;;
12 ;; -----------------------------------------------------------------------
13
14 ;;
15 ;; comboot.inc
16 ;;
17 ;; Common code for running a COMBOOT image
18 ;;
19
20 section .text
21
22 ; Parameter registers definition; this is the definition
23 ; of the stack frame used by INT 21h and INT 22h.
24 %define P_FLAGS word [bp+44]
25 %define P_FLAGSL byte [bp+44]
26 %define P_FLAGSH byte [bp+45]
27 %define P_CS word [bp+42]
28 %define P_IP word [bp+40]
29 %define P_DS word [bp+38]
30 %define P_ES word [bp+36]
31 %define P_FS word [bp+34]
32 %define P_GS word [bp+32]
33 %define P_EAX dword [bp+28]
34 %define P_AX word [bp+28]
35 %define P_HAX word [bp+30]
36 %define P_AL byte [bp+28]
37 %define P_AH byte [bp+29]
38 %define P_ECX dword [bp+24]
39 %define P_CX word [bp+24]
40 %define P_HCX word [bp+26]
41 %define P_CL byte [bp+24]
42 %define P_CH byte [bp+25]
43 %define P_EDX dword [bp+20]
44 %define P_DX word [bp+20]
45 %define P_HDX word [bp+22]
46 %define P_DL byte [bp+20]
47 %define P_DH byte [bp+21]
48 %define P_EBX dword [bp+16]
49 %define P_BX word [bp+16]
50 %define P_HBX word [bp+18]
51 %define P_BL byte [bp+16]
52 %define P_BH byte [bp+17]
53 %define P_EBP dword [bp+8]
54 %define P_BP word [bp+8]
55 %define P_HBP word [bp+10]
56 %define P_ESI dword [bp+4]
57 %define P_SI word [bp+4]
58 %define P_HSI word [bp+6]
59 %define P_EDI dword [bp]
60 %define P_DI word [bp]
61 %define P_HDI word [bp+2]
62
63 ; Looks like a COMBOOT image but too large
64 comboot_too_large:
65 mov si,err_comlarge
66 call cwritestr
67 jmp enter_command
68
69 ;
70 ; Load a COMBOOT image. A COMBOOT image is basically a DOS .COM file,
71 ; except that it may, of course, not contain any DOS system calls. We
72 ; do, however, allow the execution of INT 20h to return to SYSLINUX.
73 ;
74 is_comboot_image:
75 and dx,dx
76 jnz comboot_too_large
77 cmp ax,0ff00h ; Max size in bytes
78 jae comboot_too_large
79
80 push si ; Save file handle
81
82 call make_plain_cmdline
83
84 call comboot_setup_api
85
86 mov cx,comboot_seg
87 mov es,cx
88
89 xor di,di
90 mov cx,64 ; 256 bytes (size of PSP)
91 xor eax,eax ; Clear PSP
92 rep stosd
93
94 mov word [es:0], 020CDh ; INT 20h instruction
95 ; First non-free paragraph
96 ; This is valid because comboot_seg == real_mode_seg
97 ; == the highest segment used by all derivatives
98 int 12h ; Get DOS memory size
99 shl ax,6 ; Kilobytes -> paragraphs
100 mov word [es:02h],ax
101
102 %ifndef DEPEND
103 %if real_mode_seg != comboot_seg
104 %error "This code assumes real_mode_seg == comboot_seg"
105 %endif
106 %endif
107 ; Copy the command line from high memory
108 mov si,cmd_line_here
109 mov cx,125 ; Max cmdline len (minus space and CR)
110 mov di,081h ; Offset in PSP for command line
111 mov al,' ' ; DOS command lines begin with a space
112 stosb
113
114 .loop: es lodsb
115 and al,al
116 jz .done
117 stosb
118 loop .loop
119 .done:
120
121 mov al,0Dh ; CR after last character
122 stosb
123 mov ax,di
124 sub al,82h ; Include space but not CR
125 mov [es:80h],al ; Store command line length
126
127 ; Now actually load the file...
128 pop si ; File handle
129 mov bx,100h ; Load at <seg>:0100h
130 mov cx,0FF00h >> SECTOR_SHIFT
131 ; Absolute maximum # of sectors
132 call getfssec
133
134 ; And invoke the program...
135 mov [SavedSSSP],sp
136 mov [SavedSSSP+2],ss ; Save away SS:SP
137
138 mov ax,es
139 mov ds,ax
140 mov ss,ax
141 xor sp,sp
142 push word 0 ; Return to address 0 -> exit
143
144 jmp comboot_seg:100h ; Run it
145
146 ; Proper return vector
147 comboot_return: cli ; Don't trust anyone
148 xor ax,ax
149 jmp comboot_exit
150
151 ;
152 ; Set up the COMBOOT API interrupt vectors. This is also used
153 ; by the COM32 code.
154 ;
155 comboot_setup_api:
156 mov di,4*0x20 ; DOS interrupt vectors
157 mov eax,comboot_return ; INT 20h = exit
158 stosd
159 mov ax,comboot_int21 ; INT 21h = DOS-compatible syscalls
160 stosd
161 mov ax,comboot_int22 ; INT 22h = proprietary syscalls
162 stosd
163 mov ax,comboot_bogus
164 mov cx,29 ; All remaining DOS vectors
165 rep stosd
166 ret
167
168 ; INT 21h: generic DOS system call
169 comboot_int21: cli
170 push ds
171 push es
172 push fs
173 push gs
174 pushad
175 cld
176 mov bp,cs
177 mov ds,bp
178 mov es,bp
179 mov bp,sp ; Set up stack frame
180
181 call adjust_screen ; The COMBOOT program might have changed the screen
182
183 mov cx,int21_count
184 mov si,int21_table
185 .again: lodsb
186 cmp al,P_AH
187 lodsw
188 loopne .again
189 ; The last function in the list is the
190 ; "no such function" function
191 clc
192 call ax ; Call the invoked function
193 comboot_resume:
194 setc P_FLAGSL ; Propagate CF->error
195 popad
196 pop gs
197 pop fs
198 pop es
199 pop ds
200 iret
201
202 ; Attempted to execute non-21h DOS system call
203 comboot_bogus: cli ; Don't trust anyone
204 mov ax,err_notdos
205 ;
206 ; Generic COMBOOT return to command line code
207 ; AX -> message (if any)
208 ; BX -> where to go next
209 ;
210 comboot_exit:
211 mov bx,enter_command ; Normal return to command prompt
212 comboot_exit_special:
213 xor dx,dx
214 mov ds,dx
215 mov es,dx
216 lss sp,[SavedSSSP]
217 sti
218 cld
219 call adjust_screen ; The COMBOOT program might have changed the screen
220 and ax,ax
221 je .nomsg
222 mov si,KernelCName
223 call cwritestr
224 xchg si,ax
225 call cwritestr
226 .nomsg: jmp bx
227
228 ;
229 ; INT 21h system calls
230 ;
231 comboot_getkey: ; 01 = get key with echo
232 call vgashowcursor
233 call comboot_getchar
234 call vgahidecursor
235 call writechr
236 clc
237 ret
238
239 comboot_writechr: ; 02 = writechr
240 mov al,P_DL
241 call writechr
242 clc
243 ret
244
245 comboot_writeserial: ; 04 = write serial port
246 mov al,P_DL
247 call write_serial
248 clc
249 ret
250
251 comboot_getkeynoecho: ; 08 = get key w/o echo
252 call comboot_getchar
253 clc
254 ret
255
256 comboot_writestr: ; 09 = write DOS string
257 mov es,P_DS
258 mov si,P_DX
259 .loop: es lodsb
260 cmp al,'$' ; End string with $ - bizarre
261 je .done
262 call writechr
263 jmp short .loop
264 .done: clc
265 ret
266
267 comboot_checkkey: ; 0B = check keyboard status
268 cmp byte [APIKeyFlag],00h
269 jnz .waiting
270 call pollchar
271 .waiting: setz al
272 dec al ; AL = 0FFh if present, 0 if not
273 mov P_AL,al
274 clc
275 ret
276
277 comboot_checkver: ; 30 = check DOS version
278 ; We return 0 in all DOS-compatible version registers,
279 ; but the high part of eax-ebx-ecx-edx spell "SYSLINUX"
280 mov P_EAX,'SY' << 16
281 mov P_EBX,'SL' << 16
282 mov P_ECX,'IN' << 16
283 mov P_EDX,'UX' << 16
284 ret
285
286 comboot_getchar:
287 cmp byte [APIKeyFlag],00h
288 jne .queued
289 call getchar ; If not queued get input
290 and al,al ; Function key? (CF <- 0)
291 jnz .done
292 mov [APIKeyWait],ah ; High part of key
293 inc byte [APIKeyFlag] ; Set flag
294 .done: mov P_AL,al
295 ret
296 .queued: mov al,[APIKeyWait]
297 dec byte [APIKeyFlag]
298 jmp .done
299
300 ;
301 ; INT 22h - SYSLINUX-specific system calls
302 ; System call number in ax
303 ;
304 comboot_int22:
305 cli
306 push ds
307 push es
308 push fs
309 push gs
310 pushad
311 cld
312 mov bp,cs
313 mov ds,bp
314 mov es,bp
315 mov bp,sp ; Set up stack frame
316
317 call adjust_screen ; The COMBOOT program might have changed the screen
318
319 cmp ax,int22_count
320 jb .ok
321 xor ax,ax ; Function 0 -> unimplemented
322 .ok:
323 xchg ax,bx
324 add bx,bx ; CF <- 0
325 call [bx+int22_table]
326 jmp comboot_resume ; On return
327
328 ;
329 ; INT 22h AX=0000h Unimplemented call
330 ;
331 comapi_err:
332 stc
333 ret
334
335 ;
336 ; INT 22h AX=0001h Get SYSLINUX version
337 ;
338 comapi_get_version:
339 ; Number of API functions supported
340 mov P_AX,int22_count
341 ; SYSLINUX version
342 mov P_CX,(VER_MAJOR << 8)+VER_MINOR
343 ; SYSLINUX derivative ID byte
344 mov P_DX,my_id
345 ; For future use
346 mov P_BX,cs ; cs == 0
347
348 mov P_ES,ds
349 ; ES:SI -> version banner
350 mov P_SI,syslinux_banner
351 ; ES:DI -> copyright string
352 mov P_DI,copyright_str
353
354 comapi_nop:
355 clc
356 ret
357
358 ;
359 ; INT 22h AX=0002h Write string
360 ;
361 ; Write null-terminated string in ES:BX
362 ;
363 comapi_writestr:
364 mov ds,P_ES
365 mov si,P_BX
366 call writestr
367 clc
368 ret
369
370 ;
371 ; INT 22h AX=0003h Run command
372 ;
373 ; Terminates the COMBOOT program and executes the command line in
374 ; ES:BX as if it had been entered by the user.
375 ;
376 comapi_run:
377 mov ds,P_ES
378 mov si,P_BX
379 mov di,command_line
380 call strcpy
381 xor ax,ax
382 mov bx,load_kernel ; Run a new kernel
383 jmp comboot_exit_special ; Terminate task, clean up
384
385 ;
386 ; INT 22h AX=0004h Run default command
387 ;
388 ; Terminates the COMBOOT program and executes the default command line
389 ; as if a timeout had happened or the user pressed <Enter>.
390 ;
391 comapi_run_default:
392 mov bx,auto_boot
393 jmp comboot_exit_special
394
395 ;
396 ; INT 22h AX=0005h Force text mode
397 ;
398 ; Puts the video in standard text mode
399 ;
400 comapi_textmode:
401 call vgaclearmode
402 clc
403 ret
404
405 ;
406 ; INT 22h AX=0006h Open file
407 ;
408 comapi_open:
409 push ds
410 mov ds,P_ES
411 mov si,P_SI
412 mov di,InitRD
413 push di
414 call mangle_name
415 pop di
416 pop ds
417 call searchdir
418 jz comapi_err
419 mov P_AX,ax
420 mov P_HAX,dx
421 mov P_CX,SECTOR_SIZE
422 mov P_SI,si
423 clc
424 ret
425
426 ;
427 ; INT 22h AX=0007h Read file
428 ;
429 comapi_read:
430 mov es,P_ES
431 mov bx,P_BX
432 mov si,P_SI
433 mov cx,P_CX
434 call getfssec
435 jnc .noteof
436 xor si,si ; SI <- 0 on EOF, CF <- 0
437 .noteof: mov P_SI,si
438 ret
439
440 ;
441 ; INT 22h AX=0008h Close file
442 ;
443 comapi_close:
444 ; Do nothing for now. Eventually implement
445 ; an internal API for this.
446 clc
447 ret
448
449 ;
450 ; INT 22h AX=0009h Call PXE stack
451 ;
452 %if IS_PXELINUX
453 comapi_pxecall:
454 mov bx,P_BX
455 mov es,P_ES
456 mov di,P_DI
457 call pxenv
458 mov P_AX,ax
459 clc
460 ret
461 %else
462 comapi_pxecall equ comapi_err ; Not available
463 %endif
464
465 ;
466 ; INT 22h AX=000Ah Get Derivative-Specific Info
467 ;
468 comapi_derinfo:
469 mov P_AL,my_id
470 %if IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
471 mov al,[DriveNumber]
472 mov P_DL,al
473 mov P_ES,cs
474 mov P_BX,PartInfo
475 %elif IS_PXELINUX
476 mov ax,[APIVer]
477 mov P_DX,ax
478 mov ax,[StrucPtr]
479 mov P_BX,ax
480 mov ax,[StrucPtr+2]
481 mov P_ES,ax
482 mov ax,[InitStack]
483 mov P_SI,ax
484 mov ax,[InitStack+2]
485 mov P_FS,ax
486 %elif IS_ISOLINUX
487 mov al,[DriveNo]
488 mov P_DL,al
489 mov P_ES,cs
490 mov P_BX,spec_packet
491 %endif
492 clc
493 ret
494
495 ;
496 ; INT 22h AX=000Bh Get Serial Console Configuration
497 ;
498 comapi_serialcfg:
499 mov ax,[SerialPort]
500 mov P_DX,ax
501 mov ax,[BaudDivisor]
502 mov P_CX,ax
503 mov ax,[FlowControl]
504 or al,ah
505 mov ah,[FlowIgnore]
506 shr ah,4
507 test byte [DisplayCon],01h
508 jnz .normalconsole
509 or ah,80h
510 .normalconsole:
511 mov P_BX,ax
512 clc
513 ret
514
515 ;
516 ; INT 22h AX=000Ch Perform final cleanup
517 ;
518 comapi_cleanup:
519 %if IS_PXELINUX
520 ; Unload PXE if requested
521 test dl,3
522 setnz [KeepPXE]
523 sub bp,sp ; unload_pxe may move the stack around
524 call unload_pxe
525 add bp,sp ; restore frame pointer...
526 %elif IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
527 ; Restore original FDC table
528 mov eax,[OrigFDCTabPtr]
529 mov [fdctab],eax
530 %endif
531 ; Reset the floppy disk subsystem
532 xor ax,ax
533 xor dx,dx
534 int 13h
535 clc
536 ret
537
538 ;
539 ; INT 22h AX=000Dh Clean up then replace bootstrap
540 ;
541 comapi_chainboot:
542 call comapi_cleanup
543 mov eax,P_EDI
544 mov [trackbuf+4],eax ; Copy from
545 mov eax,P_ECX
546 mov [trackbuf+8],eax ; Total bytes
547 mov eax,7C00h
548 mov [trackbuf],eax ; Copy to
549 mov [EntryPoint],eax ; CS:IP entry point
550 mov esi,P_ESI
551 mov edx,P_EBX
552 mov bx,P_DS
553 jmp replace_bootstrap_one
554
555
556 ;
557 ; INT 22h AX=000Eh Get configuration file name
558 ;
559 comapi_configfile:
560 mov P_ES,cs
561 mov P_BX,ConfigName
562 clc
563 ret
564
565 ;
566 ; INT 22h AX=000Fh Get IPAPPEND strings
567 ;
568 %if IS_PXELINUX
569 comapi_ipappend:
570 mov P_ES,cs
571 mov P_CX,numIPAppends
572 mov P_BX,IPAppends
573 clc
574 ret
575
576 section .data
577 alignb 2, db 0
578 IPAppends dw IPOption
579 dw BOOTIFStr
580 numIPAppends equ ($-IPAppends)/2
581
582 %else
583 comapi_ipappend equ comapi_err
584 %endif
585
586 section .text
587
588 ;
589 ; INT 22h AX=0010h Resolve hostname
590 ;
591 %if IS_PXELINUX
592 comapi_dnsresolv:
593 mov ds,P_ES
594 mov si,P_BX
595 call dns_resolv
596 mov P_EAX,eax
597 ret
598 %else
599 comapi_dnsresolv equ comapi_err
600 %endif
601
602 section .text
603
604 ;
605 ; INT 22h AX=0011h Maximum number of shuffle descriptors
606 ;
607 comapi_maxshuffle:
608 mov P_CX,(2*trackbufsize)/12
609 ret
610
611 ;
612 ; INT 22h AX=0012h Cleanup, shuffle and boot
613 ;
614 comapi_shuffle:
615 call comapi_cleanup
616 mov cx,P_CX
617 cmp cx,(2*trackbufsize)/12
618 ja .error
619
620 push cx ; On stack: descriptor count
621
622 lea cx,[ecx+ecx*2] ; CX *= 3
623
624 mov fs,P_ES
625 mov si,P_DI
626 mov di,trackbuf
627 push di ; On stack: descriptor list address
628 fs rep movsd ; Copy the list
629
630 mov eax,P_EBP
631 mov [EntryPoint],eax ; CS:IP entry point
632 mov esi,P_ESI
633 mov edx,P_EBX
634 mov bx,P_DS
635 jmp replace_bootstrap
636 .error:
637 stc
638 ret
639
640 ;
641 ; INT 22h AX=0013h Idle call
642 ;
643 ;
644 ; *** FIX THIS ***
645 ; The idle call seems to have detrimental effects on some machines when
646 ; called from a COM32 context (WHY?) -- disable it for now.
647 ;
648 %if 0 ; def HAVE_IDLE
649
650 comapi_idle:
651 DO_IDLE
652 clc
653 ret
654
655 %else
656
657 comapi_idle equ comapi_err
658
659 %endif
660
661 ;
662 ; INT 22h AX=0014h Local boot
663 ;
664 %if IS_PXELINUX || IS_ISOLINUX
665 comapi_localboot:
666 mov ax,P_DX
667 jmp local_boot
668 %else
669 comapi_localboot equ comapi_err
670 %endif
671
672 ;
673 ; INT 22h AX=0015h Feature flags
674 ;
675 comapi_features:
676 mov P_ES,cs
677 mov P_BX,feature_flags
678 mov P_CX,feature_flags_len
679 clc
680 ret
681
682 ;
683 ; INT 22h AX=0016h Run kernel image
684 ;
685 comapi_runkernel:
686 push ds
687 mov ds,P_DS
688 mov si,P_SI
689 mov di,KernelName
690 push di
691 call mangle_name
692 pop di
693 pop ds
694 call searchdir
695 jz comapi_err
696
697 ; The kernel image was found, so we can load it...
698 mov [Kernel_SI],si
699 mov [Kernel_EAX],ax
700 mov [Kernel_EAX+2],dx
701
702 ; It's not just possible, but quite likely, that ES:BX
703 ; points into real_mode_seg, so we need to exercise some
704 ; special care here... use xfer_buf_seg as an intermediary
705 push ds
706 push es
707 mov ax,xfer_buf_seg
708 mov ds,P_ES
709 mov si,P_BX
710 mov es,ax
711 xor di,di
712 call strcpy
713 pop es
714 pop ds
715
716 %if IS_PXELINUX
717 mov al,P_CL
718 mov [IPAppend],al
719 %endif
720
721 xor ax,ax
722 mov bx,.finish
723 jmp comboot_exit_special
724
725 .finish:
726 ; Copy the command line into its proper place
727 push ds
728 push es
729 mov ax,xfer_buf_seg
730 mov dx,real_mode_seg
731 mov ds,ax
732 mov es,dx
733 xor si,si
734 mov di,cmd_line_here
735 call strcpy
736 mov byte [es:di-1],' ' ; Simulate APPEND
737 pop es
738 pop ds
739 mov [CmdLinePtr],di
740 mov word [CmdOptPtr],zero_string
741 jmp kernel_good_saved
742
743 section .data
744
745 %macro int21 2
746 db %1
747 dw %2
748 %endmacro
749
750 int21_table:
751 int21 00h, comboot_return
752 int21 01h, comboot_getkey
753 int21 02h, comboot_writechr
754 int21 04h, comboot_writeserial
755 int21 08h, comboot_getkeynoecho
756 int21 09h, comboot_writestr
757 int21 0Bh, comboot_checkkey
758 int21 30h, comboot_checkver
759 int21 4Ch, comboot_return
760 int21 -1, comboot_bogus
761 int21_count equ ($-int21_table)/3
762
763 align 2, db 0
764 int22_table:
765 dw comapi_err ; 0000 unimplemented syscall
766 dw comapi_get_version ; 0001 get SYSLINUX version
767 dw comapi_writestr ; 0002 write string
768 dw comapi_run ; 0003 run specified command
769 dw comapi_run_default ; 0004 run default command
770 dw comapi_textmode ; 0005 force text mode
771 dw comapi_open ; 0006 open file
772 dw comapi_read ; 0007 read file
773 dw comapi_close ; 0008 close file
774 dw comapi_pxecall ; 0009 call PXE stack
775 dw comapi_derinfo ; 000A derivative-specific info
776 dw comapi_serialcfg ; 000B get serial port config
777 dw comapi_cleanup ; 000C perform final cleanup
778 dw comapi_chainboot ; 000D clean up then bootstrap
779 dw comapi_configfile ; 000E get name of config file
780 dw comapi_ipappend ; 000F get ipappend strings
781 dw comapi_dnsresolv ; 0010 resolve hostname
782 dw comapi_maxshuffle ; 0011 maximum shuffle descriptors
783 dw comapi_shuffle ; 0012 cleanup, shuffle and boot
784 dw comapi_idle ; 0013 idle call
785 dw comapi_localboot ; 0014 local boot
786 dw comapi_features ; 0015 feature flags
787 dw comapi_runkernel ; 0016 run kernel image
788 int22_count equ ($-int22_table)/2
789
790 APIKeyWait db 0
791 APIKeyFlag db 0
792
793 zero_string db 0 ; Empty, null-terminated string
794
795 ;
796 ; This is the feature flag array for INT 22h AX=0015h
797 feature_flags:
798 %if IS_PXELINUX
799 db 1 ; Have local boot, idle not noop
800 %elif IS_ISOLINUX
801 db 3 ; Have local boot, idle is noop
802 %else
803 db 2 ; No local boot, idle is noop
804 %endif
805 feature_flags_len equ ($-feature_flags)