From a7e3e9afe22274397634e6dbe4caa9766adfb7a9 Mon Sep 17 00:00:00 2001
From: Reza Alizadeh Majd <r.majd@pantherx.org>
Date: Sun, 28 Aug 2022 12:34:46 +0430
Subject: [PATCH] bootloader: extlinux: support for optional FDTDIR

There are situations that u-boot doesn't have to load from the device tree.
some provide the device tree using a vendor bootloader (like what raspberry-pi
does) or with an external bootloader that chainloads the u-boot (what Asahi
does for m1n1 bootloader).

Unfortunately we couldn't find any reliable document to enforce u-boot to pass
the device tree via `extlinux.conf`, however during our tests, we found that
removing the `FDTDIR` line from the `extlinux.conf` tend us to do so.

There is also no reliable way to guess if u-boot bootloader should load device
tree or not on a specific hardware. in addition, there are hardware that can
be booted with both firmware device tree on some kernels and with special
device tree on other (modified) kernels.

the following changes provided to define an optional parameter in
<bootloader-configuration> record, called <device-tree-support?>  which by
default is set to #t to keep the current behavior unchanged. if this paramter
is set to #f, the FDTDIR line will be discarded from the <extlinux.conf> and
u-boot doesn't load the device tree automatically.

* gnu/bootloader.scm (<bootloader-configuration>)[device-tree-support?]: new field.
* gnu/bootloader/extlinux.scm (extlinux-configuration-file): add FDTDIR line
based on <device-tree-support?> field of <bootloader-configuration>.
* doc/guix.texi (Bootloader Configuration)[device-tree-support?]: Add
documentation for the new field.
---
 doc/guix.texi               |  7 ++++++
 gnu/bootloader.scm          | 50 ++++++++++++++++++++-----------------
 gnu/bootloader/extlinux.scm | 12 +++++++--
 3 files changed, 44 insertions(+), 25 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 023b48ae35..8171481040 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -36960,6 +36960,13 @@ corresponds to COM1 (@pxref{Serial terminal,,, grub,GNU GRUB manual}).
 The speed of the serial interface, as an integer.  For GRUB, the
 default value is chosen at run-time; currently GRUB chooses
 9600@tie{}bps (@pxref{Serial terminal,,, grub,GNU GRUB manual}).
