This is a long thread, and I have not studied the whole thread. I will add some information, but it probably is not all specific to this case, and definitely would not be complete. Most of this is no different regardless of cross compile versus native compile (I’ll add comments if specific to one or the other).
- One of the first things you need to do is to confirm you are starting with clean kernel source. Then configure to match the running system, which is usually the default system. The target “
tegra_defconfig
”, if you have setCONFIG_LOCALVERSION
, is probably a good start. Then edit for your changes using a config editor (config editors likemenuconfig
ornconfig
understand dependencies; usually editing.config
directly results in dependency errors). - If you are changing only modules, then you can keep all of the existing modules. To do that, make sure your
CONFIG_LOCALVERSION
does not change. The default is “CONFIG_LOCALVERSION=-tegra
” (set to “-tegra
”). - If you are changing any integrated feature, then you should expect to rebuild all modules and the kernel itself. For that case you’d want to start out the same, but change
CONFIG_LOCALVERSION
(this changes the suffix of the command output of “uname -r
”, and this in turn is part of the module search path). - If you build the kernel
Image
, then this will propagate configuration for anything else you might build. This is also a good “acid test” to pass even if you only want modules. - If you are building other targets (other than
Image
), then you have to propagate the configuration. There is more than one way to do this for different purposes, e.g., “modules_prepare
” before building modules, or perhaps theprepare
target. Failing this implies your other targets (such as modules and device tree) will not correctly see your configuration when they go into subdirectories. If in doubt, buildImage
once, or check out themodules_prepare
andprepare
targets. - I don’t know about the specific error you got, but there is no way to know it is a valid error if it isn’t known that the initial configuration is valid and propagated for build commands other than
Image
.
Some links regarding device trees, but not in any particular order:
- https://forums.developer.nvidia.com/t/topic/266210/11
- https://forums.developer.nvidia.com/t/topic/263834/16
- https://forums.developer.nvidia.com/t/topic/263206/2
- https://forums.developer.nvidia.com/t/topic/255583/4
Perhaps more important is information on configuration. Note that device trees are not really part of the kernel, but the device tree fragments are basically passed to drivers similar to a command line or environment; thus the device tree fragment only matters to a specific driver on specific hardware, and so if you are building that driver, then it is likely you need that part of the device tree…and thus kernel configuration is basically the same as specifying parts of the dImageevice tree that need to be created. Thus the kernel and device tree builds exist in the kernel source despite the tree not technically being kernel source. This is also why configuring correctly matters so much: You get the wrong tree fragments if the configuration is not correct.
Much of cross compile and native compile are the same. Some differences:
- For cross compile you must specify
ARCH
; for native compile, you cannot specifyARCH
. - For cross compile you must name the prefix of the toolchain. Example: “
/usr/bin/aarch64-linux-gnu-
”. For native compile you don’t specify this (there are ways you could still pick a particular compiler, but it is not via theCROSS_COMPILE
prefix method).
Things that don’t differ:
- Setting up configuration.
- The need to propagate the configuration in some cases.
- The usefulness of building
Image
once just to see if it builds correctly even if you don’t plan to useImage
. - The best practice of putting the source tree in its own directory owned and writable only by root (
sudo
). Running “sudo make mrproper
” at that location to make sure it is pristine. Then using the “O=/some/where
” option to put all build and configuration into a separate location; that location should be for your regular user, accessible and writable by your regular user, and the command should never be withsudo
after that. Every command would use the “O=/some/where
” when doing this. It guarantees the main kernel source is untouched and correct. It also means that if you want to start over, then you just delete the location named by “O=/some/where
” (you could save the “/some/where/.config
” first if you want to retry with that as your starting config).
Image
Keep in mind that if you have an existing device tree, then you can simply copy it, decompile to source, edit directly, and then recompile. You don’t have to build this from kernel source when you already have something to start with. The PINMUX spreadsheet also can create device trees.
About kernel build, in no particular order (anything on configuration is probably more important than actual build instructions):
- https://forums.developer.nvidia.com/t/topic/262647/12
- https://forums.developer.nvidia.com/t/topic/238718/25
I’ll add this comparison of a couple of kernel builds command under cross compile versus native compile to point out how it differs (some of this is redundant, the point is only in how cross and native compiles differ; assumes you are a regular user and kernel source is not writable by you and that the kernel source is pristine and unconfigured):
# Shared for native or cross compile:
mkdir ~/kernel_temp
export TEGRA_KERNEL_OUT=~/kernel_temp
# Note: The "-j 6" just says to use 6 CPU cores. No entry or naming a different number
# of CPU cores works just as well, but takes different amounts of time and RAM.
# Native:
make O=$TEGRA_KERNEL_OUT tegra_defconfig
make O=$TEGRA_KERNEL_OUT nconfig
make O=$TEGRA_KERNEL_OUT modules_prepare
make -j 6 O=$TEGRA_KERNEL_OUT Image
make -j 6 O=$TEGRA_KERNEL_OUT dtbs
# Cross compile, using environment variables and/or command line:
export ARCH=arm64
export CROSS_COMILE=/usr/bin/aarch64-linux-gnu-
make O=$TEGRA_KERNEL_OUT tegra_defconfig
make O=$TEGRA_KERNEL_OUT nconfig
make O=$TEGRA_KERNEL_OUT modules_prepare
make -j 6 O=$TEGRA_KERNEL_OUT Image
make -j 6 O=$TEGRA_KERNEL_OUT dtbs
You can always ask more questions. Note in the last example above that the commands look the same, but then environment variables CROSS_COMPILE
and ARCH
are set up. One can also put these in the command line. What you don’t want is for ARCH
or CROSS_COMPILE
to be set for native compile.