From 3b1bb7f3eb84771c47f1fd99e0534781eafd56a5 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 22 Feb 2016 00:05:40 +0100 Subject: [PATCH] DTB overrides --- grub-core/Makefile.core.def | 1 - grub-core/kern/arm/coreboot/init.c | 54 ++++++++++++------------------ include/grub/kernel.h | 3 +- include/grub/util/install.h | 2 +- util/grub-install-common.c | 2 +- util/grub-mkimage.c | 11 +++++- util/mkimage.c | 24 +++++++++++-- 7 files changed, 57 insertions(+), 40 deletions(-) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 3838c4481..98c59d1c3 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -157,7 +157,6 @@ kernel = { arm_coreboot = kern/arm/coreboot/init.c; arm_coreboot = kern/arm/coreboot/timer.c; - arm_coreboot = kern/arm/coreboot/fdt_guess.c; arm_coreboot = kern/arm/coreboot/coreboot.S; arm_coreboot = lib/fdt.c; arm_coreboot = bus/fdt.c; diff --git a/grub-core/kern/arm/coreboot/init.c b/grub-core/kern/arm/coreboot/init.c index 84251adf7..723692d62 100644 --- a/grub-core/kern/arm/coreboot/init.c +++ b/grub-core/kern/arm/coreboot/init.c @@ -93,33 +93,22 @@ heap_init (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, return 0; } -static char *mobo_vendor, *mobo_part_number; static const void *dtb; static grub_size_t dtb_size; static int iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data __attribute__ ((unused))) { - switch (table_item->tag) + if (table_item->tag != GRUB_LINUXBIOS_MEMBER_DTB) + return 0; + + if (grub_fdt_check_header (table_item + 1, table_item->size) >= 0) { - case GRUB_LINUXBIOS_MEMBER_MAINBOARD: - { - struct grub_linuxbios_mainboard *mb; - mb = (struct grub_linuxbios_mainboard *) (table_item + 1); - mobo_vendor = mb->strings + mb->vendor; - mobo_part_number = mb->strings + mb->part_number; - return 0; - } - case GRUB_LINUXBIOS_MEMBER_DTB: - if (grub_fdt_check_header (table_item + 1, table_item->size) >= 0) - { - dtb = table_item + 1; - dtb_size = table_item->size; - } - else - grub_printf ("Invalid DTB supplied by coreboot\n"); - return 0; + dtb = table_item + 1; + dtb_size = table_item->size; } + else + grub_printf ("Invalid DTB supplied by coreboot\n"); return 0; } @@ -127,6 +116,8 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data __at void grub_machine_init (void) { + struct grub_module_header *header; + modend = grub_modules_get_end (); grub_video_coreboot_fb_early_init (); @@ -140,22 +131,21 @@ grub_machine_init (void) grub_font_init (); grub_gfxterm_init (); - grub_linuxbios_table_iterate (iterate_linuxbios_table, 0); + FOR_MODULES (header) + if (header->type == OBJ_TYPE_DTB) + { + char *dtb_orig_addr, *dtb_copy; + dtb_orig_addr = (char *) header + sizeof (struct grub_module_header); + dtb_size = header->size - sizeof (struct grub_module_header); + dtb = dtb_copy = grub_malloc (dtb_size); + grub_memmove (dtb_copy, dtb_orig_addr, dtb_size); + break; + } if (!dtb) - { - struct grub_fdt_board *cur; - for (cur = grub_fdt_boards; cur->dtb; cur++) - if (grub_strcmp (cur->vendor, mobo_vendor) == 0 - && grub_strcmp (cur->part, mobo_part_number) == 0) - { - dtb = cur->dtb; - dtb_size = cur->dtb_size; - break; - } - } + grub_linuxbios_table_iterate (iterate_linuxbios_table, 0); if (!dtb) - grub_fatal ("No saved DTB found for <%s> <%s> and none is supplied", mobo_vendor, mobo_part_number); + grub_fatal ("No DTB found"); grub_fdtbus_init (dtb, dtb_size); grub_machine_timer_init (); diff --git a/include/grub/kernel.h b/include/grub/kernel.h index 20ddf2da2..ecd88ca72 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -28,7 +28,8 @@ enum OBJ_TYPE_MEMDISK, OBJ_TYPE_CONFIG, OBJ_TYPE_PREFIX, - OBJ_TYPE_PUBKEY + OBJ_TYPE_PUBKEY, + OBJ_TYPE_DTB }; /* The module header. */ diff --git a/include/grub/util/install.h b/include/grub/util/install.h index 5ca4811cd..6abd288c3 100644 --- a/include/grub/util/install.h +++ b/include/grub/util/install.h @@ -176,7 +176,7 @@ grub_install_generate_image (const char *dir, const char *prefix, char *config_path, const struct grub_install_image_target_desc *image_target, int note, - grub_compression_t comp); + grub_compression_t comp, const char *dtb_file); const struct grub_install_image_target_desc * grub_install_get_image_target (const char *arg); diff --git a/util/grub-install-common.c b/util/grub-install-common.c index 452b230da..8539ff348 100644 --- a/util/grub-install-common.c +++ b/util/grub-install-common.c @@ -499,7 +499,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, grub_install_generate_image (dir, prefix, fp, outname, modules.entries, memdisk_path, pubkeys, npubkeys, config_path, tgt, - note, compression); + note, compression, 0); while (dc--) grub_install_pop_module (); } diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 10375f4d2..ff985c6b2 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -71,6 +71,7 @@ static struct argp_option options[] = { N_("embed FILE as a memdisk image\n" "Implies `-p (memdisk)/boot/grub' and overrides any prefix supplied previously," " but the prefix itself can be overridden by later options"), 0}, + {"dtb", 'D', N_("FILE"), 0, N_("embed FILE as a device tree (DTB)\n"), 0}, /* TRANSLATORS: "embed" is a verb (command description). "*/ {"config", 'c', N_("FILE"), 0, N_("embed FILE as an early config"), 0}, /* TRANSLATORS: "embed" is a verb (command description). "*/ @@ -117,6 +118,7 @@ struct arguments char *dir; char *prefix; char *memdisk; + char *dtb; char **pubkeys; size_t npubkeys; char *font; @@ -176,6 +178,13 @@ argp_parser (int key, char *arg, struct argp_state *state) arguments->prefix = xstrdup ("(memdisk)/boot/grub"); break; + case 'D': + if (arguments->dtb) + free (arguments->dtb); + + arguments->dtb = xstrdup (arg); + break; + case 'k': arguments->pubkeys = xrealloc (arguments->pubkeys, sizeof (arguments->pubkeys[0]) @@ -299,7 +308,7 @@ main (int argc, char *argv[]) arguments.memdisk, arguments.pubkeys, arguments.npubkeys, arguments.config, arguments.image_target, arguments.note, - arguments.comp); + arguments.comp, arguments.dtb); grub_util_file_sync (fp); fclose (fp); diff --git a/util/mkimage.c b/util/mkimage.c index fc111d4f1..cdb95ae63 100644 --- a/util/mkimage.c +++ b/util/mkimage.c @@ -774,13 +774,12 @@ grub_install_generate_image (const char *dir, const char *prefix, char *memdisk_path, char **pubkey_paths, size_t npubkeys, char *config_path, const struct grub_install_image_target_desc *image_target, - int note, - grub_compression_t comp) + int note, grub_compression_t comp, const char *dtb_path) { char *kernel_img, *core_img; size_t total_module_size, core_size; size_t memdisk_size = 0, config_size = 0; - size_t prefix_size = 0; + size_t prefix_size = 0, dtb_size = 0; char *kernel_path; size_t offset; struct grub_util_path_list *path_list, *p; @@ -825,6 +824,12 @@ grub_install_generate_image (const char *dir, const char *prefix, total_module_size += memdisk_size + sizeof (struct grub_module_header); } + if (dtb_path) + { + dtb_size = ALIGN_UP(grub_util_get_image_size (dtb_path), 4); + total_module_size += dtb_size + sizeof (struct grub_module_header); + } + if (config_path) { config_size = ALIGN_ADDR (grub_util_get_image_size (config_path) + 1); @@ -947,6 +952,19 @@ grub_install_generate_image (const char *dir, const char *prefix, offset += memdisk_size; } + if (dtb_path) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_host_to_target32 (OBJ_TYPE_DTB); + header->size = grub_host_to_target32 (dtb_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (dtb_path, kernel_img + offset); + offset += dtb_size; + } + if (config_path) { struct grub_module_header *header; -- 2.47.2