8 Star 0 Fork 21

src-openEuler/uboot-tools
Closed

Create your Gitee Account
Explore and code with more than 14 million developers,Free private repositories !:)
Sign up
文件
This repository doesn't specify license. Please pay attention to the specific project description and its upstream code dependency when using it.
Clone or Download
uefi-initial-find_fdt_location-for-finding-the-DT-on-disk.patch 6.61 KB
Copy Edit Raw Blame History
lingsheng authored 2025-02-13 19:41 +08:00 . update to 2025.01
From 121fd475757e183428ca78f43420c42b9973aa33 Mon Sep 17 00:00:00 2001
From: Peter Robinson <pbrobinson@gmail.com>
Date: Tue, 31 Dec 2024 14:11:12 +0000
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/bootefi.c | 1 +
cmd/bootmenu.c | 5 ++
include/efi_loader.h | 2 +
lib/efi_loader/efi_helper.c | 105 +++++++++++++++++++++++++++++++++++-
4 files changed, 112 insertions(+), 1 deletion(-)
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index c1454ffb948..ec869047f05 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -143,6 +143,7 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, int argc,
if (argc > 2) {
uintptr_t fdt_addr;
+ /* Do we need to run find_fdt_location here?*/
fdt_addr = hextoul(argv[2], NULL);
fdt = map_sysmem(fdt_addr, 0);
} else {
diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
index b633aedf011..96a71a96820 100644
--- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c
@@ -461,6 +461,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 39809eac1bc..511eba655e7 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -514,6 +514,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 bf96f61d3d0..3f496cc0dfb 100644
--- a/lib/efi_loader/efi_helper.c
+++ b/lib/efi_loader/efi_helper.c
@@ -12,6 +12,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>
@@ -95,6 +96,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
@@ -548,11 +642,20 @@ efi_status_t efi_install_fdt(void *fdt)
/* Look for device tree that is already installed */
if (efi_get_configuration_table(&efi_guid_fdt))
return EFI_SUCCESS;
+ /* Check if there is device tree loaded from disk */
+ fdt_opt = find_fdt_location();
+ if (fdt_opt)
+ log_debug("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_debug("Using DT from U-Boot\n");
if (!fdt_opt) {
log_err("need device tree\n");
return EFI_NOT_FOUND;
--
2.47.1
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/src-openeuler/uboot-tools.git
git@gitee.com:src-openeuler/uboot-tools.git
src-openeuler
uboot-tools
uboot-tools
master

Search