+++ /dev/null
-;; $Id: comboot.inc,v 1.39 2005/01/20 18:43:22 hpa Exp $
-;; -----------------------------------------------------------------------
-;;
-;; Copyright 1994-2005 H. Peter Anvin - All Rights Reserved
-;;
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
-;; Boston MA 02111-1307, USA; either version 2 of the License, or
-;; (at your option) any later version; incorporated herein by reference.
-;;
-;; -----------------------------------------------------------------------
-
-;;
-;; comboot.inc
-;;
-;; Common code for running a COMBOOT image
-;;
-
- section .text
-
-; Parameter registers definition; this is the definition
-; of the stack frame used by INT 21h and INT 22h.
-%define P_FLAGS word [bp+44]
-%define P_FLAGSL byte [bp+44]
-%define P_FLAGSH byte [bp+45]
-%define P_CS word [bp+42]
-%define P_IP word [bp+40]
-%define P_DS word [bp+38]
-%define P_ES word [bp+36]
-%define P_FS word [bp+34]
-%define P_GS word [bp+32]
-%define P_EAX dword [bp+28]
-%define P_AX word [bp+28]
-%define P_HAX word [bp+30]
-%define P_AL byte [bp+28]
-%define P_AH byte [bp+29]
-%define P_ECX dword [bp+24]
-%define P_CX word [bp+24]
-%define P_HCX word [bp+26]
-%define P_CL byte [bp+24]
-%define P_CH byte [bp+25]
-%define P_EDX dword [bp+20]
-%define P_DX word [bp+20]
-%define P_HDX word [bp+22]
-%define P_DL byte [bp+20]
-%define P_DH byte [bp+21]
-%define P_EBX dword [bp+16]
-%define P_BX word [bp+16]
-%define P_HBX word [bp+18]
-%define P_BL byte [bp+16]
-%define P_BH byte [bp+17]
-%define P_EBP dword [bp+8]
-%define P_BP word [bp+8]
-%define P_HBP word [bp+10]
-%define P_ESI dword [bp+4]
-%define P_SI word [bp+4]
-%define P_HSI word [bp+6]
-%define P_EDI dword [bp]
-%define P_DI word [bp]
-%define P_HDI word [bp+2]
-
-; Looks like a COMBOOT image but too large
-comboot_too_large:
- mov si,err_comlarge
- call cwritestr
- jmp enter_command
-
-;
-; Load a COMBOOT image. A COMBOOT image is basically a DOS .COM file,
-; except that it may, of course, not contain any DOS system calls. We
-; do, however, allow the execution of INT 20h to return to SYSLINUX.
-;
-is_comboot_image:
- and dx,dx
- jnz comboot_too_large
- cmp ax,0ff00h ; Max size in bytes
- jae comboot_too_large
-
- push si ; Save file handle
-
- call make_plain_cmdline
-
- call comboot_setup_api
-
- mov cx,comboot_seg
- mov es,cx
-
- xor di,di
- mov cx,64 ; 256 bytes (size of PSP)
- xor eax,eax ; Clear PSP
- rep stosd
-
- mov word [es:0], 020CDh ; INT 20h instruction
- ; First non-free paragraph
- ; This is valid because comboot_seg == real_mode_seg
- ; == the highest segment used by all derivatives
- int 12h ; Get DOS memory size
- shl ax,6 ; Kilobytes -> paragraphs
- mov word [es:02h],ax
-
-%ifndef DEPEND
-%if real_mode_seg != comboot_seg
-%error "This code assumes real_mode_seg == comboot_seg"
-%endif
-%endif
- ; Copy the command line from high memory
- mov si,cmd_line_here
- mov cx,125 ; Max cmdline len (minus space and CR)
- mov di,081h ; Offset in PSP for command line
- mov al,' ' ; DOS command lines begin with a space
- stosb
-
-.loop: es lodsb
- and al,al
- jz .done
- stosb
- loop .loop
-.done:
-
- mov al,0Dh ; CR after last character
- stosb
- mov ax,di
- sub al,82h ; Include space but not CR
- mov [es:80h],al ; Store command line length
-
- ; Now actually load the file...
- pop si ; File handle
- mov bx,100h ; Load at <seg>:0100h
- mov cx,0FF00h >> SECTOR_SHIFT
- ; Absolute maximum # of sectors
- call getfssec
-
- ; And invoke the program...
- mov [SavedSSSP],sp
- mov [SavedSSSP+2],ss ; Save away SS:SP
-
- mov ax,es
- mov ds,ax
- mov ss,ax
- xor sp,sp
- push word 0 ; Return to address 0 -> exit
-
- jmp comboot_seg:100h ; Run it
-
-; Proper return vector
-comboot_return: cli ; Don't trust anyone
- xor ax,ax
- jmp comboot_exit
-
-;
-; Set up the COMBOOT API interrupt vectors. This is also used
-; by the COM32 code.
-;
-comboot_setup_api:
- mov di,4*0x20 ; DOS interrupt vectors
- mov eax,comboot_return ; INT 20h = exit
- stosd
- mov ax,comboot_int21 ; INT 21h = DOS-compatible syscalls
- stosd
- mov ax,comboot_int22 ; INT 22h = proprietary syscalls
- stosd
- mov ax,comboot_bogus
- mov cx,29 ; All remaining DOS vectors
- rep stosd
- ret
-
-; INT 21h: generic DOS system call
-comboot_int21: cli
- push ds
- push es
- push fs
- push gs
- pushad
- cld
- mov bp,cs
- mov ds,bp
- mov es,bp
- mov bp,sp ; Set up stack frame
-
- call adjust_screen ; The COMBOOT program might have changed the screen
-
- mov cx,int21_count
- mov si,int21_table
-.again: lodsb
- cmp al,P_AH
- lodsw
- loopne .again
- ; The last function in the list is the
- ; "no such function" function
- clc
- call ax ; Call the invoked function
-comboot_resume:
- setc P_FLAGSL ; Propagate CF->error
- popad
- pop gs
- pop fs
- pop es
- pop ds
- iret
-
-; Attempted to execute non-21h DOS system call
-comboot_bogus: cli ; Don't trust anyone
- mov ax,err_notdos
-;
-; Generic COMBOOT return to command line code
-; AX -> message (if any)
-; BX -> where to go next
-;
-comboot_exit:
- mov bx,enter_command ; Normal return to command prompt
-comboot_exit_special:
- xor dx,dx
- mov ds,dx
- mov es,dx
- lss sp,[SavedSSSP]
- sti
- cld
- call adjust_screen ; The COMBOOT program might have changed the screen
- and ax,ax
- je .nomsg
- mov si,KernelCName
- call cwritestr
- xchg si,ax
- call cwritestr
-.nomsg: jmp bx
-
-;
-; INT 21h system calls
-;
-comboot_getkey: ; 01 = get key with echo
- call vgashowcursor
- call comboot_getchar
- call vgahidecursor
- call writechr
- clc
- ret
-
-comboot_writechr: ; 02 = writechr
- mov al,P_DL
- call writechr
- clc
- ret
-
-comboot_writeserial: ; 04 = write serial port
- mov al,P_DL
- call write_serial
- clc
- ret
-
-comboot_getkeynoecho: ; 08 = get key w/o echo
- call comboot_getchar
- clc
- ret
-
-comboot_writestr: ; 09 = write DOS string
- mov es,P_DS
- mov si,P_DX
-.loop: es lodsb
- cmp al,'$' ; End string with $ - bizarre
- je .done
- call writechr
- jmp short .loop
-.done: clc
- ret
-
-comboot_checkkey: ; 0B = check keyboard status
- cmp byte [APIKeyFlag],00h
- jnz .waiting
- call pollchar
-.waiting: setz al
- dec al ; AL = 0FFh if present, 0 if not
- mov P_AL,al
- clc
- ret
-
-comboot_checkver: ; 30 = check DOS version
- ; We return 0 in all DOS-compatible version registers,
- ; but the high part of eax-ebx-ecx-edx spell "SYSLINUX"
- mov P_EAX,'SY' << 16
- mov P_EBX,'SL' << 16
- mov P_ECX,'IN' << 16
- mov P_EDX,'UX' << 16
- ret
-
-comboot_getchar:
- cmp byte [APIKeyFlag],00h
- jne .queued
- call getchar ; If not queued get input
- and al,al ; Function key? (CF <- 0)
- jnz .done
- mov [APIKeyWait],ah ; High part of key
- inc byte [APIKeyFlag] ; Set flag
-.done: mov P_AL,al
- ret
-.queued: mov al,[APIKeyWait]
- dec byte [APIKeyFlag]
- jmp .done
-
-;
-; INT 22h - SYSLINUX-specific system calls
-; System call number in ax
-;
-comboot_int22:
- cli
- push ds
- push es
- push fs
- push gs
- pushad
- cld
- mov bp,cs
- mov ds,bp
- mov es,bp
- mov bp,sp ; Set up stack frame
-
- call adjust_screen ; The COMBOOT program might have changed the screen
-
- cmp ax,int22_count
- jb .ok
- xor ax,ax ; Function 0 -> unimplemented
-.ok:
- xchg ax,bx
- add bx,bx ; CF <- 0
- call [bx+int22_table]
- jmp comboot_resume ; On return
-
-;
-; INT 22h AX=0000h Unimplemented call
-;
-comapi_err:
- stc
- ret
-
-;
-; INT 22h AX=0001h Get SYSLINUX version
-;
-comapi_get_version:
- ; Number of API functions supported
- mov P_AX,int22_count
- ; SYSLINUX version
- mov P_CX,(VER_MAJOR << 8)+VER_MINOR
- ; SYSLINUX derivative ID byte
- mov P_DX,my_id
- ; For future use
- mov P_BX,cs ; cs == 0
-
- mov P_ES,ds
- ; ES:SI -> version banner
- mov P_SI,syslinux_banner
- ; ES:DI -> copyright string
- mov P_DI,copyright_str
-
-comapi_nop:
- clc
- ret
-
-;
-; INT 22h AX=0002h Write string
-;
-; Write null-terminated string in ES:BX
-;
-comapi_writestr:
- mov ds,P_ES
- mov si,P_BX
- call writestr
- clc
- ret
-
-;
-; INT 22h AX=0003h Run command
-;
-; Terminates the COMBOOT program and executes the command line in
-; ES:BX as if it had been entered by the user.
-;
-comapi_run:
- mov ds,P_ES
- mov si,P_BX
- mov di,command_line
- call strcpy
- xor ax,ax
- mov bx,load_kernel ; Run a new kernel
- jmp comboot_exit_special ; Terminate task, clean up
-
-;
-; INT 22h AX=0004h Run default command
-;
-; Terminates the COMBOOT program and executes the default command line
-; as if a timeout had happened or the user pressed <Enter>.
-;
-comapi_run_default:
- mov bx,auto_boot
- jmp comboot_exit_special
-
-;
-; INT 22h AX=0005h Force text mode
-;
-; Puts the video in standard text mode
-;
-comapi_textmode:
- call vgaclearmode
- clc
- ret
-
-;
-; INT 22h AX=0006h Open file
-;
-comapi_open:
- push ds
- mov ds,P_ES
- mov si,P_SI
- mov di,InitRD
- push di
- call mangle_name
- pop di
- pop ds
- call searchdir
- jz .err
- mov P_AX,ax
- mov P_HAX,dx
- mov P_CX,SECTOR_SIZE
- mov P_SI,si
- clc
- ret
-.err:
- stc
- ret
-
-
-;
-; INT 22h AX=0007h Read file
-;
-comapi_read:
- mov es,P_ES
- mov bx,P_BX
- mov si,P_SI
- mov cx,P_CX
- call getfssec
- jnc .noteof
- xor si,si ; SI <- 0 on EOF, CF <- 0
-.noteof: mov P_SI,si
- ret
-
-;
-; INT 22h AX=0008h Close file
-;
-comapi_close:
- ; Do nothing for now. Eventually implement
- ; an internal API for this.
- clc
- ret
-
-;
-; INT 22h AX=0009h Call PXE stack
-;
-%if IS_PXELINUX
-comapi_pxecall:
- mov bx,P_BX
- mov es,P_ES
- mov di,P_DI
- call pxenv
- mov P_AX,ax
- clc
- ret
-%else
-comapi_pxecall equ comapi_err ; Not available
-%endif
-
-;
-; INT 22h AX=000Ah Get Derivative-Specific Info
-;
-comapi_derinfo:
- mov P_AL,my_id
-%if IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
- mov al,[DriveNumber]
- mov P_DL,al
- mov P_ES,cs
- mov P_BX,PartInfo
-%elif IS_PXELINUX
- mov ax,[APIVer]
- mov P_DX,ax
- mov ax,[StrucPtr]
- mov P_BX,ax
- mov ax,[StrucPtr+2]
- mov P_ES,ax
- mov ax,[InitStack]
- mov P_SI,ax
- mov ax,[InitStack+2]
- mov P_FS,ax
-%elif IS_ISOLINUX
- mov al,[DriveNo]
- mov P_DL,al
- mov P_ES,cs
- mov P_BX,spec_packet
-%endif
- clc
- ret
-
-;
-; INT 22h AX=000Bh Get Serial Console Configuration
-;
-comapi_serialcfg:
- mov ax,[SerialPort]
- mov P_DX,ax
- mov ax,[BaudDivisor]
- mov P_CX,ax
- mov ax,[FlowControl]
- or al,ah
- mov ah,[FlowIgnore]
- shr ah,4
- test byte [DisplayCon],01h
- jnz .normalconsole
- or ah,80h
-.normalconsole:
- mov P_BX,ax
- clc
- ret
-
-;
-; INT 22h AX=000Ch Perform final cleanup
-;
-comapi_cleanup:
-%if IS_PXELINUX
- ; Unload PXE if requested
- test dl,3
- setnz [KeepPXE]
- sub bp,sp ; unload_pxe may move the stack around
- call unload_pxe
- add bp,sp ; restore frame pointer...
-%elif IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
- ; Restore original FDC table
- mov eax,[OrigFDCTabPtr]
- mov [fdctab],eax
-%endif
- ; Reset the floppy disk subsystem
- xor ax,ax
- xor dx,dx
- int 13h
- clc
- ret
-
-;
-; INT 22h AX=000Dh Clean up then replace bootstrap
-;
-comapi_chainboot:
- call comapi_cleanup
- mov eax,P_EDI
- mov [trackbuf+4],eax ; Copy from
- mov eax,P_ECX
- mov [trackbuf+8],eax ; Total bytes
- mov eax,7C00h
- mov [trackbuf],eax ; Copy to
- mov [EntryPoint],eax ; CS:IP entry point
- mov esi,P_ESI
- mov edx,P_EBX
- mov bx,P_DS
- jmp replace_bootstrap_one
-
-
-;
-; INT 22h AX=000Eh Get configuration file name
-;
-comapi_configfile:
- mov P_ES,cs
- mov P_BX,ConfigName
- clc
- ret
-
-;
-; INT 22h AX=000Fh Get IPAPPEND strings
-;
-%if IS_PXELINUX
-comapi_ipappend:
- mov P_ES,cs
- mov P_CX,numIPAppends
- mov P_BX,IPAppends
- clc
- ret
-
- section .data
- alignb 2, db 0
-IPAppends dw IPOption
- dw BOOTIFStr
-numIPAppends equ ($-IPAppends)/2
-
-%else
-comapi_ipappend equ comapi_err
-%endif
-
-;
-; INT 22h AX=0010h Resolve hostname
-;
-%if IS_PXELINUX
-comapi_dnsresolv:
- mov ds,P_ES
- mov si,P_BX
- call dns_resolv
- mov P_EAX,eax
- ret
-%else
-comapi_dnsresolv equ comapi_err
-%endif
-
- section .data
-%macro int21 2
- db %1
- dw %2
-%endmacro
-
-
-;
-; INT 22h AX=0011h Maximum number of shuffle descriptors
-;
-comapi_maxshuffle:
- mov P_CX,(2*trackbufsize)/12
- ret
-
-;
-; INT 22h AX=0012h Cleanup, shuffle and boot
-;
-comapi_shuffle:
- call comapi_cleanup
- mov cx,P_CX
- cmp cx,(2*trackbufsize)/12
- ja .error
-
- push cx ; On stack: descriptor count
-
- lea cx,[ecx+ecx*2] ; CX *= 3
-
- mov fs,P_ES
- mov si,P_DI
- mov di,trackbuf
- push di ; On stack: descriptor list address
- fs rep movsd ; Copy the list
-
- mov eax,P_EBP
- mov [EntryPoint],eax ; CS:IP entry point
- mov esi,P_ESI
- mov edx,P_EBX
- mov bx,P_DS
- jmp replace_bootstrap
-.error:
- stc
- ret
-
-;
-; INT 22h AX=0013h Idle call
-;
-comapi_idle:
- DO_IDLE
- clc
- ret
-
-int21_table:
- int21 00h, comboot_return
- int21 01h, comboot_getkey
- int21 02h, comboot_writechr
- int21 04h, comboot_writeserial
- int21 08h, comboot_getkeynoecho
- int21 09h, comboot_writestr
- int21 0Bh, comboot_checkkey
- int21 30h, comboot_checkver
- int21 4Ch, comboot_return
- int21 -1, comboot_bogus
-int21_count equ ($-int21_table)/3
-
- align 2, db 0
-int22_table:
- dw comapi_err ; 0000 unimplemented syscall
- dw comapi_get_version ; 0001 get SYSLINUX version
- dw comapi_writestr ; 0002 write string
- dw comapi_run ; 0003 run specified command
- dw comapi_run_default ; 0004 run default command
- dw comapi_textmode ; 0005 force text mode
- dw comapi_open ; 0006 open file
- dw comapi_read ; 0007 read file
- dw comapi_close ; 0008 close file
- dw comapi_pxecall ; 0009 call PXE stack
- dw comapi_derinfo ; 000A derivative-specific info
- dw comapi_serialcfg ; 000B get serial port config
- dw comapi_cleanup ; 000C perform final cleanup
- dw comapi_chainboot ; 000D clean up then bootstrap
- dw comapi_configfile ; 000E get name of config file
- dw comapi_ipappend ; 000F get ipappend strings
- dw comapi_dnsresolv ; 0010 resolve hostname
- dw comapi_maxshuffle ; 0011 maximum shuffle descriptors
- dw comapi_shuffle ; 0012 cleanup, shuffle and boot
- dw comapi_idle ; 0013 idle call
-int22_count equ ($-int22_table)/2
-
-APIKeyWait db 0
-APIKeyFlag db 0