:: commit e721cecc2569a83d56d34f4b8482853e17a7dcb5

Kacper Słomiński <kacper.slominski72@gmail.com> — 2024-12-24 14:56

parents: deefcb622d

protos/linux_risc: Don't call get_device_tree_blob if using one from a file

diff --git a/common/protos/linux_risc.c b/common/protos/linux_risc.c
index 99522d1e..e510dba0 100644
--- a/common/protos/linux_risc.c
+++ b/common/protos/linux_risc.c
@@ -116,18 +116,7 @@ const char *verify_kernel(struct boot_param *p) {
     return NULL;
 }
 
-void load_files(struct boot_param *p, char *config) {
-    char *dtb_path = config_get_value(config, 0, "DTB_PATH");
-
-    if (dtb_path) {
-        struct file_handle *dtb_file;
-        if ((dtb_file = uri_open(dtb_path)) == NULL)
-            panic(true, "linux: Failed to open device tree blob with path `%#`. Is the path correct?", dtb_path);
-
-        p->dtb = freadall(dtb_file, MEMMAP_BOOTLOADER_RECLAIMABLE);
-        fclose(dtb_file);
-    }
-
+void load_module(struct boot_param *p, char *config) {
     char *module_path = config_get_value(config, 0, "MODULE_PATH");
     if (module_path) {
         print("linux: Loading module `%#`...\n", module_path);
@@ -416,8 +405,34 @@ noreturn void linux_load(char *config, char *cmdline) {
     struct boot_param p;
     memset(&p, 0, sizeof(p));
     p.cmdline = cmdline;
-    // Hopefully 4K should be enough (mainly depends on the length of cmdline)
-    p.dtb = get_device_tree_blob(0x1000);
+
+    char *dtb_path = config_get_value(config, 0, "DTB_PATH");
+    if (dtb_path) {
+        struct file_handle *dtb_file;
+        if ((dtb_file = uri_open(dtb_path)) == NULL)
+            panic(true, "linux: Failed to open device tree blob with path `%#`. Is the path correct?", dtb_path);
+
+
+        void *dtb = freadall(dtb_file, MEMMAP_BOOTLOADER_RECLAIMABLE);
+        fclose(dtb_file);
+
+        // TODO(qookie): This is a copy of the logic in get_device_tree_blob
+        size_t s = fdt_totalsize(dtb);
+
+        printv("linux: loaded dtb at %p, size %x\n", dtb, s);
+
+        void *new_dtb = ext_mem_alloc(s + 0x1000);
+
+        int ret = fdt_open_into(dtb, new_dtb, s + 0x1000);
+        if (ret < 0) {
+            panic(true, "linux: failed to resize new DTB");
+        }
+
+        p.dtb = new_dtb;
+    } else {
+        // Hopefully 4K should be enough (mainly depends on the length of cmdline)
+        p.dtb = get_device_tree_blob(0x1000);
+    }
 
     struct file_handle *kernel_file;
 
@@ -444,7 +459,7 @@ noreturn void linux_load(char *config, char *cmdline) {
     if (reason)
         panic(true, "linux: invalid kernel image: %s", reason);
 
-    load_files(&p, config);
+    load_module(&p, config);
 
     prepare_device_tree_blob(&p);
 
tab: 248 wrap: offon