[syslinux:pathbased] gptmbr: implement the new T13-approved GPT protocol

syslinux-bot for H. Peter Anvin hpa at linux.intel.com
Fri Jun 11 17:24:20 PDT 2010


Commit-ID:  d4c1eecb7c6e37432ba9ef0624e29129d9b8be24
Gitweb:     http://syslinux.zytor.com/commit/d4c1eecb7c6e37432ba9ef0624e29129d9b8be24
Author:     H. Peter Anvin <hpa at linux.intel.com>
AuthorDate: Fri, 11 Jun 2010 17:03:24 -0700
Committer:  H. Peter Anvin <hpa at linux.intel.com>
CommitDate: Fri, 11 Jun 2010 17:03:24 -0700

gptmbr: implement the new T13-approved GPT protocol

My GPT-based protocol was modified by the UEFI and T13 committees (the
former responsible for the GPT format, the latter for EDD and
therefore for the disk-related part of the BIOS specification.)  This
is thus now on its way to become an official protocol, so change the
implementation to match.

This still needs testing, and the Syslinux core needs to be adjusted
to leverage the extended information.

Signed-off-by: H. Peter Anvin <hpa at linux.intel.com>


---
 doc/gpt.txt      |   45 ++++++++++++++-------------------------------
 mbr/checksize.pl |    2 +-
 mbr/gptmbr.S     |   44 ++++++++++++++++++++++++--------------------
 3 files changed, 39 insertions(+), 52 deletions(-)

diff --git a/doc/gpt.txt b/doc/gpt.txt
index 14c1ee8..b17322d 100644
--- a/doc/gpt.txt
+++ b/doc/gpt.txt
@@ -1,13 +1,10 @@
 			  GPT boot protocol
 
-There is no official MBR-to-partition handover protocol defined for
-booting from disks partitioned using GPT partition tables with
-BIOS-style firmware.  This is because the GPT partition format comes
-from the EFI spec, which thinks the universe is all going to be EFI.
-Sigh.
+There are two ways to boot a GPT-formatted disk on a BIOS system.
+Hybrid booting, and the new GPT-only booting protocol originally
+proposed by the author, and later adopted by the T13 committee in
+slightly modified form.
 
-There are thus two alternatives: hybrid booting, and defining a new
-protocol.
 
 	*** Hybrid booting ***
 
@@ -29,31 +26,16 @@ GPT disk with BIOS firmware.
 
 	*** New protocol ***
 
-This defines an alternative (experimental) booting protocol for GPT
-partitions with BIOS firmware.  It maintains backwards compatibility
-to the extent possible.  It is implemented by the file mbr/gptmbr.bin.
+This defines the T13-approved protocol for GPT partitions with BIOS
+firmware.  It maintains backwards compatibility to the extent
+possible.  It is implemented by the file mbr/gptmbr.bin.
 
-   -> The PMBR
+The (P)MBR format is the normal PMBR specified in the UEFI
+documentation, with the first 440 bytes used for the boot code.  The
+partition to be booted is marked by setting bit 2 in the GPT Partition
+Entry Attributes field (offset 48); this bit is reserved by the UEFI
+Forum for "Legacy BIOS Bootable".
 
-The PMBR (the first 512-byte sector of the disk) is divided up as
-follows:
-
-	Offset	Size	Contents
-	---------------------------------------------------------
-	  0	424	PMBR boot code
-	424	 16	GUID of the boot partition
-	440	  4	MBR-compatible disk ID
-	444	  2	Magic number: 1D 9A
-	446	 16	PMBR protective entry
-	462	 48	PMBR null entries
-	510	  2	Boot signature: 55 AA
-
-To change the bootable partition, verify that the magic number is
-present (to avoid corrupting software not compatible with this
-specification) and enter the GUID of the boot partition at offset
-424.  It might be wise to verify that the data already there is a
-valid partition GUID already, or at least warn the user if that is not
-the case.
 
     -> The handover protocol
 
