1 ;------------------------------------------------------------------------------
3 ;* Copyright 2006 - 2007, Intel Corporation
4 ;* All rights reserved. This program and the accompanying materials
5 ;* are licensed and made available under the terms and conditions of the BSD License
6 ;* which accompanies this distribution. The full text of the license may be found at
7 ;* http://opensource.org/licenses/bsd-license.php
9 ;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 ;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 ;------------------------------------------------------------------------------
23 FAT_DIRECTORY_ENTRY_SIZE
EQU 020h
24 FAT_DIRECTORY_ENTRY_SHIFT
EQU 5
29 LOADER_FILENAME_PART1
EQU 04c494645h
; "EFIL"
30 LOADER_FILENAME_PART2
EQU 030325244h ; "DR20"
31 LOADER_FILENAME_PART3
EQU 020202030h ; "0___"
35 jmp BootSectorEntryPoint
; JMP inst - 3 bytes
38 OemId
db "INTEL " ; OemId - 8 bytes
39 ; BPB data below will be fixed by tool
40 SectorSize
dw 0 ; Sector Size - 16 bits
41 SectorsPerCluster
db 0 ; Sector Per Cluster - 8 bits
42 ReservedSectors
dw 0 ; Reserved Sectors - 16 bits
43 NoFats
db 0 ; Number of FATs - 8 bits
44 RootEntries
dw 0 ; Root Entries - 16 bits
45 Sectors
dw 0 ; Number of Sectors - 16 bits
46 Media
db 0 ; Media - 8 bits - ignored
47 SectorsPerFat
dw 0 ; Sectors Per FAT - 16 bits
48 SectorsPerTrack
dw 0 ; Sectors Per Track - 16 bits - ignored
49 Heads
dw 0 ; Heads - 16 bits - ignored
50 HiddenSectors
dd 0 ; Hidden Sectors - 32 bits - ignored
51 LargeSectors
dd 0 ; Large Sectors - 32 bits
53 ;******************************************************************************
55 ;The structure for FAT32 starting at offset 36 of the boot sector. (At this point,
56 ;the BPB/boot sector for FAT12 and FAT16 differs from the BPB/boot sector for FAT32.)
58 ;******************************************************************************
60 SectorsPerFat32
dd 0 ; Sectors Per FAT for FAT32 - 4 bytes
61 ExtFlags
dw 0 ; Mirror Flag - 2 bytes
62 FSVersion
dw 0 ; File System Version - 2 bytes
63 RootCluster
dd 0 ; 1st Cluster Number of Root Dir - 4 bytes
64 FSInfo
dw 0 ; Sector Number of FSINFO - 2 bytes
65 BkBootSector
dw 0 ; Sector Number of Bk BootSector - 2 bytes
66 Reserved
db 12 dup
(0) ; Reserved Field - 12 bytes
67 PhysicalDrive
db 0 ; Physical Drive Number - 1 byte
68 Reserved1
db 0 ; Reserved Field - 1 byte
69 Signature
db 0 ; Extended Boot Signature - 1 byte
70 VolId
db " " ; Volume Serial Number - 4 bytes
71 FatLabel
db " " ; Volume Label - 11 bytes
72 FileSystemType
db "FAT32 " ; File System Type - 8 bytes
78 ; ****************************************************************************
80 ; ****************************************************************************
81 lea si, cs:[StartString
]
84 ; ****************************************************************************
86 ; ****************************************************************************
93 mov sp,07c00h
; sp = 0x7c00
94 mov bp,sp ; bp = 0x7c00
96 mov ah,8 ; ah = 8 - Get Drive Parameters Function
97 mov byte ptr [bp+PhysicalDrive
],dl ; BBS defines that BIOS would pass the booting driver number to the loader through DL
98 int 13h ; Get Drive Parameters
101 inc al ; MaxHead = al + 1
102 push ax ; 0000:7bfe = MaxHead
104 and al,03fh
; MaxSector = al & 0x3f
105 push ax ; 0000:7bfc = MaxSector
107 cmp word ptr [bp+SectorSignature
],0aa55h
; Verify Boot Sector Signature
109 mov cx,word ptr [bp+RootEntries
] ; cx = RootEntries
110 shl cx,FAT_DIRECTORY_ENTRY_SHIFT
; cx = cx * 32 = cx * sizeof(FAT_DIRECTORY_ENTRY) = Size of Root Directory in bytes
111 mov bx,cx ; bx = size of the Root Directory in bytes
112 and bx,BLOCK_MASK
; See if it is an even number of sectors long
113 jne BadBootSector
; If is isn't, then the boot sector is bad.
114 mov bx,cx ; bx = size of the Root Directory in bytes
115 shr bx,BLOCK_SHIFT
; bx = size of Root Directory in sectors
116 mov al,byte ptr [bp+NoFats
] ; al = NoFats
117 xor ah,ah ; ah = 0 ==> ax = NoFats
118 mul word ptr [bp+SectorsPerFat32
] ; ax = NoFats * SectorsPerFat
119 add ax,word ptr [bp+ReservedSectors
] ; ax = NoFats * SectorsPerFat + ReservedSectors = RootLBA
120 add ax,bx ; ax = NoFats * SectorsPerFat + ReservedSectors + RootDirSectors = FirstClusterLBA
121 mov word ptr [bp],ax ; Save FirstClusterLBA for later use
123 mov ax,word ptr [bp+RootCluster
] ; ax = StartCluster of Root Directory
124 sub ax,2 ; ax = StartCluster - 2
126 mov bl,byte ptr [bp+SectorsPerCluster
]; bx = SectorsPerCluster
127 mul bx ; ax = (StartCluster - 2) * SectorsPerCluster
128 add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
131 xor di,di ; Store directory in es:di = 1000:0000
132 call ReadBlocks
; Read StartCluster of Root Directory
134 ; dx - variable storage (initial value is 0)
135 ; bx - loader (initial value is 0)
140 cmp dword ptr [di],LOADER_FILENAME_PART1
; Compare to "EFIL"
142 cmp dword ptr [di+4],LOADER_FILENAME_PART2
144 cmp dword ptr [di+7],LOADER_FILENAME_PART3
146 mov bx, word ptr [di+26] ; bx = Start Cluster for EFILDR <----------------------------------
148 je FindNext
; Efivar.bin is not loaded
152 ; if the file is not loader file, see if it's "EFIVAR BIN"
153 cmp dword ptr [di], 056494645h ; Compare to "EFIV"
155 cmp dword ptr [di+4], 020205241h ; Compare to "AR "
157 cmp dword ptr [di+7], 04e494220h
; Compare to " BIN"
159 mov dx, di ; dx = Offset of Start Cluster for Efivar.bin <---------------------
162 je FindNext
; Efildr is not loaded
167 add di,FAT_DIRECTORY_ENTRY_SIZE
; Increment di
168 sub cx,FAT_DIRECTORY_ENTRY_SIZE
; Decrement cx
169 ; TODO: jump to FindVarStore if ...
175 mov cx,bx ; cx = Start Cluster for EFILDR <----------------------------------
176 mov ax,cs ; Destination = 2000:0000
180 ReadFirstClusterOfEFILDR:
181 mov ax,cx ; ax = StartCluster
182 sub ax,2 ; ax = StartCluster - 2
184 mov bl,byte ptr [bp+SectorsPerCluster
] ; bx = SectorsPerCluster
187 pop dx ; ax = (StartCluster - 2) * SectorsPerCluster
188 add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
190 mov bl,byte ptr [bp+SectorsPerCluster
] ; bx = Number of Sectors in a cluster
194 JumpIntoFirstSectorOfEFILDR:
195 mov word ptr [bp+JumpSegment
],ax
213 ; ****************************************************************************
214 ; ReadBlocks - Reads a set of blocks from a block device
217 ; BX = Number of Blocks to Read
218 ; ES:DI = Buffer to store sectors read from disk
219 ; ****************************************************************************
222 ; bx = NumberOfBlocks
227 add eax,dword ptr [bp+LBAOffsetForBootSector
] ; Add LBAOffsetForBootSector to Start LBA
228 add eax,dword ptr [bp+HiddenSectors
] ; Add HiddenSectors to Start LBA
229 mov esi,eax ; esi = Start LBA
230 mov cx,bx ; cx = Number of blocks to read
232 mov bp,07bfch
; bp = 0x7bfc
233 mov eax,esi ; eax = Start LBA
234 xor edx,edx ; edx = 0
235 movzx ebx,word ptr [bp] ; bx = MaxSector
236 div ebx ; ax = StartLBA / MaxSector
237 inc dx ; dx = (StartLBA % MaxSector) + 1
238 sub bx,dx ; bx = MaxSector - Sector
239 inc bx ; bx = MaxSector - Sector + 1
240 cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)
242 mov bx,cx ; bx = Blocks
245 mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector
247 div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder
248 ; dx = ax % (MaxHead + 1) = Head
250 push bx ; Save number of blocks to transfer
251 mov dh,dl ; dh = Head
252 mov bp,07c00h
; bp = 0x7c00
253 mov dl,byte ptr [bp+PhysicalDrive
] ; dl = Drive Number
254 mov ch,al ; ch = Cylinder
255 mov al,bl ; al = Blocks
256 mov ah,2 ; ah = Function 2
257 mov bx,di ; es:bx = Buffer address
263 add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks
264 sub cx,bx ; Blocks = Blocks - NumberOfBlocks
266 shl bx,(BLOCK_SHIFT
-4)
268 mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE
274 ; ****************************************************************************
276 ; ****************************************************************************
278 ; if we found EFILDR, continue
283 lea si, cs:[ErrorString
]
289 db 'B', 0ch, 'S', 0ch, 't', 0ch, 'a', 0ch, 'r', 0ch, 't', 0ch, '!', 0ch
291 db 'B', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
293 ; ****************************************************************************
294 ; LBA Offset for BootSector, need patched by tool for HD boot.
295 ; ****************************************************************************
298 LBAOffsetForBootSector:
301 ; ****************************************************************************
303 ; ****************************************************************************
307 dw 0aa55h
; Boot Sector Signature