Ported from the asahi-quattro lane. Both are pinned by hand like linux-aurora and restricted to aarch64 and the edge channel from their first merge, since merging publishes. pkgrel sits one above the fork lanes' builds so the same filename never carries two sets of bytes.
191 lines
6.1 KiB
Diff
191 lines
6.1 KiB
Diff
From 56a985cec8592a8de88e7f254df82f5d444a5ecc Mon Sep 17 00:00:00 2001
|
|
From: Peter Robinson <pbrobinson@gmail.com>
|
|
Date: Thu, 28 May 2026 22:08:07 +0100
|
|
Subject: [PATCH] initial find_fdt_location for finding the DT on disk
|
|
|
|
The old distro boot looked for a DT on the first boot partition
|
|
in the /dtb or /dtb/current directories, and Fedora extended this
|
|
to look not just on the boot partition but all the partitions on
|
|
that disk.
|
|
|
|
The new ways of booting, both bootstd and bootefi bootmgr processes
|
|
don't properly look for those options. This provides a function
|
|
to search for the DTB on disk so that if the other DT mechanisms
|
|
don't work this will look for one on disk to provide a working DT
|
|
so that devices will continue to work as they did previously.
|
|
|
|
Signed-off-by: Peter Robinson <pbrobinson@gmail.com>
|
|
---
|
|
cmd/bootmenu.c | 5 ++
|
|
include/efi_loader.h | 2 +
|
|
lib/efi_loader/efi_helper.c | 106 +++++++++++++++++++++++++++++++++++-
|
|
3 files changed, 112 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
|
|
index 528afd221d0..a10ea35a687 100644
|
|
--- a/cmd/bootmenu.c
|
|
+++ b/cmd/bootmenu.c
|
|
@@ -502,6 +502,11 @@ static void handle_uefi_bootnext(void)
|
|
u16 bootnext;
|
|
efi_status_t ret;
|
|
efi_uintn_t size;
|
|
+ const char *fdt_opt;
|
|
+
|
|
+ /* Find the DTB on disk */
|
|
+ log_debug("We will load the DTB\n");
|
|
+ fdt_opt = find_fdt_location();
|
|
|
|
/* Initialize EFI drivers */
|
|
ret = efi_init_obj_list();
|
|
diff --git a/include/efi_loader.h b/include/efi_loader.h
|
|
index 3a4d502631c..b11f8a2cb42 100644
|
|
--- a/include/efi_loader.h
|
|
+++ b/include/efi_loader.h
|
|
@@ -574,6 +574,8 @@ struct efi_register_notify_event {
|
|
struct list_head handles;
|
|
};
|
|
|
|
+/* Find the FDT on any partition */
|
|
+char *find_fdt_location(void);
|
|
/* called at pre-initialization */
|
|
int efi_init_early(void);
|
|
/* Initialize efi execution environment */
|
|
diff --git a/lib/efi_loader/efi_helper.c b/lib/efi_loader/efi_helper.c
|
|
index 44b806aadc4..61e982091b9 100644
|
|
--- a/lib/efi_loader/efi_helper.c
|
|
+++ b/lib/efi_loader/efi_helper.c
|
|
@@ -15,6 +15,7 @@
|
|
#include <mapmem.h>
|
|
#include <dm.h>
|
|
#include <fs.h>
|
|
+#include <part.h>
|
|
#include <efi.h>
|
|
#include <efi_api.h>
|
|
#include <efi_load_initrd.h>
|
|
@@ -98,6 +99,99 @@ int efi_get_pxe_arch(void)
|
|
return -EINVAL;
|
|
}
|
|
|
|
+/* We need to pass a blk device in and return a location, or a loaded DT */
|
|
+char *find_fdt_location(void)
|
|
+{
|
|
+ const char *fdt_filename;
|
|
+ /* FIXME: dynamic size */
|
|
+ char fdt_fullpath[60];
|
|
+ const char *prefix;
|
|
+ struct udevice *blk;
|
|
+ /* FIXME: Fedora really only cares about first 2*/
|
|
+ int MAX_PART = 8;
|
|
+ int part;
|
|
+ struct disk_partition info;
|
|
+ int fdtext;
|
|
+ int ret;
|
|
+ int retfdt;
|
|
+ int retload;
|
|
+ loff_t fdtsize;
|
|
+ ulong pbraddr;
|
|
+ loff_t len_read;
|
|
+
|
|
+ /* step one logic: we have the DT name we're hunting for */
|
|
+ fdt_filename = env_get("fdtfile");
|
|
+ if (fdt_filename) {
|
|
+ log_debug("FFL: We're looking for the DTB now!: %s\n", fdt_filename);
|
|
+
|
|
+ /* probe all block disks to search for fdt */
|
|
+ uclass_foreach_dev_probe(UCLASS_BLK, blk) {
|
|
+ log_debug("FFL: dev name: %s\n", blk->name);
|
|
+ struct blk_desc *desc;
|
|
+ desc = dev_get_uclass_plat(blk);
|
|
+ /* we should get a partition count here for looping */
|
|
+ /* For loop for each partition */
|
|
+ /* Need to also deal with zero part whole disk - part_get_info_whole_disk */
|
|
+ for (part = 1; part <= MAX_PART; part++) {
|
|
+ log_debug("FFL: part num: %d\n", part);
|
|
+ ret = part_get_info(desc, part, &info);
|
|
+ /* if we have partition check it for DT */
|
|
+ if (ret < 0) {
|
|
+ log_debug("FFL: no partition\n");
|
|
+ } else {
|
|
+ log_debug("FFL: we have a partition\n");
|
|
+ /* we should have a case/for prefix in =/ /dtb/ /dtb/current/ */
|
|
+ /* but for now we hard code if for Fedora */
|
|
+ prefix = "/dtb";
|
|
+ snprintf(fdt_fullpath, sizeof(fdt_fullpath), "%s/%s", prefix, fdt_filename);
|
|
+ log_debug("FFL: full name: %s\n", fdt_fullpath);
|
|
+ /* search for DT on partition and either find and exit or continue */
|
|
+ if (fs_set_blk_dev_with_part(desc, part) == 0){
|
|
+ log_debug("FFL: set block part pass\n");
|
|
+ fdtext = fs_exists(fdt_fullpath);
|
|
+ if (fdtext) {
|
|
+ /* we have a fdt!*/
|
|
+ if (fs_set_blk_dev_with_part(desc, part) == 0){
|
|
+ retfdt = fs_size(fdt_fullpath, &fdtsize);
|
|
+ if (retfdt == 0) {
|
|
+ log_debug("FFL: we have found a DT on disk, size %lld\n", fdtsize);
|
|
+ /* Get the main fdt and map it */
|
|
+ const char *fdt_pbr;
|
|
+ fdt_pbr = env_get("fdt_addr_r");
|
|
+ pbraddr = hextoul(fdt_pbr, NULL);
|
|
+ log_debug("FFL: fdr addr: %s\n", fdt_pbr);
|
|
+ if (fs_set_blk_dev_with_part(desc, part) == 0){
|
|
+ retload = fs_read(fdt_fullpath, pbraddr, 0, fdtsize, &len_read);
|
|
+ if (retload == 0) {
|
|
+ log_debug("FFL: we have a loaded DT, size %lld we can return\n", fdtsize);
|
|
+ log_info("Found DTB: %s\n", fdt_filename);
|
|
+ return fdt_pbr;
|
|
+ } else {
|
|
+ log_debug("FFL: DT load failed\n");
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ log_debug("FFL: we DON'T have a DT with size\n");
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ /* we don't have a fdt!*/
|
|
+ log_debug("FFL: we DON'T have a DT\n");
|
|
+ }
|
|
+ } else {
|
|
+ log_debug("FFL: set block part FAIL\n");
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ log_debug("FFL: fdt_filename not defined!!\n");
|
|
+ }
|
|
+
|
|
+ /* We didn't find a FDT */
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
/**
|
|
* efi_create_current_boot_var() - Return Boot#### name were #### is replaced by
|
|
* the value of BootCurrent
|
|
@@ -558,11 +652,21 @@ efi_status_t efi_install_fdt(void *fdt)
|
|
const char *fdt_opt;
|
|
uintptr_t fdt_addr;
|
|
|
|
+ /* Check if there is device tree loaded from disk */
|
|
+ fdt_opt = find_fdt_location();
|
|
+ if (fdt_opt)
|
|
+ log_info("Found DTB on disk\n");
|
|
+
|
|
/* Check if there is a hardware device tree */
|
|
- fdt_opt = env_get("fdt_addr");
|
|
+ if (!fdt_opt) {
|
|
+ fdt_opt = env_get("fdt_addr");
|
|
+ if (fdt_opt)
|
|
+ log_info("Found DTB: Prior firmware\n");
|
|
+ }
|
|
/* Use our own device tree as fallback */
|
|
if (!fdt_opt) {
|
|
fdt_opt = env_get("fdtcontroladdr");
|
|
+ log_info("Using DT from U-Boot\n");
|
|
if (!fdt_opt) {
|
|
log_err("need device tree\n");
|
|
return EFI_NOT_FOUND;
|
|
--
|
|
2.54.0
|
|
|