Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (hide 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 niro 532 ;; $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)