]>
Commit | Line | Data |
---|---|---|
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 | ;* Mbr.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 | \r | |
82 | xor ax,ax ; AX = 0\r | |
83 | mov ss,ax ; SS = 0\r | |
84 | add ax,1000h\r | |
85 | mov ds,ax\r | |
86 | \r | |
87 | mov sp,07c00h ; SP = 0x7c00\r | |
88 | mov bp,sp ; BP = 0x7c00\r | |
89 | \r | |
90 | mov ah,8 ; AH = 8 - Get Drive Parameters Function\r | |
91 | mov byte ptr [bp+PhysicalDrive],dl ; BBS defines that BIOS would pass the booting driver number to the loader through DL\r | |
92 | int 13h ; Get Drive Parameters\r | |
93 | xor ax,ax ; AX = 0\r | |
94 | mov al,dh ; AL = DH\r | |
95 | inc al ; MaxHead = AL + 1\r | |
96 | push ax ; 0000:7bfe = MaxHead\r | |
97 | mov al,cl ; AL = CL\r | |
98 | and al,03fh ; MaxSector = AL & 0x3f\r | |
99 | push ax ; 0000:7bfc = MaxSector\r | |
100 | \r | |
101 | ; ****************************************************************************\r | |
102 | ; Read Target DBR from hard disk to 0x0000:0x7C00\r | |
103 | ; ****************************************************************************\r | |
104 | \r | |
105 | xor ax, ax\r | |
106 | mov al, byte ptr [bp+MbrPartitionIndicator] ; AX = MbrPartitionIndex\r | |
107 | cmp al, 0ffh ; 0xFF means do legacy MBR boot\r | |
108 | jnz EfiDbr\r | |
109 | LegacyMbr:\r | |
110 | mov eax, 00000600h ; Assume LegacyMBR is backuped in Sector 6\r | |
111 | jmp StartReadTo7C00 ; EAX = Header/Sector/Tracker/Zero\r | |
112 | \r | |
113 | EfiDbr:\r | |
114 | cmp al, 4 ; MbrPartitionIndex should < 4\r | |
115 | jae BadDbr\r | |
116 | shl ax, 4 ; AX = MBREntrySize * Index\r | |
117 | add ax, 1beh ; AX = MBREntryOffset\r | |
118 | mov di, ax ; DI = MBREntryOffset\r | |
119 | \r | |
120 | ; Here we don't use the C/H/S information provided by Partition table\r | |
121 | ; but calculate C/H/S from LBA ourselves\r | |
122 | ; Ci: Cylinder number\r | |
123 | ; Hi: Header number\r | |
124 | ; Si: Sector number\r | |
125 | mov eax, dword ptr es:[bp + di + 8] ; Start LBA\r | |
126 | mov edx, eax\r | |
127 | shr edx, 16 ; DX:AX = Start LBA\r | |
128 | ; = Ci * (H * S) + Hi * S + (Si - 1)\r | |
129 | \r | |
130 | ; Calculate C/H/S according to LBA\r | |
131 | mov bp, 7bfah\r | |
132 | div word ptr [bp+2] ; AX = Hi + H*Ci\r | |
133 | ; DX = Si - 1\r | |
134 | inc dx ; DX = Si\r | |
135 | push dx ; 0000:7bfa = Si <----\r | |
136 | xor dx, dx ; DX:AX = Hi + H*Ci\r | |
137 | div word ptr [bp+4] ; AX = Ci <----\r | |
138 | ; DX = Hi <----\r | |
139 | \r | |
140 | StartReadTo7C00:\r | |
141 | \r | |
142 | mov cl, byte ptr [bp] ; Si\r | |
143 | mov ch, al ; Ci[0-7]\r | |
144 | or cl, ah ; Ci[8,9]\r | |
145 | mov bx, 7c00h ; ES:BX = 0000:7C00h\r | |
146 | mov ah, 2h ; Function 02h\r | |
147 | mov al, 1 ; 1 Sector\r | |
148 | mov dh, dl ; Hi\r | |
149 | mov bp, 0600h\r | |
150 | mov dl, byte ptr [bp + PhysicalDrive] ; Drive number\r | |
151 | int 13h\r | |
152 | jc BadDbr\r | |
153 | \r | |
154 | \r | |
155 | \r | |
156 | ; ****************************************************************************\r | |
157 | ; Transfer control to BootSector - Jump to 0x0000:0x7C00\r | |
158 | ; ****************************************************************************\r | |
159 | xor ax, ax\r | |
160 | push ax ; PUSH 0x0000 - Segment\r | |
161 | mov di, 07c00h\r | |
162 | push di ; PUSH 0x7C00 - Offset\r | |
163 | retf ; JMP 0x0000:0x7C00\r | |
164 | \r | |
165 | ; ****************************************************************************\r | |
166 | ; ERROR Condition:\r | |
167 | ; ****************************************************************************\r | |
168 | \r | |
169 | BadDbr:\r | |
170 | push ax\r | |
171 | mov ax, 0b800h\r | |
172 | mov es, ax\r | |
173 | mov ax, 060h\r | |
174 | mov ds, ax\r | |
175 | lea si, cs:[ErrorString]\r | |
176 | mov di, 320\r | |
177 | pop ax\r | |
178 | call A2C\r | |
179 | mov [si+16], ah\r | |
180 | mov [si+18], al\r | |
181 | mov cx, 10\r | |
182 | rep movsw\r | |
183 | Halt:\r | |
184 | jmp Halt\r | |
185 | \r | |
186 | StartString:\r | |
187 | db 'M', 0ch, 'B', 0ch, 'R', 0ch, ' ', 0ch, 'S', 0ch, 't', 0ch, 'a', 0ch, 'r', 0ch, 't', 0ch, '!', 0ch\r | |
188 | ErrorString:\r | |
189 | db 'M', 0ch, 'B', 0ch, 'R', 0ch, ' ', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, ':', 0ch, '?', 0ch, '?', 0ch\r | |
190 | \r | |
191 | ; ****************************************************************************\r | |
192 | ; A2C - convert Ascii code stored in AH to character stored in AX\r | |
193 | ; ****************************************************************************\r | |
194 | A2C:\r | |
195 | mov al, ah\r | |
196 | shr ah, 4\r | |
197 | and al, 0Fh\r | |
198 | add ah, '0'\r | |
199 | add al, '0'\r | |
200 | \r | |
201 | cmp ah, '9'\r | |
202 | jle @f\r | |
203 | add ah, 7\r | |
204 | @@:\r | |
205 | \r | |
206 | cmp al, '9'\r | |
207 | jle @f\r | |
208 | add al, 7\r | |
209 | @@:\r | |
210 | ret\r | |
211 | \r | |
212 | \r | |
213 | ; ****************************************************************************\r | |
214 | ; PhysicalDrive - Used to indicate which disk to be boot\r | |
215 | ; Can be patched by tool\r | |
216 | ; ****************************************************************************\r | |
217 | org 01B6h\r | |
218 | PhysicalDrive db 80h\r | |
219 | \r | |
220 | ; ****************************************************************************\r | |
221 | ; MbrPartitionIndicator - Used to indicate which MBR partition to be boot\r | |
222 | ; Can be patched by tool\r | |
223 | ; OxFF means boot to legacy MBR. (LBA OFFSET 6)\r | |
224 | ; ****************************************************************************\r | |
225 | org 01B7h\r | |
226 | MbrPartitionIndicator db 0\r | |
227 | \r | |
228 | ; ****************************************************************************\r | |
229 | ; Unique MBR signature\r | |
230 | ; ****************************************************************************\r | |
231 | org 01B8h\r | |
232 | db 'DUET'\r | |
233 | \r | |
234 | ; ****************************************************************************\r | |
235 | ; Unknown\r | |
236 | ; ****************************************************************************\r | |
237 | org 01BCh\r | |
238 | dw 0\r | |
239 | \r | |
240 | ; ****************************************************************************\r | |
241 | ; MBR Entry - To be patched\r | |
242 | ; ****************************************************************************\r | |
243 | org 01BEh\r | |
244 | dd 0, 0, 0, 0\r | |
245 | org 01CEh\r | |
246 | dd 0, 0, 0, 0\r | |
247 | org 01DEh\r | |
248 | dd 0, 0, 0, 0\r | |
249 | org 01EEh\r | |
250 | dd 0, 0, 0, 0\r | |
251 | \r | |
252 | ; ****************************************************************************\r | |
253 | ; Sector Signature\r | |
254 | ; ****************************************************************************\r | |
255 | \r | |
256 | org 01FEh\r | |
257 | SectorSignature:\r | |
258 | dw 0aa55h ; Boot Sector Signature\r | |
259 | \r | |
260 | end\r | |
261 | \r |