source: bootcd/isolinux/syslinux-6.03/mbr/oldmbr.asm @ dd1be7c

Last change on this file since dd1be7c was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 5.6 KB
Line 
1; -----------------------------------------------------------------------
2;
3;   Copyright 2003-2008 H. Peter Anvin - All Rights Reserved
4;
5;   Permission is hereby granted, free of charge, to any person
6;   obtaining a copy of this software and associated documentation
7;   files (the "Software"), to deal in the Software without
8;   restriction, including without limitation the rights to use,
9;   copy, modify, merge, publish, distribute, sublicense, and/or
10;   sell copies of the Software, and to permit persons to whom
11;   the Software is furnished to do so, subject to the following
12;   conditions:
13;
14;   The above copyright notice and this permission notice shall
15;   be included in all copies or substantial portions of the Software.
16;
17;   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18;   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19;   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20;   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21;   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22;   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23;   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24;   OTHER DEALINGS IN THE SOFTWARE.
25;
26; -----------------------------------------------------------------------
27
28;
29; mbr.asm
30;
31; Simple Master Boot Record, including support for EBIOS extensions.
32;
33; The MBR lives in front of the boot sector, and is responsible for
34; loading the boot sector of the active partition.  The EBIOS support
35; is needed if the active partition starts beyond cylinder 1024.
36;
37; This MBR determines all geometry info at runtime.  It uses only the
38; linear block field in the partition table.  It does, however, pass
39; the partition table information unchanged to the target OS.
40;
41; This MBR should be "8086-clean", i.e. not require a 386.
42;
43
44%include "bios.inc"
45
46;
47; Note: The MBR is actually loaded at 0:7C00h, but we quickly move it down to
48; 0600h.
49;
50                section .text
51                cpu 8086
52                org 0600h
53
54_start:         cli
55                xor ax,ax
56                mov ds,ax
57                mov es,ax
58                mov ss,ax
59                mov sp,7C00h
60                sti
61                cld
62                mov si,sp               ; Start address
63                mov di,0600h            ; Destination address
64                mov cx,512/2
65                rep movsw
66
67;
68; Now, jump to the copy at 0600h so we can load the boot sector at 7C00h.
69; Since some BIOSes seem to think 0000:7C00h and 07C0:0000h are the same
70; thing, use a far jump to canonicalize the address.  This also makes
71; sure that it is a code speculation barrier.
72;
73
74                jmp 0:next              ; Jump to copy at 0600h
75
76next:
77                mov [DriveNo], dl               ; Drive number stored in DL
78;
79; Check for CHS parameters.  This doesn't work on floppy disks,
80; but for an MBR we don't care.
81;
82                mov ah,08h                      ; Get drive parameters
83                int 13h
84                and cx,3Fh                      ; Max sector number
85                mov [Sectors],cx
86                xor ax,ax
87                mov al,dh
88                inc ax                          ; From 0-based to count
89                mul cx                          ; Heads*Sectors
90                mov [SecPerCyl],ax
91                ; Note: we actually don't care about the number of
92                ; cylinders, since that's the highest-order division
93
94;
95; Now look for one (and only one) active partition.
96;
97                mov si,PartitionTable
98                xor ax,ax
99                mov cx,4
100checkpartloop:
101                test byte [si],80h
102                jz .notactive
103                inc ax
104                mov di,si
105.notactive:     add si,byte 16
106                loop checkpartloop
107
108                cmp ax,byte 1                   ; Better be only one
109                jnz not_one_partition
110
111;
112; Now we have the active partition partition information in DS:DI.
113; Check to see if we support EBIOS.
114;
115                mov dl,[DriveNo]
116                mov ax,4100h
117                mov bx,055AAh
118                xor cx,cx
119                xor dh,dh
120                stc
121                int 13h
122                jc no_ebios
123                cmp bx,0AA55h
124                jne no_ebios
125                test cl,1                       ; LBA device access
126                jz no_ebios
127;
128; We have EBIOS.  Load the boot sector using LBA.
129;
130                push di
131                mov si,dapa
132                mov bx,[di+8]                   ; Copy the block address
133                mov [si+8],bx
134                mov bx,[di+10]
135                mov [si+10],bx
136                mov dl,[DriveNo]
137                mov ah,42h                      ; Extended Read
138                jmp short common_tail
139;
140; No EBIOS.  Load the boot sector using CHS.
141;
142no_ebios:
143                push di
144                mov ax,[di+8]
145                mov dx,[di+10]
146                div word [SecPerCyl]    ; AX = cylinder DX = sec in cyl
147                ror ah,1
148                ror ah,1
149                mov cl,ah
150                mov ch,al                       ; CL = cyl[9:8], CH = cyl[7:0]
151
152                mov ax,dx
153                div byte [Sectors]              ; AL = head AH = sector
154                mov dh,al
155                inc ah
156                or cl,ah                        ; CX = cylinder and sector
157
158                mov dl,[DriveNo]
159                mov bx,7C00h
160                mov ax,0201h                    ; Read one sector
161common_tail:
162                int 13h
163                jc disk_error
164                pop si                          ; DS:SI -> partition table entry
165;
166; Verify that we have a boot sector, jump
167;
168                cmp word [7C00h+510],0AA55h
169                jne missing_os
170                cli
171                jmp 0:7C00h                     ; Jump to boot sector; far
172                                                ; jump is speculation barrier
173                                                ; (Probably not neecessary, but
174                                                ; there is plenty of space.)
175
176not_one_partition:
177                ja too_many_os
178missing_os:
179                mov si,missing_os_msg
180                jmp short die
181too_many_os:
182disk_error:
183                mov si,bad_disk_msg
184die:
185.msgloop:
186                lodsb
187                and al,al
188                jz .now
189                mov ah,0Eh                      ; TTY output
190                mov bh,[BIOS_page]              ; Current page
191                mov bl,07h
192                int 10h
193                jmp short .msgloop
194.now:
195                jmp short .now
196
197                align 4, db 0                   ; Begin data area
198
199;
200; EBIOS disk address packet
201;
202dapa:
203                dw 16                           ; Packet size
204.count:         dw 1                            ; Block count
205.off:           dw 7C00h                        ; Offset of buffer
206.seg:           dw 0                            ; Segment of buffer
207.lba:           dd 0                            ; LBA (LSW)
208                dd 0                            ; LBA (MSW)
209
210; CHS information
211SecPerCyl:      dw 0                            ; Heads*Sectors
212Sectors:        dw 0
213
214; Error messages
215missing_os_msg  db 'Missing operating system', 13, 10, 0
216bad_disk_msg    db 'Operating system loading error', 13, 10, 0
217
218;
219; Maximum MBR size: 446 bytes; end-of-boot-sector signature also needed.
220; Note that some operating systems (NT, DR-DOS) put additional stuff at
221; the end of the MBR, so shorter is better.  Location 440 is known to
222; have a 4-byte attempt-at-unique-ID for some OSes.
223;
224
225PartitionTable  equ $$+446                      ; Start of partition table
226
227;
228; BSS data; put at 800h
229;
230DriveNo         equ 0800h
Note: See TracBrowser for help on using the repository browser.