Move mboot documentation to the doc/ directory
[profile/ivi/syslinux.git] / comboot.inc
index 3318a31..3a9b433 100644 (file)
@@ -1,22 +1,23 @@
-;; $Id$
 ;; -----------------------------------------------------------------------
-;;   
-;;   Copyright 1994-2004 H. Peter Anvin - All Rights Reserved
+;;
+;;   Copyright 1994-2008 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,
-;;   Bostom MA 02111-1307, USA; either version 2 of the License, or
+;;   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]
@@ -125,13 +126,11 @@ is_comboot_image:
                ; Now actually load the file...
                pop si                  ; File handle
                mov bx,100h             ; Load at <seg>:0100h
-               mov cx,[ClustPerMoby]   ; Absolute maximum # of clusters
+               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
@@ -142,7 +141,7 @@ is_comboot_image:
 
 ; Proper return vector
 comboot_return:        cli                     ; Don't trust anyone
-               xor ax,ax
+               push enter_command      ; Normal return to command prompt
                jmp comboot_exit
 
 ;
@@ -185,9 +184,10 @@ comboot_int21:     cli
                loopne .again
                ; The last function in the list is the
                ; "no such function" function
-
+               clc
                call ax                 ; Call the invoked function
 comboot_resume:
+               mov bp,sp               ; In case the function clobbers BP
                setc P_FLAGSL           ; Propagate CF->error
                popad
                pop gs
@@ -198,29 +198,28 @@ comboot_resume:
 
 ; Attempted to execute non-21h DOS system call
 comboot_bogus: cli                     ; Don't trust anyone
-               mov ax,err_notdos
+               mov cx,err_notdos
+               push enter_command
+               jmp comboot_exit_msg
+
 ;
 ; Generic COMBOOT return to command line code
-;  AX -> message (if any)
-;  BX -> where to go next
+;  stack -> where to go next
+;     CX -> message (for _msg version)
 ;
 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
+               xor cx,cx
+comboot_exit_msg:
+               pop bx                  ; Return address
+               RESET_STACK_AND_SEGS AX
                call adjust_screen      ; The COMBOOT program might have changed the screen
-               and ax,ax
-               je .nomsg
+               jcxz .nomsg
                mov si,KernelCName
                call cwritestr
-               xchg si,ax
+               mov si,cx
                call cwritestr
-.nomsg:                jmp bx
+.nomsg:
+               jmp bx
 
 ;
 ; INT 21h system calls
@@ -278,14 +277,13 @@ comboot_checkver:                 ; 30 = check DOS version
                mov P_EBX,'SL' << 16
                mov P_ECX,'IN' << 16
                mov P_EDX,'UX' << 16
-               clc
                ret
 
 comboot_getchar:
                cmp byte [APIKeyFlag],00h
                jne .queued
                call getchar            ; If not queued get input
-               and al,al               ; Function key?
+               and al,al               ; Function key?  (CF <- 0)
                jnz .done
                mov [APIKeyWait],ah     ; High part of key
                inc byte [APIKeyFlag]   ; Set flag
@@ -319,7 +317,7 @@ comboot_int22:
                xor ax,ax                       ; Function 0 -> unimplemented
 .ok:
                xchg ax,bx
-               add bx,bx
+               add bx,bx                       ; CF <- 0
                call [bx+int22_table]
                jmp comboot_resume              ; On return
 
@@ -375,24 +373,19 @@ comapi_run:
                mov ds,P_ES
                mov si,P_BX
                mov di,command_line
-.copyloop:
-               lodsb
-               stosb
-               and al,al
-               jnz .copyloop
-               xor ax,ax
-               mov bx,load_kernel              ; Run a new kernel
-               jmp comboot_exit_special        ; Terminate task, clean up
+               call strcpy
+               push load_kernel                ; Run a new kernel
+               jmp comboot_exit                ; Terminate task, clean up
 
 ;
-; INT 22h AX=0004h     Run default command             
+; 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
+               push auto_boot
+               jmp comboot_exit
 
 ;
 ; INT 22h AX=0005h     Force text mode
