I’m implementing firmware for Orin NX 16GB on custom carrier board. Based on Jetpack 6.1. Secure boot is enabled, the DTB, kernel, initrd now is load directly from NVMe partitions (not using syslinux configuration file).
How can I dynamic load dtb depends on hardware revision (specified by reading ADC value on I2C bus)? Is it possible to do this in UEFI boot? Or maybe in initrd?
*** Please note that this reply is generated by LLM automatically ***
To dynamically load the DTB (Device Tree Blob) based on the hardware revision specified by reading an ADC value on the I2C bus, you have a few options to consider, both in the context of UEFI boot and within the initrd. I’ll outline the possibilities and provide a comparison where relevant.
UEFI Boot
In the UEFI boot process, you can utilize the UEFI firmware’s ability to execute UEFI applications or drivers before loading the operating system. This can be leveraged to read the ADC value from the I2C bus and then select the appropriate DTB based on that value.
UEFI Application: You can write a custom UEFI application that reads the ADC value from the I2C bus and then loads the corresponding DTB. This application would need to be compiled into a UEFI-compatible format (e.g., using the EDK II development environment) and then added to the UEFI firmware’s boot sequence. This approach requires significant development effort and knowledge of UEFI application development.
UEFI Driver: Alternatively, you could develop a UEFI driver that integrates with the UEFI firmware to read the ADC value and select the DTB. This approach also requires expertise in UEFI driver development and may involve modifying the UEFI firmware, which can be complex and may not be feasible for all use cases.
Initrd
Loading the DTB dynamically within the initrd is another viable approach. The initrd is a temporary file system used by the kernel during the boot process, allowing you to execute scripts and load necessary modules before the root file system is mounted.
Initrd Scripts: You can modify the initrd to include a script that reads the ADC value from the I2C bus and then loads the appropriate DTB. This script would need to be executed before the kernel attempts to load the DTB. This approach is more accessible than UEFI development, as it involves scripting and possibly some C programming for I2C access, but it’s still within the realm of Linux development.
Kernel Modules: Another option within the initrd context is to load a kernel module that reads the ADC value and selects the DTB. This would require developing a custom kernel module, which, while still a development effort, is more focused on Linux kernel development than UEFI.
Comparison and Considerations
Development Complexity: UEFI development (applications or drivers) is generally more complex and less common than Linux development (initrd scripts or kernel modules). If your team has more experience with Linux, the initrd approach might be more feasible.
Boot Process Integration: UEFI-level solutions integrate earlier in the boot process, potentially offering more flexibility in terms of system configuration before the kernel loads. However, this also means that any issues could prevent the system from booting at all.
Flexibility and Maintainability: Solutions implemented within the initrd might offer more flexibility and ease of maintenance, as they are part of the Linux environment and can be updated or modified without touching the UEFI firmware.
Security: If secure boot is enabled, ensure that any modifications or additions (e.g., custom UEFI applications or kernel modules) are properly signed and integrated into the secure boot process to maintain the security posture of the system.
In conclusion, while both UEFI and initrd approaches are viable, the choice between them should be based on your team’s expertise, the specific requirements of your project, and considerations around development complexity, boot process integration, flexibility, maintainability, and security.
*** Please give the thumbs up if you get answers you like. Or provide feedback to help us improve the answer. ***
I used L4TDefaultBootMode = 2 so it will load kernel & dtb from partitions directly.
My hardware setup is divided into multiple modules, so I would like to dynamically load DTB or DTBO depends on which module revision attached.
Loading different overlay for different hardware revision is fine. Can you enlighten me ways todo? Is it possible to apply dtbo inside initrd? Our hardware modules are mostly I2C devices. So the pinmux & gpio are unchanged.
Thank you.
That is why it is hard :( . As far as I can think, 2 approachs maybe possible:
A dtb which contains all devices/modules with all revision, then UEFI will enable/disable relevant device tree block or apply dtbo based on hw revision it can read.
It is much more nicer if able to apply dtbo inside initrd script. Do you know this is possible or not?