From a2d218b17e33e56829b9a23f73dded07ae5839a8 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 15 Sep 2019 09:37:45 +0200 Subject: [PATCH 177/220] blscfg: Add support for the devicetree field The BootLoaderSpec mentions that a devicetree field can be used to pass a Device Tree (DT) to the kernel, for the platforms that use it to describe information about the hardware. Allow the blscfg module to parse this field and call the grub2 devicetree command in that case. If there is a devicetree grub2 environment variable defined, this will be used if the field is not defined in the BLS snippet. Resolves: rhbz#1751307 Signed-off-by: Javier Martinez Canillas --- grub-core/commands/blscfg.c | 60 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c index 54458b1..1ec8987 100644 --- a/grub-core/commands/blscfg.c +++ b/grub-core/commands/blscfg.c @@ -698,6 +698,8 @@ static void create_entry (struct bls_entry *entry) const char *early_initrd = NULL; char **early_initrds = NULL; char *initrd_prefix = NULL; + char *devicetree = NULL; + char *dt = NULL; char *id = entry->filename; char *dotconf = id; char *hotkey = NULL; @@ -709,6 +711,7 @@ static void create_entry (struct bls_entry *entry) char *src = NULL; int i, index; + bool add_dt_prefix = false; grub_dprintf("blscfg", "%s got here\n", __func__); clinux = bls_get_val (entry, "linux", NULL); @@ -736,6 +739,14 @@ static void create_entry (struct bls_entry *entry) initrds = bls_make_list (entry, "initrd", NULL); + devicetree = expand_val (bls_get_val (entry, "devicetree", NULL)); + + if (!devicetree) + { + devicetree = expand_val (grub_env_get("devicetree")); + add_dt_prefix = true; + } + hotkey = bls_get_val (entry, "grub_hotkey", NULL); users = expand_val (bls_get_val (entry, "grub_users", NULL)); classes = bls_make_list (entry, "grub_class", NULL); @@ -801,7 +812,6 @@ static void create_entry (struct bls_entry *entry) goto finish; } - tmp = grub_stpcpy(initrd, "initrd"); for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++) { @@ -821,21 +831,65 @@ static void create_entry (struct bls_entry *entry) tmp = grub_stpcpy (tmp, "\n"); } + if (devicetree) + { + char *prefix = NULL; + int dt_size; + + if (add_dt_prefix) + { + prefix = grub_strrchr (clinux, '/'); + prefix = grub_strndup(clinux, prefix - clinux + 1); + if (!prefix) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto finish; + } + } + + dt_size = sizeof("devicetree " GRUB_BOOT_DEVICE) + grub_strlen(devicetree) + 1; + + if (add_dt_prefix) + { + dt_size += grub_strlen(prefix); + } + + dt = grub_malloc (dt_size); + if (!dt) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto finish; + } + char *tmp = dt; + tmp = grub_stpcpy (dt, "devicetree"); + tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE); + if (add_dt_prefix) + tmp = grub_stpcpy (tmp, prefix); + tmp = grub_stpcpy (tmp, devicetree); + tmp = grub_stpcpy (tmp, "\n"); + + grub_free(prefix); + } + + grub_dprintf ("blscfg2", "devicetree %s for id:\"%s\"\n", dt, id); + src = grub_xasprintf ("load_video\n" "set gfxpayload=keep\n" "insmod gzio\n" "linux %s%s%s%s\n" - "%s", + "%s%s", GRUB_BOOT_DEVICE, clinux, options ? " " : "", options ? options : "", - initrd ? initrd : ""); + initrd ? initrd : "", dt ? dt : ""); grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, src, 0, &index, entry); grub_dprintf ("blscfg", "Added entry %d id:\"%s\"\n", index, id); finish: + grub_free (dt); grub_free (initrd); grub_free (initrd_prefix); grub_free (early_initrds); + grub_free (devicetree); grub_free (initrds); grub_free (options); grub_free (classes); -- 1.8.3.1