@@ -412,23 +405,16 @@ comapi_open:
                mov ds,P_ES
                mov si,P_SI
                mov di,InitRD
-               push di
                call mangle_name
-               pop di
                pop ds
                call searchdir
-               jz .err
+               jz comapi_err
                mov P_AX,ax
                mov P_HAX,dx
-               mov ax,[ClustSize]
-               mov P_CX,ax
+               mov P_CX,SECTOR_SIZE
                mov P_SI,si
                clc
                ret
-.err:
-               stc
-               ret
-
 
 ;
 ; INT 22h AX=0007h     Read file
@@ -448,8 +434,8 @@ comapi_read:
 ; INT 22h AX=0008h     Close file
 ;
 comapi_close:
-               ; Do nothing for now.  Eventually implement
-               ; an internal API for this.
+               mov si,P_SI
+               call close_file
                clc
                ret
 
@@ -474,12 +460,7 @@ comapi_pxecall     equ comapi_err                  ; Not available
 ;
 comapi_derinfo:
                mov P_AL,my_id
-%if IS_SYSLINUX || IS_MDSLINUX
-               mov al,[bsDriveNumber]
-               mov P_DL,al
-               mov P_ES,cs
-               mov P_BX,PartInfo
-%elif IS_PXELINUX
+%if IS_PXELINUX
                mov ax,[APIVer]
                mov P_DX,ax
                mov ax,[StrucPtr]
@@ -490,12 +471,22 @@ comapi_derinfo:
                mov P_SI,ax
                mov ax,[InitStack+2]
                mov P_FS,ax
-%elif IS_ISOLINUX
-               mov al,[DriveNo]
+%else
+               ; Physical medium...
+
+               mov P_CL,SECTOR_SHIFT
+               mov al,[DriveNumber]
                mov P_DL,al
+               mov P_FS,cs
+               mov P_SI,OrigESDI
+%if IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
+               mov P_ES,cs
+               mov P_BX,PartInfo
+%elif IS_ISOLINUX
                mov P_ES,cs
                mov P_BX,spec_packet
 %endif
+%endif
                clc
                ret
 
@@ -511,6 +502,10 @@ comapi_serialcfg:
                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
@@ -526,7 +521,7 @@ comapi_cleanup:
                sub bp,sp               ; unload_pxe may move the stack around
                call unload_pxe
                add bp,sp               ; restore frame pointer...
-%elif IS_SYSLINUX || IS_MDSLINUX
+%elif IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX
                ; Restore original FDC table
                mov eax,[OrigFDCTabPtr]
                mov [fdctab],eax
@@ -538,23 +533,389 @@ comapi_cleanup:
                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
+
+               section .text
+
+;
+; 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
+               clc
+               ret
+%else
+comapi_dnsresolv equ comapi_err
+%endif
+
+               section .text
+
+;
+; INT 22h AX=0011h     Maximum number of shuffle descriptors
+;
+comapi_maxshuffle:
+               mov P_CX,trackbufsize/12
+               ret
+
+;
+; INT 22h AX=0012h     Cleanup, shuffle and boot
+;
+comapi_shuffle:
+               cmp P_CX,(2*trackbufsize)/12
+               ja .error
+
+               call comapi_cleanup
+
+               mov cx, P_CX
+               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
-               push P_EDI
-               push P_ECX
                jmp replace_bootstrap
+.error:
+               stc
+               ret
+
+;
+; INT 22h AX=0013h     Idle call
+;
+;
+; *** FIX THIS ***
+; The idle call seems to have detrimental effects on some machines when
+; called from a COM32 context (WHY?) --  disable it for now.
+;
+%if 0 ; def HAVE_IDLE
+
+comapi_idle:
+               DO_IDLE
+               clc
+               ret
+
+%else
 
+comapi_idle    equ comapi_err
+
+%endif
+
+;
+; INT 22h AX=0014h     Local boot
 ;