+
+@item @code{device-tree-support} (default: @code{#t})
+There are situations when @code{u-boot} shouldn't load the device tree from
+the file system. because it is either unnecessary for the platform being used
+or has already been loaded into RAM earlier in the boot process. in such cases
+you can set this field to @code{#f}. setting this flag to @code{#f} removes
+the @code{FDTDIR} line from the @file{/boot/extlinux/extlinux.conf}.
 @end table
 
 @end deftp
diff --git a/gnu/bootloader.scm b/gnu/bootloader.scm
index 70e1836179..335133d224 100644
--- a/gnu/bootloader.scm
+++ b/gnu/bootloader.scm
@@ -4,6 +4,7 @@
 ;;; Copyright © 2017 Leo Famulari <leo@famulari.name>
 ;;; Copyright © 2019, 2021 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
+;;; Copyright © 2022 Reza Alizadeh Majd <r.majd@pantherx.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -69,6 +70,7 @@ (define-module (gnu bootloader)
             bootloader-configuration-terminal-inputs
             bootloader-configuration-serial-unit
             bootloader-configuration-serial-speed
+            bootloader-configuration-device-tree-support?
 
             %bootloaders
             lookup-bootloader-by-name
@@ -193,29 +195,31 @@ (define-with-syntax-properties (warn-target-field-deprecation
 (define-record-type* <bootloader-configuration>
   bootloader-configuration make-bootloader-configuration
   bootloader-configuration?
-  (bootloader         bootloader-configuration-bootloader) ;<bootloader>
-  (targets            %bootloader-configuration-targets    ;list of strings
-                      (default #f))
-  (target             %bootloader-configuration-target ;deprecated
-                      (default #f) (sanitize warn-target-field-deprecation))
-  (menu-entries       bootloader-configuration-menu-entries ;list of <menu-entry>
-                      (default '()))
-  (default-entry      bootloader-configuration-default-entry ;integer
-                      (default 0))
-  (timeout            bootloader-configuration-timeout ;seconds as integer
-                      (default 5))
-  (keyboard-layout    bootloader-configuration-keyboard-layout ;<keyboard-layout> | #f
-                      (default #f))
-  (theme              bootloader-configuration-theme ;bootloader-specific theme
-                      (default #f))
-  (terminal-outputs   bootloader-configuration-terminal-outputs ;list of symbols
-                      (default '(gfxterm)))
-  (terminal-inputs    bootloader-configuration-terminal-inputs ;list of symbols
-                      (default '()))
-  (serial-unit        bootloader-configuration-serial-unit ;integer | #f
-                      (default #f))
-  (serial-speed       bootloader-configuration-serial-speed ;integer | #f
-                      (default #f)))
+  (bootloader           bootloader-configuration-bootloader) ;<bootloader>
+  (targets              %bootloader-configuration-targets    ;list of strings
+                        (default #f))
+  (target               %bootloader-configuration-target ;deprecated
+                        (default #f) (sanitize warn-target-field-deprecation))
+  (menu-entries         bootloader-configuration-menu-entries ;list of <menu-entry>
+                        (default '()))
+  (default-entry        bootloader-configuration-default-entry ;integer
+                        (default 0))
+  (timeout              bootloader-configuration-timeout ;seconds as integer
+                        (default 5))
+  (keyboard-layout      bootloader-configuration-keyboard-layout ;<keyboard-layout> | #f
+                        (default #f))
+  (theme                bootloader-configuration-theme ;bootloader-specific theme
+                        (default #f))
+  (terminal-outputs     bootloader-configuration-terminal-outputs ;list of symbols
+                        (default '(gfxterm)))
+  (terminal-inputs      bootloader-configuration-terminal-inputs ;list of symbols
+                        (default '()))
+  (serial-unit          bootloader-configuration-serial-unit ;integer | #f
+                        (default #f))
+  (serial-speed         bootloader-configuration-serial-speed ;integer | #f
+                        (default #f))
+  (device-tree-support? bootloader-configuration-device-tree-support?
+                        (default #t)))
 
 (define-deprecated (bootloader-configuration-target config)
   bootloader-configuration-targets
diff --git a/gnu/bootloader/extlinux.scm b/gnu/bootloader/extlinux.scm
index 6b5ff298e7..d9b6d8bf8a 100644
--- a/gnu/bootloader/extlinux.scm
+++ b/gnu/bootloader/extlinux.scm
@@ -1,6 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2017 David Craven <david@craven.ch>
 ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
+;;; Copyright © 2022 Reza Alizadeh Majd <r.majd@pantherx.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -38,6 +39,9 @@ (define* (extlinux-configuration-file config entries
   (define all-entries
     (append entries (bootloader-configuration-menu-entries config)))
 
+  (define with-fdtdir?
+    (bootloader-configuration-device-tree-support? config))
+
   (define (menu-entry->gexp entry)
     (let ((label (menu-entry-label entry))
           (kernel (menu-entry-linux entry))
@@ -46,12 +50,16 @@ (define (menu-entry->gexp entry)
       #~(format port "LABEL ~a
   MENU LABEL ~a
   KERNEL ~a
-  FDTDIR ~a/lib/dtbs
+  ~a
   INITRD ~a
   APPEND ~a
 ~%"
                 #$label #$label
-                #$kernel (dirname #$kernel) #$initrd
+                #$kernel
+                (if #$with-fdtdir?
+                    (string-append "FDTDIR " (dirname #$kernel) "/lib/dtbs")
+                    "")
+                #$initrd
                 (string-join (list #$@kernel-arguments)))))
 
   (define builder
-- 
2.37.1

