]>
Commit | Line | Data |
---|---|---|
c69dd9df | 1 | ;------------------------------------------------------------------------------\r |
2 | ;*\r | |
3 | ;* Copyright 2006 - 2007, Intel Corporation \r | |
4 | ;* All rights reserved. This program and the accompanying materials \r | |
5 | ;* are licensed and made available under the terms and conditions of the BSD License \r | |
6 | ;* which accompanies this distribution. The full text of the license may be found at \r | |
7 | ;* http://opensource.org/licenses/bsd-license.php \r | |
8 | ;* \r | |
9 | ;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r | |
10 | ;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r | |
11 | ;* \r | |
12 | ;* gpt.asm\r | |
13 | ;* \r | |
14 | ;* Abstract:\r | |
15 | ;*\r | |
16 | ;------------------------------------------------------------------------------\r | |
17 | \r | |
18 | .model small\r | |
19 | ; .dosseg\r | |
20 | .stack\r | |
21 | .486p\r | |
22 | .code\r | |
23 | \r | |
24 | BLOCK_SIZE EQU 0200h\r | |
25 | BLOCK_MASK EQU 01ffh\r | |
26 | BLOCK_SHIFT EQU 9\r | |
27 | \r | |
28 | ; ****************************************************************************\r | |
29 | ; Code loaded by BIOS at 0x0000:0x7C00\r | |
30 | ; ****************************************************************************\r | |
31 | \r | |
32 | org 0h\r | |
33 | Start:\r | |
34 | \r | |
35 | ; ****************************************************************************\r | |
36 | ; Start Print\r | |
37 | ; ****************************************************************************\r | |
38 | \r | |
39 | mov ax,0b800h\r | |
40 | mov es,ax\r | |
41 | mov ax, 07c0h\r | |
42 | mov ds, ax\r | |
43 | lea si, cs:[StartString]\r | |
44 | mov cx, 10\r | |
45 | mov di, 160\r | |
46 | rep movsw \r | |
47 | \r | |
48 | ; ****************************************************************************\r | |
49 | ; Print over\r | |
50 | ; ****************************************************************************\r | |
51 | \r | |
52 | ; ****************************************************************************\r | |
53 | ; Initialize segment registers and copy code at 0x0000:0x7c00 to 0x0000:0x0600\r | |
54 | ; ****************************************************************************\r | |
55 | xor ax, ax ; AX = 0x0000 \r | |
56 | mov bx, 07c00h ; BX = 0x7C00\r | |
57 | mov bp, 0600h ; BP = 0x0600\r | |
58 | mov si, OFFSET RelocatedStart ; SI = Offset(RelocatedStart)\r | |
59 | mov cx, 0200h ; CX = 0x0200\r | |
60 | sub cx, si ; CS = 0x0200 - Offset(RelocatedStart)\r | |
61 | lea di, [bp+si] ; DI = 0x0600 + Offset(RelocatedStart)\r | |
62 | lea si, [bx+si] ; BX = 0x7C00 + Offset(RelocatedStart)\r | |
63 | mov ss, ax ; SS = 0x0000\r | |
64 | mov sp, bx ; SP = 0x7C00\r | |
65 | mov es,ax ; ES = 0x0000\r | |
66 | mov ds,ax ; DS = 0x0000\r | |
67 | push ax ; PUSH 0x0000\r | |
68 | push di ; PUSH 0x0600 + Offset(RelocatedStart)\r | |
69 | cld ; Clear the direction flag\r | |
70 | rep movsb ; Copy 0x0200 bytes from 0x7C00 to 0x0600\r | |
71 | retf ; JMP 0x0000:0x0600 + Offset(RelocatedStart)\r | |
72 | \r | |
73 | ; ****************************************************************************\r | |
74 | ; Code relocated to 0x0000:0x0600\r | |
75 | ; ****************************************************************************\r | |
76 | \r | |
77 | RelocatedStart:\r | |
78 | ; ****************************************************************************\r | |
79 | ; Get Driver Parameters to 0x0000:0x7BFC\r | |
80 | ; ****************************************************************************\r | |
81 | xor ax,ax ; ax = 0\r | |
82 | mov ss,ax ; ss = 0\r | |
83 | add ax,1000h\r | |
84 | mov ds,ax\r | |
85 | \r | |
86 | mov sp,07c00h ; sp = 0x7c00\r | |
87 | mov bp,sp ; bp = 0x7c00\r | |
88 | \r | |
89 | mov ah,8 ; ah = 8 - Get Drive Parameters Function\r | |
90 | mov byte ptr [bp+PhysicalDrive],dl ; BBS defines that BIOS would pass the booting driver number to the loader through DL\r | |
91 | int 13h ; Get Drive Parameters\r | |
92 | xor ax,ax ; ax = 0\r | |
93 | mov al,dh ; al = dh\r | |
94 | inc al ; MaxHead = al + 1\r | |
95 | push ax ; 0000:7bfe = MaxHead\r | |
96 | mov al,cl ; al = cl\r | |
97 | and al,03fh ; MaxSector = al & 0x3f\r | |
98 | push ax ; 0000:7bfc = MaxSector\r | |
99 | \r | |
100 | ; ****************************************************************************\r | |
101 | ; Read GPT Header from hard disk to 0x0000:0x0800\r | |
102 | ; ****************************************************************************\r | |
103 | xor ax, ax\r | |
104 | mov es, ax ; Read to 0x0000:0x0800\r | |
105 | mov di, 0800h ; Read to 0x0000:0x0800\r | |
106 | mov eax, 1 ; Read LBA #1\r | |
107 | mov edx, 0 ; Read LBA #1\r | |
108 | mov bx, 1 ; Read 1 Block\r | |
109 | push es\r | |
110 | call ReadBlocks\r | |
111 | pop es\r | |
112 | \r | |
113 | ; ****************************************************************************\r | |
114 | ; Read Target GPT Entry from hard disk to 0x0000:0x0A00\r | |
115 | ; ****************************************************************************\r | |
116 | cmp dword ptr es:[di], 020494645h ; Check for "EFI "\r | |
117 | jne BadGpt\r | |
118 | cmp dword ptr es:[di + 4], 054524150h ; Check for "PART"\r | |
119 | jne BadGpt\r | |
120 | cmp dword ptr es:[di + 8], 000010000h ; Check Revision - 0x10000\r | |
121 | jne BadGpt\r | |
122 | \r | |
123 | mov eax, dword ptr es:[di + 84] ; EAX = SizeOfPartitionEntry\r | |
124 | mul byte ptr [bp+GptPartitionIndicator] ; EAX = SizeOfPartitionEntry * GptPartitionIndicator\r | |
125 | mov edx, eax ; EDX = SizeOfPartitionEntry * GptPartitionIndicator\r | |
126 | shr eax, BLOCK_SHIFT ; EAX = (SizeOfPartitionEntry * GptPartitionIndicator) / BLOCK_SIZE\r | |
127 | and edx, BLOCK_MASK ; EDX = Targer PartitionEntryLBA Offset\r | |
128 | ; = (SizeOfPartitionEntry * GptPartitionIndicator) % BLOCK_SIZE\r | |
129 | push edx\r | |
130 | mov ecx, dword ptr es:[di + 72] ; ECX = PartitionEntryLBA (Low)\r | |
131 | mov ebx, dword ptr es:[di + 76] ; EBX = PartitionEntryLBA (High)\r | |
132 | add eax, ecx ; EAX = Target PartitionEntryLBA (Low)\r | |
133 | ; = (PartitionEntryLBA + \r | |
134 | ; (SizeOfPartitionEntry * GptPartitionIndicator) / BLOCK_SIZE)\r | |
135 | adc edx, ebx ; EDX = Target PartitionEntryLBA (High)\r | |
136 | \r | |
137 | mov di, 0A00h ; Read to 0x0000:0x0A00\r | |
138 | mov bx, 1 ; Read 1 Block\r | |
139 | push es\r | |
140 | call ReadBlocks\r | |
141 | pop es\r | |
142 | \r | |
143 | ; ****************************************************************************\r | |
144 | ; Read Target DBR from hard disk to 0x0000:0x7C00\r | |
145 | ; ****************************************************************************\r | |
146 | pop edx ; EDX = (SizeOfPartitionEntry * GptPartitionIndicator) % BLOCK_SIZE\r | |
147 | add di, dx ; DI = Targer PartitionEntryLBA Offset\r | |
148 | cmp dword ptr es:[di], 0C12A7328h ; Check for EFI System Partition "C12A7328-F81F-11d2-BA4B-00A0C93EC93B"\r | |
149 | jne BadGpt\r | |
150 | cmp dword ptr es:[di + 4], 011d2F81Fh ; \r | |
151 | jne BadGpt\r | |
152 | cmp dword ptr es:[di + 8], 0A0004BBAh ; \r | |
153 | jne BadGpt\r | |
154 | cmp dword ptr es:[di + 0ch], 03BC93EC9h ; \r | |
155 | jne BadGpt\r | |
156 | \r | |
157 | mov eax, dword ptr es:[di + 32] ; EAX = StartingLBA (Low)\r | |
158 | mov edx, dword ptr es:[di + 36] ; EDX = StartingLBA (High)\r | |
159 | mov di, 07C00h ; Read to 0x0000:0x7C00\r | |
160 | mov bx, 1 ; Read 1 Block\r | |
161 | call ReadBlocks\r | |
162 | \r | |
163 | ; ****************************************************************************\r | |
164 | ; Transfer control to BootSector - Jump to 0x0000:0x7C00\r | |
165 | ; ****************************************************************************\r | |
166 | xor ax, ax\r | |
167 | push ax ; PUSH 0x0000\r | |
168 | mov di, 07c00h\r | |
169 | push di ; PUSH 0x7C00\r | |
170 | retf ; JMP 0x0000:0x7C00\r | |
171 | \r | |
172 | ; ****************************************************************************\r | |
173 | ; ReadBlocks - Reads a set of blocks from a block device\r | |
174 | ;\r | |
175 | ; EDX:EAX = Start LBA\r | |
176 | ; BX = Number of Blocks to Read (must < 127)\r | |
177 | ; ES:DI = Buffer to store sectors read from disk\r | |
178 | ; ****************************************************************************\r | |
179 | \r | |
180 | ; si = DiskAddressPacket\r | |
181 | \r | |
182 | ReadBlocks:\r | |
183 | pushad\r | |
184 | push ds\r | |
185 | xor cx, cx\r | |
186 | mov ds, cx\r | |
187 | mov bp, 0600h ; bp = 0x600\r | |
188 | lea si, [bp + OFFSET AddressPacket] ; DS:SI = Disk Address Packet\r | |
189 | mov BYTE PTR ds:[si+2],bl ; 02 = Number Of Block transfered\r | |
190 | mov WORD PTR ds:[si+4],di ; 04 = Transfer Buffer Offset\r | |
191 | mov WORD PTR ds:[si+6],es ; 06 = Transfer Buffer Segment\r | |
192 | mov DWORD PTR ds:[si+8],eax ; 08 = Starting LBA (Low)\r | |
193 | mov DWORD PTR ds:[si+0ch],edx ; 0C = Starting LBA (High)\r | |
194 | mov ah, 42h ; ah = Function 42\r | |
195 | mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number\r | |
196 | int 13h\r | |
197 | jc BadGpt\r | |
198 | pop ds\r | |
199 | popad\r | |
200 | ret\r | |
201 | \r | |
202 | ; ****************************************************************************\r | |
203 | ; Address Packet used by ReadBlocks\r | |
204 | ; ****************************************************************************\r | |
205 | AddressPacket:\r | |
206 | db 10h ; Size of address packet\r | |
207 | db 00h ; Reserved. Must be 0\r | |
208 | db 01h ; Read blocks at a time (To be fixed each times)\r | |
209 | db 00h ; Reserved. Must be 0\r | |
210 | dw 0000h ; Destination Address offset (To be fixed each times)\r | |
211 | dw 0000h ; Destination Address segment (To be fixed each times)\r | |
212 | AddressPacketLba:\r | |
213 | dd 0h, 0h ; Start LBA (To be fixed each times)\r | |
214 | AddressPacketEnd:\r | |
215 | \r | |
216 | ; ****************************************************************************\r | |
217 | ; ERROR Condition:\r | |
218 | ; ****************************************************************************\r | |
219 | \r | |
220 | BadGpt:\r | |
221 | mov ax,0b800h\r | |
222 | mov es,ax\r | |
223 | mov ax, 060h\r | |
224 | mov ds, ax\r | |
225 | lea si, cs:[ErrorString]\r | |
226 | mov cx, 10\r | |
227 | mov di, 320\r | |
228 | rep movsw \r | |
229 | Halt:\r | |
230 | jmp Halt\r | |
231 | \r | |
232 | StartString:\r | |
233 | db 'G', 0ch, 'P', 0ch, 'T', 0ch, ' ', 0ch, 'S', 0ch, 't', 0ch, 'a', 0ch, 'r', 0ch, 't', 0ch, '!', 0ch\r | |
234 | ErrorString:\r | |
235 | db 'G', 0ch, 'P', 0ch, 'T', 0ch, ' ', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch\r | |
236 | \r | |
237 | ; ****************************************************************************\r | |
238 | ; PhysicalDrive - Used to indicate which disk to be boot\r | |
239 | ; Can be patched by tool\r | |
240 | ; ****************************************************************************\r | |
241 | org 01B6h\r | |
242 | PhysicalDrive db 80h\r | |
243 | \r | |
244 | ; ****************************************************************************\r | |
245 | ; GptPartitionIndicator - Used to indicate which GPT partition to be boot\r | |
246 | ; Can be patched by tool\r | |
247 | ; ****************************************************************************\r | |
248 | org 01B7h\r | |
249 | GptPartitionIndicator db 0\r | |
250 | \r | |
251 | ; ****************************************************************************\r | |
252 | ; Unique MBR signature\r | |
253 | ; ****************************************************************************\r | |
254 | org 01B8h\r | |
255 | db 'DUET'\r | |
256 | \r | |
257 | ; ****************************************************************************\r | |
258 | ; Unknown\r | |
259 | ; ****************************************************************************\r | |
260 | org 01BCh\r | |
261 | dw 0\r | |
262 | \r | |
263 | ; ****************************************************************************\r | |
264 | ; PMBR Entry - Can be patched by tool\r | |
265 | ; ****************************************************************************\r | |
266 | org 01BEh\r | |
267 | db 0 ; Boot Indicator\r | |
268 | db 0ffh ; Start Header\r | |
269 | db 0ffh ; Start Sector\r | |
270 | db 0ffh ; Start Track\r | |
271 | db 0eeh ; OS Type\r | |
272 | db 0ffh ; End Header\r | |
273 | db 0ffh ; End Sector\r | |
274 | db 0ffh ; End Track\r | |
275 | dd 1 ; Starting LBA\r | |
276 | dd 0FFFFFFFFh ; End LBA\r | |
277 | \r | |
278 | org 01CEh\r | |
279 | dd 0, 0, 0, 0\r | |
280 | org 01DEh\r | |
281 | dd 0, 0, 0, 0\r | |
282 | org 01EEh\r | |
283 | dd 0, 0, 0, 0\r | |
284 | \r | |
285 | ; ****************************************************************************\r | |
286 | ; Sector Signature\r | |
287 | ; ****************************************************************************\r | |
288 | \r | |
289 | org 01FEh\r | |
290 | SectorSignature:\r | |
291 | dw 0aa55h ; Boot Sector Signature\r | |
292 | \r | |
293 | end \r | |
294 | \r |