]> git.proxmox.com Git - mirror_edk2.git/blob - DuetPkg/BootSector/Mbr.asm
03182a649a494bb98f61e89fce24016cd3e2832b
[mirror_edk2.git] / DuetPkg / BootSector / Mbr.asm
1 ;------------------------------------------------------------------------------
2 ;*
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
8 ;*
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.
11 ;*
12 ;* Mbr.asm
13 ;*
14 ;* Abstract:
15 ;*
16 ;------------------------------------------------------------------------------
17
18 .model small
19 ; .dosseg
20 .stack
21 .486p
22 .code
23
24 BLOCK_SIZE EQU 0200h
25 BLOCK_MASK EQU 01ffh
26 BLOCK_SHIFT EQU 9
27
28 ; ****************************************************************************
29 ; Code loaded by BIOS at 0x0000:0x7C00
30 ; ****************************************************************************
31
32 org 0h
33 Start:
34
35 ; ****************************************************************************
36 ; Start Print
37 ; ****************************************************************************
38
39 mov ax,0b800h
40 mov es,ax
41 mov ax, 07c0h
42 mov ds, ax
43 lea si, cs:[StartString]
44 mov cx, 10
45 mov di, 160
46 rep movsw
47
48 ; ****************************************************************************
49 ; Print over
50 ; ****************************************************************************
51
52 ; ****************************************************************************
53 ; Initialize segment registers and copy code at 0x0000:0x7c00 to 0x0000:0x0600
54 ; ****************************************************************************
55 xor ax, ax ; AX = 0x0000
56 mov bx, 07c00h ; BX = 0x7C00
57 mov bp, 0600h ; BP = 0x0600
58 mov si, OFFSET RelocatedStart ; SI = Offset(RelocatedStart)
59 mov cx, 0200h ; CX = 0x0200
60 sub cx, si ; CS = 0x0200 - Offset(RelocatedStart)
61 lea di, [bp+si] ; DI = 0x0600 + Offset(RelocatedStart)
62 lea si, [bx+si] ; BX = 0x7C00 + Offset(RelocatedStart)
63 mov ss, ax ; SS = 0x0000
64 mov sp, bx ; SP = 0x7C00
65 mov es,ax ; ES = 0x0000
66 mov ds,ax ; DS = 0x0000
67 push ax ; PUSH 0x0000
68 push di ; PUSH 0x0600 + Offset(RelocatedStart)
69 cld ; Clear the direction flag
70 rep movsb ; Copy 0x0200 bytes from 0x7C00 to 0x0600
71 retf ; JMP 0x0000:0x0600 + Offset(RelocatedStart)
72
73 ; ****************************************************************************
74 ; Code relocated to 0x0000:0x0600
75 ; ****************************************************************************
76
77 RelocatedStart:
78 ; ****************************************************************************
79 ; Get Driver Parameters to 0x0000:0x7BFC
80 ; ****************************************************************************
81
82 xor ax,ax ; AX = 0
83 mov ss,ax ; SS = 0
84 add ax,1000h
85 mov ds,ax
86
87 mov sp,07c00h ; SP = 0x7c00
88 mov bp,sp ; BP = 0x7c00
89
90 mov ah,8 ; AH = 8 - Get Drive Parameters Function
91 mov byte ptr [bp+PhysicalDrive],dl ; BBS defines that BIOS would pass the booting driver number to the loader through DL
92 int 13h ; Get Drive Parameters
93 xor ax,ax ; AX = 0
94 mov al,dh ; AL = DH
95 inc al ; MaxHead = AL + 1
96 push ax ; 0000:7bfe = MaxHead
97 mov al,cl ; AL = CL
98 and al,03fh ; MaxSector = AL & 0x3f
99 push ax ; 0000:7bfc = MaxSector
100
101 ; ****************************************************************************
102 ; Read Target DBR from hard disk to 0x0000:0x7C00
103 ; ****************************************************************************
104
105 xor ax, ax
106 mov al, byte ptr [bp+MbrPartitionIndicator] ; AX = MbrPartitionIndex
107 cmp al, 0ffh ; 0xFF means do legacy MBR boot
108 jnz EfiDbr
109 LegacyMbr:
110 mov eax, 00000600h ; Assume LegacyMBR is backuped in Sector 6
111 jmp StartReadTo7C00 ; EAX = Header/Sector/Tracker/Zero
112
113 EfiDbr:
114 cmp al, 4 ; MbrPartitionIndex should < 4
115 jae BadDbr
116 shl ax, 4 ; AX = MBREntrySize * Index
117 add ax, 1beh ; AX = MBREntryOffset
118 mov di, ax ; DI = MBREntryOffset
119
120 ; Here we don't use the C/H/S information provided by Partition table
121 ; but calculate C/H/S from LBA ourselves
122 ; Ci: Cylinder number
123 ; Hi: Header number
124 ; Si: Sector number
125 mov eax, dword ptr es:[bp + di + 8] ; Start LBA
126 mov edx, eax
127 shr edx, 16 ; DX:AX = Start LBA
128 ; = Ci * (H * S) + Hi * S + (Si - 1)
129
130 ; Calculate C/H/S according to LBA
131 mov bp, 7bfah
132 div word ptr [bp+2] ; AX = Hi + H*Ci
133 ; DX = Si - 1
134 inc dx ; DX = Si
135 push dx ; 0000:7bfa = Si <----
136 xor dx, dx ; DX:AX = Hi + H*Ci
137 div word ptr [bp+4] ; AX = Ci <----
138 ; DX = Hi <----
139
140 StartReadTo7C00:
141
142 mov cl, byte ptr [bp] ; Si
143 mov ch, al ; Ci[0-7]
144 or cl, ah ; Ci[8,9]
145 mov bx, 7c00h ; ES:BX = 0000:7C00h
146 mov ah, 2h ; Function 02h
147 mov al, 1 ; 1 Sector
148 mov dh, dl ; Hi
149 mov bp, 0600h
150 mov dl, byte ptr [bp + PhysicalDrive] ; Drive number
151 int 13h
152 jc BadDbr
153
154
155
156 ; ****************************************************************************
157 ; Transfer control to BootSector - Jump to 0x0000:0x7C00
158 ; ****************************************************************************
159 xor ax, ax
160 push ax ; PUSH 0x0000 - Segment
161 mov di, 07c00h
162 push di ; PUSH 0x7C00 - Offset
163 retf ; JMP 0x0000:0x7C00
164
165 ; ****************************************************************************
166 ; ERROR Condition:
167 ; ****************************************************************************
168
169 BadDbr:
170 push ax
171 mov ax, 0b800h
172 mov es, ax
173 mov ax, 060h
174 mov ds, ax
175 lea si, cs:[ErrorString]
176 mov di, 320
177 pop ax
178 call A2C
179 mov [si+16], ah
180 mov [si+18], al
181 mov cx, 10
182 rep movsw
183 Halt:
184 jmp Halt
185
186 StartString:
187 db 'M', 0ch, 'B', 0ch, 'R', 0ch, ' ', 0ch, 'S', 0ch, 't', 0ch, 'a', 0ch, 'r', 0ch, 't', 0ch, '!', 0ch
188 ErrorString:
189 db 'M', 0ch, 'B', 0ch, 'R', 0ch, ' ', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, ':', 0ch, '?', 0ch, '?', 0ch
190
191 ; ****************************************************************************
192 ; A2C - convert Ascii code stored in AH to character stored in AX
193 ; ****************************************************************************
194 A2C:
195 mov al, ah
196 shr ah, 4
197 and al, 0Fh
198 add ah, '0'
199 add al, '0'
200
201 cmp ah, '9'
202 jle @f
203 add ah, 7
204 @@:
205
206 cmp al, '9'
207 jle @f
208 add al, 7
209 @@:
210 ret
211
212
213 ; ****************************************************************************
214 ; PhysicalDrive - Used to indicate which disk to be boot
215 ; Can be patched by tool
216 ; ****************************************************************************
217 org 01B6h
218 PhysicalDrive db 80h
219
220 ; ****************************************************************************
221 ; MbrPartitionIndicator - Used to indicate which MBR partition to be boot
222 ; Can be patched by tool
223 ; OxFF means boot to legacy MBR. (LBA OFFSET 6)
224 ; ****************************************************************************
225 org 01B7h
226 MbrPartitionIndicator db 0
227
228 ; ****************************************************************************
229 ; Unique MBR signature
230 ; ****************************************************************************
231 org 01B8h
232 db 'DUET'
233
234 ; ****************************************************************************
235 ; Unknown
236 ; ****************************************************************************
237 org 01BCh
238 dw 0
239
240 ; ****************************************************************************
241 ; MBR Entry - To be patched
242 ; ****************************************************************************
243 org 01BEh
244 dd 0, 0, 0, 0
245 org 01CEh
246 dd 0, 0, 0, 0
247 org 01DEh
248 dd 0, 0, 0, 0
249 org 01EEh
250 dd 0, 0, 0, 0
251
252 ; ****************************************************************************
253 ; Sector Signature
254 ; ****************************************************************************
255
256 org 01FEh
257 SectorSignature:
258 dw 0aa55h ; Boot Sector Signature
259
260 end
261