-; This stuff should really be in the data section...
+%if IS_PXELINUX || IS_ISOLINUX
+comapi_localboot:
+               mov ax,P_DX
+               jmp local_boot
+%else
+comapi_localboot equ comapi_err
+%endif
+
+;
+; INT 22h AX=0015h     Feature flags
+;
+comapi_features:
+               mov P_ES,cs
+               mov P_BX,feature_flags
+               mov P_CX,feature_flags_len
+               clc
+               ret
+
 ;
-%macro                 int21 2
+; INT 22h AX=0016h     Run kernel image
+;
+comapi_runkernel:
+               mov al,P_DL
+               cmp al,VK_TYPES-1
+               ja .error
+               mov [KernelType],al
+               push ds
+               mov ds,P_DS
+               mov si,P_SI
+               mov di,KernelName
+               call mangle_name
+               pop ds
+               call searchdir
+               jz comapi_err
+
+               ; The kernel image was found, so we can load it...
+               mov [Kernel_SI],si
+               mov [Kernel_EAX],ax
+               mov [Kernel_EAX+2],dx
+
+               ; It's not just possible, but quite likely, that ES:BX
+               ; points into real_mode_seg, so we need to exercise some
+               ; special care here... use xfer_buf_seg as an intermediary
+               push ds
+               push es
+               mov ax,xfer_buf_seg
+               mov ds,P_ES
+               mov si,P_BX
+               mov es,ax
+               xor di,di
+               call strcpy
+               pop es
+               pop ds
+
+%if IS_PXELINUX
+               mov al,P_CL
+               mov [IPAppend],al
+%endif
+
+               call comboot_exit
+
+.finish:
+               ; Copy the command line into its proper place
+               push ds
+               push es
+               mov ax,xfer_buf_seg
+               mov dx,real_mode_seg
+               mov ds,ax
+               mov es,dx
+               xor si,si
+               mov di,cmd_line_here
+               call strcpy
+               mov byte [es:di-1],' '          ; Simulate APPEND
+               pop es
+               pop ds
+               mov [CmdLinePtr],di
+               mov word [CmdOptPtr],zero_string
+               jmp kernel_good_saved
+
+.error         equ comapi_shuffle.error
+
+;
+; INT 22h AX=0017h  Report video mode change
+;
+comapi_usingvga:
+               mov ax,P_BX
+               cmp ax,0Fh              ; Unknown flags = failure
+               ja .error
+               mov [UsingVGA],al
+               mov cx,P_CX
+               mov dx,P_DX
+               mov [GXPixCols],cx
+               mov [GXPixRows],dx
+               test al,08h
+               jnz .notext
+               call adjust_screen
+.notext:
+               clc
+               ret
+.error:
+               stc
+               ret
+
+;
+; INT 22h AX=0018h  Query custom font
+;
+comapi_userfont:
+               mov al,[UserFont]
+               and al,al
+               jz .done
+               mov al,[VGAFontSize]
+               mov P_ES,ds
+               mov P_BX,vgafontbuf
+
+.done:         ; CF=0 here
+               mov P_AL,al
+               ret
+
+;
+; INT 22h AX=0019h  Read disk
+;
+%if IS_SYSLINUX || IS_MDSLINUX || IS_ISOLINUX || IS_EXTLINUX
+comapi_readdisk:
+               mov esi,P_ESI           ; Enforce ESI == EDI == 0, these
+               or esi,P_EDI            ; are reserved for future expansion
+               jnz .err
+               mov eax,P_EDX
+               mov es,P_ES
+               mov bx,P_BX
+               mov bp,P_CX             ; WE CANNOT use P_* after touching bp!
+               call getlinsec
+               clc
+               ret
+.err:
+               stc
+               ret
+%else
+comapi_readdisk        equ comapi_err
+%endif
+
+;
+; INT 22h AX=001Ah     Cleanup, shuffle and boot to flat protected mode
+;
+comapi_shufflepm:
+               cmp P_CX,(2*trackbufsize)/12
+               ja .error
+
+               call comapi_cleanup
+
+               mov cx, P_CX
+               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 fs,P_DS
+               mov si,P_SI
+               mov edi,TrampolineBuf
+               mov al,0B8h                     ; MOV EAX opcode
+               mov cl,9
+.maketramp:
+               stosb                           ; MOV opcode
+               inc ax                          ; Next register opcode
+               fs movsd                        ; immediate value
+               loop .maketramp
+               mov byte [di-5],0E9h            ; Last opcode is JMP
+               sub [di-4],edi                  ; Make JMP target relative
+
+               mov dword [EntryPoint],trampoline_to_pm
+               xor bx,bx                       ; DS on entry
+               jmp replace_bootstrap
+.error:
+               stc
+               ret
+
+;
+; INT 22h AX=001Bh     Cleanup, shuffle and boot with register setting
+;
+comapi_shufflerm:
+               cmp P_CX,(2*trackbufsize)/12
+               ja .error
+
+               call comapi_cleanup
+
+               mov cx, P_CX
+               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 fs,P_DS
+               mov si,P_SI
+               mov di,TrampolineBuf
+
+               ; Generate segment-loading instructions
+               mov bx,0C08Eh                   ; MOV ES,AX
+               mov cl,6                        ; 6 segment registers (incl CS)
+.segtramp:
+               mov al,0B8h
+               stosb                           ; MOV AX,imm16 opcode
+               fs movsw                        ; imm16
+               mov ax,bx
+               add bh,8
+               stosw                           ; MOV xS,AX
+               loop .segtramp
+
+               ; Clobber the MOV CS,AX instruction.
+               mov word [di-22], 9090h         ; NOP NOP
+
+               ; Generate GPR-loading instructions
+               mov ax,0B866h                   ; MOV EAX,imm32
+               mov cl,8                        ; 8 GPRs
+.gprtramp:
+               stosw                           ; MOV ExX,imm32 opcode
+               fs movsd                        ; imm32
+               inc ah
+               loop .gprtramp
+
+               mov al,0EAh                     ; JMP FAR imm16:imm16 opcode
+               stosb
+               fs movsd                        ; CS:IP
+
+               mov dword [EntryPoint],TrampolineBuf
+               jmp replace_bootstrap
+.error:
+               stc
+               ret
+
+;
+; INT 22h AX=001Ch     Get pointer to auxillary data vector
+;
+comapi_getadv:
+               mov P_ES,ds
+               mov P_BX,adv0.data
+               mov P_CX,ADV_LEN
+               ret
+
+;
+; INT 22h AX=001Dh     Write auxillary data vector
+;
+comapi_writeadv        equ adv_write
+
+               section .data
+
+%macro         int21 2
                db %1
                dw %2
 %endmacro
