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