svn commit: r237293 - user/ae/bootcode/sys/boot/i386/pmbr
Andrey V. Elsukov
ae at FreeBSD.org
Wed Jun 20 08:02:45 UTC 2012
Author: ae
Date: Wed Jun 20 08:02:44 2012
New Revision: 237293
URL: http://svn.freebsd.org/changeset/base/237293
Log:
Teach PMBR boot code read the backup GPT header and skip GEOM's metadata.
Submitted by: hrs
Modified:
user/ae/bootcode/sys/boot/i386/pmbr/pmbr.s
Modified: user/ae/bootcode/sys/boot/i386/pmbr/pmbr.s
==============================================================================
--- user/ae/bootcode/sys/boot/i386/pmbr/pmbr.s Wed Jun 20 07:56:38 2012 (r237292)
+++ user/ae/bootcode/sys/boot/i386/pmbr/pmbr.s Wed Jun 20 08:02:44 2012 (r237293)
@@ -42,8 +42,9 @@
.set STACK,EXEC+SECSIZE*4 # Stack address
.set GPT_ADDR,STACK # GPT header address
.set GPT_SIG,0
- .set GPT_SIG_0,0x20494645
- .set GPT_SIG_1,0x54524150
+ .set GPT_SIG_0,0x20494645 # "EFI "
+ .set GPT_SIG_1,0x54524150 # "PART"
+ .set GEOM_MAGIC,0x4d4f4547 # "GEOM"
.set GPT_MYLBA,24
.set GPT_PART_LBA,72
.set GPT_NPART,80
@@ -52,6 +53,8 @@
.set PART_TYPE,0
.set PART_START_LBA,32
.set PART_END_LBA,40
+ .set DPBUF,PART_ADDR+SECSIZE
+ .set DPBUF_SEC,0x10 # Number of sectors
.set NHRDRV,0x475 # Number of hard drives
@@ -91,15 +94,39 @@ main: cmpb $0x80,%dl # Drive valid?
jb main.2 # Yes
main.1: movb $0x80,%dl # Assume drive 0x80
#
-# Load the primary GPT header from LBA 1 and verify signature.
-#
-main.2: movw $GPT_ADDR,%bx
+# Load the GPT header and verify signature. Try LBA 1 for the primary one and
+# the last LBA for the backup if it is broken. Skip the LBAs if GEOM
+# metadata found at the backup location.
+#
+main.2: call getdrvparams # Read drive parameters
+ movb $1,%dh # %dh := 1 (reading primary)
+main.2a: movw $GPT_ADDR,%bx
movw $lba,%si
- call read
+ call read # Read header and check GPT sig
cmpl $GPT_SIG_0,GPT_ADDR+GPT_SIG
- jnz err_pt
+ jnz main.2b
cmpl $GPT_SIG_1,GPT_ADDR+GPT_SIG+4
- jnz err_pt
+ jnz main.2b
+ jmp load_part
+main.2b: cmpb $1,%dh # Reading primary?
+ je main.3 # Try backup if yes
+ cmpl $GEOM_MAGIC,GPT_ADDR # GEOM sig at backup location?
+ jz main.3 # Skip GEOM metadata
+ jmp err_pt # Invalid table found
+#
+# Try alternative LBAs from the last sector for the GPT header.
+#
+main.3: movb $0,%dh # %dh := 0 (reading backup)
+ movw $DPBUF+DPBUF_SEC,%si # %si = last sector + 1
+ movw $lba,%di # %di = $lba
+ cmpl $0,(%si) #
+ jnz main.3a #
+ decl 0x4(%si) # 0x4(%si) = last sec (32-64)
+main.3a: decl (%si) # 0x0(%si) = last sec (0-31)
+ movw $2,%cx
+ rep
+ movsw # $lastsec--, copy it to $lba
+ jmp main.2a # Read the next sector
#
# Load a partition table sector from disk and look for a FreeBSD boot
# partition.
@@ -172,6 +199,16 @@ read: pushl 0x4(%si) # Set the LBA
jc err_rd # If error
ret
#
+# Check the number of LBAs on the drive index %dx. Trashes %ax and %si.
+#
+getdrvparams:
+ movw $DPBUF,%si # Set the address of result buf
+ movw $0x001e,(%si) # len
+ movw $0x4800,%ax # BIOS: Read Drive Parameters
+ int $0x13 # Call the BIOS
+ jc err_rd # "I/O error" if error
+ ret
+#
# Various error message entry points.
#
err_big: movw $msg_big,%si # "Boot loader too
More information about the svn-src-user
mailing list