diff options
-rw-r--r-- | doc/gpt.txt | 45 | ||||
-rwxr-xr-x | mbr/checksize.pl | 2 | ||||
-rw-r--r-- | mbr/gptmbr.S | 44 |
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 |