New API call: cleanup, shuffle and boot to flat protected mode
authorH. Peter Anvin <hpa@zytor.com>
Sun, 11 Mar 2007 23:26:35 +0000 (16:26 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Sun, 11 Mar 2007 23:26:35 +0000 (16:26 -0700)
Add an API call to invoke flat protected mode; e.g. to boot an ELF kernel.

bcopy32.inc
comboot.doc
comboot.inc

index d98785c..11bdae0 100644 (file)
@@ -1,6 +1,6 @@
 ;; -----------------------------------------------------------------------
 ;;
-;;   Copyright 1994-2005 H. Peter Anvin - All Rights Reserved
+;;   Copyright 1994-2007 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
@@ -394,7 +394,7 @@ try_wbinvd:
 %endif
 
 ;
-; bcopy_over_self:
+; shuffle_and_boot:
 ;
 ; This routine is used to shuffle memory around, followed by
 ; invoking an entry point somewhere in low memory.  This routine
@@ -438,6 +438,27 @@ shuffle_and_boot:
                popfd
                jmp far [cs:EntryPoint]
 
+;
+; trampoline_to_pm:
+;
+; This routine is chained to from shuffle_and_boot to invoke a
+; flat 32-bit protected mode operating system.
+;
+trampoline_to_pm:
+               cli
+               call enable_a20
+               o32 lgdt [cs:bcopy_gdt]
+               mov eax,cr0
+               or al,1
+               mov cr0,eax             ; Enter protected mode
+               mov ax,28h              ; 32-bit data segment selector
+               mov es,ax
+               mov ds,ax
+               mov ss,ax
+               mov fs,ax
+               mov gs,ax
+               jmp 020h:PMTrampolineBuf ; 20h = 32-bit code segment
+
                align 2
 A20List                dw a20_dunno, a20_none, a20_bios, a20_kbc, a20_fast
 A20DList       dw a20d_dunno, a20d_none, a20d_bios, a20d_kbc, a20d_fast
@@ -454,3 +475,4 @@ __bcopy_size        equ $-__bcopy_start
 EntryPoint     resd 1                  ; CS:IP for shuffle_and_boot
 A20Test                resw 1                  ; Counter for testing status of A20
 A20Tries       resb 1                  ; Times until giving up on A20
+PMTrampolineBuf        resb 9*9                ; Code snippet for invoking PM entry
index ced893c..1d4a164 100644 (file)
@@ -550,7 +550,7 @@ AX=0011h [3.05] Maximum number of shuffle descriptors
 
 AX=0012h [3.05] Cleanup, shuffle and boot
        Input:  AX      0012h
-               DX      derivative-specific flags (see previous function)
+               DX      derivative-specific flags (see function 000Ch)
                ES:DI   shuffle descriptor list (must be in low memory)
                CX      number of shuffle descriptors
                EBX(!)  initial value of EDX after bootstrap
@@ -755,3 +755,29 @@ AX=0019h [3.40] Read disk [SYSLINUX, ISOLINUX, EXTLINUX]
 
        This routine reports "boot failed" (and does not return) on
        disk error.
+
+
+AX=001Ah [3.40] Cleanup, shuffle and boot to flat protected mode
+       Input:  AX      001Ah
+               DX      derivative-specific flags (see function 000Ch)
+               ES:DI   shuffle descriptor list (must be in low memory)
+               CX      number of shuffle descriptors
+               DS:SI   pointer to register values (must be in low memory)
+       Output: Does not return
+               (if CX is too large the routine returns with CF=1)
+
+       This routine performs final cleanup, then performs a sequence
+       of copies, and jumps to a specified protected mode entry point.
+       This is otherwise similar to function 0012h; see that function
+       for the meaning of ES:DI and CX.
+
+       DS:SI points to the initial register file, which is a structure
+       of 9 dwords in the following order:
+
+       EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, EIP
+
+       Protected mode is entered with all data segments set up as a
+       flat 32-bit read/write segment and the code segment a flat 32-bit
+       read/execute segment.  Interrupts are off, and GDT, LDT and
+       IDT are undefined; it is up to the invoked code to set new
+       descriptor tables to its liking.
index 5ea648f..9645269 100644 (file)
@@ -1,6 +1,6 @@
 ;; -----------------------------------------------------------------------
 ;;
-;;   Copyright 1994-2006 H. Peter Anvin - All Rights Reserved
+;;   Copyright 1994-2007 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
@@ -795,6 +795,46 @@ comapi_readdisk:
 comapi_readdisk        equ comapi_err
 %endif
 
+;
+; INT 22h AX=001Ah     Cleanup, shuffle and boot to flat protected mode
+;
+comapi_shufflepm:
+               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 fs,P_DS
+               mov si,P_SI
+               xor edi,edi
+               mov di,PMTrampolineBuf
+               mov al,0B8h                     ; MOV EAX opcode
+               mov cx,9
+.maketramp:
+               stosb                           ; MOV opcode
+               inc ax                          ; Next register opcode
+               movsd                           ; immediate value
+               loop .maketramp
+               mov byte [di-9],0E9h            ; Last opcode is JMP
+               sub dword [di-8],edi            ; Make JMP target relative
+
+               mov dword [EntryPoint],trampoline_to_pm
+               xor bx,bx                       ; DS on entry
+               jmp replace_bootstrap
+.error:
+               stc
+               ret
+
                section .data
 
 %macro                 int21 2
@@ -843,6 +883,7 @@ int22_table:
                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
 int22_count    equ ($-int22_table)/2
 
 APIKeyWait     db 0