@@ -574,21 +935,57 @@ 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_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
+               dw comapi_localboot     ; 0014 local boot
+               dw comapi_features      ; 0015 feature flags
+               dw comapi_runkernel     ; 0016 run kernel image
+               dw comapi_usingvga      ; 0017 report video mode change
+               dw comapi_userfont      ; 0018 query custom font
+               dw comapi_readdisk      ; 0019 read disk
+               dw comapi_shufflepm     ; 001A cleanup, shuffle and boot to pm
+               dw comapi_shufflerm     ; 001B cleanup, shuffle and boot to rm
+               dw comapi_getadv        ; 001C get pointer to ADV
+               dw comapi_writeadv      ; 001D write ADV to disk
 int22_count    equ ($-int22_table)/2
 
 APIKeyWait     db 0
 APIKeyFlag     db 0
+
+zero_string    db 0                    ; Empty, null-terminated string
+
+;
+; This is the feature flag array for INT 22h AX=0015h
+feature_flags:
+%if IS_PXELINUX
+               db 1                    ; Have local boot, idle not noop
+%elif IS_ISOLINUX
+               db 3                    ; Have local boot, idle is noop
+%else
+               db 2                    ; No local boot, idle is noop
+%endif
+feature_flags_len equ ($-feature_flags)
+
+err_notdos     db ': attempted DOS system call', CR, LF, 0
+err_comlarge   db 'COMBOOT image too large.', CR, LF, 0
+
+               section .bss1
+ConfigName     resb    FILENAME_MAX