I don’t know much about many of your steps, but it is rather important to know that an initrd is being used when you boot to external media (e.g., an NVMe instead of eMMC). If you’ve invalidated any of the modules to be loaded by the kernel within the initrd, then you have to recreate the initrd with new modules. Not all modules are needed for boot, and it is even possible that none of the initrd modules are required for boot, but odds are high that this is the problem.
Whenever you change the integrated features of a kernel (symbols enabled via “=y”), then all modules invalidate and are likely to no longer load without also rebuilding the modules. Let’s say that you had a module for the ext4 filesystem, and this no longer loads within the initrd; this would imply the rootfs cannot load because it loads from the initrd and is ext4.
Normally, if a feature can be built as a module, then configuring the kernel source to match the existing configuration (including CONFIG_LOCALVERSION), followed by altering only module config, e.g., adding “CONFIG_MAC80211=m”, then all you need to do is build the new module(s) and copy them in place. Previous modules would still load into that kernel. Any module previously put into the initrd will continue to work. Had you changed to “CONFIG_MAC80211=y”, then the kernel Image itself must be replaced, and all modules must be rebuilt and installed. There is an application binary interface to the Image and this does not change if only module configuration is made.
Not all symbols/features can be in the form of a module, and not all symbols/features can be in the form of integrated into the kernel, but most can be either. Be sure to use a dependency aware editor for configuration changes since these understand what can or cannot be a module. A lot of people use the make target menuconfig, I prefer nconfig (it is the same except it adds a symbol search).
Incidentally, the command “uname -r” has an output which starts with the kernel version, and then appends the CONFIG_LOCALVERSION string to the end. The default CONFIG_LOCALVERSION is “-tegra”. For example, if the kernel source is version 5.10.15, and if the CONFIG_LOCALVERSION is “-tegra”, then “uname -r” responds with “5.10.15-tegra”. This becomes part of the search path for modules and is built into the kernel Image at the time of kernel build. Modules are searched for at:
/lib/modules/$(uname -r)/kernel/
If you build modules only, and keep the same “uname -r” (meaning you also kept the same CONFIG_LOCALVERSION), then any module you copy into the right place should work without further effort. If you change any integrated feature, then the opposite is true: You would then want to change CONFIG_LOCALVERSION, e.g., something meaningful like “-mac80211”; the example “uname -r” would then end up as “5.10.15-mac80211”, and the module search location would become:
/lib/modules/5.10.15-mac80211/kernel/
If you left the original kernel Image in place, then it would still be able to find the “/lib/modules/5.10.15-tegra/kernel/” content. The two kernels would have mutually exclusive modules, but it would work out well because each kernel would know where to load modules from.
An initrd is more or less an adapter between boot stages and final root filesystem load. It exists in RAM and is a simplified tree filesystem which the bootloader and Linux always understand. If you wanted to load a filesystem type which the bootloader does not understand, then placing the module in the initrd allows loading that module prior to loading this final filesystem (and then a pivot root replaces the initrd “/” with the NVMe’s “/”). I don’t know which modules were in your original initrd, but likely one or more were needed for boot.
L4T is what gets flashed, and in turn, this is just what you call Ubuntu after adding NVIDIA content. You can check your L4T release with “head -n 1 /etc/nv_tegra_release”. The docs specific to your release are here:
https://developer.nvidia.com/linux-tegra
You can flash using those procedures with your kernel, or, if you can put the old Image back in place, then that might work too (and then you could install the new kernel again, but make sure the initrd is updated). I don’t actually have an NVMe to work with, so I can’t provide details. I do recommend leaving the old Image in place and giving the new Image a file name such as “Image-mac80211” (then both kernels are available; you can delete the original, but it is a good idea to wait until reboot is tested before doing so).