[U-Boot] [PATCH v1 03/15] part: extract MBR signature from partitions
Rob Clark
robdclark at gmail.com
Thu Aug 10 18:29:31 UTC 2017
From: Peter Jones <pjones at redhat.com>
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 at redhat.com>
[separated from efi_loader part, and fixed build-errors for non-
CONFIG_EFI_PARTITION case]
Signed-off-by: Rob Clark <robdclark at gmail.com>
---
disk/part_dos.c | 12 +++++++++---
disk/part_efi.c | 20 ++++++++++++++++++++
include/blk.h | 15 +++++++++++++++
include/efi.h | 4 ++++
include/part.h | 3 ++-
include/part_efi.h | 4 ----
6 files changed, 50 insertions(+), 8 deletions(-)
diff --git a/disk/part_dos.c b/disk/part_dos.c
index 7ede15ec26..850a538e83 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -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;
}
diff --git a/disk/part_efi.c b/disk/part_efi.c
index 1b7ba27947..71e4188455 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -871,11 +871,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");
@@ -885,6 +893,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) {
diff --git a/include/blk.h b/include/blk.h
index ef29a07ee2..3a5e04c00d 100644
--- a/include/blk.h
+++ b/include/blk.h
@@ -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"
@@ -35,6 +37,14 @@ enum if_type {
IF_TYPE_COUNT, /* Number of interface types */
};
+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)
@@ -62,6 +72,11 @@ struct blk_desc {
char vendor[40+1]; /* IDE model, SCSI Vendor */
char product[20+1]; /* IDE Serial no, SCSI product */
char revision[8+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 */
+ };
#ifdef CONFIG_BLK
/*
* For now we have a few functions which take struct blk_desc as a
diff --git a/include/efi.h b/include/efi.h
index 02b78b31b1..87b0b43f20 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -28,6 +28,10 @@
struct efi_device_path;
+typedef struct {
+ u8 b[16];
+} efi_guid_t;
+
#define EFI_BITS_PER_LONG BITS_PER_LONG
/*
diff --git a/include/part.h b/include/part.h
index 83bce05a43..ac5ee895e9 100644
--- a/include/part.h
+++ b/include/part.h
@@ -259,8 +259,9 @@ struct part_driver {
#define U_BOOT_PART_TYPE(__name) \
ll_entry_declare(struct part_driver, __name, part_driver)
-#if CONFIG_IS_ENABLED(EFI_PARTITION)
#include <part_efi.h>
+
+#if CONFIG_IS_ENABLED(EFI_PARTITION)
/* disk/part_efi.c */
/**
* write_gpt_table() - Write the GUID Partition Table to disk
diff --git a/include/part_efi.h b/include/part_efi.h
index 317c044795..31e6bc6e14 100644
--- a/include/part_efi.h
+++ b/include/part_efi.h
@@ -58,10 +58,6 @@
/* linux/include/efi.h */
typedef u16 efi_char16_t;
-typedef struct {
- u8 b[16];
-} efi_guid_t;
-
/* based on linux/include/genhd.h */
struct partition {
u8 boot_ind; /* 0x80 - active */
--
2.13.0
More information about the U-Boot
mailing list