From 66950a7c945cbb4c378c6185490a0d7d773e20d1 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 11 Mar 2007 16:26:35 -0700 Subject: [PATCH] New API call: cleanup, shuffle and boot to flat protected mode Add an API call to invoke flat protected mode; e.g. to boot an ELF kernel. --- bcopy32.inc | 26 ++++++++++++++++++++++++-- comboot.doc | 28 +++++++++++++++++++++++++++- comboot.inc | 43 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 93 insertions(+), 4 deletions(-) diff --git a/bcopy32.inc b/bcopy32.inc index d98785c..11bdae0 100644 --- a/bcopy32.inc +++ b/bcopy32.inc @@ -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 diff --git a/comboot.doc b/comboot.doc index ced893c..1d4a164 100644 --- a/comboot.doc +++ b/comboot.doc @@ -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. diff --git a/comboot.inc b/comboot.inc index 5ea648f..9645269 100644 --- a/comboot.inc +++ b/comboot.inc @@ -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 -- 2.7.4