]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/BootSector/bs32.asm
Remove exit from batch file
[mirror_edk2.git] / DuetPkg / BootSector / bs32.asm
CommitLineData
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;* bs32.asm\r
13;* \r
14;* Abstract:\r
15;*\r
16;------------------------------------------------------------------------------\r
17\r
18 .model small\r
19 .stack\r
20 .486p\r
21 .code\r
22\r
23FAT_DIRECTORY_ENTRY_SIZE EQU 020h\r
24FAT_DIRECTORY_ENTRY_SHIFT EQU 5\r
25BLOCK_SIZE EQU 0200h\r
26BLOCK_MASK EQU 01ffh\r
27BLOCK_SHIFT EQU 9\r
28 ; "EFILDR_____"\r
29LOADER_FILENAME_PART1 EQU 04c494645h ; "EFIL"\r
30LOADER_FILENAME_PART2 EQU 030325244h ; "DR20"\r
31LOADER_FILENAME_PART3 EQU 020202030h ; "0___"\r
32\r
33 org 0h\r
34Ia32Jump:\r
35 jmp BootSectorEntryPoint ; JMP inst - 3 bytes\r
36 nop\r
37\r
38OemId db "INTEL " ; OemId - 8 bytes\r
39; BPB data below will be fixed by tool\r\r
40SectorSize dw 0 ; Sector Size - 16 bits\r
41SectorsPerCluster db 0 ; Sector Per Cluster - 8 bits\r
42ReservedSectors dw 0 ; Reserved Sectors - 16 bits\r
43NoFats db 0 ; Number of FATs - 8 bits\r
44RootEntries dw 0 ; Root Entries - 16 bits\r
45Sectors dw 0 ; Number of Sectors - 16 bits\r
46Media db 0 ; Media - 8 bits - ignored\r
47SectorsPerFat dw 0 ; Sectors Per FAT - 16 bits\r
48SectorsPerTrack dw 0 ; Sectors Per Track - 16 bits - ignored\r
49Heads dw 0 ; Heads - 16 bits - ignored\r
50HiddenSectors dd 0 ; Hidden Sectors - 32 bits - ignored\r
51LargeSectors dd 0 ; Large Sectors - 32 bits \r
52\r
53;******************************************************************************\r
54;\r
55;The structure for FAT32 starting at offset 36 of the boot sector. (At this point, \r
56;the BPB/boot sector for FAT12 and FAT16 differs from the BPB/boot sector for FAT32.)\r
57;\r
58;******************************************************************************\r
59\r
60SectorsPerFat32 dd 0 ; Sectors Per FAT for FAT32 - 4 bytes\r
61ExtFlags dw 0 ; Mirror Flag - 2 bytes\r
62FSVersion dw 0 ; File System Version - 2 bytes\r
63RootCluster dd 0 ; 1st Cluster Number of Root Dir - 4 bytes\r
64FSInfo dw 0 ; Sector Number of FSINFO - 2 bytes\r
65BkBootSector dw 0 ; Sector Number of Bk BootSector - 2 bytes\r
66Reserved db 12 dup(0) ; Reserved Field - 12 bytes\r
67PhysicalDrive db 0 ; Physical Drive Number - 1 byte\r
68Reserved1 db 0 ; Reserved Field - 1 byte\r
69Signature db 0 ; Extended Boot Signature - 1 byte\r
70VolId db " " ; Volume Serial Number - 4 bytes\r
71FatLabel db " " ; Volume Label - 11 bytes\r
72FileSystemType db "FAT32 " ; File System Type - 8 bytes\r
73\r
74BootSectorEntryPoint:\r
75 ASSUME ds:@code\r
76 ASSUME ss:@code\r
77\r
78; ****************************************************************************\r
79; Start Print\r
80; ****************************************************************************\r
81 lea si, cs:[StartString]\r
82 call PrintString\r
83\r
84; ****************************************************************************\r
85; Print over\r
86; ****************************************************************************\r
87\r
88 mov ax,cs ; ax = 0\r
89 mov ss,ax ; ss = 0\r
90 add ax,1000h\r
91 mov ds,ax\r
92\r
93 mov sp,07c00h ; sp = 0x7c00\r
94 mov bp,sp ; bp = 0x7c00\r
95\r
96 mov ah,8 ; ah = 8 - Get Drive Parameters Function\r
97 mov byte ptr [bp+PhysicalDrive],dl ; BBS defines that BIOS would pass the booting driver number to the loader through DL\r
98 int 13h ; Get Drive Parameters\r
99 xor ax,ax ; ax = 0\r
100 mov al,dh ; al = dh\r
101 inc al ; MaxHead = al + 1\r
102 push ax ; 0000:7bfe = MaxHead\r
103 mov al,cl ; al = cl\r
104 and al,03fh ; MaxSector = al & 0x3f\r
105 push ax ; 0000:7bfc = MaxSector\r
106\r
107 cmp word ptr [bp+SectorSignature],0aa55h ; Verify Boot Sector Signature\r
108 jne BadBootSector\r
109 mov cx,word ptr [bp+RootEntries] ; cx = RootEntries\r
110 shl cx,FAT_DIRECTORY_ENTRY_SHIFT ; cx = cx * 32 = cx * sizeof(FAT_DIRECTORY_ENTRY) = Size of Root Directory in bytes\r
111 mov bx,cx ; bx = size of the Root Directory in bytes\r
112 and bx,BLOCK_MASK ; See if it is an even number of sectors long\r
113 jne BadBootSector ; If is isn't, then the boot sector is bad.\r
114 mov bx,cx ; bx = size of the Root Directory in bytes\r
115 shr bx,BLOCK_SHIFT ; bx = size of Root Directory in sectors\r
116 mov al,byte ptr [bp+NoFats] ; al = NoFats\r
117 xor ah,ah ; ah = 0 ==> ax = NoFats\r
118 mul word ptr [bp+SectorsPerFat32] ; ax = NoFats * SectorsPerFat\r
119 add ax,word ptr [bp+ReservedSectors] ; ax = NoFats * SectorsPerFat + ReservedSectors = RootLBA\r
120 add ax,bx ; ax = NoFats * SectorsPerFat + ReservedSectors + RootDirSectors = FirstClusterLBA\r
121 mov word ptr [bp],ax ; Save FirstClusterLBA for later use\r
122 \r
123 mov ax,word ptr [bp+RootCluster] ; ax = StartCluster of Root Directory\r
124 sub ax,2 ; ax = StartCluster - 2\r
125 xor bh,bh \r
126 mov bl,byte ptr [bp+SectorsPerCluster]; bx = SectorsPerCluster\r
127 mul bx ; ax = (StartCluster - 2) * SectorsPerCluster\r
128 add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster\r
129 push ds\r
130 pop es\r
131 xor di,di ; Store directory in es:di = 1000:0000\r
132 call ReadBlocks ; Read StartCluster of Root Directory\r
133\r
134 ; dx - variable storage (initial value is 0)\r
135 ; bx - loader (initial value is 0)\r
136 xor dx, dx\r
137 xor bx, bx\r
138\r
139FindEFILDR:\r
140 cmp dword ptr [di],LOADER_FILENAME_PART1 ; Compare to "EFIL"\r
141 jne FindVARSTORE\r
142 cmp dword ptr [di+4],LOADER_FILENAME_PART2\r
143 jne FindVARSTORE\r
144 cmp dword ptr [di+7],LOADER_FILENAME_PART3\r
145 jne FindVARSTORE\r
146 mov bx, word ptr [di+26] ; bx = Start Cluster for EFILDR <----------------------------------\r
147 test dx, dx\r
148 je FindNext ; Efivar.bin is not loaded\r
149 jmp FoundAll\r
150\r
151FindVARSTORE:\r
152 ; if the file is not loader file, see if it's "EFIVAR BIN"\r
153 cmp dword ptr [di], 056494645h ; Compare to "EFIV"\r
154 jne FindNext\r
155 cmp dword ptr [di+4], 020205241h ; Compare to "AR "\r
156 jne FindNext\r
157 cmp dword ptr [di+7], 04e494220h ; Compare to " BIN"\r
158 jne FindNext\r
159 mov dx, di ; dx = Offset of Start Cluster for Efivar.bin <---------------------\r
160 add dx, 26\r
161 test bx, bx\r
162 je FindNext ; Efildr is not loaded\r
163 jmp FoundAll\r
164 \r
165FindNext:\r
166 ; go to next find\r
167 add di,FAT_DIRECTORY_ENTRY_SIZE ; Increment di\r
168 sub cx,FAT_DIRECTORY_ENTRY_SIZE ; Decrement cx\r
169 ; TODO: jump to FindVarStore if ...\r
170 jne FindEFILDR\r
171 jmp NotFoundAll\r
172\r
173FoundAll:\r
174FoundEFILDR:\r
175 mov cx,bx ; cx = Start Cluster for EFILDR <----------------------------------\r
176 mov ax,cs ; Destination = 2000:0000\r
177 add ax,2000h\r
178 mov es,ax\r
179 xor di,di\r
180ReadFirstClusterOfEFILDR:\r
181 mov ax,cx ; ax = StartCluster\r
182 sub ax,2 ; ax = StartCluster - 2\r
183 xor bh,bh \r
184 mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster\r
185 push dx\r
186 mul bx\r
187 pop dx ; ax = (StartCluster - 2) * SectorsPerCluster\r
188 add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster\r
189 xor bh,bh\r
190 mov bl,byte ptr [bp+SectorsPerCluster] ; bx = Number of Sectors in a cluster\r
191 push es\r
192 call ReadBlocks\r
193 pop ax\r
194JumpIntoFirstSectorOfEFILDR:\r
195 mov word ptr [bp+JumpSegment],ax\r
196JumpFarInstruction:\r
197 db 0eah\r
198JumpOffset:\r
199 dw 0000h\r
200JumpSegment:\r
201 dw 2000h\r
202\r
203\r
204PrintString:\r
205 mov ax,0b800h\r
206 mov es,ax\r
207 mov ax, 07c0h\r
208 mov ds, ax\r
209 mov cx, 7\r
210 mov di, 160\r
211 rep movsw\r
212 ret\r
213; ****************************************************************************\r
214; ReadBlocks - Reads a set of blocks from a block device\r
215;\r
216; AX = Start LBA\r
217; BX = Number of Blocks to Read\r
218; ES:DI = Buffer to store sectors read from disk\r
219; ****************************************************************************\r
220\r
221; cx = Blocks\r
222; bx = NumberOfBlocks\r
223; si = StartLBA\r
224\r
225ReadBlocks:\r
226 pusha\r
227 add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA\r
228 add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA\r
229 mov esi,eax ; esi = Start LBA\r
230 mov cx,bx ; cx = Number of blocks to read\r
231ReadCylinderLoop:\r
232 mov bp,07bfch ; bp = 0x7bfc\r
233 mov eax,esi ; eax = Start LBA\r
234 xor edx,edx ; edx = 0\r
235 movzx ebx,word ptr [bp] ; bx = MaxSector\r
236 div ebx ; ax = StartLBA / MaxSector\r
237 inc dx ; dx = (StartLBA % MaxSector) + 1\r
238 sub bx,dx ; bx = MaxSector - Sector\r
239 inc bx ; bx = MaxSector - Sector + 1\r
240 cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)\r
241 jg LimitTransfer\r
242 mov bx,cx ; bx = Blocks\r
243LimitTransfer:\r
244 push cx\r
245 mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector\r
246 xor dx,dx ; dx = 0\r
247 div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder \r
248 ; dx = ax % (MaxHead + 1) = Head\r
249\r
250 push bx ; Save number of blocks to transfer\r
251 mov dh,dl ; dh = Head\r
252 mov bp,07c00h ; bp = 0x7c00\r
253 mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number\r
254 mov ch,al ; ch = Cylinder\r
255 mov al,bl ; al = Blocks\r
256 mov ah,2 ; ah = Function 2\r
257 mov bx,di ; es:bx = Buffer address\r
258 int 013h\r
259 jc DiskError\r
260 pop bx\r
261 pop cx\r
262 movzx ebx,bx\r
263 add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks\r
264 sub cx,bx ; Blocks = Blocks - NumberOfBlocks\r
265 mov ax,es\r
266 shl bx,(BLOCK_SHIFT-4)\r
267 add ax,bx\r
268 mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE\r
269 cmp cx,0\r
270 jne ReadCylinderLoop\r
271 popa\r
272 ret\r
273\r
274; ****************************************************************************\r
275; ERROR Condition:\r
276; ****************************************************************************\r
277NotFoundAll:\r
278 ; if we found EFILDR, continue\r
279 test bx,bx\r
280 jne FoundEFILDR\r
281BadBootSector:\r
282DiskError:\r
283 lea si, cs:[ErrorString]\r
284 call PrintString\r
285Halt:\r
286 jmp Halt\r
287\r
288StartString:\r
289 db 'B', 0ch, 'S', 0ch, 't', 0ch, 'a', 0ch, 'r', 0ch, 't', 0ch, '!', 0ch\r
290ErrorString:\r
291 db 'B', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch\r
292\r
293; ****************************************************************************\r
294; LBA Offset for BootSector, need patched by tool for HD boot.\r
295; ****************************************************************************\r
296\r
297 org 01fah\r
298LBAOffsetForBootSector:\r
299 dd 0h\r
300\r
301; ****************************************************************************\r
302; Sector Signature\r
303; ****************************************************************************\r
304\r
305 org 01feh\r
306SectorSignature:\r
307 dw 0aa55h ; Boot Sector Signature\r
308\r
309 end \r
310 \r