(2006-08-06) rescue-bootcd
This commit is contained in:
229
extra/syslinux-3.09/mbr.asm
Normal file
229
extra/syslinux-3.09/mbr.asm
Normal file
@@ -0,0 +1,229 @@
|
||||
; -----------------------------------------------------------------------
|
||||
;
|
||||
; Copyright 2003-2004 H. Peter Anvin - All Rights Reserved
|
||||
;
|
||||
; Permission is hereby granted, free of charge, to any person
|
||||
; obtaining a copy of this software and associated documentation
|
||||
; files (the "Software"), to deal in the Software without
|
||||
; restriction, including without limitation the rights to use,
|
||||
; copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
; sell copies of the Software, and to permit persons to whom
|
||||
; the Software is furnished to do so, subject to the following
|
||||
; conditions:
|
||||
;
|
||||
; The above copyright notice and this permission notice shall
|
||||
; be included in all copies or substantial portions of the Software.
|
||||
;
|
||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
; OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
; OTHER DEALINGS IN THE SOFTWARE.
|
||||
;
|
||||
; -----------------------------------------------------------------------
|
||||
|
||||
;
|
||||
; mbr.asm
|
||||
;
|
||||
; Simple Master Boot Record, including support for EBIOS extensions.
|
||||
;
|
||||
; The MBR lives in front of the boot sector, and is responsible for
|
||||
; loading the boot sector of the active partition. The EBIOS support
|
||||
; is needed if the active partition starts beyond cylinder 1024.
|
||||
;
|
||||
; This MBR determines all geometry info at runtime. It uses only the
|
||||
; linear block field in the partition table. It does, however, pass
|
||||
; the partition table information unchanged to the target OS.
|
||||
;
|
||||
; This MBR should be "8086-clean", i.e. not require a 386.
|
||||
;
|
||||
|
||||
%include "bios.inc"
|
||||
|
||||
;
|
||||
; Note: The MBR is actually loaded at 0:7C00h, but we quickly move it down to
|
||||
; 0600h.
|
||||
;
|
||||
section .text
|
||||
cpu 8086
|
||||
org 0600h
|
||||
|
||||
_start: cli
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
mov ss,ax
|
||||
mov sp,7C00h
|
||||
sti
|
||||
cld
|
||||
mov si,sp ; Start address
|
||||
mov di,0600h ; Destination address
|
||||
mov cx,512/2
|
||||
rep movsw
|
||||
|
||||
;
|
||||
; Now, jump to the copy at 0600h so we can load the boot sector at 7C00h.
|
||||
; Since some BIOSes seem to think 0000:7C00h and 07C0:0000h are the same
|
||||
; thing, use a far jump to canonicalize the address. This also makes
|
||||
; sure that it is a code speculation barrier.
|
||||
;
|
||||
|
||||
jmp 0:next ; Jump to copy at 0600h
|
||||
|
||||
next:
|
||||
mov [DriveNo], dl ; Drive number stored in DL
|
||||
;
|
||||
; Check for CHS parameters. This doesn't work on floppy disks,
|
||||
; but for an MBR we don't care.
|
||||
;
|
||||
mov ah,08h ; Get drive parameters
|
||||
int 13h
|
||||
xor ax,ax
|
||||
mov al,dh
|
||||
inc ax ; From 0-based to count
|
||||
mov [Heads],ax
|
||||
and cl,3Fh ; Max sector number
|
||||
mov [Sectors],cl
|
||||
; Note: we actually don't care about the number of
|
||||
; cylinders, since that's the highest-order division
|
||||
|
||||
;
|
||||
; Now look for one (and only one) active partition.
|
||||
;
|
||||
mov si,PartitionTable
|
||||
xor ax,ax
|
||||
mov cx,4
|
||||
checkpartloop:
|
||||
test byte [si],80h
|
||||
jz .notactive
|
||||
inc ax
|
||||
mov di,si
|
||||
.notactive: add si,byte 16
|
||||
loop checkpartloop
|
||||
|
||||
cmp ax,byte 1 ; Better be only one
|
||||
jnz not_one_partition
|
||||
|
||||
;
|
||||
; Now we have the active partition partition information in DS:DI.
|
||||
; Check to see if we support EBIOS.
|
||||
;
|
||||
mov dl,[DriveNo]
|
||||
mov ax,4100h
|
||||
mov bx,055AAh
|
||||
xor cx,cx
|
||||
xor dh,dh
|
||||
stc
|
||||
int 13h
|
||||
jc no_ebios
|
||||
cmp bx,0AA55h
|
||||
jne no_ebios
|
||||
test cl,1 ; LBA device access
|
||||
jz no_ebios
|
||||
;
|
||||
; We have EBIOS. Load the boot sector using LBA.
|
||||
;
|
||||
push di
|
||||
mov si,dapa
|
||||
mov bx,[di+8] ; Copy the block address
|
||||
mov [si+8],bx
|
||||
mov bx,[di+10]
|
||||
mov [si+10],bx
|
||||
mov dl,[DriveNo]
|
||||
mov ah,42h ; Extended Read
|
||||
jmp short common_tail
|
||||
;
|
||||
; No EBIOS. Load the boot sector using CHS.
|
||||
;
|
||||
no_ebios:
|
||||
push di
|
||||
mov ax,[di+8]
|
||||
mov dx,[di+10]
|
||||
div word [Sectors]
|
||||
inc dx
|
||||
mov cx,dx ; Sector #
|
||||
xor dx,dx
|
||||
div word [Heads]
|
||||
; DX = head #, AX = cylinder #
|
||||
mov ch,al
|
||||
shr ax,1
|
||||
shr ax,1
|
||||
and al,0C0h
|
||||
or cl,al
|
||||
mov dh,dl ; Head #
|
||||
mov dl,[DriveNo]
|
||||
mov bx,7C00h
|
||||
mov ax,0201h ; Read one sector
|
||||
common_tail:
|
||||
int 13h
|
||||
jc disk_error
|
||||
pop si ; DS:SI -> partition table entry
|
||||
;
|
||||
; Verify that we have a boot sector, jump
|
||||
;
|
||||
cmp word [7C00h+510],0AA55h
|
||||
jne missing_os
|
||||
cli
|
||||
jmp 0:7C00h ; Jump to boot sector; far
|
||||
; jump is speculation barrier
|
||||
; (Probably not neecessary, but
|
||||
; there is plenty of space.)
|
||||
|
||||
not_one_partition:
|
||||
ja too_many_os
|
||||
missing_os:
|
||||
mov si,missing_os_msg
|
||||
jmp short die
|
||||
too_many_os:
|
||||
disk_error:
|
||||
mov si,bad_disk_msg
|
||||
die:
|
||||
.msgloop:
|
||||
lodsb
|
||||
and al,al
|
||||
jz .now
|
||||
mov ah,0Eh ; TTY output
|
||||
mov bh,[BIOS_page] ; Current page
|
||||
mov bl,07h
|
||||
int 10h
|
||||
jmp short .msgloop
|
||||
.now:
|
||||
jmp short .now
|
||||
|
||||
align 4, db 0 ; Begin data area
|
||||
|
||||
;
|
||||
; EBIOS disk address packet
|
||||
;
|
||||
dapa:
|
||||
dw 16 ; Packet size
|
||||
.count: dw 1 ; Block count
|
||||
.off: dw 7C00h ; Offset of buffer
|
||||
.seg: dw 0 ; Segment of buffer
|
||||
.lba: dd 0 ; LBA (LSW)
|
||||
dd 0 ; LBA (MSW)
|
||||
|
||||
; CHS information
|
||||
Heads: dw 0
|
||||
Sectors: dw 0
|
||||
|
||||
; Error messages
|
||||
missing_os_msg db 'Missing operating system', 13, 10, 0
|
||||
bad_disk_msg db 'Operating system loading error', 13, 10, 0
|
||||
|
||||
;
|
||||
; Maximum MBR size: 446 bytes; end-of-boot-sector signature also needed.
|
||||
; Note that some operating systems (NT, DR-DOS) put additional stuff at
|
||||
; the end of the MBR, so shorter is better. Location 440 is known to
|
||||
; have a 4-byte attempt-at-unique-ID for some OSes.
|
||||
;
|
||||
|
||||
PartitionTable equ $$+446 ; Start of partition table
|
||||
|
||||
;
|
||||
; BSS data; put at 800h
|
||||
;
|
||||
DriveNo equ 0800h
|
||||
Reference in New Issue
Block a user