We are in the process of developing a custom board based on the Jetson nano. During the process of development, we discovered that the latest kernel supported for the Jetson nano is linux-tegra 4.9.
However, we would like to update the kernel to linux-tegra 5.10 and we are already in the process of doing that. We already patched the 5.10 kernel to include some missing files such as the t210 directories at:
but no luck as the board used here is the devkit, but our board is the emmc type.
I am not very experienced in board bring-up and would need help on the possibilities of what we are attempting to do, and the proper way to go about it.
I can’t provide much help (this is more like random information). I will point out that the main difference between bringing up a dev kit versus eMMC model is device tree. Some of that difference shows up in boot stages, and some also shows up in the Linux kernel.
Often the device tree could be considered as arguments to pass to drivers. If the arguments to a 4.x driver are identical to its 5.x corollary, then you won’t need to edit that device tree node. You have roughly this category of problem to solve:
Drivers in both boot and Linux need to support eMMC.
In the case of drivers finding out about non-plug-n-play items, you need a device tree node. The dev kit drivers and device tree differ significantly between an eMMC model and a dev kit.
Is the device tree enough to pass that information in both boot and Linux? I don’t know. In theory boot is its own miniature operating system, and the original 4.x kernel series won’t have any effect on boot stages. However, the Jetson 5.x series was developed with UEFI instead of CBoot. What was the environment setup in 5.x prior to passing control to the Linux kernel? I don’t know if the 4.x default environment the Linux kernel would inherit will support the 5.x. In other words, not only do you have to pass the right arguments and transfer control to the Linux kernel, you also have to have a proper environment set up. There is no guarantee the 4.x environment is sufficient. The 5.x environment is completely different due to UEFI.
The Nano is so old, while the UEFI is for much newer systems. I couldn’t even begin to tell you what the differences are.
To shed more light, we are currently using Uboot as our bootloader and the development is done using Yocto project.
We also had the proper device tree in, the device tree for the p3448-0002 (jetson-nano-emmc) is located at kernel-src/nvidia/platform/t210/porg/kernel-dts
tegra210-p3448-0002-p3449-0000-a02.dts
tegra210-p3448-0002-p3449-0000-b00.dts
were copied over to the appropriate location in the 5.10.
We have investigated the Uboot progress by sprinkling printf in the code and able to trace the execution up to an assembly code at:
uboot-src/arch/arm/cpu/transition.S
where I think the handoff to the kernel is done.
We also confirmed the environment variable in Uboot and they are consistent with what is expected. We are working on debugging the handover process between the bootloader and the kernel.
We are open to exploring the UEFI option if that’s going to make it work.
I can’t be too useful since I don’t know enough about the environment that is inherited (and it depends on details of both the 4.x kernel requirements and the 5.x kernel requirements). I’m not sure about memory layout requirements, nor about when certain things must be set up, but perhaps you might be able to find out what the load address is for the start of the kernel, plus whether modules and firmware are loaded into memory at some address prior to transferring execution to the kernel’s IRQ vector table. Environment won’t matter if execution is not transferred to the right address, and if it is transferred, then any kind of module or firmware will also have to be in the proper location at the physical address range the kernel expects to find that content (I couldn’t tell you what those addresses are, but there are probably some big differences between 4.x and 5.x; I have not looked at that in a long time). You might want to print any relevant address ranges and the final execution address of the kernel.