summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/gpt.txt45
-rwxr-xr-xmbr/checksize.pl2
-rw-r--r--mbr/gptmbr.S44
3 files changed, 39 insertions, 52 deletions
diff --git a/doc/gpt.txt b/doc/gpt.txt
index 14c1ee8e..b17322d0 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 c1984dbf..4b42327f 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 8d42e8b8..20741acb 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