summaryrefslogtreecommitdiff
path: root/mbr
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2010-06-11 17:03:24 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2010-06-11 17:03:24 -0700
commitd4c1eecb7c6e37432ba9ef0624e29129d9b8be24 (patch)
tree8ad5fadb1d6796e22df420365f5f599a6a70f603 /mbr
parentb0ff6613d593ee88790a9299afd20ebd66c65b3c (diff)
downloadsyslinux-d4c1eecb7c6e37432ba9ef0624e29129d9b8be24.tar.gz
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@linux.intel.com>
Diffstat (limited to 'mbr')
-rwxr-xr-xmbr/checksize.pl2
-rw-r--r--mbr/gptmbr.S44
2 files changed, 25 insertions, 21 deletions
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