@@ -70,7 +52,8 @@ form:
 	  5	  3	CHS of partition end
 	  8	  4	Partition start LBA
 	 12	  4	Partition end LBA
-	 16	varies	GPT partition entry
+	 16	  4	Length of the GPT entry
+	 20	varies	GPT partition entry
 
 The CHS information is optional; gptmbr.bin currently does *NOT*
 calculate them, and just leaves them as zero.
diff --git a/mbr/checksize.pl b/mbr/checksize.pl
index c1984db..4b42327 100755
--- a/mbr/checksize.pl
+++ b/mbr/checksize.pl
@@ -26,7 +26,7 @@ if (!defined($maxsize)) {
     if ($file =~ /^mbr[^0-9a-z]/) {
 	$maxsize = $padsize = 440;
     } elsif ($file =~ /^gptmbr[^0-9a-z]/) {
-	$maxsize = $padsize = 424;
+	$maxsize = $padsize = 440;
     } elsif ($file =~ /^isohdp[fp]x[^0-9a-z]/) {
 	$maxsize = $padsize = 432;
     } elsif ($file =~ /^altmbr[^0-9a-z]/) {
diff --git a/mbr/gptmbr.S b/mbr/gptmbr.S
index 8d42e8b..20741ac 100644
--- a/mbr/gptmbr.S
+++ b/mbr/gptmbr.S
@@ -40,8 +40,6 @@ phdr		= stack		/* Above the stack, overwritten by bootsect */
 /* To handle > 32K we need to play segment tricks... */
 psec		= _phdr + 512
 
-/* BootGUID */
-bootguid	= _start + 0x1a8
 /* Where we put DS:SI */
 dssi_out	= _start + 0x1be
 
@@ -148,24 +146,31 @@ get_ptab:
 	loopw	get_ptab
 
 	/* Find the boot partition */
-	popw	%si			/* Partition table in memory */
+	xorw	%si,%si			/* Nothing found yet */
+	popw	%di			/* Partition table in memory */
 	popw	%cx			/* NumberOfPartitionEntries */
 	popw	%ax			/* SizeOfPartitionEntry */
+
 find_part:
-	pushw	%cx
-	pushw	%si
-	addw	$16,%si
-	movw	$bootguid,%di
-	movw	$8,%cx
-	repe; cmpsw
-	popw	%si
-	popw	%cx
-	je found_part
-	addw	%ax,%si
+	testb	$0x04,48(%di)
+	jz	not_this
+	andw	%si,%si
+	jnz	found_multiple
+	movw	%di,%si
+not_this:
+	addw	%ax,%di
 	loopw	find_part
 
+	andw	%si,%si
+	jnz	found_part
+
+missing_os:
 	call	error
-	.ascii	"Boot partition not found\r\n"
+	.ascii	"Missing OS\r\n"
+
+found_multiple:
+	call	error
+	.ascii	"Multiple active partitions\r\n"
 
 found_part:
 	xchgw	%ax,%cx		/* Set up %cx for rep movsb further down */
@@ -191,6 +196,9 @@ found_part:
 	call	inc64
 	call	saturate_stosl		/* Partition length */
 
+	movzwl	%cx,%eax		/* Length of GPT entry */
+	stosl
+	
 	rep; movsb			/* GPT entry follows MBR entry */
 	popw	%si
 
@@ -200,8 +208,8 @@ found_part:
  * is phdr == 0x7c00 == the address of the boot sector.
  */
 boot:
-	movl	(32+16)(%si),%eax
-	movl	(36+16)(%si),%edx
+	movl	(32+20)(%si),%eax
+	movl	(36+20)(%si),%edx
 	popw	%bx
 	call	read_sector
 	cmpw	$0xaa55, -2(%bx)
@@ -214,10 +222,6 @@ boot:
 	cli
 	jmpw	*%sp		/* %sp == bootsec */
 
-missing_os:
-	call	error
-	.ascii	"OS not bootable\r\n"
-
 saturate_stosl:
 	pushl	%eax
 	andl	%edx,%edx



More information about the Syslinux-commits mailing list