This changes somewhat depending on if this is an eMMC model, versus an SD card model. But here is some starting background…
The operating system partition (Linux, the “APP” label) is the only partition which is not signed (for eMMC there are a lot of other partitions; on SD card models there is that content inside of QSPI memory). There are other partitions containing kernel and device tree content, all of which are signed and produced by flashing.
There is also the content in “/boot
” of the Linux (“APP”/rootfs) partition. That content is not signed. SD card models have no ability to burn security fuses, but that other content is still signed, and in the case of security fuses not burned, there is a NULL key for the default. Only signed partitions are accepted, but content named in extlinux.conf
for existence within “/boot
” takes precedence if named (and that part is unsigned). Burning fuses means “/boot
” content is rejected.
So naming device tree or kernel as a file via extlinux.conf
means that content is what is used, and is simple to adjust versus using partitions.
This is complicated in some cases by the initrd
. An initial ramdisk (initrd
) is essentially a miniature filesystem in RAM, and more or less a complete Linux system. Unlike normal boot, it’s purpose is only to load certain kernel modules, like an adapter, and then to transfer to the actual root filesystem. The kernel itself is in the initrd
, and a minimal list of modules are there (think of things needed for running within the initrd
, plus things which will be needed in the future when pivoting to the actual root filesystem, e.g., a driver for some unusual filesystem format). I don’t know all of the details, but the initrd
might contain some content which will overwrite the extlinux.conf
.
Normally one would start by editing extlinux.conf
, and instead of removing the old content, adding a second boot entry which points at the new kernel (if it’s just modules, then there is no need for this, you just copy modules). Then, if the alternate boot entry works, you’d simply edit the extlinux.conf
to make this the default entry. You might or might not leave the old kernel and modules since it would serve as a backup, e.g., if a system update did something to overwrite the new configuration.
The combination of the kernel version and the “CONFIG_LOCALVERSION
” (a text string) during compile of the kernel (the Image
file…an integration of many kernel features) determines the output of the command “uname -r
”. It is different from earlier Jetsons (there is a newer kernel), but an example would be “4.9.337-tegra
”. In that example “4.9.337
” is the kernel version, and the kernel was compiled with “CONFIG_LOCALVERSION=-tegra
”. Loadable modules are searched for in a subdirectory of this:
/lib/modules/$(uname -r)/kernel
(in that example “/lib/modules/4.9.337-tegra/kernel
”)
If you do not change the Image
file (the integrated kernel), then modules will remain searched for in the same place. Assuming the module is compiled to match that’ kernel’s configuration, then you can load that module from that location with no further action (you would probably run “sudo depmod -a
” to register the change or reboot or both).
During kernel build one has to configure prior to compiling. You would always start by matching the existing kernel’s configuration, including CONFIG_LOCALVERSION
. This means any added modules will be compatible and the Image
itself won’t need change. If you run into features which require changing the kernel Image
itself (not all features can be a module), then you need to recompile all of these: The kernel Image
, the modules, and a new uname -r
via CONFIG_LOCALVERSION
.
If you were to add a completely new kernel Image
file, then I’d recommend leaving the old one there, and adding a new boot entry instead of replacing the old one (except if you are confident this new kernel will boot…flashing as a means of recovery is much more problematic compared to picking a different boot entry to the old kernel).
An example would be the rename the new Image
to Image-custom
, and placing it at “/boot/Image-custom
”. The new “CONFIG_LOCALVERSION
” could be “-custom
”. When that kernel runs, it will look for modules at (it won’t be 4.9.337
, but I’m using that as an example):
/lib/modules/4.9.337-custom/kernel
In that case you would copy or install all modules as a complete tree of modules at that location.
rsync
is a good way to copy to that location. Using an SD card or USB thumb drive, if available, is also a way to copy this to the Jetson, and then use sudo
to recursively copy this at the right location.
UEFI is a bit different on the newer Jetsons. I’ve seen some people editing extlinux.conf
and having the initrd
overwrite their edits. I have not tried this myself on the Orin (I don’t have an NX or Nano Orin). Maybe someone from NVIDIA can comment on where to edit extlinux.conf
such that alternate entries won’t get overwritten. Even so, if you use a different boot entry, and if the Image
file is renamed, it wouldn’t harm anything…it’d just boot to the original entry.
So the question comes down to this:
- Did you use the same
CONFIG_LOCALVERSION
(“-tegra
”)?
- Are you adding a module, or did you have to change the original configuration for items which cannot be made as a module?
- A restatement of the second point: Did you start by matching the original kernel configuration, which means using either “
/proc/config.gz
” (after decompressing and renaming “.config
”), or use the build target “tegra_defconfig
” (this is what stock systems ship with)?
The above changes the answer to installing. Hopefully the Image
file has not changed. Then it is very simple.
Incidentally, if you build kernel modules, then the modules appear in some subdirectory. A contrived example is maybe you get “drivers/net/something.ko
”. If your module directory is “/lib/modules/4.9.337-tegra/kernel
”, then this means your new module would go here:
/lib/modules/4.9.337-tegra/kernel/drivers/net/something.ko
…the subdirectory of the driver produced in kernel build matches the subdirectory of the module’s base path of “/lib
”.
You are using l4t_initrd_flash.sh
, and I do not have an external device, so I have never experimented with this. It is quite possible the kernel and modules still go on eMMC…it just depends on whether this is a chain load or a pivot root (they reach the same boot via different paths). So it is important to know the above questions in the bullet points even if it is an initrd
flash.
Once that is answered, someone familiar with Orin l4t_initrd_flash.sh
could answer how to modify extlinux.conf
for a second entry if this fails (failing would just use the original boot entry if you don’t overwrite the original Image
file).