[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Grub module to return partuuid of a device such as (hd0, gpt1) at bo

From: Steve Kenton
Subject: Re: Grub module to return partuuid of a device such as (hd0, gpt1) at boot time
Date: Sun, 14 Aug 2016 12:32:28 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0

Thank you for the pointers and encouragement. I knew there had to be a better way and I will do as you suggest using probe etc with current source. I was just experimenting with the source that was already available with my current Buildroot setup as a proof of concept.

Steve Kenton

On 08/14/2016 07:13 AM, Andrei Borzenkov wrote:
13.08.2016 23:25, Steve Kenton пишет:
My thought is to add a new command "partuuid" which takes a
We have "probe" command and if implemented it should be integrated there.

drive&partition string and sets an environment variable to the partition
uuid (grub "partuuid" by default). Since grub always calls the load
drive "hd0"
That's wrong in general.

this can then be passed directly to the kernel as a command
line for the rootfs in many cases. Or search could be used to find the
drive and partuuid could be used to make it palatable to the kernel. For

menuentry "Buildroot" {
     set root=(hd0,gpt1)
     partuuid $root partuuid
     linux /boot/bzImage root=PARTUUID=$partuuid rootfstype=ext4
console=tty1 quiet splash=silent

Below is my first pass at a solution. It's really pseudo code since I
have not even tried to compile it yet. I was just getting familiar with
the grub environment since I've never tinkered with it before. Lot's of
cut and paste but I think it's pretty close.

Steve Kenton

GUIDs are usually stored as 128-bit BE values, and are commonly
displayed as 32 hexadecimal digits
most commonly written in text as a sequence of hexadecimal digits
separated into five groups, such as:


Usually GUIDs are displayed in lower case

This text notation contains the following fields, separated by hyphens:
Hex digits     Description
8     Data1
4     Data2
4     Data3
4     Initial two bytes from Data4
12     Remaining six bytes from Data4

For the first three fields, the most significant digit is on the left.
The last two fields are treated as eight separate bytes, each having
their most significant digit on the left, and they follow each other
from left to right. Note that the digit order of the fourth field may be
unexpected, since it is treated differently from the other fields in the
structure. This is sometimes known as "registry format".
Not sure what it has to do with registry. For GPT GUID are pretty well
defined by UEFI spec which in turn is based on RFC 4122.


int main(int argc, char **argv) // example usage: partuuid "hd0,gpt1"

     char *name, *partnum, *var;
     int number; // the partition # of interest
Please avoid C++ comments.

     grub_disk_t disk;
     grub_err_t err;

     auto int NESTED_FUNC_ATTR find_partuuid(grub_disk_t disk, const
grub_partition_t p);
     int NESTED_FUNC_ATTR find_partuuid(grub_disk_t disk, const
grub_partition_t p)
We got rid of nested functions years ago.

         struct grub_gpt_partentry entry;
         int ret = true; // keep looking

         if (grub_disk_read(disk, p->offset, p->index, sizeof(entry),
             ret = false; // EOF
         else if (p->number == number) // number and var are in scope
from the outer function
             char partuuid[37]; // 32 hex digits, 4 dashes and a NUL

             partuuid = grub_xasprintf
("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", // need to double
grub internal implementation does not include upper case version.

check caps and endian-ness issues
             grub_be_to_cpu32 (*(grub_uint32_t *) &entry.guid[0]),
             grub_be_to_cpu16 (*(grub_uint16_t *) &entry.guid[4]),
             grub_be_to_cpu16 (*(grub_uint16_t *) &entry.guid[6]),
             entry.guid[7], entry.guid[8], // endian-ness does not matter
for single bytes
             entry.guid[9], entry.guid[10], entry.guid[10],
entry.guid[10], entry.guid[10], entry.guid[10], entry.guid[10]);
             err = grub_set_env(var, partuuid); // need to error check
             ret = false; // found it, all done

         return ret;

     // Split disk and partition from the name string and get environment
variable name - need to error check
     name = argv[1];
     partnum = grub_strchr(name, ',') + 1;
     var = argv[2]; // should default to "partuuid" if not supplied
     while (*partnum && grub_isalpha(*partnum))
You can simply read partition info directly from disk, no need to
iterate at all. grub_disk_open returns all needed information about
partition location.

     number = grub_strtoul(partnum, (char **) &partnum, 0) - 1; // need
to look at this function
     if (disk = grub_disk_open(name)) // ignores partition if present in
You should return error if open fails, not silently ignore it. Not to
mention, that it won't even compile because of warning that is treated
as error.

name string, NULL on failure
         err = grub_gpt_partition_map_iterate(disk, find_partuuid);

Linux supports synthetic "GUID" on MSDOS labels too. This should support
it as well (even though I am not sure how useful they are).

     return 0;

On 08/13/2016 06:40 PM, Andrei Borzenkov wrote:
13.08.2016 20:30, adrian15 пишет:
What's your use case?

Well, this has been requested before and this is supported by Linux
kernel. So as long as this does not increase core modules size (i.e. is
done outside of partition probing core) I think it will be OK.


El 12/08/16 a las 16:11, Steve Kenton escribió:
As far as I can tell there is no search module that can be used to get
the partuuid at boot time given a grub root device such as
(hd0,gtp1). I
think is would be a useful addition since the resulting partuuid could
be passed directly to the kernel as root=PARTUUID=xxx and it does not
seem like it should be hard to do. Am I missing something obvious? And,
before I jump end the deep end of the pool and try to write it, is
anyone else working on something similar?

There was recent patch series that adds support for user-space
grub-probe. Would be good if implementation can be shared. I do not want
to add any special code to handle partitions UUID to core as this is
very special case of really one partition type only, used infrequently
and can be entirely handled by usual device iteration.

Not subscribed, please cc me on reply.

Not sure why, but whatever reply I chose Thunderbird and Gmail only
reply to list.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]