Add an API call to invoke flat protected mode; e.g. to boot an ELF kernel.
;; -----------------------------------------------------------------------
;;
-;; 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
%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
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
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
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
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.
;; -----------------------------------------------------------------------
;;
-;; 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
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
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