Porting Duet module from EDKI to EDKII
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5076 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
30
DuetPkg/BootSector/BootSector.inf
Normal file
30
DuetPkg/BootSector/BootSector.inf
Normal file
@@ -0,0 +1,30 @@
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = BootSector
|
||||
FILE_GUID = A36495C1-C205-414e-B71F-4BE3476D699C
|
||||
MODULE_TYPE = USER_DEFINED
|
||||
VERSION_STRING = 1.0
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
DuetPkg/DuetPkg.dec
|
||||
|
||||
[Sources]
|
||||
bootsect.asm
|
||||
bs16.asm
|
||||
bs32.asm
|
||||
Gpt.asm
|
||||
Mbr.asm
|
||||
Start.asm
|
||||
Start16.asm
|
||||
Start32.asm
|
||||
Efi32.asm
|
||||
|
||||
[BuildOptions.common]
|
||||
#MSFT:*_*_IA32_DLINK_FLAGS = /out:"$(BIN_DIR)\SecMain.exe" /base:0x10000000 /pdb:"$(BIN_DIR)\SecMain.pdb" /LIBPATH:"$(VCINSTALLDIR)\Lib" /LIBPATH:"$(VCINSTALLDIR)\PlatformSdk\Lib" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib Gdi32.lib User32.lib Winmm.lib
|
||||
MSFT:*_*_IA32_CC_FLAGS = /nologo /W4 /WX /Gy /c /D UNICODE /Od /FI$(DEST_DIR_DEBUG)/AutoGen.h /EHs-c- /GF /Gs8192 /Zi /Gm /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE
|
||||
MSFT:*_*_IA32_PP_FLAGS = /nologo /E /TC /FI$(DEST_DIR_DEBUG)/AutoGen.h
|
||||
MSFT:*_*_IA32_ASM_FLAGS = /nologo /W3 /WX /c /coff /Cx /Zd /W0 /Zi
|
||||
MSFT:*_*_IA32_ASMLINK_FLAGS = /link /nologo /tiny
|
26
DuetPkg/BootSector/FILE.LST
Normal file
26
DuetPkg/BootSector/FILE.LST
Normal file
@@ -0,0 +1,26 @@
|
||||
IA32
|
||||
====
|
||||
FAT12 FAT16 FAT32
|
||||
bootsect.asm bs16.asm bs32.asm
|
||||
start.asm start16.asm start32.asm
|
||||
\ | /
|
||||
\ | /
|
||||
efi32.asm
|
||||
|
||||
X64
|
||||
===
|
||||
FAT12 FAT16 FAT32
|
||||
bootsect.asm bs16.asm bs32.asm
|
||||
start64.asm st16_64.asm st32_64.asm
|
||||
\ | /
|
||||
\ | /
|
||||
efi64.asm
|
||||
|
||||
MBR
|
||||
===
|
||||
Mbr.asm
|
||||
|
||||
|
||||
GPT
|
||||
===
|
||||
Gpt.asm
|
294
DuetPkg/BootSector/Gpt.asm
Normal file
294
DuetPkg/BootSector/Gpt.asm
Normal file
@@ -0,0 +1,294 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006 - 2007, Intel Corporation
|
||||
;* All rights reserved. This program and the accompanying materials
|
||||
;* are licensed and made available under the terms and conditions of the BSD License
|
||||
;* which accompanies this distribution. The full text of the license may be found at
|
||||
;* http://opensource.org/licenses/bsd-license.php
|
||||
;*
|
||||
;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;*
|
||||
;* gpt.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.model small
|
||||
; .dosseg
|
||||
.stack
|
||||
.486p
|
||||
.code
|
||||
|
||||
BLOCK_SIZE EQU 0200h
|
||||
BLOCK_MASK EQU 01ffh
|
||||
BLOCK_SHIFT EQU 9
|
||||
|
||||
; ****************************************************************************
|
||||
; Code loaded by BIOS at 0x0000:0x7C00
|
||||
; ****************************************************************************
|
||||
|
||||
org 0h
|
||||
Start:
|
||||
|
||||
; ****************************************************************************
|
||||
; Start Print
|
||||
; ****************************************************************************
|
||||
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov ax, 07c0h
|
||||
mov ds, ax
|
||||
lea si, cs:[StartString]
|
||||
mov cx, 10
|
||||
mov di, 160
|
||||
rep movsw
|
||||
|
||||
; ****************************************************************************
|
||||
; Print over
|
||||
; ****************************************************************************
|
||||
|
||||
; ****************************************************************************
|
||||
; Initialize segment registers and copy code at 0x0000:0x7c00 to 0x0000:0x0600
|
||||
; ****************************************************************************
|
||||
xor ax, ax ; AX = 0x0000
|
||||
mov bx, 07c00h ; BX = 0x7C00
|
||||
mov bp, 0600h ; BP = 0x0600
|
||||
mov si, OFFSET RelocatedStart ; SI = Offset(RelocatedStart)
|
||||
mov cx, 0200h ; CX = 0x0200
|
||||
sub cx, si ; CS = 0x0200 - Offset(RelocatedStart)
|
||||
lea di, [bp+si] ; DI = 0x0600 + Offset(RelocatedStart)
|
||||
lea si, [bx+si] ; BX = 0x7C00 + Offset(RelocatedStart)
|
||||
mov ss, ax ; SS = 0x0000
|
||||
mov sp, bx ; SP = 0x7C00
|
||||
mov es,ax ; ES = 0x0000
|
||||
mov ds,ax ; DS = 0x0000
|
||||
push ax ; PUSH 0x0000
|
||||
push di ; PUSH 0x0600 + Offset(RelocatedStart)
|
||||
cld ; Clear the direction flag
|
||||
rep movsb ; Copy 0x0200 bytes from 0x7C00 to 0x0600
|
||||
retf ; JMP 0x0000:0x0600 + Offset(RelocatedStart)
|
||||
|
||||
; ****************************************************************************
|
||||
; Code relocated to 0x0000:0x0600
|
||||
; ****************************************************************************
|
||||
|
||||
RelocatedStart:
|
||||
; ****************************************************************************
|
||||
; Get Driver Parameters to 0x0000:0x7BFC
|
||||
; ****************************************************************************
|
||||
xor ax,ax ; ax = 0
|
||||
mov ss,ax ; ss = 0
|
||||
add ax,1000h
|
||||
mov ds,ax
|
||||
|
||||
mov sp,07c00h ; sp = 0x7c00
|
||||
mov bp,sp ; bp = 0x7c00
|
||||
|
||||
mov ah,8 ; ah = 8 - Get Drive Parameters Function
|
||||
mov byte ptr [bp+PhysicalDrive],dl ; BBS defines that BIOS would pass the booting driver number to the loader through DL
|
||||
int 13h ; Get Drive Parameters
|
||||
xor ax,ax ; ax = 0
|
||||
mov al,dh ; al = dh
|
||||
inc al ; MaxHead = al + 1
|
||||
push ax ; 0000:7bfe = MaxHead
|
||||
mov al,cl ; al = cl
|
||||
and al,03fh ; MaxSector = al & 0x3f
|
||||
push ax ; 0000:7bfc = MaxSector
|
||||
|
||||
; ****************************************************************************
|
||||
; Read GPT Header from hard disk to 0x0000:0x0800
|
||||
; ****************************************************************************
|
||||
xor ax, ax
|
||||
mov es, ax ; Read to 0x0000:0x0800
|
||||
mov di, 0800h ; Read to 0x0000:0x0800
|
||||
mov eax, 1 ; Read LBA #1
|
||||
mov edx, 0 ; Read LBA #1
|
||||
mov bx, 1 ; Read 1 Block
|
||||
push es
|
||||
call ReadBlocks
|
||||
pop es
|
||||
|
||||
; ****************************************************************************
|
||||
; Read Target GPT Entry from hard disk to 0x0000:0x0A00
|
||||
; ****************************************************************************
|
||||
cmp dword ptr es:[di], 020494645h ; Check for "EFI "
|
||||
jne BadGpt
|
||||
cmp dword ptr es:[di + 4], 054524150h ; Check for "PART"
|
||||
jne BadGpt
|
||||
cmp dword ptr es:[di + 8], 000010000h ; Check Revision - 0x10000
|
||||
jne BadGpt
|
||||
|
||||
mov eax, dword ptr es:[di + 84] ; EAX = SizeOfPartitionEntry
|
||||
mul byte ptr [bp+GptPartitionIndicator] ; EAX = SizeOfPartitionEntry * GptPartitionIndicator
|
||||
mov edx, eax ; EDX = SizeOfPartitionEntry * GptPartitionIndicator
|
||||
shr eax, BLOCK_SHIFT ; EAX = (SizeOfPartitionEntry * GptPartitionIndicator) / BLOCK_SIZE
|
||||
and edx, BLOCK_MASK ; EDX = Targer PartitionEntryLBA Offset
|
||||
; = (SizeOfPartitionEntry * GptPartitionIndicator) % BLOCK_SIZE
|
||||
push edx
|
||||
mov ecx, dword ptr es:[di + 72] ; ECX = PartitionEntryLBA (Low)
|
||||
mov ebx, dword ptr es:[di + 76] ; EBX = PartitionEntryLBA (High)
|
||||
add eax, ecx ; EAX = Target PartitionEntryLBA (Low)
|
||||
; = (PartitionEntryLBA +
|
||||
; (SizeOfPartitionEntry * GptPartitionIndicator) / BLOCK_SIZE)
|
||||
adc edx, ebx ; EDX = Target PartitionEntryLBA (High)
|
||||
|
||||
mov di, 0A00h ; Read to 0x0000:0x0A00
|
||||
mov bx, 1 ; Read 1 Block
|
||||
push es
|
||||
call ReadBlocks
|
||||
pop es
|
||||
|
||||
; ****************************************************************************
|
||||
; Read Target DBR from hard disk to 0x0000:0x7C00
|
||||
; ****************************************************************************
|
||||
pop edx ; EDX = (SizeOfPartitionEntry * GptPartitionIndicator) % BLOCK_SIZE
|
||||
add di, dx ; DI = Targer PartitionEntryLBA Offset
|
||||
cmp dword ptr es:[di], 0C12A7328h ; Check for EFI System Partition "C12A7328-F81F-11d2-BA4B-00A0C93EC93B"
|
||||
jne BadGpt
|
||||
cmp dword ptr es:[di + 4], 011d2F81Fh ;
|
||||
jne BadGpt
|
||||
cmp dword ptr es:[di + 8], 0A0004BBAh ;
|
||||
jne BadGpt
|
||||
cmp dword ptr es:[di + 0ch], 03BC93EC9h ;
|
||||
jne BadGpt
|
||||
|
||||
mov eax, dword ptr es:[di + 32] ; EAX = StartingLBA (Low)
|
||||
mov edx, dword ptr es:[di + 36] ; EDX = StartingLBA (High)
|
||||
mov di, 07C00h ; Read to 0x0000:0x7C00
|
||||
mov bx, 1 ; Read 1 Block
|
||||
call ReadBlocks
|
||||
|
||||
; ****************************************************************************
|
||||
; Transfer control to BootSector - Jump to 0x0000:0x7C00
|
||||
; ****************************************************************************
|
||||
xor ax, ax
|
||||
push ax ; PUSH 0x0000
|
||||
mov di, 07c00h
|
||||
push di ; PUSH 0x7C00
|
||||
retf ; JMP 0x0000:0x7C00
|
||||
|
||||
; ****************************************************************************
|
||||
; ReadBlocks - Reads a set of blocks from a block device
|
||||
;
|
||||
; EDX:EAX = Start LBA
|
||||
; BX = Number of Blocks to Read (must < 127)
|
||||
; ES:DI = Buffer to store sectors read from disk
|
||||
; ****************************************************************************
|
||||
|
||||
; si = DiskAddressPacket
|
||||
|
||||
ReadBlocks:
|
||||
pushad
|
||||
push ds
|
||||
xor cx, cx
|
||||
mov ds, cx
|
||||
mov bp, 0600h ; bp = 0x600
|
||||
lea si, [bp + OFFSET AddressPacket] ; DS:SI = Disk Address Packet
|
||||
mov BYTE PTR ds:[si+2],bl ; 02 = Number Of Block transfered
|
||||
mov WORD PTR ds:[si+4],di ; 04 = Transfer Buffer Offset
|
||||
mov WORD PTR ds:[si+6],es ; 06 = Transfer Buffer Segment
|
||||
mov DWORD PTR ds:[si+8],eax ; 08 = Starting LBA (Low)
|
||||
mov DWORD PTR ds:[si+0ch],edx ; 0C = Starting LBA (High)
|
||||
mov ah, 42h ; ah = Function 42
|
||||
mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number
|
||||
int 13h
|
||||
jc BadGpt
|
||||
pop ds
|
||||
popad
|
||||
ret
|
||||
|
||||
; ****************************************************************************
|
||||
; Address Packet used by ReadBlocks
|
||||
; ****************************************************************************
|
||||
AddressPacket:
|
||||
db 10h ; Size of address packet
|
||||
db 00h ; Reserved. Must be 0
|
||||
db 01h ; Read blocks at a time (To be fixed each times)
|
||||
db 00h ; Reserved. Must be 0
|
||||
dw 0000h ; Destination Address offset (To be fixed each times)
|
||||
dw 0000h ; Destination Address segment (To be fixed each times)
|
||||
AddressPacketLba:
|
||||
dd 0h, 0h ; Start LBA (To be fixed each times)
|
||||
AddressPacketEnd:
|
||||
|
||||
; ****************************************************************************
|
||||
; ERROR Condition:
|
||||
; ****************************************************************************
|
||||
|
||||
BadGpt:
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov ax, 060h
|
||||
mov ds, ax
|
||||
lea si, cs:[ErrorString]
|
||||
mov cx, 10
|
||||
mov di, 320
|
||||
rep movsw
|
||||
Halt:
|
||||
jmp Halt
|
||||
|
||||
StartString:
|
||||
db 'G', 0ch, 'P', 0ch, 'T', 0ch, ' ', 0ch, 'S', 0ch, 't', 0ch, 'a', 0ch, 'r', 0ch, 't', 0ch, '!', 0ch
|
||||
ErrorString:
|
||||
db 'G', 0ch, 'P', 0ch, 'T', 0ch, ' ', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
|
||||
|
||||
; ****************************************************************************
|
||||
; PhysicalDrive - Used to indicate which disk to be boot
|
||||
; Can be patched by tool
|
||||
; ****************************************************************************
|
||||
org 01B6h
|
||||
PhysicalDrive db 80h
|
||||
|
||||
; ****************************************************************************
|
||||
; GptPartitionIndicator - Used to indicate which GPT partition to be boot
|
||||
; Can be patched by tool
|
||||
; ****************************************************************************
|
||||
org 01B7h
|
||||
GptPartitionIndicator db 0
|
||||
|
||||
; ****************************************************************************
|
||||
; Unique MBR signature
|
||||
; ****************************************************************************
|
||||
org 01B8h
|
||||
db 'DUET'
|
||||
|
||||
; ****************************************************************************
|
||||
; Unknown
|
||||
; ****************************************************************************
|
||||
org 01BCh
|
||||
dw 0
|
||||
|
||||
; ****************************************************************************
|
||||
; PMBR Entry - Can be patched by tool
|
||||
; ****************************************************************************
|
||||
org 01BEh
|
||||
db 0 ; Boot Indicator
|
||||
db 0ffh ; Start Header
|
||||
db 0ffh ; Start Sector
|
||||
db 0ffh ; Start Track
|
||||
db 0eeh ; OS Type
|
||||
db 0ffh ; End Header
|
||||
db 0ffh ; End Sector
|
||||
db 0ffh ; End Track
|
||||
dd 1 ; Starting LBA
|
||||
dd 0FFFFFFFFh ; End LBA
|
||||
|
||||
org 01CEh
|
||||
dd 0, 0, 0, 0
|
||||
org 01DEh
|
||||
dd 0, 0, 0, 0
|
||||
org 01EEh
|
||||
dd 0, 0, 0, 0
|
||||
|
||||
; ****************************************************************************
|
||||
; Sector Signature
|
||||
; ****************************************************************************
|
||||
|
||||
org 01FEh
|
||||
SectorSignature:
|
||||
dw 0aa55h ; Boot Sector Signature
|
||||
|
||||
end
|
||||
|
276
DuetPkg/BootSector/Makefile
Normal file
276
DuetPkg/BootSector/Makefile
Normal file
@@ -0,0 +1,276 @@
|
||||
|
||||
#
|
||||
# Platform Macro Definition
|
||||
#
|
||||
PLATFORM_NAME = DuetPkg
|
||||
PLATFORM_GUID = 199E24E0-0989-42aa-87F2-611A8C397E72
|
||||
PLATFORM_VERSION = 0.3
|
||||
PLATFORM_RELATIVE_DIR = DuetPkg
|
||||
PLATFORM_DIR = $(WORKSPACE)\DuetPkg
|
||||
PLATFORM_OUTPUT_DIR = Build\DuetPkg
|
||||
|
||||
#
|
||||
# Module Macro Definition
|
||||
#
|
||||
MODULE_NAME = BootSector
|
||||
MODULE_GUID = 2410F0DF-D915-4137-BD04-AAB6BA4C50E0
|
||||
MODULE_VERSION = 1.0
|
||||
MODULE_TYPE = USER_DEFINED
|
||||
MODULE_FILE_BASE_NAME = BootSector
|
||||
BASE_NAME = $(MODULE_NAME)
|
||||
MODULE_RELATIVE_DIR = DuetPkg\BootSector
|
||||
MODULE_DIR = $(WORKSPACE)\DuetPkg\BootSector
|
||||
|
||||
#
|
||||
# Build Configuration Macro Definition
|
||||
#
|
||||
ARCH = IA32
|
||||
TOOLCHAIN_TAG = MYTOOLS
|
||||
TARGET = DEBUG
|
||||
BASETOOLS_DIR=m:\tree\working\BaseTools\Bin\Win32
|
||||
|
||||
#
|
||||
# Build Directory Macro Definition
|
||||
#
|
||||
# PLATFORM_BUILD_DIR = m:\tree\working\Build\DuetPkg\DEBUG_MYTOOLS
|
||||
BUILD_DIR = $(WORKSPACE)\Build\DuetPkg\DEBUG_MYTOOLS
|
||||
BIN_DIR = $(BUILD_DIR)\IA32
|
||||
LIB_DIR = $(BIN_DIR)
|
||||
MODULE_BUILD_DIR = $(BUILD_DIR)\IA32\DuetPkg\BootSector\BootSector
|
||||
OUTPUT_DIR = $(MODULE_BUILD_DIR)\OUTPUT
|
||||
DEBUG_DIR = $(MODULE_BUILD_DIR)\DEBUG
|
||||
DEST_DIR_OUTPUT = $(OUTPUT_DIR)
|
||||
DEST_DIR_DEBUG = $(DEBUG_DIR)
|
||||
|
||||
#
|
||||
# Default Tools Flags Macro Definition (from tools_def.txt by default)
|
||||
#
|
||||
DEFAULT_PP_FLAGS = /nologo /E /TC /FIAutoGen.h
|
||||
DEFAULT_SLINK_FLAGS = /nologo /LTCG
|
||||
DEFAULT_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs8192 /Gy /D UNICODE /O1ib2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Zi /Gm
|
||||
DEFAULT_APP_FLAGS = /nologo /E /TC
|
||||
DEFAULT_VFRPP_FLAGS = /nologo /E /TC /DVFRCOMPILE /FIAutoGen.h
|
||||
DEFAULT_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4086 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /MACHINE:I386 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:CONSOLE /SAFESEH:NO /BASE:0 /DRIVER /DEBUG /PDB:$(DEBUG_DIR)/$(BASE_NAME).pdb
|
||||
DEFAULT_ASM_FLAGS = /nologo /c /WX /W3 /coff /Cx /Zd /Zi
|
||||
DEFAULT_TIANO_FLAGS =
|
||||
DEFAULT_MAKE_FLAGS = /nologo
|
||||
DEFAULT_ASMLINK_FLAGS = /nologo /tiny
|
||||
DEFAULT_ASL_FLAGS =
|
||||
|
||||
|
||||
#
|
||||
# Platform Tools Flags Macro Definition (from platform description file)
|
||||
#
|
||||
PLATFORM_PP_FLAGS =
|
||||
PLATFORM_SLINK_FLAGS =
|
||||
PLATFORM_CC_FLAGS =
|
||||
PLATFORM_APP_FLAGS =
|
||||
PLATFORM_VFRPP_FLAGS =
|
||||
PLATFORM_DLINK_FLAGS =
|
||||
PLATFORM_ASM_FLAGS =
|
||||
PLATFORM_TIANO_FLAGS =
|
||||
PLATFORM_MAKE_FLAGS =
|
||||
PLATFORM_ASMLINK_FLAGS =
|
||||
PLATFORM_ASL_FLAGS =
|
||||
|
||||
|
||||
#
|
||||
# Module Tools Flags Macro Definition (from platform/module description file)
|
||||
#
|
||||
MODULE_PP_FLAGS =
|
||||
MODULE_SLINK_FLAGS =
|
||||
MODULE_CC_FLAGS =
|
||||
MODULE_APP_FLAGS =
|
||||
MODULE_VFRPP_FLAGS =
|
||||
MODULE_DLINK_FLAGS =
|
||||
MODULE_ASM_FLAGS =
|
||||
MODULE_TIANO_FLAGS =
|
||||
MODULE_MAKE_FLAGS =
|
||||
MODULE_ASMLINK_FLAGS =
|
||||
MODULE_ASL_FLAGS =
|
||||
|
||||
|
||||
#
|
||||
# Tools Flag Macro
|
||||
#
|
||||
PP_FLAGS = $(DEFAULT_PP_FLAGS) $(PLATFORM_PP_FLAGS) $(MODULE_PP_FLAGS)
|
||||
SLINK_FLAGS = $(DEFAULT_SLINK_FLAGS) $(PLATFORM_SLINK_FLAGS) $(MODULE_SLINK_FLAGS)
|
||||
CC_FLAGS = $(DEFAULT_CC_FLAGS) $(PLATFORM_CC_FLAGS) $(MODULE_CC_FLAGS)
|
||||
APP_FLAGS = $(DEFAULT_APP_FLAGS) $(PLATFORM_APP_FLAGS) $(MODULE_APP_FLAGS)
|
||||
VFRPP_FLAGS = $(DEFAULT_VFRPP_FLAGS) $(PLATFORM_VFRPP_FLAGS) $(MODULE_VFRPP_FLAGS)
|
||||
DLINK_FLAGS = $(DEFAULT_DLINK_FLAGS) $(PLATFORM_DLINK_FLAGS) $(MODULE_DLINK_FLAGS)
|
||||
ASM_FLAGS = $(DEFAULT_ASM_FLAGS) $(PLATFORM_ASM_FLAGS) $(MODULE_ASM_FLAGS)
|
||||
TIANO_FLAGS = $(DEFAULT_TIANO_FLAGS) $(PLATFORM_TIANO_FLAGS) $(MODULE_TIANO_FLAGS)
|
||||
MAKE_FLAGS = $(DEFAULT_MAKE_FLAGS) $(PLATFORM_MAKE_FLAGS) $(MODULE_MAKE_FLAGS)
|
||||
ASMLINK_FLAGS = $(DEFAULT_ASMLINK_FLAGS) $(PLATFORM_ASMLINK_FLAGS) $(MODULE_ASMLINK_FLAGS)
|
||||
ASL_FLAGS = $(DEFAULT_ASL_FLAGS) $(PLATFORM_ASL_FLAGS) $(MODULE_ASL_FLAGS)
|
||||
|
||||
|
||||
#
|
||||
# Tools Path Macro
|
||||
#
|
||||
PP = C:\Program Files\Microsoft Visual Studio 8\Vc\bin\cl.exe
|
||||
SLINK = C:\Program Files\Microsoft Visual Studio 8\Vc\bin\lib.exe
|
||||
CC = C:\Program Files\Microsoft Visual Studio 8\Vc\bin\cl.exe
|
||||
APP = C:\Program Files\Microsoft Visual Studio 8\Vc\bin\cl.exe
|
||||
VFRPP = C:\Program Files\Microsoft Visual Studio 8\Vc\bin\cl.exe
|
||||
DLINK = C:\Program Files\Microsoft Visual Studio 8\Vc\bin\link.exe
|
||||
ASM = C:\WINDDK\3790.1830\bin\x86\ml.exe
|
||||
TIANO = TianoCompress.exe
|
||||
MAKE = C:\Program Files\Microsoft Visual Studio 8\Vc\bin\nmake.exe
|
||||
#ASMLINK = C:\WINDDK\3790.1830\bin\bin16\link.exe
|
||||
ASMLINK = C:\WINDDK\3790.1830\bin\bin16\link16.exe
|
||||
ASL = C:\ASL\iasl.exe
|
||||
|
||||
|
||||
MAKE_FILE = $(MODULE_BUILD_DIR)\Makefile
|
||||
|
||||
#
|
||||
# Shell Command Macro
|
||||
#
|
||||
RD = rmdir /s /q
|
||||
RM = del /f /q
|
||||
MD = mkdir
|
||||
CP = copy /y
|
||||
MV = move /y
|
||||
|
||||
|
||||
#
|
||||
# Build Macro
|
||||
#
|
||||
ASSEMBLY_CODE_FILE_LIST = $(MODULE_DIR)\bootsect.asm \
|
||||
$(MODULE_DIR)\bs16.asm \
|
||||
$(MODULE_DIR)\bs32.asm \
|
||||
$(MODULE_DIR)\efi32.asm \
|
||||
$(MODULE_DIR)\Gpt.asm \
|
||||
$(MODULE_DIR)\Mbr.asm \
|
||||
$(MODULE_DIR)\start.asm \
|
||||
$(MODULE_DIR)\start16.asm \
|
||||
$(MODULE_DIR)\start32.asm
|
||||
|
||||
TARGET_FILES = $(OUTPUT_DIR)\bootsect.com \
|
||||
$(OUTPUT_DIR)\bs16.com \
|
||||
$(OUTPUT_DIR)\bs32.com \
|
||||
$(OUTPUT_DIR)\Gpt.com \
|
||||
$(OUTPUT_DIR)\Mbr.com \
|
||||
$(OUTPUT_DIR)\Start.com \
|
||||
$(OUTPUT_DIR)\Start16.com \
|
||||
$(OUTPUT_DIR)\Start32.com \
|
||||
$(OUTPUT_DIR)\efi32.com2
|
||||
|
||||
INC =
|
||||
|
||||
|
||||
#OBJECTS =
|
||||
|
||||
LIBS =
|
||||
|
||||
COMMON_DEPS =
|
||||
|
||||
all: init $(TARGET_FILES) loader
|
||||
|
||||
init:
|
||||
if not exist $(OUTPUT_DIR) mkdir $(OUTPUT_DIR)
|
||||
if not exist $(DEBUG_DIR) mkdir $(DEBUG_DIR)
|
||||
|
||||
#=============
|
||||
$(OUTPUT_DIR)\bootsect.obj:$(MODULE_DIR)\bootsect.asm
|
||||
$(ASM) /c /omf /Fo"$(OUTPUT_DIR)\bootsect.obj" /FR"$(OUTPUT_DIR)\bootsect.txt" "$(MODULE_DIR)\bootsect.asm"
|
||||
|
||||
$(OUTPUT_DIR)\bootsect.com:$(OUTPUT_DIR)\bootsect.obj
|
||||
"$(ASMLINK)" /tiny $(OUTPUT_DIR)\bootsect.obj,$(OUTPUT_DIR)\bootsect.com,$(OUTPUT_DIR)\bootsect.map,,,
|
||||
|
||||
#=============
|
||||
|
||||
$(OUTPUT_DIR)\bs16.obj:$(MODULE_DIR)\bs16.asm
|
||||
$(ASM) /c /omf /Fo"$(OUTPUT_DIR)\bs16.obj" "$(MODULE_DIR)\bs16.asm"
|
||||
|
||||
$(OUTPUT_DIR)\bs16.com:$(OUTPUT_DIR)\bs16.obj
|
||||
"$(ASMLINK)" /tiny $(OUTPUT_DIR)\bs16.obj,$(OUTPUT_DIR)\bs16.com,$(OUTPUT_DIR)\bs16.map,,,
|
||||
|
||||
#=============
|
||||
|
||||
$(OUTPUT_DIR)\bs32.obj:$(MODULE_DIR)\bs32.asm
|
||||
$(ASM) /c /omf /Fo"$(OUTPUT_DIR)\bs32.obj" "$(MODULE_DIR)\bs32.asm"
|
||||
|
||||
$(OUTPUT_DIR)\bs32.com:$(OUTPUT_DIR)\bs32.obj
|
||||
"$(ASMLINK)" /tiny $(OUTPUT_DIR)\bs32.obj,$(OUTPUT_DIR)\bs32.com,$(OUTPUT_DIR)\bs32.map,,,
|
||||
|
||||
#=============
|
||||
|
||||
$(OUTPUT_DIR)\Gpt.obj:$(MODULE_DIR)\Gpt.asm
|
||||
$(ASM) /c /omf /Fo"$(OUTPUT_DIR)\Gpt.obj" "$(MODULE_DIR)\Gpt.asm"
|
||||
|
||||
$(OUTPUT_DIR)\Gpt.com:$(OUTPUT_DIR)\Gpt.obj
|
||||
"$(ASMLINK)" /tiny $(OUTPUT_DIR)\Gpt.obj,$(OUTPUT_DIR)\Gpt.com,$(OUTPUT_DIR)\Gpt.map,,,
|
||||
|
||||
#=============
|
||||
|
||||
$(OUTPUT_DIR)\Mbr.obj:$(MODULE_DIR)\Mbr.asm
|
||||
$(ASM) /c /omf /Fo"$(OUTPUT_DIR)\Mbr.obj" "$(MODULE_DIR)\Mbr.asm"
|
||||
|
||||
$(OUTPUT_DIR)\Mbr.com:$(OUTPUT_DIR)\Mbr.obj
|
||||
"$(ASMLINK)" /tiny $(OUTPUT_DIR)\Mbr.obj,$(OUTPUT_DIR)\Mbr.com,$(OUTPUT_DIR)\Mbr.map,,,
|
||||
|
||||
#============
|
||||
|
||||
$(OUTPUT_DIR)\Start.obj:$(MODULE_DIR)\Start.asm
|
||||
$(ASM) /c /omf /Fo"$(OUTPUT_DIR)\Start.obj" "$(MODULE_DIR)\Start.asm"
|
||||
|
||||
$(OUTPUT_DIR)\Start.com:$(OUTPUT_DIR)\Start.obj
|
||||
"$(ASMLINK)" /tiny $(OUTPUT_DIR)\Start.obj,$(OUTPUT_DIR)\Start.com,$(OUTPUT_DIR)\Start.map,,,
|
||||
|
||||
#=============
|
||||
|
||||
$(OUTPUT_DIR)\Start16.obj:$(MODULE_DIR)\Start16.asm
|
||||
$(ASM) /c /omf /Fo"$(OUTPUT_DIR)\Start16.obj" "$(MODULE_DIR)\Start16.asm"
|
||||
|
||||
$(OUTPUT_DIR)\Start16.com:$(OUTPUT_DIR)\Start16.obj
|
||||
"$(ASMLINK)" /tiny $(OUTPUT_DIR)\Start16.obj,$(OUTPUT_DIR)\Start16.com,$(OUTPUT_DIR)\Start16.map,,,
|
||||
|
||||
#=============
|
||||
|
||||
$(OUTPUT_DIR)\Start32.obj:$(MODULE_DIR)\Start32.asm
|
||||
$(ASM) /c /omf /Fo"$(OUTPUT_DIR)\Start32.obj" "$(MODULE_DIR)\Start32.asm"
|
||||
|
||||
$(OUTPUT_DIR)\Start32.com:$(OUTPUT_DIR)\Start32.obj
|
||||
"$(ASMLINK)" /tiny $(OUTPUT_DIR)\Start32.obj,$(OUTPUT_DIR)\Start32.com,$(OUTPUT_DIR)\Start32.map,,,
|
||||
|
||||
#=============
|
||||
|
||||
$(OUTPUT_DIR)\efi32.obj:$(MODULE_DIR)\efi32.asm
|
||||
$(ASM) /c /omf /Fo"$(OUTPUT_DIR)\efi32.obj" "$(MODULE_DIR)\efi32.asm"
|
||||
|
||||
$(OUTPUT_DIR)\efi32.com:$(OUTPUT_DIR)\efi32.obj
|
||||
"$(ASMLINK)" /tiny $(OUTPUT_DIR)\efi32.obj,$(OUTPUT_DIR)\efi32.com,$(OUTPUT_DIR)\efi32.map,,,
|
||||
|
||||
#=============
|
||||
|
||||
$(OUTPUT_DIR)\efi32.com2:$(OUTPUT_DIR)\efi32.com
|
||||
$(BASETOOLS_DIR)\Split.exe -f $(OUTPUT_DIR)\efi32.com -t $(OUTPUT_DIR)\efi32.com2 -s 135168
|
||||
#
|
||||
# clean all generated files
|
||||
#
|
||||
|
||||
loader:$(BUILD_DIR)\FV\Efildr
|
||||
|
||||
$(BUILD_DIR)\FV\DUETEFIMAINFV.z:$(BUILD_DIR)\FV\DUETEFIMAINFV.Fv
|
||||
$(BASETOOLS_DIR)\TianoCompress -e -o $(BUILD_DIR)\FV\DUETEFIMAINFV.z $(BUILD_DIR)\FV\DUETEFIMAINFV.Fv
|
||||
|
||||
$(BUILD_DIR)\FV\DxeMain.z:$(BUILD_DIR)\IA32\DxeMain.efi
|
||||
$(BASETOOLS_DIR)\TianoCompress -e -o $(BUILD_DIR)\FV\DxeMain.z $(BUILD_DIR)\IA32\DxeMain.efi
|
||||
|
||||
$(BUILD_DIR)\FV\DxeIpl.z:$(BUILD_DIR)\IA32\DxeIpl.efi
|
||||
$(BASETOOLS_DIR)\TianoCompress -e -o $(BUILD_DIR)\FV\DxeIpl.z $(BUILD_DIR)\IA32\DxeIpl.efi
|
||||
|
||||
$(BUILD_DIR)\FV\Efildr32:$(BUILD_DIR)\IA32\EfiLoader.efi $(BUILD_DIR)\FV\DxeIpl.z $(BUILD_DIR)\FV\DUETEFIMAINFV.z
|
||||
$(BASETOOLS_DIR)\EfiLdrImage.exe -o $(BUILD_DIR)\FV\Efildr32 $(BUILD_DIR)\IA32\EfiLoader.efi $(BUILD_DIR)\FV\DxeIpl.z $(BUILD_DIR)\FV\DUETEFIMAINFV.z
|
||||
|
||||
$(BUILD_DIR)\FV\Efildr:$(OUTPUT_DIR)\Start.com $(OUTPUT_DIR)\Efi32.com2 $(BUILD_DIR)\FV\Efildr32
|
||||
copy /b $(OUTPUT_DIR)\BootSect.com+$(OUTPUT_DIR)\Efi32.com2+$(BUILD_DIR)\FV\Efildr32 $(BUILD_DIR)\FV\Efildr
|
||||
|
||||
clean:
|
||||
if exist $(DEBUG_DIR) rmdir /s /q $(DEBUG_DIR)
|
||||
if exist $(OUTPUT_DIR) rmdir /s /q $(OUTPUT_DIR)
|
||||
|
||||
|
261
DuetPkg/BootSector/Mbr.asm
Normal file
261
DuetPkg/BootSector/Mbr.asm
Normal file
@@ -0,0 +1,261 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006 - 2007, Intel Corporation
|
||||
;* All rights reserved. This program and the accompanying materials
|
||||
;* are licensed and made available under the terms and conditions of the BSD License
|
||||
;* which accompanies this distribution. The full text of the license may be found at
|
||||
;* http://opensource.org/licenses/bsd-license.php
|
||||
;*
|
||||
;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;*
|
||||
;* Mbr.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.model small
|
||||
; .dosseg
|
||||
.stack
|
||||
.486p
|
||||
.code
|
||||
|
||||
BLOCK_SIZE EQU 0200h
|
||||
BLOCK_MASK EQU 01ffh
|
||||
BLOCK_SHIFT EQU 9
|
||||
|
||||
; ****************************************************************************
|
||||
; Code loaded by BIOS at 0x0000:0x7C00
|
||||
; ****************************************************************************
|
||||
|
||||
org 0h
|
||||
Start:
|
||||
|
||||
; ****************************************************************************
|
||||
; Start Print
|
||||
; ****************************************************************************
|
||||
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov ax, 07c0h
|
||||
mov ds, ax
|
||||
lea si, cs:[StartString]
|
||||
mov cx, 10
|
||||
mov di, 160
|
||||
rep movsw
|
||||
|
||||
; ****************************************************************************
|
||||
; Print over
|
||||
; ****************************************************************************
|
||||
|
||||
; ****************************************************************************
|
||||
; Initialize segment registers and copy code at 0x0000:0x7c00 to 0x0000:0x0600
|
||||
; ****************************************************************************
|
||||
xor ax, ax ; AX = 0x0000
|
||||
mov bx, 07c00h ; BX = 0x7C00
|
||||
mov bp, 0600h ; BP = 0x0600
|
||||
mov si, OFFSET RelocatedStart ; SI = Offset(RelocatedStart)
|
||||
mov cx, 0200h ; CX = 0x0200
|
||||
sub cx, si ; CS = 0x0200 - Offset(RelocatedStart)
|
||||
lea di, [bp+si] ; DI = 0x0600 + Offset(RelocatedStart)
|
||||
lea si, [bx+si] ; BX = 0x7C00 + Offset(RelocatedStart)
|
||||
mov ss, ax ; SS = 0x0000
|
||||
mov sp, bx ; SP = 0x7C00
|
||||
mov es,ax ; ES = 0x0000
|
||||
mov ds,ax ; DS = 0x0000
|
||||
push ax ; PUSH 0x0000
|
||||
push di ; PUSH 0x0600 + Offset(RelocatedStart)
|
||||
cld ; Clear the direction flag
|
||||
rep movsb ; Copy 0x0200 bytes from 0x7C00 to 0x0600
|
||||
retf ; JMP 0x0000:0x0600 + Offset(RelocatedStart)
|
||||
|
||||
; ****************************************************************************
|
||||
; Code relocated to 0x0000:0x0600
|
||||
; ****************************************************************************
|
||||
|
||||
RelocatedStart:
|
||||
; ****************************************************************************
|
||||
; Get Driver Parameters to 0x0000:0x7BFC
|
||||
; ****************************************************************************
|
||||
|
||||
xor ax,ax ; AX = 0
|
||||
mov ss,ax ; SS = 0
|
||||
add ax,1000h
|
||||
mov ds,ax
|
||||
|
||||
mov sp,07c00h ; SP = 0x7c00
|
||||
mov bp,sp ; BP = 0x7c00
|
||||
|
||||
mov ah,8 ; AH = 8 - Get Drive Parameters Function
|
||||
mov byte ptr [bp+PhysicalDrive],dl ; BBS defines that BIOS would pass the booting driver number to the loader through DL
|
||||
int 13h ; Get Drive Parameters
|
||||
xor ax,ax ; AX = 0
|
||||
mov al,dh ; AL = DH
|
||||
inc al ; MaxHead = AL + 1
|
||||
push ax ; 0000:7bfe = MaxHead
|
||||
mov al,cl ; AL = CL
|
||||
and al,03fh ; MaxSector = AL & 0x3f
|
||||
push ax ; 0000:7bfc = MaxSector
|
||||
|
||||
; ****************************************************************************
|
||||
; Read Target DBR from hard disk to 0x0000:0x7C00
|
||||
; ****************************************************************************
|
||||
|
||||
xor ax, ax
|
||||
mov al, byte ptr [bp+MbrPartitionIndicator] ; AX = MbrPartitionIndex
|
||||
cmp al, 0ffh ; 0xFF means do legacy MBR boot
|
||||
jnz EfiDbr
|
||||
LegacyMbr:
|
||||
mov eax, 00000600h ; Assume LegacyMBR is backuped in Sector 6
|
||||
jmp StartReadTo7C00 ; EAX = Header/Sector/Tracker/Zero
|
||||
|
||||
EfiDbr:
|
||||
cmp al, 4 ; MbrPartitionIndex should < 4
|
||||
jae BadDbr
|
||||
shl ax, 4 ; AX = MBREntrySize * Index
|
||||
add ax, 1beh ; AX = MBREntryOffset
|
||||
mov di, ax ; DI = MBREntryOffset
|
||||
|
||||
; Here we don't use the C/H/S information provided by Partition table
|
||||
; but calculate C/H/S from LBA ourselves
|
||||
; Ci: Cylinder number
|
||||
; Hi: Header number
|
||||
; Si: Sector number
|
||||
mov eax, dword ptr es:[bp + di + 8] ; Start LBA
|
||||
mov edx, eax
|
||||
shr edx, 16 ; DX:AX = Start LBA
|
||||
; = Ci * (H * S) + Hi * S + (Si - 1)
|
||||
|
||||
; Calculate C/H/S according to LBA
|
||||
mov bp, 7bfah
|
||||
div word ptr [bp+2] ; AX = Hi + H*Ci
|
||||
; DX = Si - 1
|
||||
inc dx ; DX = Si
|
||||
push dx ; 0000:7bfa = Si <----
|
||||
xor dx, dx ; DX:AX = Hi + H*Ci
|
||||
div word ptr [bp+4] ; AX = Ci <----
|
||||
; DX = Hi <----
|
||||
|
||||
StartReadTo7C00:
|
||||
|
||||
mov cl, byte ptr [bp] ; Si
|
||||
mov ch, al ; Ci[0-7]
|
||||
or cl, ah ; Ci[8,9]
|
||||
mov bx, 7c00h ; ES:BX = 0000:7C00h
|
||||
mov ah, 2h ; Function 02h
|
||||
mov al, 1 ; 1 Sector
|
||||
mov dh, dl ; Hi
|
||||
mov bp, 0600h
|
||||
mov dl, byte ptr [bp + PhysicalDrive] ; Drive number
|
||||
int 13h
|
||||
jc BadDbr
|
||||
|
||||
|
||||
|
||||
; ****************************************************************************
|
||||
; Transfer control to BootSector - Jump to 0x0000:0x7C00
|
||||
; ****************************************************************************
|
||||
xor ax, ax
|
||||
push ax ; PUSH 0x0000 - Segment
|
||||
mov di, 07c00h
|
||||
push di ; PUSH 0x7C00 - Offset
|
||||
retf ; JMP 0x0000:0x7C00
|
||||
|
||||
; ****************************************************************************
|
||||
; ERROR Condition:
|
||||
; ****************************************************************************
|
||||
|
||||
BadDbr:
|
||||
push ax
|
||||
mov ax, 0b800h
|
||||
mov es, ax
|
||||
mov ax, 060h
|
||||
mov ds, ax
|
||||
lea si, cs:[ErrorString]
|
||||
mov di, 320
|
||||
pop ax
|
||||
call A2C
|
||||
mov [si+16], ah
|
||||
mov [si+18], al
|
||||
mov cx, 10
|
||||
rep movsw
|
||||
Halt:
|
||||
jmp Halt
|
||||
|
||||
StartString:
|
||||
db 'M', 0ch, 'B', 0ch, 'R', 0ch, ' ', 0ch, 'S', 0ch, 't', 0ch, 'a', 0ch, 'r', 0ch, 't', 0ch, '!', 0ch
|
||||
ErrorString:
|
||||
db 'M', 0ch, 'B', 0ch, 'R', 0ch, ' ', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, ':', 0ch, '?', 0ch, '?', 0ch
|
||||
|
||||
; ****************************************************************************
|
||||
; A2C - convert Ascii code stored in AH to character stored in AX
|
||||
; ****************************************************************************
|
||||
A2C:
|
||||
mov al, ah
|
||||
shr ah, 4
|
||||
and al, 0Fh
|
||||
add ah, '0'
|
||||
add al, '0'
|
||||
|
||||
cmp ah, '9'
|
||||
jle @f
|
||||
add ah, 7
|
||||
@@:
|
||||
|
||||
cmp al, '9'
|
||||
jle @f
|
||||
add al, 7
|
||||
@@:
|
||||
ret
|
||||
|
||||
|
||||
; ****************************************************************************
|
||||
; PhysicalDrive - Used to indicate which disk to be boot
|
||||
; Can be patched by tool
|
||||
; ****************************************************************************
|
||||
org 01B6h
|
||||
PhysicalDrive db 80h
|
||||
|
||||
; ****************************************************************************
|
||||
; MbrPartitionIndicator - Used to indicate which MBR partition to be boot
|
||||
; Can be patched by tool
|
||||
; OxFF means boot to legacy MBR. (LBA OFFSET 6)
|
||||
; ****************************************************************************
|
||||
org 01B7h
|
||||
MbrPartitionIndicator db 0
|
||||
|
||||
; ****************************************************************************
|
||||
; Unique MBR signature
|
||||
; ****************************************************************************
|
||||
org 01B8h
|
||||
db 'DUET'
|
||||
|
||||
; ****************************************************************************
|
||||
; Unknown
|
||||
; ****************************************************************************
|
||||
org 01BCh
|
||||
dw 0
|
||||
|
||||
; ****************************************************************************
|
||||
; MBR Entry - To be patched
|
||||
; ****************************************************************************
|
||||
org 01BEh
|
||||
dd 0, 0, 0, 0
|
||||
org 01CEh
|
||||
dd 0, 0, 0, 0
|
||||
org 01DEh
|
||||
dd 0, 0, 0, 0
|
||||
org 01EEh
|
||||
dd 0, 0, 0, 0
|
||||
|
||||
; ****************************************************************************
|
||||
; Sector Signature
|
||||
; ****************************************************************************
|
||||
|
||||
org 01FEh
|
||||
SectorSignature:
|
||||
dw 0aa55h ; Boot Sector Signature
|
||||
|
||||
end
|
||||
|
288
DuetPkg/BootSector/bootsect.asm
Normal file
288
DuetPkg/BootSector/bootsect.asm
Normal file
@@ -0,0 +1,288 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006 - 2007, Intel Corporation
|
||||
;* All rights reserved. This program and the accompanying materials
|
||||
;* are licensed and made available under the terms and conditions of the BSD License
|
||||
;* which accompanies this distribution. The full text of the license may be found at
|
||||
;* http://opensource.org/licenses/bsd-license.php
|
||||
;*
|
||||
;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;*
|
||||
;* bootsect.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.model small
|
||||
.stack
|
||||
.486p
|
||||
.code
|
||||
|
||||
FAT_DIRECTORY_ENTRY_SIZE EQU 020h
|
||||
FAT_DIRECTORY_ENTRY_SHIFT EQU 5
|
||||
BLOCK_SIZE EQU 0200h
|
||||
BLOCK_MASK EQU 01ffh
|
||||
BLOCK_SHIFT EQU 9
|
||||
; "EFILDR_____"
|
||||
LOADER_FILENAME_PART1 EQU 04c494645h ; "EFIL"
|
||||
LOADER_FILENAME_PART2 EQU 020205244h ; "DR__"
|
||||
LOADER_FILENAME_PART3 EQU 020202020h ; "____"
|
||||
|
||||
org 0h
|
||||
Ia32Jump:
|
||||
jmp BootSectorEntryPoint ; JMP inst - 3 bytes
|
||||
nop
|
||||
|
||||
OemId db "INTEL " ; OemId - 8 bytes
|
||||
; BPB data below will be fixed by tool
|
||||
SectorSize dw 0 ; Sector Size - 16 bits
|
||||
SectorsPerCluster db 0 ; Sector Per Cluster - 8 bits
|
||||
ReservedSectors dw 0 ; Reserved Sectors - 16 bits
|
||||
NoFats db 0 ; Number of FATs - 8 bits
|
||||
RootEntries dw 0 ; Root Entries - 16 bits
|
||||
Sectors dw 0 ; Number of Sectors - 16 bits
|
||||
Media db 0 ; Media - 8 bits - ignored
|
||||
SectorsPerFat dw 0 ; Sectors Per FAT - 16 bits
|
||||
SectorsPerTrack dw 0 ; Sectors Per Track - 16 bits - ignored
|
||||
Heads dw 0 ; Heads - 16 bits - ignored
|
||||
HiddenSectors dd 0 ; Hidden Sectors - 32 bits - ignored
|
||||
LargeSectors dd 0 ; Large Sectors - 32 bits
|
||||
PhysicalDrive db 0 ; PhysicalDriveNumber - 8 bits - ignored
|
||||
CurrentHead db 0 ; Current Head - 8 bits
|
||||
Signature db 0 ; Signature - 8 bits - ignored
|
||||
Id db " " ; Id - 4 bytes
|
||||
FatLabel db " " ; Label - 11 bytes
|
||||
SystemId db "FAT12 " ; SystemId - 8 bytes
|
||||
|
||||
BootSectorEntryPoint:
|
||||
ASSUME ds:@code
|
||||
ASSUME ss:@code
|
||||
|
||||
; ****************************************************************************
|
||||
; Start Print
|
||||
; ****************************************************************************
|
||||
lea si, cs:[StartString]
|
||||
call PrintString
|
||||
|
||||
; ****************************************************************************
|
||||
; Print over
|
||||
; ****************************************************************************
|
||||
|
||||
mov ax,cs ; ax = 0
|
||||
mov ss,ax ; ss = 0
|
||||
add ax,1000h
|
||||
mov ds,ax
|
||||
|
||||
mov sp,07c00h ; sp = 0x7c00
|
||||
mov bp,sp ; bp = 0x7c00
|
||||
|
||||
mov ah,8 ; ah = 8 - Get Drive Parameters Function
|
||||
mov byte ptr [bp+PhysicalDrive],dl ; BBS defines that BIOS would pass the booting driver number to the loader through DL
|
||||
int 13h ; Get Drive Parameters
|
||||
xor ax,ax ; ax = 0
|
||||
mov al,dh ; al = dh
|
||||
inc al ; MaxHead = al + 1
|
||||
push ax ; 0000:7bfe = MaxHead
|
||||
mov al,cl ; al = cl
|
||||
and al,03fh ; MaxSector = al & 0x3f
|
||||
push ax ; 0000:7bfc = MaxSector
|
||||
|
||||
cmp word ptr [bp+SectorSignature],0aa55h ; Verify Boot Sector Signature
|
||||
jne BadBootSector
|
||||
mov cx,word ptr [bp+RootEntries] ; cx = RootEntries
|
||||
shl cx,FAT_DIRECTORY_ENTRY_SHIFT ; cx = cx * 32 = cx * sizeof(FAT_DIRECTORY_ENTRY) = Size of Root Directory in bytes
|
||||
mov bx,cx ; bx = size of the Root Directory in bytes
|
||||
and bx,BLOCK_MASK ; See if it is an even number of sectors long
|
||||
jne BadBootSector ; If is isn't, then the boot sector is bad.
|
||||
mov bx,cx ; bx = size of the Root Directory in bytes
|
||||
shr bx,BLOCK_SHIFT ; bx = size of Root Directory in sectors
|
||||
mov al,byte ptr [bp+NoFats] ; al = NoFats
|
||||
xor ah,ah ; ah = 0 ==> ax = NoFats
|
||||
mul word ptr [bp+SectorsPerFat] ; ax = NoFats * SectorsPerFat
|
||||
add ax,word ptr [bp+ReservedSectors] ; ax = NoFats * SectorsPerFat + ReservedSectors = RootLBA
|
||||
push ds
|
||||
pop es
|
||||
xor di,di ; Store directory in es:di = 1000:0000
|
||||
call ReadBlocks ; Read entire Root Directory
|
||||
add ax,bx ; ax = NoFats * SectorsPerFat + ReservedSectors + RootDirSectors = FirstClusterLBA (FirstDataSector)
|
||||
mov word ptr [bp],ax ; Save FirstClusterLBA (FirstDataSector) for later use
|
||||
|
||||
; dx - variable storage (initial value is 0)
|
||||
; bx - loader (initial value is 0)
|
||||
xor dx, dx
|
||||
xor bx, bx
|
||||
|
||||
FindEFILDR:
|
||||
cmp dword ptr [di],LOADER_FILENAME_PART1 ; Compare to "EFIL"
|
||||
jne FindVARSTORE
|
||||
cmp dword ptr [di+4],LOADER_FILENAME_PART2
|
||||
jne FindVARSTORE
|
||||
cmp dword ptr [di+7],LOADER_FILENAME_PART3
|
||||
jne FindVARSTORE
|
||||
mov bx, word ptr [di+26] ; bx = Start Cluster for EFILDR <----------------------------------
|
||||
test dx, dx
|
||||
je FindNext ; Efivar.bin is not loaded
|
||||
jmp FoundAll
|
||||
|
||||
FindVARSTORE:
|
||||
; if the file is not loader file, see if it's "EFIVAR BIN"
|
||||
cmp dword ptr [di], 056494645h ; Compare to "EFIV"
|
||||
jne FindNext
|
||||
cmp dword ptr [di+4], 020205241h ; Compare to "AR "
|
||||
jne FindNext
|
||||
cmp dword ptr [di+7], 04e494220h ; Compare to " BIN"
|
||||
jne FindNext
|
||||
mov dx, di ; dx = Offset of Start Cluster for Efivar.bin <---------------------
|
||||
add dx, 26
|
||||
test bx, bx
|
||||
je FindNext ; Efildr is not loaded
|
||||
jmp FoundAll
|
||||
|
||||
FindNext:
|
||||
; go to next find
|
||||
add di,FAT_DIRECTORY_ENTRY_SIZE ; Increment di
|
||||
sub cx,FAT_DIRECTORY_ENTRY_SIZE ; Decrement cx
|
||||
; TODO: jump to FindVarStore if ...
|
||||
jne FindEFILDR
|
||||
jmp NotFoundAll
|
||||
|
||||
FoundAll:
|
||||
FoundEFILDR:
|
||||
mov cx,bx ; cx = Start Cluster for EFILDR <----------------------------------
|
||||
mov ax,cs ; Destination = 2000:0000
|
||||
add ax,2000h
|
||||
mov es,ax
|
||||
xor di,di
|
||||
ReadFirstClusterOfEFILDR:
|
||||
mov ax,cx ; ax = StartCluster
|
||||
sub ax,2 ; ax = StartCluster - 2
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster
|
||||
push dx
|
||||
mul bx
|
||||
pop dx ; ax = (StartCluster - 2) * SectorsPerCluster
|
||||
add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = Number of Sectors in a cluster
|
||||
push es
|
||||
call ReadBlocks
|
||||
pop ax
|
||||
JumpIntoFirstSectorOfEFILDR:
|
||||
mov word ptr [bp+JumpSegment],ax
|
||||
JumpFarInstruction:
|
||||
db 0eah
|
||||
JumpOffset:
|
||||
dw 0000h
|
||||
JumpSegment:
|
||||
dw 2000h
|
||||
|
||||
|
||||
PrintString:
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov ax, 07c0h
|
||||
mov ds, ax
|
||||
mov cx, 7
|
||||
mov di, 160
|
||||
rep movsw
|
||||
ret
|
||||
; ****************************************************************************
|
||||
; ReadBlocks - Reads a set of blocks from a block device
|
||||
;
|
||||
; AX = Start LBA
|
||||
; BX = Number of Blocks to Read
|
||||
; ES:DI = Buffer to store sectors read from disk
|
||||
; ****************************************************************************
|
||||
|
||||
; cx = Blocks
|
||||
; bx = NumberOfBlocks
|
||||
; si = StartLBA
|
||||
|
||||
ReadBlocks:
|
||||
pusha
|
||||
add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA
|
||||
add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA
|
||||
mov esi,eax ; esi = Start LBA
|
||||
mov cx,bx ; cx = Number of blocks to read
|
||||
ReadCylinderLoop:
|
||||
mov bp,07bfch ; bp = 0x7bfc
|
||||
mov eax,esi ; eax = Start LBA
|
||||
xor edx,edx ; edx = 0
|
||||
movzx ebx,word ptr [bp] ; bx = MaxSector
|
||||
div ebx ; ax = StartLBA / MaxSector
|
||||
inc dx ; dx = (StartLBA % MaxSector) + 1
|
||||
sub bx,dx ; bx = MaxSector - Sector
|
||||
inc bx ; bx = MaxSector - Sector + 1
|
||||
cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)
|
||||
jg LimitTransfer
|
||||
mov bx,cx ; bx = Blocks
|
||||
LimitTransfer:
|
||||
push cx
|
||||
mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector
|
||||
xor dx,dx ; dx = 0
|
||||
div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder
|
||||
; dx = ax % (MaxHead + 1) = Head
|
||||
|
||||
push bx ; Save number of blocks to transfer
|
||||
mov dh,dl ; dh = Head
|
||||
mov bp,07c00h ; bp = 0x7c00
|
||||
mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number
|
||||
mov ch,al ; ch = Cylinder
|
||||
mov al,bl ; al = Blocks
|
||||
mov ah,2 ; ah = Function 2
|
||||
mov bx,di ; es:bx = Buffer address
|
||||
int 013h
|
||||
jc DiskError
|
||||
pop bx
|
||||
pop cx
|
||||
movzx ebx,bx
|
||||
add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks
|
||||
sub cx,bx ; Blocks = Blocks - NumberOfBlocks
|
||||
mov ax,es
|
||||
shl bx,(BLOCK_SHIFT-4)
|
||||
add ax,bx
|
||||
mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE
|
||||
cmp cx,0
|
||||
jne ReadCylinderLoop
|
||||
popa
|
||||
ret
|
||||
|
||||
; ****************************************************************************
|
||||
; ERROR Condition:
|
||||
; ****************************************************************************
|
||||
NotFoundAll:
|
||||
; if we found EFILDR, continue
|
||||
test bx,bx
|
||||
jne FoundEFILDR
|
||||
BadBootSector:
|
||||
DiskError:
|
||||
lea si, cs:[ErrorString]
|
||||
call PrintString
|
||||
Halt:
|
||||
jmp Halt
|
||||
|
||||
StartString:
|
||||
db 'B', 0ch, 'S', 0ch, 't', 0ch, 'a', 0ch, 'r', 0ch, 't', 0ch, '!', 0ch
|
||||
ErrorString:
|
||||
db 'B', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
|
||||
|
||||
; ****************************************************************************
|
||||
; LBA Offset for BootSector, need patched by tool for HD boot.
|
||||
; ****************************************************************************
|
||||
|
||||
org 01fah
|
||||
LBAOffsetForBootSector:
|
||||
dd 0h
|
||||
|
||||
; ****************************************************************************
|
||||
; Sector Signature
|
||||
; ****************************************************************************
|
||||
|
||||
org 01feh
|
||||
SectorSignature:
|
||||
dw 0aa55h ; Boot Sector Signature
|
||||
|
||||
end
|
||||
|
288
DuetPkg/BootSector/bs16.asm
Normal file
288
DuetPkg/BootSector/bs16.asm
Normal file
@@ -0,0 +1,288 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006 - 2007, Intel Corporation
|
||||
;* All rights reserved. This program and the accompanying materials
|
||||
;* are licensed and made available under the terms and conditions of the BSD License
|
||||
;* which accompanies this distribution. The full text of the license may be found at
|
||||
;* http://opensource.org/licenses/bsd-license.php
|
||||
;*
|
||||
;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;*
|
||||
;* bs16.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.model small
|
||||
.stack
|
||||
.486p
|
||||
.code
|
||||
|
||||
FAT_DIRECTORY_ENTRY_SIZE EQU 020h
|
||||
FAT_DIRECTORY_ENTRY_SHIFT EQU 5
|
||||
BLOCK_SIZE EQU 0200h
|
||||
BLOCK_MASK EQU 01ffh
|
||||
BLOCK_SHIFT EQU 9
|
||||
; "EFILDR_____"
|
||||
LOADER_FILENAME_PART1 EQU 04c494645h ; "EFIL"
|
||||
LOADER_FILENAME_PART2 EQU 036315244h ; "DR16"
|
||||
LOADER_FILENAME_PART3 EQU 020202036h ; "6___"
|
||||
|
||||
org 0h
|
||||
Ia32Jump:
|
||||
jmp BootSectorEntryPoint ; JMP inst - 3 bytes
|
||||
nop
|
||||
|
||||
OemId db "INTEL " ; OemId - 8 bytes
|
||||
; BPB data below will be fixed by tool
|
||||
|
||||
SectorSize dw 0 ; Sector Size - 16 bits
|
||||
SectorsPerCluster db 0 ; Sector Per Cluster - 8 bits
|
||||
ReservedSectors dw 0 ; Reserved Sectors - 16 bits
|
||||
NoFats db 0 ; Number of FATs - 8 bits
|
||||
RootEntries dw 0 ; Root Entries - 16 bits
|
||||
Sectors dw 0 ; Number of Sectors - 16 bits
|
||||
Media db 0 ; Media - 8 bits - ignored
|
||||
SectorsPerFat dw 0 ; Sectors Per FAT - 16 bits
|
||||
SectorsPerTrack dw 0 ; Sectors Per Track - 16 bits - ignored
|
||||
Heads dw 0 ; Heads - 16 bits - ignored
|
||||
HiddenSectors dd 0 ; Hidden Sectors - 32 bits - ignored
|
||||
LargeSectors dd 0 ; Large Sectors - 32 bits
|
||||
PhysicalDrive db 0 ; PhysicalDriveNumber - 8 bits - ignored
|
||||
CurrentHead db 0 ; Current Head - 8 bits
|
||||
Signature db 0 ; Signature - 8 bits - ignored
|
||||
Id db " " ; Id - 4 bytes
|
||||
FatLabel db " " ; Label - 11 bytes
|
||||
SystemId db "FAT16 " ; SystemId - 8 bytes
|
||||
|
||||
BootSectorEntryPoint:
|
||||
ASSUME ds:@code
|
||||
ASSUME ss:@code
|
||||
|
||||
; ****************************************************************************
|
||||
; Start Print
|
||||
; ****************************************************************************
|
||||
lea si, cs:[StartString]
|
||||
call PrintString
|
||||
|
||||
; ****************************************************************************
|
||||
; Print over
|
||||
; ****************************************************************************
|
||||
|
||||
mov ax,cs ; ax = 0
|
||||
mov ss,ax ; ss = 0
|
||||
add ax,1000h
|
||||
mov ds,ax
|
||||
|
||||
mov sp,07c00h ; sp = 0x7c00
|
||||
mov bp,sp ; bp = 0x7c00
|
||||
|
||||
mov ah,8 ; ah = 8 - Get Drive Parameters Function
|
||||
mov byte ptr [bp+PhysicalDrive],dl ; BBS defines that BIOS would pass the booting driver number to the loader through DL
|
||||
int 13h ; Get Drive Parameters
|
||||
xor ax,ax ; ax = 0
|
||||
mov al,dh ; al = dh
|
||||
inc al ; MaxHead = al + 1
|
||||
push ax ; 0000:7bfe = MaxHead
|
||||
mov al,cl ; al = cl
|
||||
and al,03fh ; MaxSector = al & 0x3f
|
||||
push ax ; 0000:7bfc = MaxSector
|
||||
|
||||
cmp word ptr [bp+SectorSignature],0aa55h ; Verify Boot Sector Signature
|
||||
jne BadBootSector
|
||||
mov cx,word ptr [bp+RootEntries] ; cx = RootEntries
|
||||
shl cx,FAT_DIRECTORY_ENTRY_SHIFT ; cx = cx * 32 = cx * sizeof(FAT_DIRECTORY_ENTRY) = Size of Root Directory in bytes
|
||||
mov bx,cx ; bx = size of the Root Directory in bytes
|
||||
and bx,BLOCK_MASK ; See if it is an even number of sectors long
|
||||
jne BadBootSector ; If is isn't, then the boot sector is bad.
|
||||
mov bx,cx ; bx = size of the Root Directory in bytes
|
||||
shr bx,BLOCK_SHIFT ; bx = size of Root Directory in sectors
|
||||
mov al,byte ptr [bp+NoFats] ; al = NoFats
|
||||
xor ah,ah ; ah = 0 ==> ax = NoFats
|
||||
mul word ptr [bp+SectorsPerFat] ; ax = NoFats * SectorsPerFat
|
||||
add ax,word ptr [bp+ReservedSectors] ; ax = NoFats * SectorsPerFat + ReservedSectors = RootLBA
|
||||
push ds
|
||||
pop es
|
||||
xor di,di ; Store directory in es:di = 1000:0000
|
||||
call ReadBlocks ; Read entire Root Directory
|
||||
add ax,bx ; ax = NoFats * SectorsPerFat + ReservedSectors + RootDirSectors = FirstClusterLBA (FirstDataSector)
|
||||
mov word ptr [bp],ax ; Save FirstClusterLBA (FirstDataSector) for later use
|
||||
|
||||
; dx - variable storage (initial value is 0)
|
||||
; bx - loader (initial value is 0)
|
||||
xor dx, dx
|
||||
xor bx, bx
|
||||
|
||||
FindEFILDR:
|
||||
cmp dword ptr [di],LOADER_FILENAME_PART1 ; Compare to "EFIL"
|
||||
jne FindVARSTORE
|
||||
cmp dword ptr [di+4],LOADER_FILENAME_PART2
|
||||
jne FindVARSTORE
|
||||
cmp dword ptr [di+7],LOADER_FILENAME_PART3
|
||||
jne FindVARSTORE
|
||||
mov bx, word ptr [di+26] ; bx = Start Cluster for EFILDR <----------------------------------
|
||||
test dx, dx
|
||||
je FindNext ; Efivar.bin is not loaded
|
||||
jmp FoundAll
|
||||
|
||||
FindVARSTORE:
|
||||
; if the file is not loader file, see if it's "EFIVAR BIN"
|
||||
cmp dword ptr [di], 056494645h ; Compare to "EFIV"
|
||||
jne FindNext
|
||||
cmp dword ptr [di+4], 020205241h ; Compare to "AR "
|
||||
jne FindNext
|
||||
cmp dword ptr [di+7], 04e494220h ; Compare to " BIN"
|
||||
jne FindNext
|
||||
mov dx, di ; dx = Offset of Start Cluster for Efivar.bin <---------------------
|
||||
add dx, 26
|
||||
test bx, bx
|
||||
je FindNext ; Efildr is not loaded
|
||||
jmp FoundAll
|
||||
|
||||
FindNext:
|
||||
; go to next find
|
||||
add di,FAT_DIRECTORY_ENTRY_SIZE ; Increment di
|
||||
sub cx,FAT_DIRECTORY_ENTRY_SIZE ; Decrement cx
|
||||
; TODO: jump to FindVarStore if ...
|
||||
jne FindEFILDR
|
||||
jmp NotFoundAll
|
||||
|
||||
FoundAll:
|
||||
FoundEFILDR:
|
||||
mov cx,bx ; cx = Start Cluster for EFILDR <----------------------------------
|
||||
mov ax,cs ; Destination = 2000:0000
|
||||
add ax,2000h
|
||||
mov es,ax
|
||||
xor di,di
|
||||
ReadFirstClusterOfEFILDR:
|
||||
mov ax,cx ; ax = StartCluster
|
||||
sub ax,2 ; ax = StartCluster - 2
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster
|
||||
push dx
|
||||
mul bx
|
||||
pop dx ; ax = (StartCluster - 2) * SectorsPerCluster
|
||||
add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = Number of Sectors in a cluster
|
||||
push es
|
||||
call ReadBlocks
|
||||
pop ax
|
||||
JumpIntoFirstSectorOfEFILDR:
|
||||
mov word ptr [bp+JumpSegment],ax
|
||||
JumpFarInstruction:
|
||||
db 0eah
|
||||
JumpOffset:
|
||||
dw 0000h
|
||||
JumpSegment:
|
||||
dw 2000h
|
||||
|
||||
|
||||
PrintString:
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov ax, 07c0h
|
||||
mov ds, ax
|
||||
mov cx, 7
|
||||
mov di, 160
|
||||
rep movsw
|
||||
ret
|
||||
; ****************************************************************************
|
||||
; ReadBlocks - Reads a set of blocks from a block device
|
||||
;
|
||||
; AX = Start LBA
|
||||
; BX = Number of Blocks to Read
|
||||
; ES:DI = Buffer to store sectors read from disk
|
||||
; ****************************************************************************
|
||||
|
||||
; cx = Blocks
|
||||
; bx = NumberOfBlocks
|
||||
; si = StartLBA
|
||||
|
||||
ReadBlocks:
|
||||
pusha
|
||||
add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA
|
||||
add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA
|
||||
mov esi,eax ; esi = Start LBA
|
||||
mov cx,bx ; cx = Number of blocks to read
|
||||
ReadCylinderLoop:
|
||||
mov bp,07bfch ; bp = 0x7bfc
|
||||
mov eax,esi ; eax = Start LBA
|
||||
xor edx,edx ; edx = 0
|
||||
movzx ebx,word ptr [bp] ; bx = MaxSector
|
||||
div ebx ; ax = StartLBA / MaxSector
|
||||
inc dx ; dx = (StartLBA % MaxSector) + 1
|
||||
sub bx,dx ; bx = MaxSector - Sector
|
||||
inc bx ; bx = MaxSector - Sector + 1
|
||||
cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)
|
||||
jg LimitTransfer
|
||||
mov bx,cx ; bx = Blocks
|
||||
LimitTransfer:
|
||||
push cx
|
||||
mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector
|
||||
xor dx,dx ; dx = 0
|
||||
div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder
|
||||
; dx = ax % (MaxHead + 1) = Head
|
||||
|
||||
push bx ; Save number of blocks to transfer
|
||||
mov dh,dl ; dh = Head
|
||||
mov bp,07c00h ; bp = 0x7c00
|
||||
mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number
|
||||
mov ch,al ; ch = Cylinder
|
||||
mov al,bl ; al = Blocks
|
||||
mov ah,2 ; ah = Function 2
|
||||
mov bx,di ; es:bx = Buffer address
|
||||
int 013h
|
||||
jc DiskError
|
||||
pop bx
|
||||
pop cx
|
||||
movzx ebx,bx
|
||||
add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks
|
||||
sub cx,bx ; Blocks = Blocks - NumberOfBlocks
|
||||
mov ax,es
|
||||
shl bx,(BLOCK_SHIFT-4)
|
||||
add ax,bx
|
||||
mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE
|
||||
cmp cx,0
|
||||
jne ReadCylinderLoop
|
||||
popa
|
||||
ret
|
||||
|
||||
; ****************************************************************************
|
||||
; ERROR Condition:
|
||||
; ****************************************************************************
|
||||
NotFoundAll:
|
||||
; if we found EFILDR, continue
|
||||
test bx,bx
|
||||
jne FoundEFILDR
|
||||
BadBootSector:
|
||||
DiskError:
|
||||
lea si, cs:[ErrorString]
|
||||
call PrintString
|
||||
Halt:
|
||||
jmp Halt
|
||||
|
||||
StartString:
|
||||
db 'B', 0ch, 'S', 0ch, 't', 0ch, 'a', 0ch, 'r', 0ch, 't', 0ch, '!', 0ch
|
||||
ErrorString:
|
||||
db 'B', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
|
||||
|
||||
; ****************************************************************************
|
||||
; LBA Offset for BootSector, need patched by tool for HD boot.
|
||||
; ****************************************************************************
|
||||
|
||||
org 01fah
|
||||
LBAOffsetForBootSector:
|
||||
dd 0h
|
||||
|
||||
; ****************************************************************************
|
||||
; Sector Signature
|
||||
; ****************************************************************************
|
||||
|
||||
org 01feh
|
||||
SectorSignature:
|
||||
dw 0aa55h ; Boot Sector Signature
|
||||
|
||||
end
|
310
DuetPkg/BootSector/bs32.asm
Normal file
310
DuetPkg/BootSector/bs32.asm
Normal file
@@ -0,0 +1,310 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006 - 2007, Intel Corporation
|
||||
;* All rights reserved. This program and the accompanying materials
|
||||
;* are licensed and made available under the terms and conditions of the BSD License
|
||||
;* which accompanies this distribution. The full text of the license may be found at
|
||||
;* http://opensource.org/licenses/bsd-license.php
|
||||
;*
|
||||
;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;*
|
||||
;* bs32.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.model small
|
||||
.stack
|
||||
.486p
|
||||
.code
|
||||
|
||||
FAT_DIRECTORY_ENTRY_SIZE EQU 020h
|
||||
FAT_DIRECTORY_ENTRY_SHIFT EQU 5
|
||||
BLOCK_SIZE EQU 0200h
|
||||
BLOCK_MASK EQU 01ffh
|
||||
BLOCK_SHIFT EQU 9
|
||||
; "EFILDR_____"
|
||||
LOADER_FILENAME_PART1 EQU 04c494645h ; "EFIL"
|
||||
LOADER_FILENAME_PART2 EQU 030325244h ; "DR20"
|
||||
LOADER_FILENAME_PART3 EQU 020202030h ; "0___"
|
||||
|
||||
org 0h
|
||||
Ia32Jump:
|
||||
jmp BootSectorEntryPoint ; JMP inst - 3 bytes
|
||||
nop
|
||||
|
||||
OemId db "INTEL " ; OemId - 8 bytes
|
||||
; BPB data below will be fixed by tool
|
||||
|
||||
SectorSize dw 0 ; Sector Size - 16 bits
|
||||
SectorsPerCluster db 0 ; Sector Per Cluster - 8 bits
|
||||
ReservedSectors dw 0 ; Reserved Sectors - 16 bits
|
||||
NoFats db 0 ; Number of FATs - 8 bits
|
||||
RootEntries dw 0 ; Root Entries - 16 bits
|
||||
Sectors dw 0 ; Number of Sectors - 16 bits
|
||||
Media db 0 ; Media - 8 bits - ignored
|
||||
SectorsPerFat dw 0 ; Sectors Per FAT - 16 bits
|
||||
SectorsPerTrack dw 0 ; Sectors Per Track - 16 bits - ignored
|
||||
Heads dw 0 ; Heads - 16 bits - ignored
|
||||
HiddenSectors dd 0 ; Hidden Sectors - 32 bits - ignored
|
||||
LargeSectors dd 0 ; Large Sectors - 32 bits
|
||||
|
||||
;******************************************************************************
|
||||
;
|
||||
;The structure for FAT32 starting at offset 36 of the boot sector. (At this point,
|
||||
;the BPB/boot sector for FAT12 and FAT16 differs from the BPB/boot sector for FAT32.)
|
||||
;
|
||||
;******************************************************************************
|
||||
|
||||
SectorsPerFat32 dd 0 ; Sectors Per FAT for FAT32 - 4 bytes
|
||||
ExtFlags dw 0 ; Mirror Flag - 2 bytes
|
||||
FSVersion dw 0 ; File System Version - 2 bytes
|
||||
RootCluster dd 0 ; 1st Cluster Number of Root Dir - 4 bytes
|
||||
FSInfo dw 0 ; Sector Number of FSINFO - 2 bytes
|
||||
BkBootSector dw 0 ; Sector Number of Bk BootSector - 2 bytes
|
||||
Reserved db 12 dup(0) ; Reserved Field - 12 bytes
|
||||
PhysicalDrive db 0 ; Physical Drive Number - 1 byte
|
||||
Reserved1 db 0 ; Reserved Field - 1 byte
|
||||
Signature db 0 ; Extended Boot Signature - 1 byte
|
||||
VolId db " " ; Volume Serial Number - 4 bytes
|
||||
FatLabel db " " ; Volume Label - 11 bytes
|
||||
FileSystemType db "FAT32 " ; File System Type - 8 bytes
|
||||
|
||||
BootSectorEntryPoint:
|
||||
ASSUME ds:@code
|
||||
ASSUME ss:@code
|
||||
|
||||
; ****************************************************************************
|
||||
; Start Print
|
||||
; ****************************************************************************
|
||||
lea si, cs:[StartString]
|
||||
call PrintString
|
||||
|
||||
; ****************************************************************************
|
||||
; Print over
|
||||
; ****************************************************************************
|
||||
|
||||
mov ax,cs ; ax = 0
|
||||
mov ss,ax ; ss = 0
|
||||
add ax,1000h
|
||||
mov ds,ax
|
||||
|
||||
mov sp,07c00h ; sp = 0x7c00
|
||||
mov bp,sp ; bp = 0x7c00
|
||||
|
||||
mov ah,8 ; ah = 8 - Get Drive Parameters Function
|
||||
mov byte ptr [bp+PhysicalDrive],dl ; BBS defines that BIOS would pass the booting driver number to the loader through DL
|
||||
int 13h ; Get Drive Parameters
|
||||
xor ax,ax ; ax = 0
|
||||
mov al,dh ; al = dh
|
||||
inc al ; MaxHead = al + 1
|
||||
push ax ; 0000:7bfe = MaxHead
|
||||
mov al,cl ; al = cl
|
||||
and al,03fh ; MaxSector = al & 0x3f
|
||||
push ax ; 0000:7bfc = MaxSector
|
||||
|
||||
cmp word ptr [bp+SectorSignature],0aa55h ; Verify Boot Sector Signature
|
||||
jne BadBootSector
|
||||
mov cx,word ptr [bp+RootEntries] ; cx = RootEntries
|
||||
shl cx,FAT_DIRECTORY_ENTRY_SHIFT ; cx = cx * 32 = cx * sizeof(FAT_DIRECTORY_ENTRY) = Size of Root Directory in bytes
|
||||
mov bx,cx ; bx = size of the Root Directory in bytes
|
||||
and bx,BLOCK_MASK ; See if it is an even number of sectors long
|
||||
jne BadBootSector ; If is isn't, then the boot sector is bad.
|
||||
mov bx,cx ; bx = size of the Root Directory in bytes
|
||||
shr bx,BLOCK_SHIFT ; bx = size of Root Directory in sectors
|
||||
mov al,byte ptr [bp+NoFats] ; al = NoFats
|
||||
xor ah,ah ; ah = 0 ==> ax = NoFats
|
||||
mul word ptr [bp+SectorsPerFat32] ; ax = NoFats * SectorsPerFat
|
||||
add ax,word ptr [bp+ReservedSectors] ; ax = NoFats * SectorsPerFat + ReservedSectors = RootLBA
|
||||
add ax,bx ; ax = NoFats * SectorsPerFat + ReservedSectors + RootDirSectors = FirstClusterLBA
|
||||
mov word ptr [bp],ax ; Save FirstClusterLBA for later use
|
||||
|
||||
mov ax,word ptr [bp+RootCluster] ; ax = StartCluster of Root Directory
|
||||
sub ax,2 ; ax = StartCluster - 2
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster]; bx = SectorsPerCluster
|
||||
mul bx ; ax = (StartCluster - 2) * SectorsPerCluster
|
||||
add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
|
||||
push ds
|
||||
pop es
|
||||
xor di,di ; Store directory in es:di = 1000:0000
|
||||
call ReadBlocks ; Read StartCluster of Root Directory
|
||||
|
||||
; dx - variable storage (initial value is 0)
|
||||
; bx - loader (initial value is 0)
|
||||
xor dx, dx
|
||||
xor bx, bx
|
||||
|
||||
FindEFILDR:
|
||||
cmp dword ptr [di],LOADER_FILENAME_PART1 ; Compare to "EFIL"
|
||||
jne FindVARSTORE
|
||||
cmp dword ptr [di+4],LOADER_FILENAME_PART2
|
||||
jne FindVARSTORE
|
||||
cmp dword ptr [di+7],LOADER_FILENAME_PART3
|
||||
jne FindVARSTORE
|
||||
mov bx, word ptr [di+26] ; bx = Start Cluster for EFILDR <----------------------------------
|
||||
test dx, dx
|
||||
je FindNext ; Efivar.bin is not loaded
|
||||
jmp FoundAll
|
||||
|
||||
FindVARSTORE:
|
||||
; if the file is not loader file, see if it's "EFIVAR BIN"
|
||||
cmp dword ptr [di], 056494645h ; Compare to "EFIV"
|
||||
jne FindNext
|
||||
cmp dword ptr [di+4], 020205241h ; Compare to "AR "
|
||||
jne FindNext
|
||||
cmp dword ptr [di+7], 04e494220h ; Compare to " BIN"
|
||||
jne FindNext
|
||||
mov dx, di ; dx = Offset of Start Cluster for Efivar.bin <---------------------
|
||||
add dx, 26
|
||||
test bx, bx
|
||||
je FindNext ; Efildr is not loaded
|
||||
jmp FoundAll
|
||||
|
||||
FindNext:
|
||||
; go to next find
|
||||
add di,FAT_DIRECTORY_ENTRY_SIZE ; Increment di
|
||||
sub cx,FAT_DIRECTORY_ENTRY_SIZE ; Decrement cx
|
||||
; TODO: jump to FindVarStore if ...
|
||||
jne FindEFILDR
|
||||
jmp NotFoundAll
|
||||
|
||||
FoundAll:
|
||||
FoundEFILDR:
|
||||
mov cx,bx ; cx = Start Cluster for EFILDR <----------------------------------
|
||||
mov ax,cs ; Destination = 2000:0000
|
||||
add ax,2000h
|
||||
mov es,ax
|
||||
xor di,di
|
||||
ReadFirstClusterOfEFILDR:
|
||||
mov ax,cx ; ax = StartCluster
|
||||
sub ax,2 ; ax = StartCluster - 2
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster
|
||||
push dx
|
||||
mul bx
|
||||
pop dx ; ax = (StartCluster - 2) * SectorsPerCluster
|
||||
add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = Number of Sectors in a cluster
|
||||
push es
|
||||
call ReadBlocks
|
||||
pop ax
|
||||
JumpIntoFirstSectorOfEFILDR:
|
||||
mov word ptr [bp+JumpSegment],ax
|
||||
JumpFarInstruction:
|
||||
db 0eah
|
||||
JumpOffset:
|
||||
dw 0000h
|
||||
JumpSegment:
|
||||
dw 2000h
|
||||
|
||||
|
||||
PrintString:
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov ax, 07c0h
|
||||
mov ds, ax
|
||||
mov cx, 7
|
||||
mov di, 160
|
||||
rep movsw
|
||||
ret
|
||||
; ****************************************************************************
|
||||
; ReadBlocks - Reads a set of blocks from a block device
|
||||
;
|
||||
; AX = Start LBA
|
||||
; BX = Number of Blocks to Read
|
||||
; ES:DI = Buffer to store sectors read from disk
|
||||
; ****************************************************************************
|
||||
|
||||
; cx = Blocks
|
||||
; bx = NumberOfBlocks
|
||||
; si = StartLBA
|
||||
|
||||
ReadBlocks:
|
||||
pusha
|
||||
add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA
|
||||
add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA
|
||||
mov esi,eax ; esi = Start LBA
|
||||
mov cx,bx ; cx = Number of blocks to read
|
||||
ReadCylinderLoop:
|
||||
mov bp,07bfch ; bp = 0x7bfc
|
||||
mov eax,esi ; eax = Start LBA
|
||||
xor edx,edx ; edx = 0
|
||||
movzx ebx,word ptr [bp] ; bx = MaxSector
|
||||
div ebx ; ax = StartLBA / MaxSector
|
||||
inc dx ; dx = (StartLBA % MaxSector) + 1
|
||||
sub bx,dx ; bx = MaxSector - Sector
|
||||
inc bx ; bx = MaxSector - Sector + 1
|
||||
cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)
|
||||
jg LimitTransfer
|
||||
mov bx,cx ; bx = Blocks
|
||||
LimitTransfer:
|
||||
push cx
|
||||
mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector
|
||||
xor dx,dx ; dx = 0
|
||||
div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder
|
||||
; dx = ax % (MaxHead + 1) = Head
|
||||
|
||||
push bx ; Save number of blocks to transfer
|
||||
mov dh,dl ; dh = Head
|
||||
mov bp,07c00h ; bp = 0x7c00
|
||||
mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number
|
||||
mov ch,al ; ch = Cylinder
|
||||
mov al,bl ; al = Blocks
|
||||
mov ah,2 ; ah = Function 2
|
||||
mov bx,di ; es:bx = Buffer address
|
||||
int 013h
|
||||
jc DiskError
|
||||
pop bx
|
||||
pop cx
|
||||
movzx ebx,bx
|
||||
add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks
|
||||
sub cx,bx ; Blocks = Blocks - NumberOfBlocks
|
||||
mov ax,es
|
||||
shl bx,(BLOCK_SHIFT-4)
|
||||
add ax,bx
|
||||
mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE
|
||||
cmp cx,0
|
||||
jne ReadCylinderLoop
|
||||
popa
|
||||
ret
|
||||
|
||||
; ****************************************************************************
|
||||
; ERROR Condition:
|
||||
; ****************************************************************************
|
||||
NotFoundAll:
|
||||
; if we found EFILDR, continue
|
||||
test bx,bx
|
||||
jne FoundEFILDR
|
||||
BadBootSector:
|
||||
DiskError:
|
||||
lea si, cs:[ErrorString]
|
||||
call PrintString
|
||||
Halt:
|
||||
jmp Halt
|
||||
|
||||
StartString:
|
||||
db 'B', 0ch, 'S', 0ch, 't', 0ch, 'a', 0ch, 'r', 0ch, 't', 0ch, '!', 0ch
|
||||
ErrorString:
|
||||
db 'B', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
|
||||
|
||||
; ****************************************************************************
|
||||
; LBA Offset for BootSector, need patched by tool for HD boot.
|
||||
; ****************************************************************************
|
||||
|
||||
org 01fah
|
||||
LBAOffsetForBootSector:
|
||||
dd 0h
|
||||
|
||||
; ****************************************************************************
|
||||
; Sector Signature
|
||||
; ****************************************************************************
|
||||
|
||||
org 01feh
|
||||
SectorSignature:
|
||||
dw 0aa55h ; Boot Sector Signature
|
||||
|
||||
end
|
581
DuetPkg/BootSector/efi32.asm
Normal file
581
DuetPkg/BootSector/efi32.asm
Normal file
@@ -0,0 +1,581 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006, Intel Corporation
|
||||
;* All rights reserved. This program and the accompanying materials
|
||||
;* are licensed and made available under the terms and conditions of the BSD License
|
||||
;* which accompanies this distribution. The full text of the license may be found at
|
||||
;* http://opensource.org/licenses/bsd-license.php
|
||||
;*
|
||||
;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;*
|
||||
;* efi32.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Now in 32-bit protected mode.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
.486
|
||||
.model flat
|
||||
.stack
|
||||
.code
|
||||
org 21000h
|
||||
|
||||
DEFAULT_HANDLER_SIZE EQU INT1 - INT0
|
||||
|
||||
JmpCommonIdtEntry macro
|
||||
; jmp commonIdtEntry - this must be hand coded to keep the assembler from
|
||||
; using a 8 bit reletive jump when the entries are
|
||||
; within 255 bytes of the common entry. This must
|
||||
; be done to maintain the consistency of the size
|
||||
; of entry points...
|
||||
db 0e9h ; jmp 16 bit relative
|
||||
dd commonIdtEntry - $ - 4 ; offset to jump to
|
||||
endm
|
||||
|
||||
|
||||
Start:
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
mov fs,ax
|
||||
mov gs,ax
|
||||
mov ss,ax
|
||||
mov esp,0001ffff0h
|
||||
|
||||
call ClearScreen
|
||||
|
||||
; Populate IDT with meaningful offsets for exception handlers...
|
||||
sidt fword ptr [Idtr] ; get fword address of IDT
|
||||
|
||||
mov eax, offset Halt
|
||||
mov ebx, eax ; use bx to copy 15..0 to descriptors
|
||||
shr eax, 16 ; use ax to copy 31..16 to descriptors
|
||||
mov ecx, 78h ; 78h IDT entries to initialize with unique entry points (exceptions)
|
||||
mov esi, [offset Idtr + 2]
|
||||
mov edi, [esi]
|
||||
|
||||
@@: ; loop through all IDT entries exception handlers and initialize to default handler
|
||||
mov word ptr [edi], bx ; write bits 15..0 of offset
|
||||
mov word ptr [edi+2], 20h ; SYS_CODE_SEL from GDT
|
||||
mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
|
||||
mov word ptr [edi+6], ax ; write bits 31..16 of offset
|
||||
add edi, 8 ; move up to next descriptor
|
||||
add bx, DEFAULT_HANDLER_SIZE ; move to next entry point
|
||||
loop @b ; loop back through again until all descriptors are initialized
|
||||
|
||||
;; at this point edi contains the offset of the descriptor for INT 20
|
||||
;; and bx contains the low 16 bits of the offset of the default handler
|
||||
;; so initialize all the rest of the descriptors with these two values...
|
||||
; mov ecx, 101 ; there are 100 descriptors left (INT 20 (14h) - INT 119 (77h)
|
||||
;@@: ; loop through all IDT entries exception handlers and initialize to default handler
|
||||
; mov word ptr [edi], bx ; write bits 15..0 of offset
|
||||
; mov word ptr [edi+2], 20h ; SYS_CODE_SEL from GDT
|
||||
; mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
|
||||
; mov word ptr [edi+6], ax ; write bits 31..16 of offset
|
||||
; add edi, 8 ; move up to next descriptor
|
||||
; loop @b ; loop back through again until all descriptors are initialized
|
||||
|
||||
|
||||
;; DUMP location of IDT and several of the descriptors
|
||||
; mov ecx, 8
|
||||
; mov eax, [offset Idtr + 2]
|
||||
; mov eax, [eax]
|
||||
; mov edi, 0b8000h
|
||||
; call PrintDword
|
||||
; mov esi, eax
|
||||
; mov edi, 0b80a0h
|
||||
; jmp OuterLoop
|
||||
|
||||
;;
|
||||
;; just for fun, let's do a software interrupt to see if we correctly land in the exception handler...
|
||||
; mov eax, 011111111h
|
||||
; mov ebx, 022222222h
|
||||
; mov ecx, 033333333h
|
||||
; mov edx, 044444444h
|
||||
; mov ebp, 055555555h
|
||||
; mov esi, 066666666h
|
||||
; mov edi, 077777777h
|
||||
; push 011111111h
|
||||
; push 022222222h
|
||||
; push 033333333h
|
||||
; int 119
|
||||
|
||||
|
||||
mov esi,022000h ; esi = 22000
|
||||
mov eax,[esi+014h] ; eax = [22014]
|
||||
add esi,eax ; esi = 22000 + [22014] = Base of EFILDR.C
|
||||
mov ebp,[esi+03ch] ; ebp = [22000 + [22014] + 3c] = NT Image Header for EFILDR.C
|
||||
add ebp,esi
|
||||
mov edi,[ebp+034h] ; edi = [[22000 + [22014] + 3c] + 30] = ImageBase
|
||||
mov eax,[ebp+028h] ; eax = [[22000 + [22014] + 3c] + 24] = EntryPoint
|
||||
add eax,edi ; eax = ImageBase + EntryPoint
|
||||
mov dword ptr [EfiLdrOffset],eax ; Modify far jump instruction for correct entry point
|
||||
|
||||
mov bx,word ptr[ebp+6] ; bx = Number of sections
|
||||
xor eax,eax
|
||||
mov ax,word ptr[ebp+014h] ; ax = Optional Header Size
|
||||
add ebp,eax
|
||||
add ebp,018h ; ebp = Start of 1st Section
|
||||
|
||||
SectionLoop:
|
||||
push esi ; Save Base of EFILDR.C
|
||||
push edi ; Save ImageBase
|
||||
add esi,[ebp+014h] ; esi = Base of EFILDR.C + PointerToRawData
|
||||
add edi,[ebp+00ch] ; edi = ImageBase + VirtualAddress
|
||||
mov ecx,[ebp+010h] ; ecs = SizeOfRawData
|
||||
|
||||
cld
|
||||
shr ecx,2
|
||||
rep movsd
|
||||
|
||||
pop edi ; Restore ImageBase
|
||||
pop esi ; Restore Base of EFILDR.C
|
||||
|
||||
add bp,028h ; ebp = ebp + 028h = Pointer to next section record
|
||||
dec bx
|
||||
cmp bx,0
|
||||
jne SectionLoop
|
||||
|
||||
movzx eax, word ptr [Idtr] ; get size of IDT
|
||||
inc eax
|
||||
add eax, dword ptr [Idtr + 2] ; add to base of IDT to get location of memory map...
|
||||
push eax ; push memory map location on stack for call to EFILDR...
|
||||
|
||||
push eax ; push return address (useless, just for stack balance)
|
||||
db 0b8h
|
||||
EfiLdrOffset:
|
||||
dd 000401000h ; Offset of EFILDR
|
||||
; mov eax, 401000h
|
||||
push eax
|
||||
ret
|
||||
|
||||
; db "**** DEFAULT IDT ENTRY ***",0
|
||||
align 02h
|
||||
Halt:
|
||||
INT0:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 0h
|
||||
JmpCommonIdtEntry
|
||||
; db 0e9h ; jmp 16 bit reletive
|
||||
; dd commonIdtEntry - $ - 4 ; offset to jump to
|
||||
|
||||
INT1:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 1h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT2:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 2h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT3:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 3h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT4:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 4h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT5:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 5h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT6:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 6h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT7:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 7h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT8:
|
||||
; Double fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 8h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT9:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 9h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT10:
|
||||
; Invalid TSS causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 10
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT11:
|
||||
; Segment Not Present causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 11
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT12:
|
||||
; Stack fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 12
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT13:
|
||||
; GP fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 13
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT14:
|
||||
; Page fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 14
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT15:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 15
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT16:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 16
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT17:
|
||||
; Alignment check causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 17
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT18:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 18
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT19:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 19
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INTUnknown:
|
||||
REPEAT (78h - 20)
|
||||
push 0h ; push error code place holder on the stack
|
||||
; push xxh ; push vector number
|
||||
db 06ah
|
||||
db ( $ - INTUnknown - 3 ) / 9 + 20 ; vector number
|
||||
JmpCommonIdtEntry
|
||||
ENDM
|
||||
|
||||
commonIdtEntry:
|
||||
pushad
|
||||
mov ebp, esp
|
||||
;;
|
||||
;; At this point the stack looks like this:
|
||||
;;
|
||||
;; eflags
|
||||
;; Calling CS
|
||||
;; Calling EIP
|
||||
;; Error code or 0
|
||||
;; Int num or 0ffh for unknown int num
|
||||
;; eax
|
||||
;; ecx
|
||||
;; edx
|
||||
;; ebx
|
||||
;; esp
|
||||
;; ebp
|
||||
;; esi
|
||||
;; edi <------- ESP, EBP
|
||||
;;
|
||||
|
||||
call ClearScreen
|
||||
mov esi, offset String1
|
||||
call PrintString
|
||||
mov eax, [ebp + 32] ;; move Int number into EAX
|
||||
cmp eax, 19
|
||||
ja PrintDefaultString
|
||||
PrintExceptionString:
|
||||
shl eax, 2 ;; multiply by 4 to get offset from StringTable to actual string address
|
||||
add eax, offset StringTable
|
||||
mov esi, [eax]
|
||||
jmp PrintTheString
|
||||
PrintDefaultString:
|
||||
mov esi, offset IntUnknownString
|
||||
; patch Int number
|
||||
mov edx, eax
|
||||
call A2C
|
||||
mov [esi + 1], al
|
||||
mov eax, edx
|
||||
shr eax, 4
|
||||
call A2C
|
||||
mov [esi], al
|
||||
PrintTheString:
|
||||
call PrintString
|
||||
mov esi, offset String2
|
||||
call PrintString
|
||||
mov eax, [ebp+44] ; CS
|
||||
call PrintDword
|
||||
mov al, ':'
|
||||
mov byte ptr [edi], al
|
||||
add edi, 2
|
||||
mov eax, [ebp+40] ; EIP
|
||||
call PrintDword
|
||||
mov esi, offset String3
|
||||
call PrintString
|
||||
|
||||
mov edi, 0b8140h
|
||||
|
||||
mov esi, offset StringEax ; eax
|
||||
call PrintString
|
||||
mov eax, [ebp+28]
|
||||
call PrintDword
|
||||
|
||||
mov esi, offset StringEbx ; ebx
|
||||
call PrintString
|
||||
mov eax, [ebp+16]
|
||||
call PrintDword
|
||||
|
||||
mov esi, offset StringEcx ; ecx
|
||||
call PrintString
|
||||
mov eax, [ebp+24]
|
||||
call PrintDword
|
||||
|
||||
mov esi, offset StringEdx ; edx
|
||||
call PrintString
|
||||
mov eax, [ebp+20]
|
||||
call PrintDword
|
||||
|
||||
mov esi, offset StringEcode ; error code
|
||||
call PrintString
|
||||
mov eax, [ebp+36]
|
||||
call PrintDword
|
||||
|
||||
mov edi, 0b81e0h
|
||||
|
||||
mov esi, offset StringEsp ; esp
|
||||
call PrintString
|
||||
mov eax, [ebp+12]
|
||||
call PrintDword
|
||||
|
||||
mov esi, offset StringEbp ; ebp
|
||||
call PrintString
|
||||
mov eax, [ebp+8]
|
||||
call PrintDword
|
||||
|
||||
mov esi, offset StringEsi ; esi
|
||||
call PrintString
|
||||
mov eax, [ebp+4]
|
||||
call PrintDword
|
||||
|
||||
mov esi, offset StringEdi ; edi
|
||||
call PrintString
|
||||
mov eax, [ebp]
|
||||
call PrintDword
|
||||
|
||||
mov esi, offset StringEflags ; eflags
|
||||
call PrintString
|
||||
mov eax, [ebp+48]
|
||||
call PrintDword
|
||||
|
||||
mov edi, 0b8320h
|
||||
|
||||
mov esi, ebp
|
||||
add esi, 52
|
||||
mov ecx, 8
|
||||
|
||||
|
||||
OuterLoop:
|
||||
push ecx
|
||||
mov ecx, 8
|
||||
mov edx, edi
|
||||
|
||||
InnerLoop:
|
||||
mov eax, [esi]
|
||||
call PrintDword
|
||||
add esi, 4
|
||||
mov al, ' '
|
||||
mov [edi], al
|
||||
add edi, 2
|
||||
loop InnerLoop
|
||||
|
||||
pop ecx
|
||||
add edx, 0a0h
|
||||
mov edi, edx
|
||||
loop OuterLoop
|
||||
|
||||
|
||||
mov edi, 0b8960h
|
||||
|
||||
mov eax, [ebp+40] ; EIP
|
||||
sub eax, 32 * 4
|
||||
mov esi, eax ; esi = eip - 32 DWORD linear (total 64 DWORD)
|
||||
|
||||
mov ecx, 8
|
||||
|
||||
OuterLoop1:
|
||||
push ecx
|
||||
mov ecx, 8
|
||||
mov edx, edi
|
||||
|
||||
InnerLoop1:
|
||||
mov eax, [esi]
|
||||
call PrintDword
|
||||
add esi, 4
|
||||
mov al, ' '
|
||||
mov [edi], al
|
||||
add edi, 2
|
||||
loop InnerLoop1
|
||||
|
||||
pop ecx
|
||||
add edx, 0a0h
|
||||
mov edi, edx
|
||||
loop OuterLoop1
|
||||
|
||||
|
||||
|
||||
; wbinvd ; Ken: this intruction does not support in early than 486 arch
|
||||
@@:
|
||||
jmp @b
|
||||
;
|
||||
; return
|
||||
;
|
||||
mov esp, ebp
|
||||
popad
|
||||
add esp, 8 ; error code and INT number
|
||||
|
||||
iretd
|
||||
|
||||
|
||||
PrintString:
|
||||
push eax
|
||||
@@:
|
||||
mov al, byte ptr [esi]
|
||||
cmp al, 0
|
||||
je @f
|
||||
mov byte ptr [edi], al
|
||||
inc esi
|
||||
add edi, 2
|
||||
jmp @b
|
||||
@@:
|
||||
pop eax
|
||||
ret
|
||||
|
||||
;; EAX contains dword to print
|
||||
;; EDI contains memory location (screen location) to print it to
|
||||
PrintDword:
|
||||
push ecx
|
||||
push ebx
|
||||
push eax
|
||||
|
||||
mov ecx, 8
|
||||
looptop:
|
||||
rol eax, 4
|
||||
mov bl, al
|
||||
and bl, 0fh
|
||||
add bl, '0'
|
||||
cmp bl, '9'
|
||||
jle @f
|
||||
add bl, 7
|
||||
@@:
|
||||
mov byte ptr [edi], bl
|
||||
add edi, 2
|
||||
loop looptop
|
||||
wbinvd
|
||||
|
||||
pop eax
|
||||
pop ebx
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
ClearScreen:
|
||||
push eax
|
||||
push ecx
|
||||
|
||||
mov al, ' '
|
||||
mov ah, 0ch
|
||||
mov edi, 0b8000h
|
||||
mov ecx, 80 * 24
|
||||
@@:
|
||||
mov word ptr [edi], ax
|
||||
add edi, 2
|
||||
loop @b
|
||||
mov edi, 0b8000h
|
||||
|
||||
pop ecx
|
||||
pop eax
|
||||
|
||||
ret
|
||||
|
||||
A2C:
|
||||
and al, 0fh
|
||||
add al, '0'
|
||||
cmp al, '9'
|
||||
jle @f
|
||||
add al, 7
|
||||
@@:
|
||||
ret
|
||||
|
||||
String1 db "*** INT ",0
|
||||
|
||||
Int0String db "00h Divide by 0 -",0
|
||||
Int1String db "01h Debug exception -",0
|
||||
Int2String db "02h NMI -",0
|
||||
Int3String db "03h Breakpoint -",0
|
||||
Int4String db "04h Overflow -",0
|
||||
Int5String db "05h Bound -",0
|
||||
Int6String db "06h Invalid opcode -",0
|
||||
Int7String db "07h Device not available -",0
|
||||
Int8String db "08h Double fault -",0
|
||||
Int9String db "09h Coprocessor seg overrun (reserved) -",0
|
||||
Int10String db "0Ah Invalid TSS -",0
|
||||
Int11String db "0Bh Segment not present -",0
|
||||
Int12String db "0Ch Stack fault -",0
|
||||
Int13String db "0Dh General protection fault -",0
|
||||
Int14String db "0Eh Page fault -",0
|
||||
Int15String db "0Fh (Intel reserved) -",0
|
||||
Int16String db "10h Floating point error -",0
|
||||
Int17String db "11h Alignment check -",0
|
||||
Int18String db "12h Machine check -",0
|
||||
Int19String db "13h SIMD Floating-Point Exception -",0
|
||||
IntUnknownString db "??h Unknown interrupt -",0
|
||||
|
||||
StringTable dd offset Int0String, offset Int1String, offset Int2String, offset Int3String,
|
||||
offset Int4String, offset Int5String, offset Int6String, offset Int7String,
|
||||
offset Int8String, offset Int9String, offset Int10String, offset Int11String,
|
||||
offset Int12String, offset Int13String, offset Int14String, offset Int15String,
|
||||
offset Int16String, offset Int17String, offset Int18String, offset Int19String
|
||||
|
||||
String2 db " HALT!! *** (",0
|
||||
String3 db ")",0
|
||||
StringEax db "EAX=",0
|
||||
StringEbx db " EBX=",0
|
||||
StringEcx db " ECX=",0
|
||||
StringEdx db " EDX=",0
|
||||
StringEcode db " ECODE=",0
|
||||
StringEsp db "ESP=",0
|
||||
StringEbp db " EBP=",0
|
||||
StringEsi db " ESI=",0
|
||||
StringEdi db " EDI=",0
|
||||
StringEflags db " EFLAGS=",0
|
||||
|
||||
Idtr df 0
|
||||
|
||||
org 21ffeh
|
||||
BlockSignature:
|
||||
dw 0aa55h
|
||||
|
||||
end
|
787
DuetPkg/BootSector/efi64.asm
Normal file
787
DuetPkg/BootSector/efi64.asm
Normal file
@@ -0,0 +1,787 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006, Intel Corporation
|
||||
;* All rights reserved. This program and the accompanying materials
|
||||
;* are licensed and made available under the terms and conditions of the BSD License
|
||||
;* which accompanies this distribution. The full text of the license may be found at
|
||||
;* http://opensource.org/licenses/bsd-license.php
|
||||
;*
|
||||
;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;*
|
||||
;* efi64.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Now in 64-bit long mode.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
.486
|
||||
.model flat
|
||||
.stack
|
||||
.code
|
||||
org 21000h
|
||||
|
||||
DEFAULT_HANDLER_SIZE EQU INT1 - INT0
|
||||
|
||||
JmpCommonIdtEntry macro
|
||||
; jmp commonIdtEntry - this must be hand coded to keep the assembler from
|
||||
; using a 8 bit reletive jump when the entries are
|
||||
; within 255 bytes of the common entry. This must
|
||||
; be done to maintain the consistency of the size
|
||||
; of entry points...
|
||||
db 0e9h ; jmp 16 bit reletive
|
||||
dd commonIdtEntry - $ - 4 ; offset to jump to
|
||||
endm
|
||||
|
||||
|
||||
Start:
|
||||
|
||||
mov esp,0001fffe8h ; make final stack aligned
|
||||
|
||||
; set OSFXSR and OSXMMEXCPT because some code will use XMM register
|
||||
db 0fh
|
||||
db 20h
|
||||
db 0e0h
|
||||
; mov rax, cr4
|
||||
bts eax, 9
|
||||
bts eax, 0ah
|
||||
db 0fh
|
||||
db 22h
|
||||
db 0e0h
|
||||
; mov cr4, rax
|
||||
|
||||
call ClearScreen
|
||||
|
||||
; Populate IDT with meaningful offsets for exception handlers...
|
||||
mov eax, offset Idtr
|
||||
sidt fword ptr [eax] ; get fword address of IDT
|
||||
|
||||
mov eax, offset Halt
|
||||
mov ebx, eax ; use bx to copy 15..0 to descriptors
|
||||
shr eax, 16 ; use ax to copy 31..16 to descriptors
|
||||
; 63..32 of descriptors is 0
|
||||
mov ecx, 78h ; 78h IDT entries to initialize with unique entry points (exceptions)
|
||||
mov esi, [offset Idtr + 2]
|
||||
mov edi, [esi]
|
||||
|
||||
@@: ; loop through all IDT entries exception handlers and initialize to default handler
|
||||
mov word ptr [edi], bx ; write bits 15..0 of offset
|
||||
mov word ptr [edi+2], 38h ; SYS_CODE64_SEL from GDT
|
||||
mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
|
||||
mov word ptr [edi+6], ax ; write bits 31..16 of offset
|
||||
mov dword ptr [edi+8], 0 ; write bits 63..32 of offset
|
||||
add edi, 16 ; move up to next descriptor
|
||||
add bx, DEFAULT_HANDLER_SIZE ; move to next entry point
|
||||
loop @b ; loop back through again until all descriptors are initialized
|
||||
|
||||
;; at this point edi contains the offset of the descriptor for INT 20
|
||||
;; and bx contains the low 16 bits of the offset of the default handler
|
||||
;; so initialize all the rest of the descriptors with these two values...
|
||||
; mov ecx, 101 ; there are 100 descriptors left (INT 20 (14h) - INT 119 (77h)
|
||||
;@@: ; loop through all IDT entries exception handlers and initialize to default handler
|
||||
; mov word ptr [edi], bx ; write bits 15..0 of offset
|
||||
; mov word ptr [edi+2], 38h ; SYS_CODE64_SEL from GDT
|
||||
; mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
|
||||
; mov word ptr [edi+6], ax ; write bits 31..16 of offset
|
||||
; mov dword ptr [edi+8], 0 ; write bits 63..32 of offset
|
||||
; add edi, 16 ; move up to next descriptor
|
||||
; loop @b ; loop back through again until all descriptors are initialized
|
||||
|
||||
|
||||
;; DUMP location of IDT and several of the descriptors
|
||||
; mov ecx, 8
|
||||
; mov eax, [offset Idtr + 2]
|
||||
; mov eax, [eax]
|
||||
; mov edi, 0b8000h
|
||||
; call PrintQword
|
||||
; mov esi, eax
|
||||
; mov edi, 0b80a0h
|
||||
; jmp OuterLoop
|
||||
|
||||
;;
|
||||
;; just for fun, let's do a software interrupt to see if we correctly land in the exception handler...
|
||||
; mov eax, 011111111h
|
||||
; mov ebx, 022222222h
|
||||
; mov ecx, 033333333h
|
||||
; mov edx, 044444444h
|
||||
; mov ebp, 055555555h
|
||||
; mov esi, 066666666h
|
||||
; mov edi, 077777777h
|
||||
; push 011111111h
|
||||
; push 022222222h
|
||||
; push 033333333h
|
||||
; int 119
|
||||
|
||||
mov esi,022000h ; esi = 22000
|
||||
mov eax,[esi+014h] ; eax = [22014]
|
||||
add esi,eax ; esi = 22000 + [22014] = Base of EFILDR.C
|
||||
mov ebp,[esi+03ch] ; ebp = [22000 + [22014] + 3c] = NT Image Header for EFILDR.C
|
||||
add ebp,esi
|
||||
mov edi,[ebp+030h] ; edi = [[22000 + [22014] + 3c] + 2c] = ImageBase (63..32 is zero, ignore)
|
||||
mov eax,[ebp+028h] ; eax = [[22000 + [22014] + 3c] + 24] = EntryPoint
|
||||
add eax,edi ; eax = ImageBase + EntryPoint
|
||||
mov ebx, offset EfiLdrOffset
|
||||
mov dword ptr [ebx],eax ; Modify far jump instruction for correct entry point
|
||||
|
||||
mov bx,word ptr[ebp+6] ; bx = Number of sections
|
||||
xor eax,eax
|
||||
mov ax,word ptr[ebp+014h] ; ax = Optional Header Size
|
||||
add ebp,eax
|
||||
add ebp,018h ; ebp = Start of 1st Section
|
||||
|
||||
SectionLoop:
|
||||
push esi ; Save Base of EFILDR.C
|
||||
push edi ; Save ImageBase
|
||||
add esi,[ebp+014h] ; esi = Base of EFILDR.C + PointerToRawData
|
||||
add edi,[ebp+00ch] ; edi = ImageBase + VirtualAddress
|
||||
mov ecx,[ebp+010h] ; ecs = SizeOfRawData
|
||||
|
||||
cld
|
||||
shr ecx,2
|
||||
rep movsd
|
||||
|
||||
pop edi ; Restore ImageBase
|
||||
pop esi ; Restore Base of EFILDR.C
|
||||
|
||||
add bp,028h ; ebp = ebp + 028h = Pointer to next section record
|
||||
db 66h
|
||||
db 0ffh
|
||||
db 0cbh
|
||||
; dec bx
|
||||
cmp bx,0
|
||||
jne SectionLoop
|
||||
|
||||
mov edx, offset Idtr
|
||||
movzx eax, word ptr [edx] ; get size of IDT
|
||||
db 0ffh
|
||||
db 0c0h
|
||||
; inc eax
|
||||
add eax, dword ptr [edx + 2] ; add to base of IDT to get location of memory map...
|
||||
xor ecx, ecx
|
||||
mov ecx, eax ; put argument to RCX
|
||||
|
||||
db 48h
|
||||
db 0c7h
|
||||
db 0c0h
|
||||
EfiLdrOffset:
|
||||
dd 000401000h ; Offset of EFILDR
|
||||
; mov rax, 401000h
|
||||
db 50h
|
||||
; push rax
|
||||
|
||||
; ret
|
||||
db 0c3h
|
||||
|
||||
; db "**** DEFAULT IDT ENTRY ***",0
|
||||
align 02h
|
||||
Halt:
|
||||
INT0:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 0h
|
||||
JmpCommonIdtEntry
|
||||
; db 0e9h ; jmp 16 bit reletive
|
||||
; dd commonIdtEntry - $ - 4 ; offset to jump to
|
||||
|
||||
INT1:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 1h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT2:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 2h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT3:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 3h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT4:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 4h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT5:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 5h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT6:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 6h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT7:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 7h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT8:
|
||||
; Double fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 8h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT9:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 9h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT10:
|
||||
; Invalid TSS causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 10
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT11:
|
||||
; Segment Not Present causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 11
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT12:
|
||||
; Stack fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 12
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT13:
|
||||
; GP fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 13
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT14:
|
||||
; Page fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 14
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT15:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 15
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT16:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 16
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT17:
|
||||
; Alignment check causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 17
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT18:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 18
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT19:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 19
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INTUnknown:
|
||||
REPEAT (78h - 20)
|
||||
push 0h ; push error code place holder on the stack
|
||||
; push xxh ; push vector number
|
||||
db 06ah
|
||||
db ( $ - INTUnknown - 3 ) / 9 + 20 ; vector number
|
||||
JmpCommonIdtEntry
|
||||
ENDM
|
||||
|
||||
commonIdtEntry:
|
||||
push eax
|
||||
push ecx
|
||||
push edx
|
||||
push ebx
|
||||
push esp
|
||||
push ebp
|
||||
push esi
|
||||
push edi
|
||||
db 41h
|
||||
db 50h
|
||||
; push r8
|
||||
db 41h
|
||||
db 51h
|
||||
; push r9
|
||||
db 41h
|
||||
db 52h
|
||||
; push r10
|
||||
db 41h
|
||||
db 53h
|
||||
; push r11
|
||||
db 41h
|
||||
db 54h
|
||||
; push r12
|
||||
db 41h
|
||||
db 55h
|
||||
; push r13
|
||||
db 41h
|
||||
db 56h
|
||||
; push r14
|
||||
db 41h
|
||||
db 57h
|
||||
; push r15
|
||||
db 48h
|
||||
mov ebp, esp
|
||||
; mov rbp, rsp
|
||||
|
||||
;;
|
||||
;; At this point the stack looks like this:
|
||||
;;
|
||||
;; Calling SS
|
||||
;; Calling RSP
|
||||
;; rflags
|
||||
;; Calling CS
|
||||
;; Calling RIP
|
||||
;; Error code or 0
|
||||
;; Int num or 0ffh for unknown int num
|
||||
;; rax
|
||||
;; rcx
|
||||
;; rdx
|
||||
;; rbx
|
||||
;; rsp
|
||||
;; rbp
|
||||
;; rsi
|
||||
;; rdi
|
||||
;; r8
|
||||
;; r9
|
||||
;; r10
|
||||
;; r11
|
||||
;; r12
|
||||
;; r13
|
||||
;; r14
|
||||
;; r15 <------- RSP, RBP
|
||||
;;
|
||||
|
||||
call ClearScreen
|
||||
mov esi, offset String1
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp + 16*8] ;; move Int number into RAX
|
||||
db 48h
|
||||
cmp eax, 18
|
||||
ja PrintDefaultString
|
||||
PrintExceptionString:
|
||||
shl eax, 3 ;; multiply by 8 to get offset from StringTable to actual string address
|
||||
add eax, offset StringTable
|
||||
mov esi, [eax]
|
||||
jmp PrintTheString
|
||||
PrintDefaultString:
|
||||
mov esi, offset IntUnknownString
|
||||
; patch Int number
|
||||
mov edx, eax
|
||||
call A2C
|
||||
mov [esi + 1], al
|
||||
mov eax, edx
|
||||
shr eax, 4
|
||||
call A2C
|
||||
mov [esi], al
|
||||
PrintTheString:
|
||||
call PrintString
|
||||
mov esi, offset String2
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+19*8] ; CS
|
||||
call PrintQword
|
||||
mov al, ':'
|
||||
mov byte ptr [edi], al
|
||||
add edi, 2
|
||||
db 48h
|
||||
mov eax, [ebp+18*8] ; RIP
|
||||
call PrintQword
|
||||
mov esi, offset String3
|
||||
call PrintString
|
||||
|
||||
mov edi, 0b8140h
|
||||
|
||||
mov esi, offset StringRax ; rax
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+15*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringRcx ; rcx
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+14*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringRdx ; rdx
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+13*8]
|
||||
call PrintQword
|
||||
|
||||
mov edi, 0b81e0h
|
||||
|
||||
mov esi, offset StringRbx ; rbx
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+12*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringRsp ; rsp
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+21*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringRbp ; rbp
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+10*8]
|
||||
call PrintQword
|
||||
|
||||
mov edi, 0b8280h
|
||||
|
||||
mov esi, offset StringRsi ; rsi
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+9*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringRdi ; rdi
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+8*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringEcode ; error code
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+17*8]
|
||||
call PrintQword
|
||||
|
||||
mov edi, 0b8320h
|
||||
|
||||
mov esi, offset StringR8 ; r8
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+7*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringR9 ; r9
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+6*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringR10 ; r10
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+5*8]
|
||||
call PrintQword
|
||||
|
||||
mov edi, 0b83c0h
|
||||
|
||||
mov esi, offset StringR11 ; r11
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+4*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringR12 ; r12
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+3*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringR13 ; r13
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+2*8]
|
||||
call PrintQword
|
||||
|
||||
mov edi, 0b8460h
|
||||
|
||||
mov esi, offset StringR14 ; r14
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+1*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringR15 ; r15
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+0*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringSs ; ss
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+22*8]
|
||||
call PrintQword
|
||||
|
||||
mov edi, 0b8500h
|
||||
|
||||
mov esi, offset StringRflags ; rflags
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+20*8]
|
||||
call PrintQword
|
||||
|
||||
mov edi, 0b8640h
|
||||
|
||||
mov esi, ebp
|
||||
add esi, 23*8
|
||||
mov ecx, 4
|
||||
|
||||
|
||||
OuterLoop:
|
||||
push ecx
|
||||
mov ecx, 4
|
||||
db 48h
|
||||
mov edx, edi
|
||||
|
||||
InnerLoop:
|
||||
db 48h
|
||||
mov eax, [esi]
|
||||
call PrintQword
|
||||
add esi, 8
|
||||
mov al, ' '
|
||||
mov [edi], al
|
||||
add edi, 2
|
||||
loop InnerLoop
|
||||
|
||||
pop ecx
|
||||
add edx, 0a0h
|
||||
mov edi, edx
|
||||
loop OuterLoop
|
||||
|
||||
|
||||
mov edi, 0b8960h
|
||||
|
||||
db 48h
|
||||
mov eax, [ebp+18*8] ; RIP
|
||||
sub eax, 8 * 8
|
||||
db 48h
|
||||
mov esi, eax ; esi = rip - 8 QWORD linear (total 16 QWORD)
|
||||
|
||||
mov ecx, 4
|
||||
|
||||
OuterLoop1:
|
||||
push ecx
|
||||
mov ecx, 4
|
||||
mov edx, edi
|
||||
|
||||
InnerLoop1:
|
||||
db 48h
|
||||
mov eax, [esi]
|
||||
call PrintQword
|
||||
add esi, 8
|
||||
mov al, ' '
|
||||
mov [edi], al
|
||||
add edi, 2
|
||||
loop InnerLoop1
|
||||
|
||||
pop ecx
|
||||
add edx, 0a0h
|
||||
mov edi, edx
|
||||
loop OuterLoop1
|
||||
|
||||
|
||||
|
||||
wbinvd
|
||||
@@:
|
||||
jmp @b
|
||||
|
||||
;
|
||||
; return
|
||||
;
|
||||
mov esp, ebp
|
||||
; mov rsp, rbp
|
||||
db 41h
|
||||
db 5fh
|
||||
; pop r15
|
||||
db 41h
|
||||
db 5eh
|
||||
; pop r14
|
||||
db 41h
|
||||
db 5dh
|
||||
; pop r13
|
||||
db 41h
|
||||
db 5ch
|
||||
; pop r12
|
||||
db 41h
|
||||
db 5bh
|
||||
; pop r11
|
||||
db 41h
|
||||
db 5ah
|
||||
; pop r10
|
||||
db 41h
|
||||
db 59h
|
||||
; pop r9
|
||||
db 41h
|
||||
db 58h
|
||||
; pop r8
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebp
|
||||
pop eax ; esp
|
||||
pop ebx
|
||||
pop edx
|
||||
pop ecx
|
||||
pop eax
|
||||
|
||||
db 48h
|
||||
db 83h
|
||||
db 0c4h
|
||||
db 10h
|
||||
; add esp, 16 ; error code and INT number
|
||||
|
||||
db 48h
|
||||
db 0cfh
|
||||
; iretq
|
||||
|
||||
PrintString:
|
||||
push eax
|
||||
@@:
|
||||
mov al, byte ptr [esi]
|
||||
cmp al, 0
|
||||
je @f
|
||||
mov byte ptr [edi], al
|
||||
db 0ffh
|
||||
db 0c6h
|
||||
; inc esi
|
||||
add edi, 2
|
||||
jmp @b
|
||||
@@:
|
||||
pop eax
|
||||
ret
|
||||
|
||||
;; RAX contains qword to print
|
||||
;; RDI contains memory location (screen location) to print it to
|
||||
PrintQword:
|
||||
push ecx
|
||||
push ebx
|
||||
push eax
|
||||
|
||||
db 48h
|
||||
db 0c7h
|
||||
db 0c1h
|
||||
dd 16
|
||||
; mov rcx, 16
|
||||
looptop:
|
||||
db 48h
|
||||
rol eax, 4
|
||||
mov bl, al
|
||||
and bl, 0fh
|
||||
add bl, '0'
|
||||
cmp bl, '9'
|
||||
jle @f
|
||||
add bl, 7
|
||||
@@:
|
||||
mov byte ptr [edi], bl
|
||||
add edi, 2
|
||||
loop looptop
|
||||
wbinvd
|
||||
|
||||
pop eax
|
||||
pop ebx
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
ClearScreen:
|
||||
push eax
|
||||
push ecx
|
||||
|
||||
mov al, ' '
|
||||
mov ah, 0ch
|
||||
mov edi, 0b8000h
|
||||
mov ecx, 80 * 24
|
||||
@@:
|
||||
mov word ptr [edi], ax
|
||||
add edi, 2
|
||||
loop @b
|
||||
mov edi, 0b8000h
|
||||
|
||||
pop ecx
|
||||
pop eax
|
||||
|
||||
ret
|
||||
|
||||
A2C:
|
||||
and al, 0fh
|
||||
add al, '0'
|
||||
cmp al, '9'
|
||||
jle @f
|
||||
add al, 7
|
||||
@@:
|
||||
ret
|
||||
|
||||
String1 db "*** INT ",0
|
||||
|
||||
Int0String db "00h Divide by 0 -",0
|
||||
Int1String db "01h Debug exception -",0
|
||||
Int2String db "02h NMI -",0
|
||||
Int3String db "03h Breakpoint -",0
|
||||
Int4String db "04h Overflow -",0
|
||||
Int5String db "05h Bound -",0
|
||||
Int6String db "06h Invalid opcode -",0
|
||||
Int7String db "07h Device not available -",0
|
||||
Int8String db "08h Double fault -",0
|
||||
Int9String db "09h Coprocessor seg overrun (reserved) -",0
|
||||
Int10String db "0Ah Invalid TSS -",0
|
||||
Int11String db "0Bh Segment not present -",0
|
||||
Int12String db "0Ch Stack fault -",0
|
||||
Int13String db "0Dh General protection fault -",0
|
||||
Int14String db "0Eh Page fault -",0
|
||||
Int15String db "0Fh (Intel reserved) -",0
|
||||
Int16String db "10h Floating point error -",0
|
||||
Int17String db "11h Alignment check -",0
|
||||
Int18String db "12h Machine check -",0
|
||||
Int19String db "13h SIMD Floating-Point Exception -",0
|
||||
IntUnknownString db "??h Unknown interrupt -",0
|
||||
|
||||
StringTable dq offset Int0String, offset Int1String, offset Int2String, offset Int3String,
|
||||
offset Int4String, offset Int5String, offset Int6String, offset Int7String,
|
||||
offset Int8String, offset Int9String, offset Int10String, offset Int11String,
|
||||
offset Int12String, offset Int13String, offset Int14String, offset Int15String,
|
||||
offset Int16String, offset Int17String, offset Int18String, offset Int19String
|
||||
|
||||
String2 db " HALT!! *** (",0
|
||||
String3 db ")",0
|
||||
StringRax db "RAX=",0
|
||||
StringRcx db " RCX=",0
|
||||
StringRdx db " RDX=",0
|
||||
StringRbx db "RBX=",0
|
||||
StringRsp db " RSP=",0
|
||||
StringRbp db " RBP=",0
|
||||
StringRsi db "RSI=",0
|
||||
StringRdi db " RDI=",0
|
||||
StringEcode db " ECODE=",0
|
||||
StringR8 db "R8 =",0
|
||||
StringR9 db " R9 =",0
|
||||
StringR10 db " R10=",0
|
||||
StringR11 db "R11=",0
|
||||
StringR12 db " R12=",0
|
||||
StringR13 db " R13=",0
|
||||
StringR14 db "R14=",0
|
||||
StringR15 db " R15=",0
|
||||
StringSs db " SS =",0
|
||||
StringRflags db "RFLAGS=",0
|
||||
|
||||
Idtr df 0
|
||||
df 0
|
||||
|
||||
org 21ffeh
|
||||
BlockSignature:
|
||||
dw 0aa55h
|
||||
|
||||
end
|
1140
DuetPkg/BootSector/st16_64.asm
Normal file
1140
DuetPkg/BootSector/st16_64.asm
Normal file
File diff suppressed because it is too large
Load Diff
1156
DuetPkg/BootSector/st32_64.asm
Normal file
1156
DuetPkg/BootSector/st32_64.asm
Normal file
File diff suppressed because it is too large
Load Diff
921
DuetPkg/BootSector/start.asm
Normal file
921
DuetPkg/BootSector/start.asm
Normal file
@@ -0,0 +1,921 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006 - 2007, Intel Corporation
|
||||
;* All rights reserved. This program and the accompanying materials
|
||||
;* are licensed and made available under the terms and conditions of the BSD License
|
||||
;* which accompanies this distribution. The full text of the license may be found at
|
||||
;* http://opensource.org/licenses/bsd-license.php
|
||||
;*
|
||||
;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;*
|
||||
;* start.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.model small
|
||||
.stack
|
||||
.486p
|
||||
.code
|
||||
|
||||
FAT_DIRECTORY_ENTRY_SIZE EQU 020h
|
||||
FAT_DIRECTORY_ENTRY_SHIFT EQU 5
|
||||
BLOCK_SIZE EQU 0200h
|
||||
BLOCK_MASK EQU 01ffh
|
||||
BLOCK_SHIFT EQU 9
|
||||
|
||||
org 0h
|
||||
Ia32Jump:
|
||||
jmp BootSectorEntryPoint ; JMP inst - 3 bytes
|
||||
nop
|
||||
|
||||
OemId db "INTEL " ; OemId - 8 bytes
|
||||
|
||||
SectorSize dw 0 ; Sector Size - 16 bits
|
||||
SectorsPerCluster db 0 ; Sector Per Cluster - 8 bits
|
||||
ReservedSectors dw 0 ; Reserved Sectors - 16 bits
|
||||
NoFats db 0 ; Number of FATs - 8 bits
|
||||
RootEntries dw 0 ; Root Entries - 16 bits
|
||||
Sectors dw 0 ; Number of Sectors - 16 bits
|
||||
Media db 0 ; Media - 8 bits - ignored
|
||||
SectorsPerFat dw 0 ; Sectors Per FAT - 16 bits
|
||||
SectorsPerTrack dw 0 ; Sectors Per Track - 16 bits - ignored
|
||||
Heads dw 0 ; Heads - 16 bits - ignored
|
||||
HiddenSectors dd 0 ; Hidden Sectors - 32 bits - ignored
|
||||
LargeSectors dd 0 ; Large Sectors - 32 bits
|
||||
PhysicalDrive db 0 ; PhysicalDriveNumber - 8 bits - ignored
|
||||
CurrentHead db 0 ; Current Head - 8 bits
|
||||
Signature db 0 ; Signature - 8 bits - ignored
|
||||
VolId db " " ; Volume Serial Number- 4 bytes
|
||||
FatLabel db " " ; Label - 11 bytes
|
||||
SystemId db "FAT12 " ; SystemId - 8 bytes
|
||||
|
||||
BootSectorEntryPoint:
|
||||
ASSUME ds:@code
|
||||
ASSUME ss:@code
|
||||
; ds = 1000, es = 2000 + x (size of first cluster >> 4)
|
||||
; cx = Start Cluster of EfiLdr
|
||||
; dx = Start Cluster of Efivar.bin
|
||||
|
||||
; Re use the BPB data stored in Boot Sector
|
||||
mov bp,07c00h
|
||||
|
||||
push cx
|
||||
; Read Efivar.bin
|
||||
; 1000:dx = DirectoryEntry of Efivar.bin -> BS.com has filled already
|
||||
mov ax,01900h
|
||||
mov es,ax
|
||||
test dx,dx
|
||||
jnz CheckVarStoreSize
|
||||
|
||||
mov al,1
|
||||
NoVarStore:
|
||||
push es
|
||||
; Set the 5th byte start @ 0:19000 to non-zero indicating we should init var store header in DxeIpl
|
||||
mov byte ptr es:[4],al
|
||||
jmp SaveVolumeId
|
||||
|
||||
CheckVarStoreSize:
|
||||
mov di,dx
|
||||
cmp dword ptr ds:[di+2], 04000h
|
||||
mov al,2
|
||||
jne NoVarStore
|
||||
|
||||
LoadVarStore:
|
||||
mov al,0
|
||||
mov byte ptr es:[4],al
|
||||
mov cx,word ptr[di]
|
||||
; ES:DI = 1500:0
|
||||
xor di,di
|
||||
push es
|
||||
mov ax,01500h
|
||||
mov es,ax
|
||||
call ReadFile
|
||||
SaveVolumeId:
|
||||
pop es
|
||||
mov ax,word ptr [bp+VolId]
|
||||
mov word ptr es:[0],ax ; Save Volume Id to 0:19000. we will find the correct volume according to this VolumeId
|
||||
mov ax,word ptr [bp+VolId+2]
|
||||
mov word ptr es:[2],ax
|
||||
|
||||
; Read Efildr
|
||||
pop cx
|
||||
; cx = Start Cluster of Efildr -> BS.com has filled already
|
||||
; ES:DI = 2000:0, first cluster will be read again
|
||||
xor di,di ; di = 0
|
||||
mov ax,02000h
|
||||
mov es,ax
|
||||
call ReadFile
|
||||
mov ax,cs
|
||||
mov word ptr cs:[JumpSegment],ax
|
||||
|
||||
JumpFarInstruction:
|
||||
db 0eah
|
||||
JumpOffset:
|
||||
dw 0200h
|
||||
JumpSegment:
|
||||
dw 2000h
|
||||
|
||||
|
||||
|
||||
; ****************************************************************************
|
||||
; ReadFile
|
||||
;
|
||||
; Arguments:
|
||||
; CX = Start Cluster of File
|
||||
; ES:DI = Buffer to store file content read from disk
|
||||
;
|
||||
; Return:
|
||||
; (ES << 4 + DI) = end of file content Buffer
|
||||
;
|
||||
; ****************************************************************************
|
||||
ReadFile:
|
||||
; si = NumberOfClusters
|
||||
; cx = ClusterNumber
|
||||
; dx = CachedFatSectorNumber
|
||||
; ds:0000 = CacheFatSectorBuffer
|
||||
; es:di = Buffer to load file
|
||||
; bx = NextClusterNumber
|
||||
pusha
|
||||
mov si,1 ; NumberOfClusters = 1
|
||||
push cx ; Push Start Cluster onto stack
|
||||
mov dx,0fffh ; CachedFatSectorNumber = 0xfff
|
||||
FatChainLoop:
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
and ax,0ff8h ; ax = ax & 0xff8
|
||||
cmp ax,0ff8h ; See if this is the last cluster
|
||||
je FoundLastCluster ; Jump if last cluster found
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
shl ax,1 ; ax = ClusterNumber * 2
|
||||
add ax,cx ; ax = ClusterNumber * 2 + ClusterNumber = ClusterNumber * 3
|
||||
shr ax,1 ; FatOffset = ClusterNumber*3 / 2
|
||||
push si ; Save si
|
||||
mov si,ax ; si = FatOffset
|
||||
shr ax,BLOCK_SHIFT ; ax = FatOffset >> BLOCK_SHIFT
|
||||
add ax,word ptr [bp+ReservedSectors] ; ax = FatSectorNumber = ReservedSectors + (FatOffset >> BLOCK_OFFSET)
|
||||
and si,BLOCK_MASK ; si = FatOffset & BLOCK_MASK
|
||||
cmp ax,dx ; Compare FatSectorNumber to CachedFatSectorNumber
|
||||
je SkipFatRead
|
||||
mov bx,2
|
||||
push es
|
||||
push ds
|
||||
pop es
|
||||
call ReadBlocks ; Read 2 blocks starting at AX storing at ES:DI
|
||||
pop es
|
||||
mov dx,ax ; CachedFatSectorNumber = FatSectorNumber
|
||||
SkipFatRead:
|
||||
mov bx,word ptr [si] ; bx = NextClusterNumber
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
and ax,1 ; See if this is an odd cluster number
|
||||
je EvenFatEntry
|
||||
shr bx,4 ; NextClusterNumber = NextClusterNumber >> 4
|
||||
EvenFatEntry:
|
||||
and bx,0fffh ; Strip upper 4 bits of NextClusterNumber
|
||||
pop si ; Restore si
|
||||
dec bx ; bx = NextClusterNumber - 1
|
||||
cmp bx,cx ; See if (NextClusterNumber-1)==ClusterNumber
|
||||
jne ReadClusters
|
||||
inc bx ; bx = NextClusterNumber
|
||||
inc si ; NumberOfClusters++
|
||||
mov cx,bx ; ClusterNumber = NextClusterNumber
|
||||
jmp FatChainLoop
|
||||
ReadClusters:
|
||||
inc bx
|
||||
pop ax ; ax = StartCluster
|
||||
push bx ; StartCluster = NextClusterNumber
|
||||
mov cx,bx ; ClusterNumber = NextClusterNumber
|
||||
sub ax,2 ; ax = StartCluster - 2
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster
|
||||
mul bx ; ax = (StartCluster - 2) * SectorsPerCluster
|
||||
add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
|
||||
push ax ; save start sector
|
||||
mov ax,si ; ax = NumberOfClusters
|
||||
mul bx ; ax = NumberOfClusters * SectorsPerCluster
|
||||
mov bx,ax ; bx = Number of Sectors
|
||||
pop ax ; ax = Start Sector
|
||||
call ReadBlocks
|
||||
mov si,1 ; NumberOfClusters = 1
|
||||
jmp FatChainLoop
|
||||
FoundLastCluster:
|
||||
pop cx
|
||||
popa
|
||||
ret
|
||||
|
||||
|
||||
; ****************************************************************************
|
||||
; ReadBlocks - Reads a set of blocks from a block device
|
||||
;
|
||||
; AX = Start LBA
|
||||
; BX = Number of Blocks to Read
|
||||
; ES:DI = Buffer to store sectors read from disk
|
||||
; ****************************************************************************
|
||||
|
||||
; cx = Blocks
|
||||
; bx = NumberOfBlocks
|
||||
; si = StartLBA
|
||||
|
||||
ReadBlocks:
|
||||
pusha
|
||||
add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA
|
||||
add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA
|
||||
mov esi,eax ; esi = Start LBA
|
||||
mov cx,bx ; cx = Number of blocks to read
|
||||
ReadCylinderLoop:
|
||||
mov bp,07bfch ; bp = 0x7bfc
|
||||
mov eax,esi ; eax = Start LBA
|
||||
xor edx,edx ; edx = 0
|
||||
movzx ebx,word ptr [bp] ; bx = MaxSector
|
||||
div ebx ; ax = StartLBA / MaxSector
|
||||
inc dx ; dx = (StartLBA % MaxSector) + 1
|
||||
|
||||
mov bx,word ptr [bp] ; bx = MaxSector
|
||||
sub bx,dx ; bx = MaxSector - Sector
|
||||
inc bx ; bx = MaxSector - Sector + 1
|
||||
cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)
|
||||
jg LimitTransfer
|
||||
mov bx,cx ; bx = Blocks
|
||||
LimitTransfer:
|
||||
push ax ; save ax
|
||||
mov ax,es ; ax = es
|
||||
shr ax,(BLOCK_SHIFT-4) ; ax = Number of blocks into mem system
|
||||
and ax,07fh ; ax = Number of blocks into current seg
|
||||
add ax,bx ; ax = End Block number of transfer
|
||||
cmp ax,080h ; See if it crosses a 64K boundry
|
||||
jle NotCrossing64KBoundry ; Branch if not crossing 64K boundry
|
||||
sub ax,080h ; ax = Number of blocks past 64K boundry
|
||||
sub bx,ax ; Decrease transfer size by block overage
|
||||
NotCrossing64KBoundry:
|
||||
pop ax ; restore ax
|
||||
|
||||
push cx
|
||||
mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector
|
||||
xor dx,dx ; dx = 0
|
||||
div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder
|
||||
; dx = ax % (MaxHead + 1) = Head
|
||||
|
||||
push bx ; Save number of blocks to transfer
|
||||
mov dh,dl ; dh = Head
|
||||
mov bp,07c00h ; bp = 0x7c00
|
||||
mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number
|
||||
mov ch,al ; ch = Cylinder
|
||||
mov al,bl ; al = Blocks
|
||||
mov ah,2 ; ah = Function 2
|
||||
mov bx,di ; es:bx = Buffer address
|
||||
int 013h
|
||||
jc DiskError
|
||||
pop bx
|
||||
pop cx
|
||||
movzx ebx,bx
|
||||
add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks
|
||||
sub cx,bx ; Blocks = Blocks - NumberOfBlocks
|
||||
mov ax,es
|
||||
shl bx,(BLOCK_SHIFT-4)
|
||||
add ax,bx
|
||||
mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE
|
||||
cmp cx,0
|
||||
jne ReadCylinderLoop
|
||||
popa
|
||||
ret
|
||||
|
||||
DiskError:
|
||||
push cs
|
||||
pop ds
|
||||
lea si, [ErrorString]
|
||||
mov cx, 7
|
||||
jmp PrintStringAndHalt
|
||||
|
||||
PrintStringAndHalt:
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov di,160
|
||||
rep movsw
|
||||
Halt:
|
||||
jmp Halt
|
||||
|
||||
ErrorString:
|
||||
db 'S', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
|
||||
|
||||
org 01fah
|
||||
LBAOffsetForBootSector:
|
||||
dd 0h
|
||||
|
||||
org 01feh
|
||||
dw 0aa55h
|
||||
|
||||
;******************************************************************************
|
||||
;******************************************************************************
|
||||
;******************************************************************************
|
||||
|
||||
DELAY_PORT equ 0edh ; Port to use for 1uS delay
|
||||
KBD_CONTROL_PORT equ 060h ; 8042 control port
|
||||
KBD_STATUS_PORT equ 064h ; 8042 status port
|
||||
WRITE_DATA_PORT_CMD equ 0d1h ; 8042 command to write the data port
|
||||
ENABLE_A20_CMD equ 0dfh ; 8042 command to enable A20
|
||||
|
||||
org 200h
|
||||
jmp start
|
||||
Em64String:
|
||||
db 'E', 0ch, 'm', 0ch, '6', 0ch, '4', 0ch, 'T', 0ch, ' ', 0ch, 'U', 0ch, 'n', 0ch, 's', 0ch, 'u', 0ch, 'p', 0ch, 'p', 0ch, 'o', 0ch, 'r', 0ch, 't', 0ch, 'e', 0ch, 'd', 0ch, '!', 0ch
|
||||
|
||||
start:
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
mov ss,ax
|
||||
mov sp,MyStack
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[160],'a'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
mov ebx,0
|
||||
lea edi,MemoryMap
|
||||
MemMapLoop:
|
||||
mov eax,0e820h
|
||||
mov ecx,20
|
||||
mov edx,'SMAP'
|
||||
int 15h
|
||||
jc MemMapDone
|
||||
add edi,20
|
||||
cmp ebx,0
|
||||
je MemMapDone
|
||||
jmp MemMapLoop
|
||||
MemMapDone:
|
||||
lea eax,MemoryMap
|
||||
sub edi,eax ; Get the address of the memory map
|
||||
mov dword ptr [MemoryMapSize],edi ; Save the size of the memory map
|
||||
|
||||
xor ebx,ebx
|
||||
mov bx,cs ; BX=segment
|
||||
shl ebx,4 ; BX="linear" address of segment base
|
||||
lea eax,[GDT_BASE + ebx] ; EAX=PHYSICAL address of gdt
|
||||
mov dword ptr [gdtr + 2],eax ; Put address of gdt into the gdtr
|
||||
lea eax,[IDT_BASE + ebx] ; EAX=PHYSICAL address of idt
|
||||
mov dword ptr [idtr + 2],eax ; Put address of idt into the idtr
|
||||
lea edx,[MemoryMapSize + ebx] ; Physical base address of the memory map
|
||||
|
||||
add ebx,01000h ; Source of EFI32
|
||||
mov dword ptr [JUMP+2],ebx
|
||||
add ebx,01000h
|
||||
mov esi,ebx ; Source of EFILDR32
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[162],'b'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
;
|
||||
; Enable A20 Gate
|
||||
;
|
||||
|
||||
mov ax,2401h ; Enable A20 Gate
|
||||
int 15h
|
||||
jnc A20GateEnabled ; Jump if it suceeded
|
||||
|
||||
;
|
||||
; If INT 15 Function 2401 is not supported, then attempt to Enable A20 manually.
|
||||
;
|
||||
|
||||
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
|
||||
jnz Timeout8042 ; Jump if the 8042 timed out
|
||||
out DELAY_PORT,ax ; Delay 1 uS
|
||||
mov al,WRITE_DATA_PORT_CMD ; 8042 cmd to write output port
|
||||
out KBD_STATUS_PORT,al ; Send command to the 8042
|
||||
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
|
||||
jnz Timeout8042 ; Jump if the 8042 timed out
|
||||
mov al,ENABLE_A20_CMD ; gate address bit 20 on
|
||||
out KBD_CONTROL_PORT,al ; Send command to thre 8042
|
||||
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
|
||||
mov cx,25 ; Delay 25 uS for the command to complete on the 8042
|
||||
Delay25uS:
|
||||
out DELAY_PORT,ax ; Delay 1 uS
|
||||
loop Delay25uS
|
||||
Timeout8042:
|
||||
|
||||
|
||||
A20GateEnabled:
|
||||
|
||||
;
|
||||
; DISABLE INTERRUPTS - Entering Protected Mode
|
||||
;
|
||||
|
||||
cli
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[164],'c'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
db 66h
|
||||
lgdt fword ptr [gdtr]
|
||||
db 66h
|
||||
lidt fword ptr [idtr]
|
||||
|
||||
mov eax,cr0
|
||||
or al,1
|
||||
mov cr0,eax
|
||||
|
||||
mov eax,0008h ; Flat data descriptor
|
||||
mov ebp,000400000h ; Destination of EFILDR32
|
||||
mov ebx,000070000h ; Length of copy
|
||||
|
||||
JUMP:
|
||||
; jmp far 0010:00020000
|
||||
db 066h
|
||||
db 0eah
|
||||
dd 000020000h
|
||||
dw 00010h
|
||||
|
||||
Empty8042InputBuffer:
|
||||
mov cx,0
|
||||
Empty8042Loop:
|
||||
out DELAY_PORT,ax ; Delay 1us
|
||||
in al,KBD_STATUS_PORT ; Read the 8042 Status Port
|
||||
and al,02h ; Check the Input Buffer Full Flag
|
||||
loopnz Empty8042Loop ; Loop until the input buffer is empty or a timout of 65536 uS
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; data
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 02h
|
||||
|
||||
gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit
|
||||
dd 0 ; (GDT base gets set above)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; global descriptor table (GDT)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 02h
|
||||
|
||||
public GDT_BASE
|
||||
GDT_BASE:
|
||||
; null descriptor
|
||||
NULL_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 15:0
|
||||
dw 0 ; base 15:0
|
||||
db 0 ; base 23:16
|
||||
db 0 ; type
|
||||
db 0 ; limit 19:16, flags
|
||||
db 0 ; base 31:24
|
||||
|
||||
; linear data segment descriptor
|
||||
LINEAR_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; linear code segment descriptor
|
||||
LINEAR_CODE_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; system data segment descriptor
|
||||
SYS_DATA_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; system code segment descriptor
|
||||
SYS_CODE_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE3_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE4_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE5_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
GDT_END:
|
||||
|
||||
align 02h
|
||||
|
||||
|
||||
|
||||
idtr dw IDT_END - IDT_BASE - 1 ; IDT limit
|
||||
dd 0 ; (IDT base gets set above)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; interrupt descriptor table (IDT)
|
||||
;
|
||||
; Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ
|
||||
; mappings. This implementation only uses the system timer and all other
|
||||
; IRQs will remain masked. The descriptors for vectors 33+ are provided
|
||||
; for convenience.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;idt_tag db "IDT",0
|
||||
align 02h
|
||||
|
||||
public IDT_BASE
|
||||
IDT_BASE:
|
||||
; divide by zero (INT 0)
|
||||
DIV_ZERO_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; debug exception (INT 1)
|
||||
DEBUG_EXCEPT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; NMI (INT 2)
|
||||
NMI_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; soft breakpoint (INT 3)
|
||||
BREAKPOINT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; overflow (INT 4)
|
||||
OVERFLOW_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; bounds check (INT 5)
|
||||
BOUNDS_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; invalid opcode (INT 6)
|
||||
INVALID_OPCODE_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; device not available (INT 7)
|
||||
DEV_NOT_AVAIL_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; double fault (INT 8)
|
||||
DOUBLE_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Coprocessor segment overrun - reserved (INT 9)
|
||||
RSVD_INTR_SEL1 equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; invalid TSS (INT 0ah)
|
||||
INVALID_TSS_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; segment not present (INT 0bh)
|
||||
SEG_NOT_PRESENT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; stack fault (INT 0ch)
|
||||
STACK_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; general protection (INT 0dh)
|
||||
GP_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; page fault (INT 0eh)
|
||||
PAGE_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Intel reserved - do not use (INT 0fh)
|
||||
RSVD_INTR_SEL2 equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; floating point error (INT 10h)
|
||||
FLT_POINT_ERR_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; alignment check (INT 11h)
|
||||
ALIGNMENT_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; machine check (INT 12h)
|
||||
MACHINE_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; SIMD floating-point exception (INT 13h)
|
||||
SIMD_EXCEPTION_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; 85 unspecified descriptors, First 12 of them are reserved, the rest are avail
|
||||
db (85 * 8) dup(0)
|
||||
|
||||
; IRQ 0 (System timer) - (INT 68h)
|
||||
IRQ0_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 1 (8042 Keyboard controller) - (INT 69h)
|
||||
IRQ1_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
|
||||
IRQ2_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 3 (COM 2) - (INT 6bh)
|
||||
IRQ3_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 4 (COM 1) - (INT 6ch)
|
||||
IRQ4_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 5 (LPT 2) - (INT 6dh)
|
||||
IRQ5_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 6 (Floppy controller) - (INT 6eh)
|
||||
IRQ6_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 7 (LPT 1) - (INT 6fh)
|
||||
IRQ7_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 8 (RTC Alarm) - (INT 70h)
|
||||
IRQ8_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 9 - (INT 71h)
|
||||
IRQ9_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 10 - (INT 72h)
|
||||
IRQ10_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 11 - (INT 73h)
|
||||
IRQ11_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 12 (PS/2 mouse) - (INT 74h)
|
||||
IRQ12_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 13 (Floating point error) - (INT 75h)
|
||||
IRQ13_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 14 (Secondary IDE) - (INT 76h)
|
||||
IRQ14_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 15 (Primary IDE) - (INT 77h)
|
||||
IRQ15_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
IDT_END:
|
||||
|
||||
align 02h
|
||||
|
||||
MemoryMapSize dd 0
|
||||
MemoryMap dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
|
||||
dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
|
||||
org 0fe0h
|
||||
MyStack:
|
||||
; below is the pieces of the IVT that is used to redirect INT 68h - 6fh
|
||||
; back to INT 08h - 0fh when in real mode... It is 'org'ed to a
|
||||
; known low address (20f00) so it can be set up by PlMapIrqToVect in
|
||||
; 8259.c
|
||||
|
||||
int 8
|
||||
iret
|
||||
|
||||
int 9
|
||||
iret
|
||||
|
||||
int 10
|
||||
iret
|
||||
|
||||
int 11
|
||||
iret
|
||||
|
||||
int 12
|
||||
iret
|
||||
|
||||
int 13
|
||||
iret
|
||||
|
||||
int 14
|
||||
iret
|
||||
|
||||
int 15
|
||||
iret
|
||||
|
||||
|
||||
org 0ffeh
|
||||
BlockSignature:
|
||||
dw 0aa55h
|
||||
|
||||
end
|
914
DuetPkg/BootSector/start16.asm
Normal file
914
DuetPkg/BootSector/start16.asm
Normal file
@@ -0,0 +1,914 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006 - 2007, Intel Corporation
|
||||
;* All rights reserved. This program and the accompanying materials
|
||||
;* are licensed and made available under the terms and conditions of the BSD License
|
||||
;* which accompanies this distribution. The full text of the license may be found at
|
||||
;* http://opensource.org/licenses/bsd-license.php
|
||||
;*
|
||||
;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;*
|
||||
;* start16.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.model small
|
||||
.stack
|
||||
.486p
|
||||
.code
|
||||
|
||||
FAT_DIRECTORY_ENTRY_SIZE EQU 020h
|
||||
FAT_DIRECTORY_ENTRY_SHIFT EQU 5
|
||||
BLOCK_SIZE EQU 0200h
|
||||
BLOCK_MASK EQU 01ffh
|
||||
BLOCK_SHIFT EQU 9
|
||||
|
||||
org 0h
|
||||
Ia32Jump:
|
||||
jmp BootSectorEntryPoint ; JMP inst - 3 bytes
|
||||
nop
|
||||
|
||||
OemId db "INTEL " ; OemId - 8 bytes
|
||||
|
||||
SectorSize dw 0 ; Sector Size - 16 bits
|
||||
SectorsPerCluster db 0 ; Sector Per Cluster - 8 bits
|
||||
ReservedSectors dw 0 ; Reserved Sectors - 16 bits
|
||||
NoFats db 0 ; Number of FATs - 8 bits
|
||||
RootEntries dw 0 ; Root Entries - 16 bits
|
||||
Sectors dw 0 ; Number of Sectors - 16 bits
|
||||
Media db 0 ; Media - 8 bits - ignored
|
||||
SectorsPerFat dw 0 ; Sectors Per FAT - 16 bits
|
||||
SectorsPerTrack dw 0 ; Sectors Per Track - 16 bits - ignored
|
||||
Heads dw 0 ; Heads - 16 bits - ignored
|
||||
HiddenSectors dd 0 ; Hidden Sectors - 32 bits - ignored
|
||||
LargeSectors dd 0 ; Large Sectors - 32 bits
|
||||
PhysicalDrive db 0 ; PhysicalDriveNumber - 8 bits - ignored
|
||||
CurrentHead db 0 ; Current Head - 8 bits
|
||||
Signature db 0 ; Signature - 8 bits - ignored
|
||||
VolId db " " ; Volume Serial Number- 4 bytes
|
||||
FatLabel db " " ; Label - 11 bytes
|
||||
SystemId db "FAT16 " ; SystemId - 8 bytes
|
||||
|
||||
BootSectorEntryPoint:
|
||||
ASSUME ds:@code
|
||||
ASSUME ss:@code
|
||||
; ds = 1000, es = 2000 + x (size of first cluster >> 4)
|
||||
; cx = Start Cluster of EfiLdr
|
||||
; dx = Start Cluster of Efivar.bin
|
||||
|
||||
; Re use the BPB data stored in Boot Sector
|
||||
mov bp,07c00h
|
||||
|
||||
push cx
|
||||
; Read Efivar.bin
|
||||
; 1000:dx = DirectoryEntry of Efivar.bin -> BS.com has filled already
|
||||
mov ax,01900h
|
||||
mov es,ax
|
||||
test dx,dx
|
||||
jnz CheckVarStoreSize
|
||||
|
||||
mov al,1
|
||||
NoVarStore:
|
||||
push es
|
||||
; Set the 5th byte start @ 0:19000 to non-zero indicating we should init var store header in DxeIpl
|
||||
mov byte ptr es:[4],al
|
||||
jmp SaveVolumeId
|
||||
|
||||
CheckVarStoreSize:
|
||||
mov di,dx
|
||||
cmp dword ptr ds:[di+2], 04000h
|
||||
mov al,2
|
||||
jne NoVarStore
|
||||
|
||||
LoadVarStore:
|
||||
mov al,0
|
||||
mov byte ptr es:[4],al
|
||||
mov cx,word ptr[di]
|
||||
; ES:DI = 1500:0
|
||||
xor di,di
|
||||
push es
|
||||
mov ax,01500h
|
||||
mov es,ax
|
||||
call ReadFile
|
||||
SaveVolumeId:
|
||||
pop es
|
||||
mov ax,word ptr [bp+VolId]
|
||||
mov word ptr es:[0],ax ; Save Volume Id to 0:19000. we will find the correct volume according to this VolumeId
|
||||
mov ax,word ptr [bp+VolId+2]
|
||||
mov word ptr es:[2],ax
|
||||
|
||||
; Read Efildr
|
||||
pop cx
|
||||
; cx = Start Cluster of Efildr -> BS.com has filled already
|
||||
; ES:DI = 2000:0, first cluster will be read again
|
||||
xor di,di ; di = 0
|
||||
mov ax,02000h
|
||||
mov es,ax
|
||||
call ReadFile
|
||||
mov ax,cs
|
||||
mov word ptr cs:[JumpSegment],ax
|
||||
|
||||
JumpFarInstruction:
|
||||
db 0eah
|
||||
JumpOffset:
|
||||
dw 0200h
|
||||
JumpSegment:
|
||||
dw 2000h
|
||||
|
||||
|
||||
|
||||
; ****************************************************************************
|
||||
; ReadFile
|
||||
;
|
||||
; Arguments:
|
||||
; CX = Start Cluster of File
|
||||
; ES:DI = Buffer to store file content read from disk
|
||||
;
|
||||
; Return:
|
||||
; (ES << 4 + DI) = end of file content Buffer
|
||||
;
|
||||
; ****************************************************************************
|
||||
ReadFile:
|
||||
; si = NumberOfClusters
|
||||
; cx = ClusterNumber
|
||||
; dx = CachedFatSectorNumber
|
||||
; ds:0000 = CacheFatSectorBuffer
|
||||
; es:di = Buffer to load file
|
||||
; bx = NextClusterNumber
|
||||
pusha
|
||||
mov si,1 ; NumberOfClusters = 1
|
||||
push cx ; Push Start Cluster onto stack
|
||||
mov dx,0fffh ; CachedFatSectorNumber = 0xfff
|
||||
FatChainLoop:
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
and ax,0fff8h ; ax = ax & 0xfff8
|
||||
cmp ax,0fff8h ; See if this is the last cluster
|
||||
je FoundLastCluster ; Jump if last cluster found
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
shl ax,1 ; FatOffset = ClusterNumber * 2
|
||||
push si ; Save si
|
||||
mov si,ax ; si = FatOffset
|
||||
shr ax,BLOCK_SHIFT ; ax = FatOffset >> BLOCK_SHIFT
|
||||
add ax,word ptr [bp+ReservedSectors] ; ax = FatSectorNumber = ReservedSectors + (FatOffset >> BLOCK_OFFSET)
|
||||
and si,BLOCK_MASK ; si = FatOffset & BLOCK_MASK
|
||||
cmp ax,dx ; Compare FatSectorNumber to CachedFatSectorNumber
|
||||
je SkipFatRead
|
||||
mov bx,2
|
||||
push es
|
||||
push ds
|
||||
pop es
|
||||
call ReadBlocks ; Read 2 blocks starting at AX storing at ES:DI
|
||||
pop es
|
||||
mov dx,ax ; CachedFatSectorNumber = FatSectorNumber
|
||||
SkipFatRead:
|
||||
mov bx,word ptr [si] ; bx = NextClusterNumber
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
pop si ; Restore si
|
||||
dec bx ; bx = NextClusterNumber - 1
|
||||
cmp bx,cx ; See if (NextClusterNumber-1)==ClusterNumber
|
||||
jne ReadClusters
|
||||
inc bx ; bx = NextClusterNumber
|
||||
inc si ; NumberOfClusters++
|
||||
mov cx,bx ; ClusterNumber = NextClusterNumber
|
||||
jmp FatChainLoop
|
||||
ReadClusters:
|
||||
inc bx
|
||||
pop ax ; ax = StartCluster
|
||||
push bx ; StartCluster = NextClusterNumber
|
||||
mov cx,bx ; ClusterNumber = NextClusterNumber
|
||||
sub ax,2 ; ax = StartCluster - 2
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster
|
||||
mul bx ; ax = (StartCluster - 2) * SectorsPerCluster
|
||||
add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
|
||||
push ax ; save start sector
|
||||
mov ax,si ; ax = NumberOfClusters
|
||||
mul bx ; ax = NumberOfClusters * SectorsPerCluster
|
||||
mov bx,ax ; bx = Number of Sectors
|
||||
pop ax ; ax = Start Sector
|
||||
call ReadBlocks
|
||||
mov si,1 ; NumberOfClusters = 1
|
||||
jmp FatChainLoop
|
||||
FoundLastCluster:
|
||||
pop cx
|
||||
popa
|
||||
ret
|
||||
|
||||
|
||||
; ****************************************************************************
|
||||
; ReadBlocks - Reads a set of blocks from a block device
|
||||
;
|
||||
; AX = Start LBA
|
||||
; BX = Number of Blocks to Read
|
||||
; ES:DI = Buffer to store sectors read from disk
|
||||
; ****************************************************************************
|
||||
|
||||
; cx = Blocks
|
||||
; bx = NumberOfBlocks
|
||||
; si = StartLBA
|
||||
|
||||
ReadBlocks:
|
||||
pusha
|
||||
add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA
|
||||
add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA
|
||||
mov esi,eax ; esi = Start LBA
|
||||
mov cx,bx ; cx = Number of blocks to read
|
||||
ReadCylinderLoop:
|
||||
mov bp,07bfch ; bp = 0x7bfc
|
||||
mov eax,esi ; eax = Start LBA
|
||||
xor edx,edx ; edx = 0
|
||||
movzx ebx,word ptr [bp] ; bx = MaxSector
|
||||
div ebx ; ax = StartLBA / MaxSector
|
||||
inc dx ; dx = (StartLBA % MaxSector) + 1
|
||||
|
||||
mov bx,word ptr [bp] ; bx = MaxSector
|
||||
sub bx,dx ; bx = MaxSector - Sector
|
||||
inc bx ; bx = MaxSector - Sector + 1
|
||||
cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)
|
||||
jg LimitTransfer
|
||||
mov bx,cx ; bx = Blocks
|
||||
LimitTransfer:
|
||||
push ax ; save ax
|
||||
mov ax,es ; ax = es
|
||||
shr ax,(BLOCK_SHIFT-4) ; ax = Number of blocks into mem system
|
||||
and ax,07fh ; ax = Number of blocks into current seg
|
||||
add ax,bx ; ax = End Block number of transfer
|
||||
cmp ax,080h ; See if it crosses a 64K boundry
|
||||
jle NotCrossing64KBoundry ; Branch if not crossing 64K boundry
|
||||
sub ax,080h ; ax = Number of blocks past 64K boundry
|
||||
sub bx,ax ; Decrease transfer size by block overage
|
||||
NotCrossing64KBoundry:
|
||||
pop ax ; restore ax
|
||||
|
||||
push cx
|
||||
mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector
|
||||
xor dx,dx ; dx = 0
|
||||
div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder
|
||||
; dx = ax % (MaxHead + 1) = Head
|
||||
|
||||
push bx ; Save number of blocks to transfer
|
||||
mov dh,dl ; dh = Head
|
||||
mov bp,07c00h ; bp = 0x7c00
|
||||
mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number
|
||||
mov ch,al ; ch = Cylinder
|
||||
mov al,bl ; al = Blocks
|
||||
mov ah,2 ; ah = Function 2
|
||||
mov bx,di ; es:bx = Buffer address
|
||||
int 013h
|
||||
jc DiskError
|
||||
pop bx
|
||||
pop cx
|
||||
movzx ebx,bx
|
||||
add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks
|
||||
sub cx,bx ; Blocks = Blocks - NumberOfBlocks
|
||||
mov ax,es
|
||||
shl bx,(BLOCK_SHIFT-4)
|
||||
add ax,bx
|
||||
mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE
|
||||
cmp cx,0
|
||||
jne ReadCylinderLoop
|
||||
popa
|
||||
ret
|
||||
|
||||
DiskError:
|
||||
push cs
|
||||
pop ds
|
||||
lea si, [ErrorString]
|
||||
mov cx, 7
|
||||
jmp PrintStringAndHalt
|
||||
|
||||
PrintStringAndHalt:
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov di,160
|
||||
rep movsw
|
||||
Halt:
|
||||
jmp Halt
|
||||
|
||||
ErrorString:
|
||||
db 'S', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
|
||||
|
||||
org 01fah
|
||||
LBAOffsetForBootSector:
|
||||
dd 0h
|
||||
|
||||
org 01feh
|
||||
dw 0aa55h
|
||||
|
||||
;******************************************************************************
|
||||
;******************************************************************************
|
||||
;******************************************************************************
|
||||
|
||||
DELAY_PORT equ 0edh ; Port to use for 1uS delay
|
||||
KBD_CONTROL_PORT equ 060h ; 8042 control port
|
||||
KBD_STATUS_PORT equ 064h ; 8042 status port
|
||||
WRITE_DATA_PORT_CMD equ 0d1h ; 8042 command to write the data port
|
||||
ENABLE_A20_CMD equ 0dfh ; 8042 command to enable A20
|
||||
|
||||
org 200h
|
||||
jmp start
|
||||
Em64String:
|
||||
db 'E', 0ch, 'm', 0ch, '6', 0ch, '4', 0ch, 'T', 0ch, ' ', 0ch, 'U', 0ch, 'n', 0ch, 's', 0ch, 'u', 0ch, 'p', 0ch, 'p', 0ch, 'o', 0ch, 'r', 0ch, 't', 0ch, 'e', 0ch, 'd', 0ch, '!', 0ch
|
||||
|
||||
start:
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
mov ss,ax
|
||||
mov sp,MyStack
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[160],'a'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
mov ebx,0
|
||||
lea edi,MemoryMap
|
||||
MemMapLoop:
|
||||
mov eax,0e820h
|
||||
mov ecx,20
|
||||
mov edx,'SMAP'
|
||||
int 15h
|
||||
jc MemMapDone
|
||||
add edi,20
|
||||
cmp ebx,0
|
||||
je MemMapDone
|
||||
jmp MemMapLoop
|
||||
MemMapDone:
|
||||
lea eax,MemoryMap
|
||||
sub edi,eax ; Get the address of the memory map
|
||||
mov dword ptr [MemoryMapSize],edi ; Save the size of the memory map
|
||||
|
||||
xor ebx,ebx
|
||||
mov bx,cs ; BX=segment
|
||||
shl ebx,4 ; BX="linear" address of segment base
|
||||
lea eax,[GDT_BASE + ebx] ; EAX=PHYSICAL address of gdt
|
||||
mov dword ptr [gdtr + 2],eax ; Put address of gdt into the gdtr
|
||||
lea eax,[IDT_BASE + ebx] ; EAX=PHYSICAL address of idt
|
||||
mov dword ptr [idtr + 2],eax ; Put address of idt into the idtr
|
||||
lea edx,[MemoryMapSize + ebx] ; Physical base address of the memory map
|
||||
|
||||
add ebx,01000h ; Source of EFI32
|
||||
mov dword ptr [JUMP+2],ebx
|
||||
add ebx,01000h
|
||||
mov esi,ebx ; Source of EFILDR32
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[162],'b'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
;
|
||||
; Enable A20 Gate
|
||||
;
|
||||
|
||||
mov ax,2401h ; Enable A20 Gate
|
||||
int 15h
|
||||
jnc A20GateEnabled ; Jump if it suceeded
|
||||
|
||||
;
|
||||
; If INT 15 Function 2401 is not supported, then attempt to Enable A20 manually.
|
||||
;
|
||||
|
||||
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
|
||||
jnz Timeout8042 ; Jump if the 8042 timed out
|
||||
out DELAY_PORT,ax ; Delay 1 uS
|
||||
mov al,WRITE_DATA_PORT_CMD ; 8042 cmd to write output port
|
||||
out KBD_STATUS_PORT,al ; Send command to the 8042
|
||||
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
|
||||
jnz Timeout8042 ; Jump if the 8042 timed out
|
||||
mov al,ENABLE_A20_CMD ; gate address bit 20 on
|
||||
out KBD_CONTROL_PORT,al ; Send command to thre 8042
|
||||
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
|
||||
mov cx,25 ; Delay 25 uS for the command to complete on the 8042
|
||||
Delay25uS:
|
||||
out DELAY_PORT,ax ; Delay 1 uS
|
||||
loop Delay25uS
|
||||
Timeout8042:
|
||||
|
||||
|
||||
A20GateEnabled:
|
||||
|
||||
;
|
||||
; DISABLE INTERRUPTS - Entering Protected Mode
|
||||
;
|
||||
|
||||
cli
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[164],'c'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
db 66h
|
||||
lgdt fword ptr [gdtr]
|
||||
db 66h
|
||||
lidt fword ptr [idtr]
|
||||
|
||||
mov eax,cr0
|
||||
or al,1
|
||||
mov cr0,eax
|
||||
|
||||
mov eax,0008h ; Flat data descriptor
|
||||
mov ebp,000400000h ; Destination of EFILDR32
|
||||
mov ebx,000070000h ; Length of copy
|
||||
|
||||
JUMP:
|
||||
; jmp far 0010:00020000
|
||||
db 066h
|
||||
db 0eah
|
||||
dd 000020000h
|
||||
dw 00010h
|
||||
|
||||
Empty8042InputBuffer:
|
||||
mov cx,0
|
||||
Empty8042Loop:
|
||||
out DELAY_PORT,ax ; Delay 1us
|
||||
in al,KBD_STATUS_PORT ; Read the 8042 Status Port
|
||||
and al,02h ; Check the Input Buffer Full Flag
|
||||
loopnz Empty8042Loop ; Loop until the input buffer is empty or a timout of 65536 uS
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; data
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 02h
|
||||
|
||||
gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit
|
||||
dd 0 ; (GDT base gets set above)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; global descriptor table (GDT)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 02h
|
||||
|
||||
public GDT_BASE
|
||||
GDT_BASE:
|
||||
; null descriptor
|
||||
NULL_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 15:0
|
||||
dw 0 ; base 15:0
|
||||
db 0 ; base 23:16
|
||||
db 0 ; type
|
||||
db 0 ; limit 19:16, flags
|
||||
db 0 ; base 31:24
|
||||
|
||||
; linear data segment descriptor
|
||||
LINEAR_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; linear code segment descriptor
|
||||
LINEAR_CODE_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; system data segment descriptor
|
||||
SYS_DATA_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; system code segment descriptor
|
||||
SYS_CODE_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE3_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE4_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE5_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
GDT_END:
|
||||
|
||||
align 02h
|
||||
|
||||
|
||||
|
||||
idtr dw IDT_END - IDT_BASE - 1 ; IDT limit
|
||||
dd 0 ; (IDT base gets set above)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; interrupt descriptor table (IDT)
|
||||
;
|
||||
; Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ
|
||||
; mappings. This implementation only uses the system timer and all other
|
||||
; IRQs will remain masked. The descriptors for vectors 33+ are provided
|
||||
; for convenience.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;idt_tag db "IDT",0
|
||||
align 02h
|
||||
|
||||
public IDT_BASE
|
||||
IDT_BASE:
|
||||
; divide by zero (INT 0)
|
||||
DIV_ZERO_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; debug exception (INT 1)
|
||||
DEBUG_EXCEPT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; NMI (INT 2)
|
||||
NMI_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; soft breakpoint (INT 3)
|
||||
BREAKPOINT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; overflow (INT 4)
|
||||
OVERFLOW_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; bounds check (INT 5)
|
||||
BOUNDS_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; invalid opcode (INT 6)
|
||||
INVALID_OPCODE_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; device not available (INT 7)
|
||||
DEV_NOT_AVAIL_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; double fault (INT 8)
|
||||
DOUBLE_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Coprocessor segment overrun - reserved (INT 9)
|
||||
RSVD_INTR_SEL1 equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; invalid TSS (INT 0ah)
|
||||
INVALID_TSS_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; segment not present (INT 0bh)
|
||||
SEG_NOT_PRESENT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; stack fault (INT 0ch)
|
||||
STACK_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; general protection (INT 0dh)
|
||||
GP_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; page fault (INT 0eh)
|
||||
PAGE_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Intel reserved - do not use (INT 0fh)
|
||||
RSVD_INTR_SEL2 equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; floating point error (INT 10h)
|
||||
FLT_POINT_ERR_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; alignment check (INT 11h)
|
||||
ALIGNMENT_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; machine check (INT 12h)
|
||||
MACHINE_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; SIMD floating-point exception (INT 13h)
|
||||
SIMD_EXCEPTION_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; 85 unspecified descriptors, First 12 of them are reserved, the rest are avail
|
||||
db (85 * 8) dup(0)
|
||||
|
||||
; IRQ 0 (System timer) - (INT 68h)
|
||||
IRQ0_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 1 (8042 Keyboard controller) - (INT 69h)
|
||||
IRQ1_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
|
||||
IRQ2_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 3 (COM 2) - (INT 6bh)
|
||||
IRQ3_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 4 (COM 1) - (INT 6ch)
|
||||
IRQ4_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 5 (LPT 2) - (INT 6dh)
|
||||
IRQ5_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 6 (Floppy controller) - (INT 6eh)
|
||||
IRQ6_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 7 (LPT 1) - (INT 6fh)
|
||||
IRQ7_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 8 (RTC Alarm) - (INT 70h)
|
||||
IRQ8_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 9 - (INT 71h)
|
||||
IRQ9_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 10 - (INT 72h)
|
||||
IRQ10_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 11 - (INT 73h)
|
||||
IRQ11_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 12 (PS/2 mouse) - (INT 74h)
|
||||
IRQ12_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 13 (Floating point error) - (INT 75h)
|
||||
IRQ13_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 14 (Secondary IDE) - (INT 76h)
|
||||
IRQ14_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 15 (Primary IDE) - (INT 77h)
|
||||
IRQ15_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
IDT_END:
|
||||
|
||||
align 02h
|
||||
|
||||
MemoryMapSize dd 0
|
||||
MemoryMap dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
|
||||
dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
|
||||
org 0fe0h
|
||||
MyStack:
|
||||
; below is the pieces of the IVT that is used to redirect INT 68h - 6fh
|
||||
; back to INT 08h - 0fh when in real mode... It is 'org'ed to a
|
||||
; known low address (20f00) so it can be set up by PlMapIrqToVect in
|
||||
; 8259.c
|
||||
|
||||
int 8
|
||||
iret
|
||||
|
||||
int 9
|
||||
iret
|
||||
|
||||
int 10
|
||||
iret
|
||||
|
||||
int 11
|
||||
iret
|
||||
|
||||
int 12
|
||||
iret
|
||||
|
||||
int 13
|
||||
iret
|
||||
|
||||
int 14
|
||||
iret
|
||||
|
||||
int 15
|
||||
iret
|
||||
|
||||
|
||||
org 0ffeh
|
||||
BlockSignature:
|
||||
dw 0aa55h
|
||||
|
||||
end
|
929
DuetPkg/BootSector/start32.asm
Normal file
929
DuetPkg/BootSector/start32.asm
Normal file
@@ -0,0 +1,929 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006 - 2007, Intel Corporation
|
||||
;* All rights reserved. This program and the accompanying materials
|
||||
;* are licensed and made available under the terms and conditions of the BSD License
|
||||
;* which accompanies this distribution. The full text of the license may be found at
|
||||
;* http://opensource.org/licenses/bsd-license.php
|
||||
;*
|
||||
;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;*
|
||||
;* start32.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.model small
|
||||
.stack
|
||||
.486p
|
||||
.code
|
||||
|
||||
FAT_DIRECTORY_ENTRY_SIZE EQU 020h
|
||||
FAT_DIRECTORY_ENTRY_SHIFT EQU 5
|
||||
BLOCK_SIZE EQU 0200h
|
||||
BLOCK_MASK EQU 01ffh
|
||||
BLOCK_SHIFT EQU 9
|
||||
|
||||
org 0h
|
||||
Ia32Jump:
|
||||
jmp BootSectorEntryPoint ; JMP inst - 3 bytes
|
||||
nop
|
||||
|
||||
OemId db "INTEL " ; OemId - 8 bytes
|
||||
SectorSize dw 0 ; Sector Size - 2 bytes
|
||||
SectorsPerCluster db 0 ; Sector Per Cluster - 1 byte
|
||||
ReservedSectors dw 0 ; Reserved Sectors - 2 bytes
|
||||
NoFats db 0 ; Number of FATs - 1 byte
|
||||
RootEntries dw 0 ; Root Entries - 2 bytes
|
||||
Sectors dw 0 ; Number of Sectors - 2 bytes
|
||||
Media db 0 ; Media - 1 byte
|
||||
SectorsPerFat16 dw 0 ; Sectors Per FAT for FAT12/FAT16 - 2 byte
|
||||
SectorsPerTrack dw 0 ; Sectors Per Track - 2 bytes
|
||||
Heads dw 0 ; Heads - 2 bytes
|
||||
HiddenSectors dd 0 ; Hidden Sectors - 4 bytes
|
||||
LargeSectors dd 0 ; Large Sectors - 4 bytes
|
||||
|
||||
;******************************************************************************
|
||||
;
|
||||
;The structure for FAT32 starting at offset 36 of the boot sector. (At this point,
|
||||
;the BPB/boot sector for FAT12 and FAT16 differs from the BPB/boot sector for FAT32.)
|
||||
;
|
||||
;******************************************************************************
|
||||
|
||||
SectorsPerFat32 dd 0 ; Sectors Per FAT for FAT32 - 4 bytes
|
||||
ExtFlags dw 0 ; Mirror Flag - 2 bytes
|
||||
FSVersion dw 0 ; File System Version - 2 bytes
|
||||
RootCluster dd 0 ; 1st Cluster Number of Root Dir - 4 bytes
|
||||
FSInfo dw 0 ; Sector Number of FSINFO - 2 bytes
|
||||
BkBootSector dw 0 ; Sector Number of Bk BootSector - 2 bytes
|
||||
Reserved db 12 dup(0) ; Reserved Field - 12 bytes
|
||||
PhysicalDrive db 0 ; Physical Drive Number - 1 byte
|
||||
Reserved1 db 0 ; Reserved Field - 1 byte
|
||||
Signature db 0 ; Extended Boot Signature - 1 byte
|
||||
VolId db " " ; Volume Serial Number - 4 bytes
|
||||
FatLabel db " " ; Volume Label - 11 bytes
|
||||
FileSystemType db "FAT32 " ; File System Type - 8 bytes
|
||||
|
||||
BootSectorEntryPoint:
|
||||
ASSUME ds:@code
|
||||
ASSUME ss:@code
|
||||
; ds = 1000, es = 2000 + x (size of first cluster >> 4)
|
||||
; cx = Start Cluster of EfiLdr
|
||||
; dx = Start Cluster of Efivar.bin
|
||||
|
||||
; Re use the BPB data stored in Boot Sector
|
||||
mov bp,07c00h
|
||||
|
||||
|
||||
push cx
|
||||
; Read Efivar.bin
|
||||
; 1000:dx = DirectoryEntry of Efivar.bin -> BS.com has filled already
|
||||
mov ax,01900h
|
||||
mov es,ax
|
||||
test dx,dx
|
||||
jnz CheckVarStoreSize
|
||||
|
||||
mov al,1
|
||||
NoVarStore:
|
||||
push es
|
||||
; Set the 5th byte start @ 0:19000 to non-zero indicating we should init var store header in DxeIpl
|
||||
mov byte ptr es:[4],al
|
||||
jmp SaveVolumeId
|
||||
|
||||
CheckVarStoreSize:
|
||||
mov di,dx
|
||||
cmp dword ptr ds:[di+2], 04000h
|
||||
mov al,2
|
||||
jne NoVarStore
|
||||
|
||||
LoadVarStore:
|
||||
mov al,0
|
||||
mov byte ptr es:[4],al
|
||||
mov cx,word ptr[di]
|
||||
; ES:DI = 1500:0
|
||||
xor di,di
|
||||
push es
|
||||
mov ax,01500h
|
||||
mov es,ax
|
||||
call ReadFile
|
||||
SaveVolumeId:
|
||||
pop es
|
||||
mov ax,word ptr [bp+VolId]
|
||||
mov word ptr es:[0],ax ; Save Volume Id to 0:19000. we will find the correct volume according to this VolumeId
|
||||
mov ax,word ptr [bp+VolId+2]
|
||||
mov word ptr es:[2],ax
|
||||
|
||||
; Read Efildr
|
||||
pop cx
|
||||
; cx = Start Cluster of Efildr -> BS.com has filled already
|
||||
; ES:DI = 2000:0, first cluster will be read again
|
||||
xor di,di ; di = 0
|
||||
mov ax,02000h
|
||||
mov es,ax
|
||||
call ReadFile
|
||||
mov ax,cs
|
||||
mov word ptr cs:[JumpSegment],ax
|
||||
JumpFarInstruction:
|
||||
db 0eah
|
||||
JumpOffset:
|
||||
dw 0200h
|
||||
JumpSegment:
|
||||
dw 2000h
|
||||
|
||||
|
||||
|
||||
|
||||
; ****************************************************************************
|
||||
; ReadFile
|
||||
;
|
||||
; Arguments:
|
||||
; CX = Start Cluster of File
|
||||
; ES:DI = Buffer to store file content read from disk
|
||||
;
|
||||
; Return:
|
||||
; (ES << 4 + DI) = end of file content Buffer
|
||||
;
|
||||
; ****************************************************************************
|
||||
ReadFile:
|
||||
; si = NumberOfClusters
|
||||
; cx = ClusterNumber
|
||||
; dx = CachedFatSectorNumber
|
||||
; ds:0000 = CacheFatSectorBuffer
|
||||
; es:di = Buffer to load file
|
||||
; bx = NextClusterNumber
|
||||
pusha
|
||||
mov si,1 ; NumberOfClusters = 1
|
||||
push cx ; Push Start Cluster onto stack
|
||||
mov dx,0fffh ; CachedFatSectorNumber = 0xfff
|
||||
FatChainLoop:
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
and ax,0fff8h ; ax = ax & 0xfff8
|
||||
cmp ax,0fff8h ; See if this is the last cluster
|
||||
je FoundLastCluster ; Jump if last cluster found
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
shl ax,2 ; FatOffset = ClusterNumber * 4
|
||||
push si ; Save si
|
||||
mov si,ax ; si = FatOffset
|
||||
shr ax,BLOCK_SHIFT ; ax = FatOffset >> BLOCK_SHIFT
|
||||
add ax,word ptr [bp+ReservedSectors] ; ax = FatSectorNumber = ReservedSectors + (FatOffset >> BLOCK_OFFSET)
|
||||
and si,BLOCK_MASK ; si = FatOffset & BLOCK_MASK
|
||||
cmp ax,dx ; Compare FatSectorNumber to CachedFatSectorNumber
|
||||
je SkipFatRead
|
||||
mov bx,2
|
||||
push es
|
||||
push ds
|
||||
pop es
|
||||
call ReadBlocks ; Read 2 blocks starting at AX storing at ES:DI
|
||||
pop es
|
||||
mov dx,ax ; CachedFatSectorNumber = FatSectorNumber
|
||||
SkipFatRead:
|
||||
mov bx,word ptr [si] ; bx = NextClusterNumber
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
pop si ; Restore si
|
||||
dec bx ; bx = NextClusterNumber - 1
|
||||
cmp bx,cx ; See if (NextClusterNumber-1)==ClusterNumber
|
||||
jne ReadClusters
|
||||
inc bx ; bx = NextClusterNumber
|
||||
inc si ; NumberOfClusters++
|
||||
mov cx,bx ; ClusterNumber = NextClusterNumber
|
||||
jmp FatChainLoop
|
||||
ReadClusters:
|
||||
inc bx
|
||||
pop ax ; ax = StartCluster
|
||||
push bx ; StartCluster = NextClusterNumber
|
||||
mov cx,bx ; ClusterNumber = NextClusterNumber
|
||||
sub ax,2 ; ax = StartCluster - 2
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster
|
||||
mul bx ; ax = (StartCluster - 2) * SectorsPerCluster
|
||||
add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
|
||||
push ax ; save start sector
|
||||
mov ax,si ; ax = NumberOfClusters
|
||||
mul bx ; ax = NumberOfClusters * SectorsPerCluster
|
||||
mov bx,ax ; bx = Number of Sectors
|
||||
pop ax ; ax = Start Sector
|
||||
call ReadBlocks
|
||||
mov si,1 ; NumberOfClusters = 1
|
||||
jmp FatChainLoop
|
||||
FoundLastCluster:
|
||||
pop cx
|
||||
popa
|
||||
ret
|
||||
|
||||
|
||||
; ****************************************************************************
|
||||
; ReadBlocks - Reads a set of blocks from a block device
|
||||
;
|
||||
; AX = Start LBA
|
||||
; BX = Number of Blocks to Read
|
||||
; ES:DI = Buffer to store sectors read from disk
|
||||
; ****************************************************************************
|
||||
|
||||
; cx = Blocks
|
||||
; bx = NumberOfBlocks
|
||||
; si = StartLBA
|
||||
|
||||
ReadBlocks:
|
||||
pusha
|
||||
add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA
|
||||
add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA
|
||||
mov esi,eax ; esi = Start LBA
|
||||
mov cx,bx ; cx = Number of blocks to read
|
||||
ReadCylinderLoop:
|
||||
mov bp,07bfch ; bp = 0x7bfc
|
||||
mov eax,esi ; eax = Start LBA
|
||||
xor edx,edx ; edx = 0
|
||||
movzx ebx,word ptr [bp] ; bx = MaxSector
|
||||
div ebx ; ax = StartLBA / MaxSector
|
||||
inc dx ; dx = (StartLBA % MaxSector) + 1
|
||||
|
||||
mov bx,word ptr [bp] ; bx = MaxSector
|
||||
sub bx,dx ; bx = MaxSector - Sector
|
||||
inc bx ; bx = MaxSector - Sector + 1
|
||||
cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)
|
||||
jg LimitTransfer
|
||||
mov bx,cx ; bx = Blocks
|
||||
LimitTransfer:
|
||||
push ax ; save ax
|
||||
mov ax,es ; ax = es
|
||||
shr ax,(BLOCK_SHIFT-4) ; ax = Number of blocks into mem system
|
||||
and ax,07fh ; ax = Number of blocks into current seg
|
||||
add ax,bx ; ax = End Block number of transfer
|
||||
cmp ax,080h ; See if it crosses a 64K boundry
|
||||
jle NotCrossing64KBoundry ; Branch if not crossing 64K boundry
|
||||
sub ax,080h ; ax = Number of blocks past 64K boundry
|
||||
sub bx,ax ; Decrease transfer size by block overage
|
||||
NotCrossing64KBoundry:
|
||||
pop ax ; restore ax
|
||||
|
||||
push cx
|
||||
mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector
|
||||
xor dx,dx ; dx = 0
|
||||
div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder
|
||||
; dx = ax % (MaxHead + 1) = Head
|
||||
|
||||
push bx ; Save number of blocks to transfer
|
||||
mov dh,dl ; dh = Head
|
||||
mov bp,07c00h ; bp = 0x7c00
|
||||
mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number
|
||||
mov ch,al ; ch = Cylinder
|
||||
mov al,bl ; al = Blocks
|
||||
mov ah,2 ; ah = Function 2
|
||||
mov bx,di ; es:bx = Buffer address
|
||||
int 013h
|
||||
jc DiskError
|
||||
pop bx
|
||||
pop cx
|
||||
movzx ebx,bx
|
||||
add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks
|
||||
sub cx,bx ; Blocks = Blocks - NumberOfBlocks
|
||||
mov ax,es
|
||||
shl bx,(BLOCK_SHIFT-4)
|
||||
add ax,bx
|
||||
mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE
|
||||
cmp cx,0
|
||||
jne ReadCylinderLoop
|
||||
popa
|
||||
ret
|
||||
|
||||
DiskError:
|
||||
push cs
|
||||
pop ds
|
||||
lea si, [ErrorString]
|
||||
mov cx, 7
|
||||
jmp PrintStringAndHalt
|
||||
|
||||
PrintStringAndHalt:
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov di,160
|
||||
rep movsw
|
||||
Halt:
|
||||
jmp Halt
|
||||
|
||||
ErrorString:
|
||||
db 'S', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
|
||||
|
||||
org 01fah
|
||||
LBAOffsetForBootSector:
|
||||
dd 0h
|
||||
|
||||
org 01feh
|
||||
dw 0aa55h
|
||||
|
||||
;******************************************************************************
|
||||
;******************************************************************************
|
||||
;******************************************************************************
|
||||
|
||||
DELAY_PORT equ 0edh ; Port to use for 1uS delay
|
||||
KBD_CONTROL_PORT equ 060h ; 8042 control port
|
||||
KBD_STATUS_PORT equ 064h ; 8042 status port
|
||||
WRITE_DATA_PORT_CMD equ 0d1h ; 8042 command to write the data port
|
||||
ENABLE_A20_CMD equ 0dfh ; 8042 command to enable A20
|
||||
|
||||
org 200h
|
||||
jmp start
|
||||
Em64String:
|
||||
db 'E', 0ch, 'm', 0ch, '6', 0ch, '4', 0ch, 'T', 0ch, ' ', 0ch, 'U', 0ch, 'n', 0ch, 's', 0ch, 'u', 0ch, 'p', 0ch, 'p', 0ch, 'o', 0ch, 'r', 0ch, 't', 0ch, 'e', 0ch, 'd', 0ch, '!', 0ch
|
||||
|
||||
start:
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
mov ss,ax
|
||||
mov sp,MyStack
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[160],'a'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
mov ebx,0
|
||||
lea edi,MemoryMap
|
||||
MemMapLoop:
|
||||
mov eax,0e820h
|
||||
mov ecx,20
|
||||
mov edx,'SMAP'
|
||||
int 15h
|
||||
jc MemMapDone
|
||||
add edi,20
|
||||
cmp ebx,0
|
||||
je MemMapDone
|
||||
jmp MemMapLoop
|
||||
MemMapDone:
|
||||
lea eax,MemoryMap
|
||||
sub edi,eax ; Get the address of the memory map
|
||||
mov dword ptr [MemoryMapSize],edi ; Save the size of the memory map
|
||||
|
||||
xor ebx,ebx
|
||||
mov bx,cs ; BX=segment
|
||||
shl ebx,4 ; BX="linear" address of segment base
|
||||
lea eax,[GDT_BASE + ebx] ; EAX=PHYSICAL address of gdt
|
||||
mov dword ptr [gdtr + 2],eax ; Put address of gdt into the gdtr
|
||||
lea eax,[IDT_BASE + ebx] ; EAX=PHYSICAL address of idt
|
||||
mov dword ptr [idtr + 2],eax ; Put address of idt into the idtr
|
||||
lea edx,[MemoryMapSize + ebx] ; Physical base address of the memory map
|
||||
|
||||
add ebx,01000h ; Source of EFI32
|
||||
mov dword ptr [JUMP+2],ebx
|
||||
add ebx,01000h
|
||||
mov esi,ebx ; Source of EFILDR32
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[162],'b'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
;
|
||||
; Enable A20 Gate
|
||||
;
|
||||
|
||||
mov ax,2401h ; Enable A20 Gate
|
||||
int 15h
|
||||
jnc A20GateEnabled ; Jump if it suceeded
|
||||
|
||||
;
|
||||
; If INT 15 Function 2401 is not supported, then attempt to Enable A20 manually.
|
||||
;
|
||||
|
||||
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
|
||||
jnz Timeout8042 ; Jump if the 8042 timed out
|
||||
out DELAY_PORT,ax ; Delay 1 uS
|
||||
mov al,WRITE_DATA_PORT_CMD ; 8042 cmd to write output port
|
||||
out KBD_STATUS_PORT,al ; Send command to the 8042
|
||||
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
|
||||
jnz Timeout8042 ; Jump if the 8042 timed out
|
||||
mov al,ENABLE_A20_CMD ; gate address bit 20 on
|
||||
out KBD_CONTROL_PORT,al ; Send command to thre 8042
|
||||
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
|
||||
mov cx,25 ; Delay 25 uS for the command to complete on the 8042
|
||||
Delay25uS:
|
||||
out DELAY_PORT,ax ; Delay 1 uS
|
||||
loop Delay25uS
|
||||
Timeout8042:
|
||||
|
||||
|
||||
A20GateEnabled:
|
||||
|
||||
;
|
||||
; DISABLE INTERRUPTS - Entering Protected Mode
|
||||
;
|
||||
|
||||
cli
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[164],'c'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
db 66h
|
||||
lgdt fword ptr [gdtr]
|
||||
db 66h
|
||||
lidt fword ptr [idtr]
|
||||
|
||||
mov eax,cr0
|
||||
or al,1
|
||||
mov cr0,eax
|
||||
|
||||
mov eax,0008h ; Flat data descriptor
|
||||
mov ebp,000400000h ; Destination of EFILDR32
|
||||
mov ebx,000070000h ; Length of copy
|
||||
|
||||
JUMP:
|
||||
; jmp far 0010:00020000
|
||||
db 066h
|
||||
db 0eah
|
||||
dd 000020000h
|
||||
dw 00010h
|
||||
|
||||
Empty8042InputBuffer:
|
||||
mov cx,0
|
||||
Empty8042Loop:
|
||||
out DELAY_PORT,ax ; Delay 1us
|
||||
in al,KBD_STATUS_PORT ; Read the 8042 Status Port
|
||||
and al,02h ; Check the Input Buffer Full Flag
|
||||
loopnz Empty8042Loop ; Loop until the input buffer is empty or a timout of 65536 uS
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; data
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 02h
|
||||
|
||||
gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit
|
||||
dd 0 ; (GDT base gets set above)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; global descriptor table (GDT)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 02h
|
||||
|
||||
public GDT_BASE
|
||||
GDT_BASE:
|
||||
; null descriptor
|
||||
NULL_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 15:0
|
||||
dw 0 ; base 15:0
|
||||
db 0 ; base 23:16
|
||||
db 0 ; type
|
||||
db 0 ; limit 19:16, flags
|
||||
db 0 ; base 31:24
|
||||
|
||||
; linear data segment descriptor
|
||||
LINEAR_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; linear code segment descriptor
|
||||
LINEAR_CODE_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; system data segment descriptor
|
||||
SYS_DATA_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; system code segment descriptor
|
||||
SYS_CODE_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE3_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE4_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE5_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
GDT_END:
|
||||
|
||||
align 02h
|
||||
|
||||
|
||||
|
||||
idtr dw IDT_END - IDT_BASE - 1 ; IDT limit
|
||||
dd 0 ; (IDT base gets set above)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; interrupt descriptor table (IDT)
|
||||
;
|
||||
; Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ
|
||||
; mappings. This implementation only uses the system timer and all other
|
||||
; IRQs will remain masked. The descriptors for vectors 33+ are provided
|
||||
; for convenience.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;idt_tag db "IDT",0
|
||||
align 02h
|
||||
|
||||
public IDT_BASE
|
||||
IDT_BASE:
|
||||
; divide by zero (INT 0)
|
||||
DIV_ZERO_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; debug exception (INT 1)
|
||||
DEBUG_EXCEPT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; NMI (INT 2)
|
||||
NMI_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; soft breakpoint (INT 3)
|
||||
BREAKPOINT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; overflow (INT 4)
|
||||
OVERFLOW_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; bounds check (INT 5)
|
||||
BOUNDS_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; invalid opcode (INT 6)
|
||||
INVALID_OPCODE_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; device not available (INT 7)
|
||||
DEV_NOT_AVAIL_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; double fault (INT 8)
|
||||
DOUBLE_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Coprocessor segment overrun - reserved (INT 9)
|
||||
RSVD_INTR_SEL1 equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; invalid TSS (INT 0ah)
|
||||
INVALID_TSS_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; segment not present (INT 0bh)
|
||||
SEG_NOT_PRESENT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; stack fault (INT 0ch)
|
||||
STACK_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; general protection (INT 0dh)
|
||||
GP_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; page fault (INT 0eh)
|
||||
PAGE_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Intel reserved - do not use (INT 0fh)
|
||||
RSVD_INTR_SEL2 equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; floating point error (INT 10h)
|
||||
FLT_POINT_ERR_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; alignment check (INT 11h)
|
||||
ALIGNMENT_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; machine check (INT 12h)
|
||||
MACHINE_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; SIMD floating-point exception (INT 13h)
|
||||
SIMD_EXCEPTION_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; 85 unspecified descriptors, First 12 of them are reserved, the rest are avail
|
||||
db (85 * 8) dup(0)
|
||||
|
||||
; IRQ 0 (System timer) - (INT 68h)
|
||||
IRQ0_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 1 (8042 Keyboard controller) - (INT 69h)
|
||||
IRQ1_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
|
||||
IRQ2_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 3 (COM 2) - (INT 6bh)
|
||||
IRQ3_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 4 (COM 1) - (INT 6ch)
|
||||
IRQ4_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 5 (LPT 2) - (INT 6dh)
|
||||
IRQ5_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 6 (Floppy controller) - (INT 6eh)
|
||||
IRQ6_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 7 (LPT 1) - (INT 6fh)
|
||||
IRQ7_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 8 (RTC Alarm) - (INT 70h)
|
||||
IRQ8_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 9 - (INT 71h)
|
||||
IRQ9_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 10 - (INT 72h)
|
||||
IRQ10_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 11 - (INT 73h)
|
||||
IRQ11_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 12 (PS/2 mouse) - (INT 74h)
|
||||
IRQ12_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 13 (Floating point error) - (INT 75h)
|
||||
IRQ13_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 14 (Secondary IDE) - (INT 76h)
|
||||
IRQ14_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 15 (Primary IDE) - (INT 77h)
|
||||
IRQ15_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
IDT_END:
|
||||
|
||||
align 02h
|
||||
|
||||
MemoryMapSize dd 0
|
||||
MemoryMap dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
|
||||
dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
|
||||
org 0fe0h
|
||||
MyStack:
|
||||
; below is the pieces of the IVT that is used to redirect INT 68h - 6fh
|
||||
; back to INT 08h - 0fh when in real mode... It is 'org'ed to a
|
||||
; known low address (20f00) so it can be set up by PlMapIrqToVect in
|
||||
; 8259.c
|
||||
|
||||
int 8
|
||||
iret
|
||||
|
||||
int 9
|
||||
iret
|
||||
|
||||
int 10
|
||||
iret
|
||||
|
||||
int 11
|
||||
iret
|
||||
|
||||
int 12
|
||||
iret
|
||||
|
||||
int 13
|
||||
iret
|
||||
|
||||
int 14
|
||||
iret
|
||||
|
||||
int 15
|
||||
iret
|
||||
|
||||
|
||||
org 0ffeh
|
||||
BlockSignature:
|
||||
dw 0aa55h
|
||||
|
||||
end
|
1147
DuetPkg/BootSector/start64.asm
Normal file
1147
DuetPkg/BootSector/start64.asm
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user