]> git.ipfire.org Git - people/ms/u-boot.git/commitdiff
part: extract MBR signature from partitions
authorPeter Jones <pjones@redhat.com>
Wed, 13 Sep 2017 22:05:25 +0000 (18:05 -0400)
committerAlexander Graf <agraf@suse.de>
Wed, 20 Sep 2017 08:20:19 +0000 (10:20 +0200)
EFI client programs need the signature information from the partition
table to determine the disk a partition is on, so we need to fill that
in here.

Signed-off-by: Peter Jones <pjones@redhat.com>
[separated from efi_loader part, and fixed build-errors for non-
 CONFIG_EFI_PARTITION case]
Signed-off-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
disk/part_dos.c
disk/part_efi.c
include/blk.h

index 7aff73d6f8c8cb547dd750d60281f3b57076538a..1a36be0446ac06d30ce23aa4dfedfd3fa16a6827 100644 (file)
@@ -89,14 +89,20 @@ static int test_block_type(unsigned char *buffer)
 
 static int part_test_dos(struct blk_desc *dev_desc)
 {
-       ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
+       ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, mbr, dev_desc->blksz);
 
-       if (blk_dread(dev_desc, 0, 1, (ulong *)buffer) != 1)
+       if (blk_dread(dev_desc, 0, 1, (ulong *)mbr) != 1)
                return -1;
 
-       if (test_block_type(buffer) != DOS_MBR)
+       if (test_block_type((unsigned char *)mbr) != DOS_MBR)
                return -1;
 
+       if (dev_desc->sig_type == SIG_TYPE_NONE &&
+           mbr->unique_mbr_signature != 0) {
+               dev_desc->sig_type = SIG_TYPE_MBR;
+               dev_desc->mbr_sig = mbr->unique_mbr_signature;
+       }
+
        return 0;
 }
 
index 2973d52f6abb278756a814057e3b77d7c08945ca..208bb14ee88e2e5115134070b41feac72dce1b02 100644 (file)
@@ -923,11 +923,19 @@ static int is_pmbr_valid(legacy_mbr * mbr)
 static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba,
                        gpt_header *pgpt_head, gpt_entry **pgpt_pte)
 {
+       ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, mbr, dev_desc->blksz);
+
        if (!dev_desc || !pgpt_head) {
                printf("%s: Invalid Argument(s)\n", __func__);
                return 0;
        }
 
+       /* Read MBR Header from device */
+       if (blk_dread(dev_desc, 0, 1, (ulong *)mbr) != 1) {
+               printf("*** ERROR: Can't read MBR header ***\n");
+               return 0;
+       }
+
        /* Read GPT Header from device */
        if (blk_dread(dev_desc, (lbaint_t)lba, 1, pgpt_head) != 1) {
                printf("*** ERROR: Can't read GPT header ***\n");
@@ -937,6 +945,18 @@ static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba,
        if (validate_gpt_header(pgpt_head, (lbaint_t)lba, dev_desc->lba))
                return 0;
 
+       if (dev_desc->sig_type == SIG_TYPE_NONE) {
+               efi_guid_t empty = {};
+               if (memcmp(&pgpt_head->disk_guid, &empty, sizeof(empty))) {
+                       dev_desc->sig_type = SIG_TYPE_GUID;
+                       memcpy(&dev_desc->guid_sig, &pgpt_head->disk_guid,
+                             sizeof(empty));
+               } else if (mbr->unique_mbr_signature != 0) {
+                       dev_desc->sig_type = SIG_TYPE_MBR;
+                       dev_desc->mbr_sig = mbr->unique_mbr_signature;
+               }
+       }
+
        /* Read and allocate Partition Table Entries */
        *pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head);
        if (*pgpt_pte == NULL) {
index 1965812a9d5a39f0148ce133a895a69b4058d07b..41b4d7efa82b3f88994b95a61071310ae51462fe 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef BLK_H
 #define BLK_H
 
+#include <efi.h>
+
 #ifdef CONFIG_SYS_64BIT_LBA
 typedef uint64_t lbaint_t;
 #define LBAFlength "ll"
@@ -40,6 +42,17 @@ enum if_type {
 #define BLK_PRD_SIZE           20
 #define BLK_REV_SIZE           8
 
+/*
+ * Identifies the partition table type (ie. MBR vs GPT GUID) signature
+ */
+enum sig_type {
+       SIG_TYPE_NONE,
+       SIG_TYPE_MBR,
+       SIG_TYPE_GUID,
+
+       SIG_TYPE_COUNT                  /* Number of signature types */
+};
+
 /*
  * With driver model (CONFIG_BLK) this is uclass platform data, accessible
  * with dev_get_uclass_platdata(dev)
@@ -67,6 +80,11 @@ struct blk_desc {
        char            vendor[BLK_VEN_SIZE + 1]; /* device vendor string */
        char            product[BLK_PRD_SIZE + 1]; /* device product number */
        char            revision[BLK_REV_SIZE + 1]; /* firmware revision */
+       enum sig_type   sig_type;       /* Partition table signature type */
+       union {
+               uint32_t mbr_sig;       /* MBR integer signature */
+               efi_guid_t guid_sig;    /* GPT GUID Signature */
+       };
 #if CONFIG_IS_ENABLED(BLK)
        /*
         * For now we have a few functions which take struct blk_desc as a