mirror of
git://git.openwrt.org/openwrt/openwrt.git
synced 2024-12-23 07:03:44 +00:00
firmware-utils/ptgen: set GPT partition attributes and name
Allow setting GPT partition names as used by TF-A bl2 to identify the FIP volume to load from eMMC and SD-card. While at it, also allow setting 'required' attribute as it should be used for volumes which are essential for the system to boot. Also properly handle setting the LEGACY_BOOT flag on the partition selected as 'active', as this is how it is specified in the spec. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
parent
0235186182
commit
049ac36b2f
@ -52,6 +52,8 @@
|
|||||||
#define swap(a, b) \
|
#define swap(a, b) \
|
||||||
do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)
|
do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)
|
||||||
|
|
||||||
|
#define BIT(_x) (1UL << (_x))
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t b[16];
|
uint8_t b[16];
|
||||||
} guid_t;
|
} guid_t;
|
||||||
@ -80,11 +82,23 @@ typedef struct {
|
|||||||
GUID_INIT( 0x21686148, 0x6449, 0x6E6F, \
|
GUID_INIT( 0x21686148, 0x6449, 0x6E6F, \
|
||||||
0x74, 0x4E, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49)
|
0x74, 0x4E, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49)
|
||||||
|
|
||||||
|
#define GUID_PARTITION_LINUX_FIT_GUID \
|
||||||
|
GUID_INIT( 0xcae9be83, 0xb15f, 0x49cc, \
|
||||||
|
0x86, 0x3f, 0x08, 0x1b, 0x74, 0x4a, 0x2d, 0x93)
|
||||||
|
|
||||||
|
#define GUID_PARTITION_LINUX_FS_GUID \
|
||||||
|
GUID_INIT( 0x0fc63daf, 0x8483, 0x4772, \
|
||||||
|
0x8e, 0x79, 0x3d, 0x69, 0xd8, 0x47, 0x7d, 0xe4)
|
||||||
|
|
||||||
#define GPT_HEADER_SIZE 92
|
#define GPT_HEADER_SIZE 92
|
||||||
#define GPT_ENTRY_SIZE 128
|
#define GPT_ENTRY_SIZE 128
|
||||||
#define GPT_ENTRY_MAX 128
|
#define GPT_ENTRY_MAX 128
|
||||||
#define GPT_ENTRY_NAME_SIZE 72
|
#define GPT_ENTRY_NAME_SIZE 72
|
||||||
|
|
||||||
|
#define GPT_ATTR_PLAT_REQUIRED BIT(0)
|
||||||
|
#define GPT_ATTR_EFI_IGNORE BIT(1)
|
||||||
|
#define GPT_ATTR_LEGACY_BOOT BIT(2)
|
||||||
|
|
||||||
#define GPT_HEADER_SECTOR 1
|
#define GPT_HEADER_SECTOR 1
|
||||||
#define GPT_FIRST_ENTRY_SECTOR 2
|
#define GPT_FIRST_ENTRY_SECTOR 2
|
||||||
|
|
||||||
@ -109,6 +123,9 @@ struct partinfo {
|
|||||||
unsigned long start;
|
unsigned long start;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
int type;
|
int type;
|
||||||
|
char *name;
|
||||||
|
short int required;
|
||||||
|
guid_t guid;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* GPT Partition table header */
|
/* GPT Partition table header */
|
||||||
@ -294,7 +311,7 @@ static int gen_ptable(uint32_t signature, int nr)
|
|||||||
if (parts[i].start != 0) {
|
if (parts[i].start != 0) {
|
||||||
if (parts[i].start * 2 < start) {
|
if (parts[i].start * 2 < start) {
|
||||||
fprintf(stderr, "Invalid start %ld for partition %d!\n",
|
fprintf(stderr, "Invalid start %ld for partition %d!\n",
|
||||||
parts[i].start, i);
|
parts[i].start, i, start);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
start = parts[i].start * 2;
|
start = parts[i].start * 2;
|
||||||
@ -381,7 +398,7 @@ static int gen_gptable(uint32_t signature, guid_t guid, unsigned nr)
|
|||||||
if (parts[i].start != 0) {
|
if (parts[i].start != 0) {
|
||||||
if (parts[i].start * 2 < start) {
|
if (parts[i].start * 2 < start) {
|
||||||
fprintf(stderr, "Invalid start %ld for partition %d!\n",
|
fprintf(stderr, "Invalid start %ld for partition %d!\n",
|
||||||
parts[i].start, i);
|
parts[i].start, i, start);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
start = parts[i].start * 2;
|
start = parts[i].start * 2;
|
||||||
@ -396,12 +413,16 @@ static int gen_gptable(uint32_t signature, guid_t guid, unsigned nr)
|
|||||||
gpte[i].end = cpu_to_le64(sect -1);
|
gpte[i].end = cpu_to_le64(sect -1);
|
||||||
gpte[i].guid = guid;
|
gpte[i].guid = guid;
|
||||||
gpte[i].guid.b[sizeof(guid_t) -1] += i + 1;
|
gpte[i].guid.b[sizeof(guid_t) -1] += i + 1;
|
||||||
if (parts[i].type == 0xEF || (i + 1) == (unsigned)active) {
|
gpte[i].type = parts[i].guid;
|
||||||
gpte[i].type = GUID_PARTITION_SYSTEM;
|
|
||||||
init_utf16("EFI System Partition", (uint16_t *)gpte[i].name, GPT_ENTRY_NAME_SIZE / sizeof(uint16_t));
|
if (parts[i].name)
|
||||||
} else {
|
init_utf16(parts[i].name, (uint16_t *)gpte[i].name, GPT_ENTRY_NAME_SIZE / sizeof(uint16_t));
|
||||||
gpte[i].type = GUID_PARTITION_BASIC_DATA;
|
|
||||||
}
|
if ((i + 1) == (unsigned)active)
|
||||||
|
gpte[i].attr |= GPT_ATTR_LEGACY_BOOT;
|
||||||
|
|
||||||
|
if (parts[i].required)
|
||||||
|
gpte[i].attr |= GPT_ATTR_PLAT_REQUIRED;
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
fprintf(stderr, "Partition %d: start=%" PRIu64 ", end=%" PRIu64 ", size=%" PRIu64 "\n",
|
fprintf(stderr, "Partition %d: start=%" PRIu64 ", end=%" PRIu64 ", size=%" PRIu64 "\n",
|
||||||
@ -498,21 +519,44 @@ fail:
|
|||||||
|
|
||||||
static void usage(char *prog)
|
static void usage(char *prog)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: %s [-v] [-n] [-g] -h <heads> -s <sectors> -o <outputfile> [-a 0..4] [-l <align kB>] [-G <guid>] [[-t <type>] -p <size>[@<start>]...] \n", prog);
|
fprintf(stderr, "Usage: %s [-v] [-n] [-g] -h <heads> -s <sectors> -o <outputfile> [-a 0..4] [-l <align kB>] [-G <guid>] [[-t <type>] [-r] [-N <name>] -p <size>[@<start>]...] \n", prog);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static guid_t type_to_guid_and_name(unsigned char type, char **name)
|
||||||
|
{
|
||||||
|
guid_t guid = GUID_PARTITION_BASIC_DATA;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 0xef:
|
||||||
|
*name = "EFI System Partition";
|
||||||
|
guid = GUID_PARTITION_SYSTEM;
|
||||||
|
break;
|
||||||
|
case 0x83:
|
||||||
|
guid = GUID_PARTITION_LINUX_FS_GUID;
|
||||||
|
break;
|
||||||
|
case 0x2e:
|
||||||
|
guid = GUID_PARTITION_LINUX_FIT_GUID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return guid;
|
||||||
|
}
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
int main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
unsigned char type = 0x83;
|
unsigned char type = 0x83;
|
||||||
char *p;
|
char *p;
|
||||||
int ch;
|
int ch;
|
||||||
int part = 0;
|
int part = 0;
|
||||||
|
char *name = NULL;
|
||||||
|
unsigned short int required = 0;
|
||||||
uint32_t signature = 0x5452574F; /* 'OWRT' */
|
uint32_t signature = 0x5452574F; /* 'OWRT' */
|
||||||
guid_t guid = GUID_INIT( signature, 0x2211, 0x4433, \
|
guid_t guid = GUID_INIT( signature, 0x2211, 0x4433, \
|
||||||
0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0x00);
|
0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0x00);
|
||||||
|
guid_t part_guid = GUID_PARTITION_BASIC_DATA;
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, "h:s:p:a:t:o:vngl:S:G:")) != -1) {
|
while ((ch = getopt(argc, argv, "h:s:p:a:t:o:vnN:gl:rS:G:")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'o':
|
case 'o':
|
||||||
filename = optarg;
|
filename = optarg;
|
||||||
@ -543,11 +587,28 @@ int main (int argc, char **argv)
|
|||||||
parts[part].start = to_kbytes(p);
|
parts[part].start = to_kbytes(p);
|
||||||
}
|
}
|
||||||
parts[part].size = to_kbytes(optarg);
|
parts[part].size = to_kbytes(optarg);
|
||||||
|
parts[part].required = required;
|
||||||
|
parts[part].name = name;
|
||||||
|
parts[part].guid = part_guid;
|
||||||
fprintf(stderr, "part %ld %ld\n", parts[part].start, parts[part].size);
|
fprintf(stderr, "part %ld %ld\n", parts[part].start, parts[part].size);
|
||||||
parts[part++].type = type;
|
parts[part++].type = type;
|
||||||
|
/*
|
||||||
|
* reset 'name' and 'required'
|
||||||
|
* 'type' is deliberately inherited from the previous delcaration
|
||||||
|
*/
|
||||||
|
name = NULL;
|
||||||
|
required = 0;
|
||||||
|
part_guid = type_to_guid_and_name(type, &name);
|
||||||
|
break;
|
||||||
|
case 'N':
|
||||||
|
name = optarg;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
required = 1;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
type = (char)strtoul(optarg, NULL, 16);
|
type = (char)strtoul(optarg, NULL, 16);
|
||||||
|
part_guid = type_to_guid_and_name(type, &name);
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
active = (int)strtoul(optarg, NULL, 0);
|
active = (int)strtoul(optarg, NULL, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user