Sorry, this will be a bit at a time, it is hard to know where to start sometimes. It’ll seem easy after you’ve set things up and built a kernel once. Do know that “make
” is a command on the command line, and this is run at the top level of the kernel source. Various arguments may be used, e.g., “make O=/some/where Image
” would use the “/some/where
” location to place output when building the target file Image
. There are several uses of make O=/some/where ...
in which the “O=...
” is always the same, but the rest of the command changes…
If your kernel source is on the Xavier, then this is where you run the commands with make
in their simplest form. If your kernel source is on the host PC, then you will need to also add some options for the cross compiler tool chain location and architecuture (if you see ARCH=...
, then you are cross compiling, and there would also be a CROSS_COMPILE=...
). Most of the instructions you see in the official documents are for cross compile from a PC. If you have kernel source on the Xavier, then it simplifies instructions.
Where is your kernel source (sorry, I know this is sort of what you were asking to start with)…is it on the Xavier (if so, what directory?), or are you cross compiling on the host PC? Which directory is your cross compile tool chain in (only applies if cross compiling from the PC)? I can give more explicit information if you provide the locations of directories where you have (or state if you are trying to find those locations, I can then say how to create the location or find the information):
- Kernel source directory and if on the Xavier or PC.
- Temporary output location of basic build.
- Temporary output location of modules if you are building modules.
- Temporary output location of device tree files if you are building device trees.
- The result of the command on an unmodified Xavier
uname -r
.
- Which L4T release is this for? See “
head -n 1 /etc/nv_tegra_release
”.
The following are some semi random details, not necessarily in a specific order…if you can answer those questions, then what follows isn’t too important. I add these to help with the above, and to add some details to the use of “make
”.
Some comments on this:
- You never use the “
ARCH=
” unless you are cross compiling. If you compile natively on the Jetson, then “make
” already knows the architecture is arm64. If you are cross compiling, then you also need to include “CROSS_COMPILE=/some/where/to/alternate/gcc/prefix/name”. Native compiles on the Xavier do not require special tools (no “CROSS_COMPILE
” when building on an Xavier for an Xavier).
- Don’t use the “modules_install” step unless you’ve specified an alternate module output location (since the “
INSTALL_MOD_PATH
” was given in the example, then this works well when you name a temporary location, but the example is complicated via cross compile). The example they gave is to use on a host PC prior to flash such that the output goes into the sample rootfs directory prior to the flash.
When you have kernel source, then it needs to be configured prior to building. The configuration produces a “.config” file, and the directory with that file must be used consistently. Best practice is to name a build location outside of the actual source code so that the source code remains untouched; this implies the “.config” file is in the output location, which in turn uses the “O=/some/where” option. An example of native compile to a temp location without cross compiler:
mkdir ~/my_build
cd /where/ever/source/is
make O=~/my_build tegra_defconfig
…and as a result the location “~/my_build/
” will contain file “.config
”. From then on all compile commands would include “O=~/my_build
”. If you fail to use the “O=
”, then your config would be lost.
Or you could copy an existing config there:
mkdir ~/my_build
cp /proc/config.gz ~/my_build/.config
cd ~/my_build
gunzip config.gz
# Use an editor so you get this line edited:
CONFIG_LOCALVERSION="-tegra"
The reason for CONFIG_LOCALVERSION="-tegra"
is so that the modules will be found. Before building a new kernel you will find that the output of “uname -r
” ends with “-tegra
”, and that this setting keeps “uname -r
” the same even if you install another boot kernel Image. Modules are searched for at “/lib/modules/$(uname -r)/
”.
You don’t necessarily need to use flash tools to install the Image file (depends on signing, which in turn may depend on which release). The location you will find the Image is within the “O=/some/where
”. If you set environment variable “$TEGRA_KERNEL_OUT
” to “~/my_build
”, then this implies:
make O=$TEGRA_KERNEL_OUT ...
…and you would find Image via:
# This is the same as "cd ~/my_build"
cd $TEGRA_KERNEL_OUT
find . -name Image
What complicates this is that when you flash it uses the kernel on the PC at the location you mentioned: ~/nvidia/nvidia_sdk/JetPack_4.4_DP_Linux_DP_JETSON_AGX_XAVIER/Linux_for_Tegra/kernel/
. This gets copied to the location “nvidia/nvidia_sdk/JetPack_4.4_DP_Linux_DP_JETSON_AGX_XAVIER/Linux_for_Tegra/rootfs/boot/
” (file name “Image
”), and then this is what gets flashed. If you are installing without flashing, then you can just directly copy Image
to the Jetson in “/boot
”, but you want to be careful to do this correctly or else it won’t boot and you’ll have to flash.
It is incredibly difficult to say exactly what step to do since the instructions vary depending on release, but you might try the following once you have built a new kernel Image file (which is relatively risk free…the following is on the Xavier, and you will need serial console to pick kernel at boot…and if it fails, it won’t hurt anything):
sudo -s
cd /boot/extlinux
# ...use any editor you want...edit file "extlinux.conf":
# Copy the block with "LABEL primary" and make a renamed duplicate block like this:
LABEL primary
MENU LABEL primary kernel
LINUX /boot/Image
APPEND ${cbootargs} root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4
LABEL testing
MENU LABEL testing
LINUX /boot/Image.testing
APPEND ${cbootargs} root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4
Note how any kind of label was replaced with “testing” in the duplicate entry, and the Image file name was replaced with Image.testing
. So if you copy your newly compiled Image
file into “/boot
” with the new file name Image.testing
, then the alternate boot entry will use that kernel instead of the default, and the default will still be there. If for some reason this does not work, then the default is still the same thing it always was and there is no risk of not booting.