1 ;; -----------------------------------------------------------------------
3 ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
5 ;; This program is free software; you can redistribute it and/or modify
6 ;; it under the terms of the GNU General Public License as published by
7 ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 ;; Boston MA 02111-1307, USA; either version 2 of the License, or
9 ;; (at your option) any later version; incorporated herein by reference.
11 ;; -----------------------------------------------------------------------
16 ;; Common code for running a COMBOOT image
21 ; Parameter registers definition; this is the definition
22 ; of the stack frame used by INT 21h and INT 22h.
23 %define P_FLAGS word [bp+44]
24 %define P_FLAGSL byte [bp+44]
25 %define P_FLAGSH byte [bp+45]
26 %define P_CS word [bp+42]
27 %define P_IP word [bp+40]
28 %define P_DS word [bp+38]
29 %define P_ES word [bp+36]
30 %define P_FS word [bp+34]
31 %define P_GS word [bp+32]
32 %define P_EAX dword [bp+28]
33 %define P_AX word [bp+28]
34 %define P_HAX word [bp+30]
35 %define P_AL byte [bp+28]
36 %define P_AH byte [bp+29]
37 %define P_ECX dword [bp+24]
38 %define P_CX word [bp+24]
39 %define P_HCX word [bp+26]
40 %define P_CL byte [bp+24]
41 %define P_CH byte [bp+25]
42 %define P_EDX dword [bp+20]
43 %define P_DX word [bp+20]
44 %define P_HDX word [bp+22]
45 %define P_DL byte [bp+20]
46 %define P_DH byte [bp+21]
47 %define P_EBX dword [bp+16]
48 %define P_BX word [bp+16]
49 %define P_HBX word [bp+18]
50 %define P_BL byte [bp+16]
51 %define P_BH byte [bp+17]
52 %define P_EBP dword [bp+8]
53 %define P_BP word [bp+8]
54 %define P_HBP word [bp+10]
55 %define P_ESI dword [bp+4]
56 %define P_SI word [bp+4]
57 %define P_HSI word [bp+6]
58 %define P_EDI dword [bp]
59 %define P_DI word [bp]
60 %define P_HDI word [bp+2]
62 ; Looks like a COMBOOT image but too large
69 ; Load a COMBOOT image. A COMBOOT image is basically a DOS .COM file,
70 ; except that it may, of course, not contain any DOS system calls. We
71 ; do, however, allow the execution of INT 20h to return to SYSLINUX.
76 cmp ax,0ff00h ; Max size in bytes
79 push si ; Save file handle
81 call make_plain_cmdline
83 call comboot_setup_api
89 mov cx,64 ; 256 bytes (size of PSP)
90 xor eax,eax ; Clear PSP
93 mov word [es:0], 020CDh ; INT 20h instruction
94 ; First non-free paragraph
95 ; This is valid because comboot_seg == real_mode_seg
96 ; == the highest segment used by all derivatives
97 int 12h ; Get DOS memory size
98 shl ax,6 ; Kilobytes -> paragraphs
102 %if real_mode_seg != comboot_seg
103 %error "This code assumes real_mode_seg == comboot_seg"
106 ; Copy the command line from high memory
108 mov cx,125 ; Max cmdline len (minus space and CR)
109 mov di,081h ; Offset in PSP for command line
110 mov al,' ' ; DOS command lines begin with a space
120 mov al,0Dh ; CR after last character
123 sub al,82h ; Include space but not CR
124 mov [es:80h],al ; Store command line length
126 ; Now actually load the file...
128 mov bx,100h ; Load at <seg>:0100h
129 mov cx,0FF00h >> SECTOR_SHIFT
130 ; Absolute maximum # of sectors
133 ; And invoke the program...
138 push word 0 ; Return to address 0 -> exit
140 jmp comboot_seg:100h ; Run it
142 ; Proper return vector
143 comboot_return: cli ; Don't trust anyone
144 push enter_command ; Normal return to command prompt
148 ; Set up the COMBOOT API interrupt vectors. This is also used
152 mov di,4*0x20 ; DOS interrupt vectors
153 mov eax,comboot_return ; INT 20h = exit
155 mov ax,comboot_int21 ; INT 21h = DOS-compatible syscalls
157 mov ax,comboot_int22 ; INT 22h = proprietary syscalls
160 mov cx,29 ; All remaining DOS vectors
164 ; INT 21h: generic DOS system call
175 mov bp,sp ; Set up stack frame
177 call adjust_screen ; The COMBOOT program might have changed the screen
185 ; The last function in the list is the
186 ; "no such function" function
188 call ax ; Call the invoked function
190 mov bp,sp ; In case the function clobbers BP
191 setc P_FLAGSL ; Propagate CF->error
199 ; Attempted to execute non-21h DOS system call
200 comboot_bogus: cli ; Don't trust anyone
206 ; Generic COMBOOT return to command line code
207 ; stack -> where to go next
208 ; CX -> message (for _msg version)
213 pop bx ; Return address
214 RESET_STACK_AND_SEGS AX
215 call adjust_screen ; The COMBOOT program might have changed the screen
225 ; INT 21h system calls
227 comboot_getkey: ; 01 = get key with echo
235 comboot_writechr: ; 02 = writechr
241 comboot_writeserial: ; 04 = write serial port
247 comboot_getkeynoecho: ; 08 = get key w/o echo
252 comboot_writestr: ; 09 = write DOS string
256 cmp al,'$' ; End string with $ - bizarre
263 comboot_checkkey: ; 0B = check keyboard status
264 cmp byte [APIKeyFlag],00h
268 dec al ; AL = 0FFh if present, 0 if not
273 comboot_checkver: ; 30 = check DOS version
274 ; We return 0 in all DOS-compatible version registers,
275 ; but the high part of eax-ebx-ecx-edx spell "SYSLINUX"
283 cmp byte [APIKeyFlag],00h
285 call getchar ; If not queued get input
286 and al,al ; Function key? (CF <- 0)
288 mov [APIKeyWait],ah ; High part of key
289 inc byte [APIKeyFlag] ; Set flag
292 .queued: mov al,[APIKeyWait]
293 dec byte [APIKeyFlag]
297 ; INT 22h - SYSLINUX-specific system calls
298 ; System call number in ax
311 mov bp,sp ; Set up stack frame
313 call adjust_screen ; The COMBOOT program might have changed the screen
317 xor ax,ax ; Function 0 -> unimplemented
321 call [bx+int22_table]
322 jmp comboot_resume ; On return
325 ; INT 22h AX=0000h Unimplemented call
332 ; INT 22h AX=0001h Get SYSLINUX version
335 ; Number of API functions supported
338 mov P_CX,(VER_MAJOR << 8)+VER_MINOR
339 ; SYSLINUX derivative ID byte
342 mov P_BX,cs ; cs == 0
345 ; ES:SI -> version banner
346 mov P_SI,syslinux_banner
347 ; ES:DI -> copyright string
348 mov P_DI,copyright_str
355 ; INT 22h AX=0002h Write string
357 ; Write null-terminated string in ES:BX
367 ; INT 22h AX=0003h Run command
369 ; Terminates the COMBOOT program and executes the command line in
370 ; ES:BX as if it had been entered by the user.
377 push load_kernel ; Run a new kernel
378 jmp comboot_exit ; Terminate task, clean up
381 ; INT 22h AX=0004h Run default command
383 ; Terminates the COMBOOT program and executes the default command line
384 ; as if a timeout had happened or the user pressed <Enter>.
391 ; INT 22h AX=0005h Force text mode
393 ; Puts the video in standard text mode
401 ; INT 22h AX=0006h Open file
420 ; INT 22h AX=0007h Read file
429 xor si,si ; SI <- 0 on EOF, CF <- 0
434 ; INT 22h AX=0008h Close file
443 ; INT 22h AX=0009h Call PXE stack
455 comapi_pxecall equ comapi_err ; Not available
459 ; INT 22h AX=000Ah Get Derivative-Specific Info
477 mov P_CL,SECTOR_SHIFT
482 %if IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
494 ; INT 22h AX=000Bh Get Serial Console Configuration
505 test byte [DisplayCon],01h
514 ; INT 22h AX=000Ch Perform final cleanup
518 ; Unload PXE if requested
521 sub bp,sp ; unload_pxe may move the stack around
523 add bp,sp ; restore frame pointer...
524 %elif IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
525 ; Restore original FDC table
526 mov eax,[OrigFDCTabPtr]
529 ; Reset the floppy disk subsystem
537 ; INT 22h AX=000Dh Clean up then replace bootstrap
542 mov [trackbuf+4],eax ; Copy from
544 mov [trackbuf+8],eax ; Total bytes
546 mov [trackbuf],eax ; Copy to
547 mov [EntryPoint],eax ; CS:IP entry point
551 jmp replace_bootstrap_one
555 ; INT 22h AX=000Eh Get configuration file name
564 ; INT 22h AX=000Fh Get IPAPPEND strings
569 mov P_CX,numIPAppends
576 IPAppends dw IPOption
578 numIPAppends equ ($-IPAppends)/2
581 comapi_ipappend equ comapi_err
587 ; INT 22h AX=0010h Resolve hostname
598 comapi_dnsresolv equ comapi_err
604 ; INT 22h AX=0011h Maximum number of shuffle descriptors
607 mov P_CX,(2*trackbufsize)/12
611 ; INT 22h AX=0012h Cleanup, shuffle and boot
614 cmp P_CX,(2*trackbufsize)/12
620 push cx ; On stack: descriptor count
622 lea cx,[ecx+ecx*2] ; CX *= 3
627 push di ; On stack: descriptor list address
628 fs rep movsd ; Copy the list
631 mov [EntryPoint],eax ; CS:IP entry point
635 jmp replace_bootstrap
641 ; INT 22h AX=0013h Idle call
645 ; The idle call seems to have detrimental effects on some machines when
646 ; called from a COM32 context (WHY?) -- disable it for now.
648 %if 0 ; def HAVE_IDLE
657 comapi_idle equ comapi_err
662 ; INT 22h AX=0014h Local boot
664 %if IS_PXELINUX || IS_ISOLINUX
669 comapi_localboot equ comapi_err
673 ; INT 22h AX=0015h Feature flags
677 mov P_BX,feature_flags
678 mov P_CX,feature_flags_len
683 ; INT 22h AX=0016h Run kernel image
699 ; The kernel image was found, so we can load it...
702 mov [Kernel_EAX+2],dx
704 ; It's not just possible, but quite likely, that ES:BX
705 ; points into real_mode_seg, so we need to exercise some
706 ; special care here... use xfer_buf_seg as an intermediary
726 ; Copy the command line into its proper place
736 mov byte [es:di-1],' ' ; Simulate APPEND
740 mov word [CmdOptPtr],zero_string
741 jmp kernel_good_saved
743 .error equ comapi_shuffle.error
746 ; INT 22h AX=0017h Report video mode change
750 cmp ax,0Fh ; Unknown flags = failure
768 ; INT 22h AX=0018h Query custom font
783 ; INT 22h AX=0019h Read disk
785 %if IS_SYSLINUX || IS_MDSLINUX || IS_ISOLINUX || IS_EXTLINUX
787 mov esi,P_ESI ; Enforce ESI == EDI == 0, these
788 or esi,P_EDI ; are reserved for future expansion
793 mov bp,P_CX ; WE CANNOT use P_* after touching bp!
801 comapi_readdisk equ comapi_err
805 ; INT 22h AX=001Ah Cleanup, shuffle and boot to flat protected mode
808 cmp P_CX,(2*trackbufsize)/12
814 push cx ; On stack: descriptor count
816 lea cx,[ecx+ecx*2] ; CX *= 3
821 push di ; On stack: descriptor list address
822 fs rep movsd ; Copy the list
826 mov edi,TrampolineBuf
827 mov al,0B8h ; MOV EAX opcode
831 inc ax ; Next register opcode
832 fs movsd ; immediate value
834 mov byte [di-5],0E9h ; Last opcode is JMP
835 sub [di-4],edi ; Make JMP target relative
837 mov dword [EntryPoint],trampoline_to_pm
838 xor bx,bx ; DS on entry
839 jmp replace_bootstrap
845 ; INT 22h AX=001Bh Cleanup, shuffle and boot with register setting
848 cmp P_CX,(2*trackbufsize)/12
854 push cx ; On stack: descriptor count
856 lea cx,[ecx+ecx*2] ; CX *= 3
861 push di ; On stack: descriptor list address
862 fs rep movsd ; Copy the list
868 ; Generate segment-loading instructions
869 mov bx,0C08Eh ; MOV ES,AX
870 mov cl,6 ; 6 segment registers (incl CS)
873 stosb ; MOV AX,imm16 opcode
880 ; Clobber the MOV CS,AX instruction.
881 mov word [di-22], 9090h ; NOP NOP
883 ; Generate GPR-loading instructions
884 mov ax,0B866h ; MOV EAX,imm32
887 stosw ; MOV ExX,imm32 opcode
892 mov al,0EAh ; JMP FAR imm16:imm16 opcode
896 mov dword [EntryPoint],TrampolineBuf
897 jmp replace_bootstrap
903 ; INT 22h AX=001Ch Get pointer to auxillary data vector
912 ; INT 22h AX=001Dh Write auxillary data vector
914 comapi_writeadv equ adv_write
924 int21 00h, comboot_return
925 int21 01h, comboot_getkey
926 int21 02h, comboot_writechr
927 int21 04h, comboot_writeserial
928 int21 08h, comboot_getkeynoecho
929 int21 09h, comboot_writestr
930 int21 0Bh, comboot_checkkey
931 int21 30h, comboot_checkver
932 int21 4Ch, comboot_return
933 int21 -1, comboot_bogus
934 int21_count equ ($-int21_table)/3
938 dw comapi_err ; 0000 unimplemented syscall
939 dw comapi_get_version ; 0001 get SYSLINUX version
940 dw comapi_writestr ; 0002 write string
941 dw comapi_run ; 0003 run specified command
942 dw comapi_run_default ; 0004 run default command
943 dw comapi_textmode ; 0005 force text mode
944 dw comapi_open ; 0006 open file
945 dw comapi_read ; 0007 read file
946 dw comapi_close ; 0008 close file
947 dw comapi_pxecall ; 0009 call PXE stack
948 dw comapi_derinfo ; 000A derivative-specific info
949 dw comapi_serialcfg ; 000B get serial port config
950 dw comapi_cleanup ; 000C perform final cleanup
951 dw comapi_chainboot ; 000D clean up then bootstrap
952 dw comapi_configfile ; 000E get name of config file
953 dw comapi_ipappend ; 000F get ipappend strings
954 dw comapi_dnsresolv ; 0010 resolve hostname
955 dw comapi_maxshuffle ; 0011 maximum shuffle descriptors
956 dw comapi_shuffle ; 0012 cleanup, shuffle and boot
957 dw comapi_idle ; 0013 idle call
958 dw comapi_localboot ; 0014 local boot
959 dw comapi_features ; 0015 feature flags
960 dw comapi_runkernel ; 0016 run kernel image
961 dw comapi_usingvga ; 0017 report video mode change
962 dw comapi_userfont ; 0018 query custom font
963 dw comapi_readdisk ; 0019 read disk
964 dw comapi_shufflepm ; 001A cleanup, shuffle and boot to pm
965 dw comapi_shufflerm ; 001B cleanup, shuffle and boot to rm
966 dw comapi_getadv ; 001C get pointer to ADV
967 dw comapi_writeadv ; 001D write ADV to disk
968 int22_count equ ($-int22_table)/2
973 zero_string db 0 ; Empty, null-terminated string
976 ; This is the feature flag array for INT 22h AX=0015h
979 db 1 ; Have local boot, idle not noop
981 db 3 ; Have local boot, idle is noop
983 db 2 ; No local boot, idle is noop
985 feature_flags_len equ ($-feature_flags)
987 err_notdos db ': attempted DOS system call', CR, LF, 0
988 err_comlarge db 'COMBOOT image too large.', CR, LF, 0
991 ConfigName resb FILENAME_MAX