1 ;; -----------------------------------------------------------------------
3 ;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
4 ;; Copyright 2009 Intel Corporation; author: H. Peter Anvin
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.
12 ;; -----------------------------------------------------------------------
17 ;; Common code for running a COMBOOT image
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_CSIP dword [bp+40]
30 %define P_DS word [bp+38]
31 %define P_ES word [bp+36]
32 %define P_FS word [bp+34]
33 %define P_GS word [bp+32]
34 %define P_EAX dword [bp+28]
35 %define P_AX word [bp+28]
36 %define P_HAX word [bp+30]
37 %define P_AL byte [bp+28]
38 %define P_AH byte [bp+29]
39 %define P_ECX dword [bp+24]
40 %define P_CX word [bp+24]
41 %define P_HCX word [bp+26]
42 %define P_CL byte [bp+24]
43 %define P_CH byte [bp+25]
44 %define P_EDX dword [bp+20]
45 %define P_DX word [bp+20]
46 %define P_HDX word [bp+22]
47 %define P_DL byte [bp+20]
48 %define P_DH byte [bp+21]
49 %define P_EBX dword [bp+16]
50 %define P_BX word [bp+16]
51 %define P_HBX word [bp+18]
52 %define P_BL byte [bp+16]
53 %define P_BH byte [bp+17]
54 %define P_EBP dword [bp+8]
55 %define P_BP word [bp+8]
56 %define P_HBP word [bp+10]
57 %define P_ESI dword [bp+4]
58 %define P_SI word [bp+4]
59 %define P_HSI word [bp+6]
60 %define P_EDI dword [bp]
61 %define P_DI word [bp]
62 %define P_HDI word [bp+2]
64 ; Looks like a COMBOOT image but too large
72 ; Load a COMBOOT image. A COMBOOT image is basically a DOS .COM file,
73 ; except that it may, of course, not contain any DOS system calls. We
74 ; do, however, allow the execution of INT 20h to return to SYSLINUX.
77 push si ; Save file handle
79 call make_plain_cmdline
81 call comboot_setup_api
87 mov cx,64 ; 256 bytes (size of PSP)
88 xor eax,eax ; Clear PSP
91 mov word [es:0], 020CDh ; INT 20h instruction
92 ; First non-free paragraph
93 ; This is valid because comboot_seg == real_mode_seg
94 ; == the highest segment used by all derivatives
95 int 12h ; Get DOS memory size
96 shl ax,6 ; Kilobytes -> paragraphs
100 %if real_mode_seg != comboot_seg
101 %error "This code assumes real_mode_seg == comboot_seg"
104 ; Copy the command line from high memory
106 mov cx,125 ; Max cmdline len (minus space and CR)
107 mov di,081h ; Offset in PSP for command line
108 mov al,' ' ; DOS command lines begin with a space
118 mov al,0Dh ; CR after last character
121 sub al,82h ; Include space but not CR
122 mov [es:80h],al ; Store command line length
124 ; Now actually load the file...
126 mov bx,100h ; Load at <seg>:0100h
127 mov cx,10000h >> SECTOR_SHIFT
128 ; Absolute maximum # of sectors
130 cmp ecx,65536-256-2 ; Maximum size
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 ; Note: this gets invoked both via INT 21h and directly via INT 20h.
144 ; We don't need to cld explicitly here, because comboot_exit does that
145 ; when invoking RESET_STACK_AND_SEGS.
146 comboot_return: cli ; May not have a safe stack
147 push enter_command ; Normal return to command prompt
151 ; Set up the COMBOOT API interrupt vectors. This is now done at
152 ; initialization time.
155 mov di,DOSErrTramp ; Error trampolines
158 mov eax,02EB206Ah ; push 20h; jmp $+4
164 mov ax,comboot_bogus-2
169 mov si,4*20h ; DOS interrupt vectors
170 mov bx,comboot_vectors
171 mov di,DOSSaveVectors
182 ; Restore the original state of the COMBOOT API vectors
186 mov si,DOSSaveVectors
189 rep movsd ; Restore DOS-range vectors
195 DOSSaveVectors resd 32
198 %define comboot_err(x) (DOSErrTramp+4*((x)-20h))
201 dw comboot_return ; INT 20 = exit
202 dw comboot_int21 ; INT 21 = DOS-compatible system calls
203 dw comboot_int22 ; INT 22 = native system calls
204 dw comboot_err(23h) ; INT 23 = DOS Ctrl-C handler
205 dw comboot_err(24h) ; INT 24 = DOS critical error handler
206 dw comboot_err(25h) ; INT 25 = DOS absolute disk read
207 dw comboot_err(26h) ; INT 26 = DOS absolute disk write
208 dw comboot_err(27h) ; INT 27 = DOS TSR
209 dw comboot_int28 ; INT 28 = DOS idle interrupt
210 dw comboot_int29 ; INT 29 = DOS fast console output
211 dw comboot_err(2Ah) ; INT 2A = DOS network API (NetBIOS)
212 dw comboot_err(2Bh) ; INT 2B = DOS reserved
213 dw comboot_err(2Ch) ; INT 2C = DOS reserved
214 dw comboot_iret ; INT 2D = DOS reserved, AMIS
215 dw comboot_err(2Eh) ; INT 2E = DOS run command
216 dw comboot_iret ; INT 2F = DOS multiplex interrupt
217 dw comboot_err(30h) ; INT 30 = DOS CP/M system calls
218 dw comboot_err(31h) ; INT 31 = DPMI
219 dw comboot_err(32h) ; INT 32 = DOS reserved
220 dw comboot_iret ; INT 33 = DOS mouse API
221 dw comboot_err(34h) ; INT 34 = DOS FPU emulation
222 dw comboot_err(35h) ; INT 35 = DOS FPU emulation
223 dw comboot_err(36h) ; INT 36 = DOS FPU emulation
224 dw comboot_err(37h) ; INT 37 = DOS FPU emulation
225 dw comboot_err(38h) ; INT 38 = DOS FPU emulation
226 dw comboot_err(39h) ; INT 39 = DOS FPU emulation
227 dw comboot_err(3Ah) ; INT 3A = DOS FPU emulation
228 dw comboot_err(3Bh) ; INT 3B = DOS FPU emulation
229 dw comboot_err(3Ch) ; INT 3C = DOS FPU emulation
230 dw comboot_err(3Dh) ; INT 3D = DOS FPU emulation
231 dw comboot_err(3Eh) ; INT 3E = DOS FPU emulation
232 dw comboot_err(3Fh) ; INT 3F = DOS overlay manager
236 ; INT 21h: generic DOS system call
247 mov bp,sp ; Set up stack frame
249 call adjust_screen ; The COMBOOT program might have changed the screen
257 ; The last function in the list is the
258 ; "no such function" function
260 call ax ; Call the invoked function
262 mov bp,sp ; In case the function clobbers BP
263 setc P_FLAGSL ; Propagate CF->error
278 ; Attempted to execute invalid DOS system call
279 ; The interrupt number is on the stack.
280 comboot_bogus: pop dx ; Interrupt number
283 push comboot_bogus_tail
287 call writehex2 ; Interrupt number
291 call writehex4 ; Function number (AX)
295 call writehex8 ; CS:IP of the origin
300 ; Generic COMBOOT return to command line code
301 ; stack -> where to go next
302 ; CX -> message (for _msg version)
307 pop bx ; Return address
308 RESET_STACK_AND_SEGS SI ; Contains sti, cld
309 call adjust_screen ; The COMBOOT program might have changed the screen
319 ; INT 21h system calls
321 comboot_getkey: ; 01 = get key with echo
329 comboot_writechr: ; 02 = writechr
335 comboot_writeserial: ; 04 = write serial port
341 comboot_getkeynoecho: ; 08 = get key w/o echo
346 comboot_writestr: ; 09 = write DOS string
350 cmp al,'$' ; End string with $ - bizarre
357 comboot_checkkey: ; 0B = check keyboard status
358 cmp byte [APIKeyFlag],00h
362 dec al ; AL = 0FFh if present, 0 if not
367 comboot_checkver: ; 30 = check DOS version
368 ; We return 0 in all DOS-compatible version registers,
369 ; but the high part of eax-ebx-ecx-edx spell "SYSLINUX"
377 cmp byte [APIKeyFlag],00h
379 call getchar ; If not queued get input
380 and al,al ; Function key? (CF <- 0)
382 mov [APIKeyWait],ah ; High part of key
383 inc byte [APIKeyFlag] ; Set flag
386 .queued: mov al,[APIKeyWait]
387 dec byte [APIKeyFlag]
400 ; INT 29h - DOS fast write character
405 call writechr ; Preserves registers!
409 ; INT 22h - SYSLINUX-specific system calls
410 ; System call number in ax
423 mov bp,sp ; Set up stack frame
425 call adjust_screen ; The COMBOOT program might have changed the screen
429 xor ax,ax ; Function 0 -> unimplemented
433 call [bx+int22_table]
434 jmp comboot_resume ; On return
437 ; INT 22h AX=0000h Unimplemented call
444 ; INT 22h AX=0001h Get SYSLINUX version
447 ; Number of API functions supported
450 mov P_CX,(VERSION_MAJOR << 8)+VERSION_MINOR
451 ; SYSLINUX derivative ID byte
454 mov P_BX,cs ; cs == 0
457 ; ES:SI -> version banner
458 mov P_SI,syslinux_banner
459 ; ES:DI -> copyright string
460 mov P_DI,copyright_str
467 ; INT 22h AX=0002h Write string
469 ; Write null-terminated string in ES:BX
479 ; INT 22h AX=0003h Run command
481 ; Terminates the COMBOOT program and executes the command line in
482 ; ES:BX as if it had been entered by the user.
489 push load_kernel ; Run a new kernel
490 jmp comboot_exit ; Terminate task, clean up
493 ; INT 22h AX=0004h Run default command
495 ; Terminates the COMBOOT program and executes the default command line
496 ; as if a timeout had happened or the user pressed <Enter>.
503 ; INT 22h AX=0005h Force text mode
505 ; Puts the video in standard text mode
513 ; INT 22h AX=0006h Open file
520 pm_call pm_mangle_name
531 ; INT 22h AX=0007h Read file
540 xor si,si ; SI <- 0 on EOF, CF <- 0
546 ; INT 22h AX=0008h Close file
555 ; INT 22h AX=0009h Call PXE stack
567 comapi_pxecall equ comapi_err ; Not available
571 ; INT 22h AX=000Ah Get Derivative-Specific Info
591 mov P_CL,SECTOR_SHIFT
596 %if IS_SYSLINUX || IS_EXTLINUX
605 mov P_CH,al ; Mode (el torito/cbios/ebios)
612 ; INT 22h AX=000Bh Get Serial Console Configuration
623 test byte [DisplayCon],01h
632 ; INT 22h AX=000Ch Perform final cleanup
636 ; Unload PXE if requested
639 sub bp,sp ; unload_pxe may move the stack around
641 add bp,sp ; restore frame pointer...
642 %elif IS_SYSLINUX || IS_EXTLINUX
643 ; Restore original FDC table
644 mov eax,[OrigFDCTabPtr]
647 call cleanup_hardware
652 ; INT 22h AX=000Dh Clean up then replace bootstrap
657 mov [trackbuf+4],eax ; Copy from
659 mov [trackbuf+8],eax ; Total bytes
661 mov [trackbuf],eax ; Copy to
662 push eax ; Entry point on stack
666 jmp replace_bootstrap_one
669 ; INT 22h AX=000Eh Get configuration file name
678 ; INT 22h AX=000Fh Get IPAPPEND strings
682 mov P_CX,numIPAppends
688 ; INT 22h AX=0010h Resolve hostname
691 extern pxe_dns_resolv
695 pm_call pxe_dns_resolv
700 comapi_dnsresolv equ comapi_err
706 ; INT 22h AX=0011h Obsolete
710 ; INT 22h AX=0012h Obsolete
714 ; INT 22h AX=0013h Idle call
722 ; INT 22h AX=0014h Local boot
729 comapi_localboot equ comapi_err
730 %endif ; HAS_LOCALBOOT
733 ; INT 22h AX=0015h Feature flags
737 mov P_BX,feature_flags
738 mov P_CX,feature_flags_len
743 ; INT 22h AX=0016h Run kernel image
754 pm_call pm_mangle_name
759 ; The kernel image was found, so we can load it...
763 ; It's not just possible, but quite likely, that ES:BX
764 ; points into real_mode_seg or xfer_buf_seg, so we
765 ; need to exercise some special care here... use
766 ; trackbuf as an intermediary
782 ; Copy the command line into its proper place
789 mov byte [es:di-1],' ' ; Simulate APPEND
792 mov word [CmdOptPtr],zero_string
793 jmp kernel_good_saved
795 .error equ comapi_usingvga.error
798 ; INT 22h AX=0017h Report video mode change
802 cmp ax,0Fh ; Unknown flags = failure
820 ; INT 22h AX=0018h Query custom font
835 ; INT 22h AX=0019h Read disk
837 %if IS_SYSLINUX || IS_ISOLINUX || IS_EXTLINUX
839 mov esi,P_ESI ; Enforce ESI == EDI == 0, these
840 or esi,P_EDI ; are reserved for future expansion
845 mov bp,P_CX ; WE CANNOT use P_* after touching bp!
853 comapi_readdisk equ comapi_err
857 ; INT 22h AX=001Ah Obsolete
861 ; INT 22h AX=001Bh Obsolete
865 ; INT 22h AX=001Ch Get pointer to auxillary data vector
874 ; INT 22h AX=001Dh Write auxillary data vector
876 comapi_writeadv equ adv_write
879 ; INT 22h AX=001Eh Keyboard remapping table
884 mov P_CX,256 ; Length
893 ; INT 22h AX=001Fh Get current working directory
897 mov P_BX,CurrentDirName
902 ; INT 22h AX=0020h Open directory
905 comapi_opendir equ comapi_err
913 jz comapi_err ; Didn't find a directory
915 jz comapi_err ; Found nothing
922 ; INT 22h AX=0021h Read directory
925 comapi_readdir equ comapi_err
929 mov esi,P_ESI ; The address of DIR structure
931 mov P_EAX,eax ; The address of newly read dirent structure
936 ; INT 22h AX=0022h Close directory
939 mov esi,P_ESI ; The address of DIR structure
944 ; INT 22h AX=0023h Query shuffler size
947 ; +15 is padding to guarantee alignment
948 mov P_CX,__bcopyxx_len + 15
952 ; INT 22h AX=0024h Cleanup, shuffle and boot raw
959 jmp shuffle_and_boot_raw
969 int21 00h, comboot_return
970 int21 01h, comboot_getkey
971 int21 02h, comboot_writechr
972 int21 04h, comboot_writeserial
973 int21 08h, comboot_getkeynoecho
974 int21 09h, comboot_writestr
975 int21 0Bh, comboot_checkkey
976 int21 30h, comboot_checkver
977 int21 4Ch, comboot_return
978 int21 -1, comboot_bad_int21
979 int21_count equ ($-int21_table)/3
983 dw comapi_err ; 0000 unimplemented syscall
984 dw comapi_get_version ; 0001 get SYSLINUX version
985 dw comapi_writestr ; 0002 write string
986 dw comapi_run ; 0003 run specified command
987 dw comapi_run_default ; 0004 run default command
988 dw comapi_textmode ; 0005 force text mode
989 dw comapi_open ; 0006 open file
990 dw comapi_read ; 0007 read file
991 dw comapi_close ; 0008 close file
992 dw comapi_pxecall ; 0009 call PXE stack
993 dw comapi_derinfo ; 000A derivative-specific info
994 dw comapi_serialcfg ; 000B get serial port config
995 dw comapi_cleanup ; 000C perform final cleanup
996 dw comapi_err ; 000D clean up then bootstrap
997 dw comapi_configfile ; 000E get name of config file
998 dw comapi_ipappend ; 000F get ipappend strings
999 dw comapi_dnsresolv ; 0010 resolve hostname
1000 dw comapi_err ; 0011 maximum shuffle descriptors
1001 dw comapi_err ; 0012 cleanup, shuffle and boot
1002 dw comapi_idle ; 0013 idle call
1003 dw comapi_localboot ; 0014 local boot
1004 dw comapi_features ; 0015 feature flags
1005 dw comapi_runkernel ; 0016 run kernel image
1006 dw comapi_usingvga ; 0017 report video mode change
1007 dw comapi_userfont ; 0018 query custom font
1008 dw comapi_readdisk ; 0019 read disk
1009 dw comapi_err ; 001A cleanup, shuffle and boot to pm
1010 dw comapi_err ; 001B cleanup, shuffle and boot to rm
1011 dw comapi_getadv ; 001C get pointer to ADV
1012 dw comapi_writeadv ; 001D write ADV to disk
1013 dw comapi_kbdtable ; 001E keyboard remapping table
1014 dw comapi_getcwd ; 001F get current working directory
1015 dw comapi_opendir ; 0020 open directory
1016 dw comapi_readdir ; 0021 read directory
1017 dw comapi_closedir ; 0022 close directory
1018 dw comapi_shufsize ; 0023 query shuffler size
1019 dw comapi_shufraw ; 0024 cleanup, shuffle and boot raw
1020 int22_count equ ($-int22_table)/2
1025 zero_string db 0 ; Empty, null-terminated string
1028 ; This is the feature flag array for INT 22h AX=0015h
1030 ; Note: PXELINUX clears the idle is noop flag if appropriate
1031 ; in pxe_detect_nic_type
1034 db 1 ; Have local boot, idle is not noop
1035 feature_flags_len equ ($-feature_flags)
1037 err_notdos db ': attempted DOS system call INT ',0
1038 err_comlarge db 'COMBOOT image too large.', CR, LF, 0
1042 DOSErrTramp resd 33 ; Error trampolines
1045 ConfigName resb FILENAME_MAX
1046 %ifndef HAVE_CURRENTDIRNAME
1047 global CurrentDirName
1048 CurrentDirName resb FILENAME_MAX