]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/BootSector/bs16.asm
Update the copyright notice format
[mirror_edk2.git] / DuetPkg / BootSector / bs16.asm
CommitLineData
c69dd9df 1;------------------------------------------------------------------------------\r
2;*\r
b1f700a8
HT
3;* Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.<BR>\r
4;* This program and the accompanying materials \r
c69dd9df 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;* bs16.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 036315244h ; "DR16"\r
31LOADER_FILENAME_PART3 EQU 020202036h ; "6___"\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
52PhysicalDrive db 0 ; PhysicalDriveNumber - 8 bits - ignored\r
53CurrentHead db 0 ; Current Head - 8 bits\r
54Signature db 0 ; Signature - 8 bits - ignored\r
55Id db " " ; Id - 4 bytes\r
56FatLabel db " " ; Label - 11 bytes\r
57SystemId db "FAT16 " ; SystemId - 8 bytes\r
58\r
59BootSectorEntryPoint:\r
60 ASSUME ds:@code\r
61 ASSUME ss:@code\r
62\r
63; ****************************************************************************\r
64; Start Print\r
65; ****************************************************************************\r
66 lea si, cs:[StartString]\r
67 call PrintString\r
68\r
69; ****************************************************************************\r
70; Print over\r
71; ****************************************************************************\r
72\r
73 mov ax,cs ; ax = 0\r
74 mov ss,ax ; ss = 0\r
75 add ax,1000h\r
76 mov ds,ax\r
77\r
78 mov sp,07c00h ; sp = 0x7c00\r
79 mov bp,sp ; bp = 0x7c00\r
80\r
81 mov ah,8 ; ah = 8 - Get Drive Parameters Function\r
82 mov byte ptr [bp+PhysicalDrive],dl ; BBS defines that BIOS would pass the booting driver number to the loader through DL\r
83 int 13h ; Get Drive Parameters\r
84 xor ax,ax ; ax = 0\r
85 mov al,dh ; al = dh\r
86 inc al ; MaxHead = al + 1\r
87 push ax ; 0000:7bfe = MaxHead\r
88 mov al,cl ; al = cl\r
89 and al,03fh ; MaxSector = al & 0x3f\r
90 push ax ; 0000:7bfc = MaxSector\r
91\r
92 cmp word ptr [bp+SectorSignature],0aa55h ; Verify Boot Sector Signature\r
93 jne BadBootSector\r
94 mov cx,word ptr [bp+RootEntries] ; cx = RootEntries\r
95 shl cx,FAT_DIRECTORY_ENTRY_SHIFT ; cx = cx * 32 = cx * sizeof(FAT_DIRECTORY_ENTRY) = Size of Root Directory in bytes\r
96 mov bx,cx ; bx = size of the Root Directory in bytes\r
97 and bx,BLOCK_MASK ; See if it is an even number of sectors long\r
98 jne BadBootSector ; If is isn't, then the boot sector is bad.\r
99 mov bx,cx ; bx = size of the Root Directory in bytes\r
100 shr bx,BLOCK_SHIFT ; bx = size of Root Directory in sectors\r
101 mov al,byte ptr [bp+NoFats] ; al = NoFats\r
102 xor ah,ah ; ah = 0 ==> ax = NoFats\r
103 mul word ptr [bp+SectorsPerFat] ; ax = NoFats * SectorsPerFat\r
104 add ax,word ptr [bp+ReservedSectors] ; ax = NoFats * SectorsPerFat + ReservedSectors = RootLBA\r
105 push ds\r
106 pop es\r
107 xor di,di ; Store directory in es:di = 1000:0000\r
108 call ReadBlocks ; Read entire Root Directory\r
109 add ax,bx ; ax = NoFats * SectorsPerFat + ReservedSectors + RootDirSectors = FirstClusterLBA (FirstDataSector)\r
110 mov word ptr [bp],ax ; Save FirstClusterLBA (FirstDataSector) for later use\r
111\r
112 ; dx - variable storage (initial value is 0)\r
113 ; bx - loader (initial value is 0)\r
114 xor dx, dx\r
115 xor bx, bx\r
116\r
117FindEFILDR:\r
118 cmp dword ptr [di],LOADER_FILENAME_PART1 ; Compare to "EFIL"\r
119 jne FindVARSTORE\r
120 cmp dword ptr [di+4],LOADER_FILENAME_PART2\r
121 jne FindVARSTORE\r
122 cmp dword ptr [di+7],LOADER_FILENAME_PART3\r
123 jne FindVARSTORE\r
124 mov bx, word ptr [di+26] ; bx = Start Cluster for EFILDR <----------------------------------\r
125 test dx, dx\r
126 je FindNext ; Efivar.bin is not loaded\r
127 jmp FoundAll\r
128\r
129FindVARSTORE:\r
130 ; if the file is not loader file, see if it's "EFIVAR BIN"\r
131 cmp dword ptr [di], 056494645h ; Compare to "EFIV"\r
132 jne FindNext\r
133 cmp dword ptr [di+4], 020205241h ; Compare to "AR "\r
134 jne FindNext\r
135 cmp dword ptr [di+7], 04e494220h ; Compare to " BIN"\r
136 jne FindNext\r
137 mov dx, di ; dx = Offset of Start Cluster for Efivar.bin <---------------------\r
138 add dx, 26\r
139 test bx, bx\r
140 je FindNext ; Efildr is not loaded\r
141 jmp FoundAll\r
142 \r
143FindNext:\r
144 ; go to next find\r
145 add di,FAT_DIRECTORY_ENTRY_SIZE ; Increment di\r
146 sub cx,FAT_DIRECTORY_ENTRY_SIZE ; Decrement cx\r
147 ; TODO: jump to FindVarStore if ...\r
148 jne FindEFILDR\r
149 jmp NotFoundAll\r
150\r
151FoundAll:\r
152FoundEFILDR:\r
153 mov cx,bx ; cx = Start Cluster for EFILDR <----------------------------------\r
154 mov ax,cs ; Destination = 2000:0000\r
155 add ax,2000h\r
156 mov es,ax\r
157 xor di,di\r
158ReadFirstClusterOfEFILDR:\r
159 mov ax,cx ; ax = StartCluster\r
160 sub ax,2 ; ax = StartCluster - 2\r
161 xor bh,bh \r
162 mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster\r
163 push dx\r
164 mul bx\r
165 pop dx ; ax = (StartCluster - 2) * SectorsPerCluster\r
166 add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster\r
167 xor bh,bh\r
168 mov bl,byte ptr [bp+SectorsPerCluster] ; bx = Number of Sectors in a cluster\r
169 push es\r
170 call ReadBlocks\r
171 pop ax\r
172JumpIntoFirstSectorOfEFILDR:\r
173 mov word ptr [bp+JumpSegment],ax\r
174JumpFarInstruction:\r
175 db 0eah\r
176JumpOffset:\r
177 dw 0000h\r
178JumpSegment:\r
179 dw 2000h\r
180\r
181\r
182PrintString:\r
183 mov ax,0b800h\r
184 mov es,ax\r
185 mov ax, 07c0h\r
186 mov ds, ax\r
187 mov cx, 7\r
188 mov di, 160\r
189 rep movsw\r
190 ret\r
191; ****************************************************************************\r
192; ReadBlocks - Reads a set of blocks from a block device\r
193;\r
194; AX = Start LBA\r
195; BX = Number of Blocks to Read\r
196; ES:DI = Buffer to store sectors read from disk\r
197; ****************************************************************************\r
198\r
199; cx = Blocks\r
200; bx = NumberOfBlocks\r
201; si = StartLBA\r
202\r
203ReadBlocks:\r
204 pusha\r
205 add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA\r
206 add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA\r
207 mov esi,eax ; esi = Start LBA\r
208 mov cx,bx ; cx = Number of blocks to read\r
209ReadCylinderLoop:\r
210 mov bp,07bfch ; bp = 0x7bfc\r
211 mov eax,esi ; eax = Start LBA\r
212 xor edx,edx ; edx = 0\r
213 movzx ebx,word ptr [bp] ; bx = MaxSector\r
214 div ebx ; ax = StartLBA / MaxSector\r
215 inc dx ; dx = (StartLBA % MaxSector) + 1\r
216 sub bx,dx ; bx = MaxSector - Sector\r
217 inc bx ; bx = MaxSector - Sector + 1\r
218 cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)\r
219 jg LimitTransfer\r
220 mov bx,cx ; bx = Blocks\r
221LimitTransfer:\r
222 push cx\r
223 mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector\r
224 xor dx,dx ; dx = 0\r
225 div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder \r
226 ; dx = ax % (MaxHead + 1) = Head\r
227\r
228 push bx ; Save number of blocks to transfer\r
229 mov dh,dl ; dh = Head\r
230 mov bp,07c00h ; bp = 0x7c00\r
231 mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number\r
232 mov ch,al ; ch = Cylinder\r
233 mov al,bl ; al = Blocks\r
234 mov ah,2 ; ah = Function 2\r
235 mov bx,di ; es:bx = Buffer address\r
236 int 013h\r
237 jc DiskError\r
238 pop bx\r
239 pop cx\r
240 movzx ebx,bx\r
241 add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks\r
242 sub cx,bx ; Blocks = Blocks - NumberOfBlocks\r
243 mov ax,es\r
244 shl bx,(BLOCK_SHIFT-4)\r
245 add ax,bx\r
246 mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE\r
247 cmp cx,0\r
248 jne ReadCylinderLoop\r
249 popa\r
250 ret\r
251\r
252; ****************************************************************************\r
253; ERROR Condition:\r
254; ****************************************************************************\r
255NotFoundAll:\r
256 ; if we found EFILDR, continue\r
257 test bx,bx\r
258 jne FoundEFILDR\r
259BadBootSector:\r
260DiskError:\r
261 lea si, cs:[ErrorString]\r
262 call PrintString\r
263Halt:\r
264 jmp Halt\r
265\r
266StartString:\r
267 db 'B', 0ch, 'S', 0ch, 't', 0ch, 'a', 0ch, 'r', 0ch, 't', 0ch, '!', 0ch\r
268ErrorString:\r
269 db 'B', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch\r
270\r
271; ****************************************************************************\r
272; LBA Offset for BootSector, need patched by tool for HD boot.\r
273; ****************************************************************************\r
274\r
275 org 01fah\r
276LBAOffsetForBootSector:\r
277 dd 0h\r
278\r
279; ****************************************************************************\r
280; Sector Signature\r
281; ****************************************************************************\r
282\r
283 org 01feh\r
284SectorSignature:\r
285 dw 0aa55h ; Boot Sector Signature\r
286\r
287 end \r
288 \r