;
; Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
; Copyright 2009 Intel Corporation; author: H. Peter Anvin
+; Portions copyright 2009 Shao Miller [El Torito code, mBFT, safe hook]
;
; 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
org 0h
-%define SECTORSIZE_LG2 9 ; log2(sector size)
%define SECTORSIZE (1 << SECTORSIZE_LG2)
; Parameter registers definition; this is the definition
; must be first in the binary
Pointers: dw Int13Start
dw Int15Start
- dw PatchArea
+ dw MemDisk_Info ; Portions are patched by installer
dw TotalSize
dw IretPtr
IretPtr equ Int13Start.iret
Int13Start:
+ jmp strict near .SafeHookEnd ; 3-byte jump
+ db '$INT13SF' ; Signature for "safe hook"
+ db 'MEMDISK ' ; Vendor ID
+ dd 0 ; SEG:OFF of previous INT 13h hook
+ ; Must be filled in by installer
+ dd 0 ; "Safe hook" flags
+; ---- "Safe hook" structure ends here ---
+
+; This next field should be guaranteed at this position after the
+; "safe hook" structure. This allows for a MEMDISK OS driver to
+; immediately find out the particular parameters using the mBFT
+; and MDI structures. This binary will have the offset to the mBFT
+; in this field to begin with, so the installer knows where the mBFT
+; is. This is akin to the "Pointers" section above. The installer
+; will refill this field with the physical address of the mBFT for
+; future consumers, such as OS drivers.
+ dd mBFT ; Offset from hook to the mBFT
+
+.SafeHookEnd:
cmp word [cs:Recursive],0
jne recursive
mov ss,ax
mov sp,[cs:MyStack]
+%if ELTORITO
+ cmp word [cs:SavedAX],4a00h ; El Torito function?
+ jae our_drive ; We grab it
+%endif
; See if DL points to our class of device (FD, HD)
push dx
push dx
cmp byte [cs:SavedAX+1],08h ; Get drive params function?
je .norestoredl ; DL = number of drives
cmp byte [cs:SavedAX+1],15h ; Get disk type function?
- je .norestoredl ; CX:DX = size of device
+ jne .restoredl
+ test byte [bp+4],80h ; Hard disk?
+ jnz .norestoredl ; CX:DX = size of device
.restoredl:
mov dl,[bp+4]
.norestoredl:
; Note: AX == P_AX here
cmp ah,Int13FuncsCnt-1
ja Invalid_jump
+%if ELTORITO
+ mov al,[CD_PKT.type] ; Check if we are in
+ cmp al,0 ; El Torito no emulation mode
+ ja .emulation ; No. We support the function
+ cmp ah,3fh ; Yes. We must not support functions
+ jbe Invalid_jump ; 0 through 3Fh. Check and decide
+.emulation:
+%endif
xor al,al ; AL = 0 is standard entry condition
mov di,ax
shr di,7 ; Convert AH to an offset in DI
jne Invalid
mov P_BX,0AA55h ; EDD signature
mov P_AX,03000h ; EDD 3.0
- mov P_CX,0003h ; Bit 0 - Fixed disk access subset
+ mov P_CX,0007h ; Bit 0 - Fixed disk access subset
; Bit 1 - Locking and ejecting subset
+ ; Bit 2 - EDD subset
pop ax ; Drop return address
xor ax,ax ; Success
jmp DoneWeird ; Success, but AH != 0, sigh...
EDDEject:
mov ax,0B200h ; Volume Not Removable
ret
-
+%if ELTORITO
+ElToritoTerminate:
+ TRACER 'T'
+ mov ax,[cs:SavedAX]
+ cmp al,1 ; We only support query, not terminate
+ jne ElToritoErr ; Fail
+ cmp dl,7fh ; Terminate all?
+ je .doit
+ cmp dl,[cs:DriveNo] ; Terminate our drive?
+ je .doit
+ jmp ElToritoErr ; Fail
+.doit: mov es,P_DS ; Caller's DS:SI pointed to packet
+ mov di,P_SI ; We'll use ES:DI
+ mov si,CD_PKT.size ; First byte is packet size
+ xor cx,0 ; Empty our count
+ ;mov cl,[ds:si] ; We'll copy that many bytes
+ mov cl,13h
+ rep movsb ; Copy until CX is zero
+ mov ax,0 ; Success
+ ret
+ElToritoEmulate:
+ElToritoBoot:
+ElToritoCatalog:
+ElToritoErr:
+ TRACER '!'
+ mov ax,100h ; Invalid parameter
+ ret
+%endif ; ELTORITO
%endif ; EDD
-
;
; INT 15h intercept routines
;
ret
%endif
- section .data
+ section .data align=16
alignb 2
Int13Funcs dw Reset ; 00h - RESET
dw GetStatus ; 01h - GET STATUS
dw EDDSeek ; 47h - EDD SEEK
dw EDDGetParms ; 48h - EDD GET PARAMETERS
dw EDDDetectChange ; 49h - EDD MEDIA CHANGE STATUS
-%endif
+%if ELTORITO ; EDD El Torito Functions
+ ; ELTORITO _must_ also have EDD
+ dw ElToritoEmulate ; 4Ah - Initiate Disk Emulation
+ dw ElToritoTerminate ; 4Bh - Terminate Disk Emulation
+ dw ElToritoBoot ; 4Ch - Initiate Disk Emu. and Reboot
+ dw ElToritoCatalog ; 4Dh - Return Boot Catalog
+%endif ; ELTORITO
+%endif ; EDD
Int13FuncsEnd equ $
Int13FuncsCnt equ (Int13FuncsEnd-Int13Funcs) >> 1
Mover_dst2: db 0 ; High 8 bits of source addy
Mover_dummy2: dd 0, 0, 0, 0 ; More space for the BIOS
- alignb 4, db 0
+ alignb 16, db 0
+mBFT:
+; Fields common to all ACPI tables
+ dd ' ' ; ACPI signature ("mBFT")
+ ; This is filled-in by the installer
+ ; to avoid an accidentally valid mBFT
+ dd mBFT_Len ; ACPI table length
+ db 1 ; ACPI revision
+ db 0 ; ACPI table checksum
+ db 'MEMDSK' ; ACPI OEM ID
+ db 'Syslinux' ; ACPI OEM table ID
+ dd 0 ; ACPI OEM revision
+ dd 0 ; ACPI ASL compiler vendor ID
+ dd 0 ; ACPI ASL compiler revision
+; The next field is mBFT-specific and filled-in by the installer
+ dd 0 ; "Safe hook" physical address
+
+; Note that the above ends on a DWORD boundary.
+; The MDI has always started at such a boundary.
+; Portions of the MDI are patched by the installer
MemDisk_Info equ $ ; Pointed to by installation check
MDI_Bytes dw MDI_Len ; Total bytes in MDI structure
MDI_Version db VERSION_MINOR, VERSION_MAJOR ; MEMDISK version
-PatchArea equ $ ; This gets filled in by the installer
-
DiskBuf dd 0 ; Linear address of high memory disk
DiskSize dd 0 ; Size of disk in blocks
CommandLine dw 0, 0 ; Far pointer to saved command line
; Original DPT pointer follows
MDI_Len equ $-MemDisk_Info
+mBFT_Len equ $-mBFT ; mBFT includes the MDI
; ---- MDI structure ends here ---
-DriveShiftLimit db 0ffh ; Installer will [soon] probe for
+DriveShiftLimit db 0ffh ; Installer will probe for
; a range of contiguous drives.
; Any BIOS drives above this region
; shall not be impacted by our
.res3 db 0 ; Reserved
.chksum db 0 ; DPI checksum
-%endif
+%if ELTORITO
+; El Torito CD Specification Packet - mostly filled in by installer
+CD_PKT:
+.size db 13h ; Packet size (19 bytes)
+.type db 0 ; Boot media type (flags)
+.driveno db 0E0h ; INT 13h drive number
+.controller db 0 ; Controller index
+.start dd 0 ; Starting LBA of image
+.devno dw 0 ; Device number
+.user_buf dw 0 ; User buffer segment
+.load_seg dw 0 ; Load segment
+.sect_count dw 0 ; Emulated sectors to load
+.geom1 db 0 ; Cylinders bits 0 thru 7
+.geom2 db 0 ; Sects/track 0 thru 5, cyls 8, 9
+.geom3 db 0 ; Heads
+%endif ; ELTORITO
+
+%endif ; EDD
+
+; End patch area
- ; End patch area
alignb 4, db 0
Stack dd 0 ; Saved SS:ESP on invocation
dw 0