Keep in mind that what follows is true for both cross compile and native compile. Whatever you do from the host PC though (cross compile) requires extra steps for use of cross tools. Only in cross compile would you first βexport ARCH=arm64
β (or add in the build commands βARCH=arm64
β, the two are equivalent). Similarly, only in cross compile would you use βexport CROSS_COMPILE=/some/where/bin/aarch64-linux-gnu-
β. Those steps would be in addition to what follows when you cross compile. In native compile references to βuname -r
β refer to what the Jetson would respond with in that command, while in cross compile one could not use the host PCβs βuname -r
β.
If you have just downloaded or unpacked the kernel source, then there is no need to clear any old content. However, one probably wants to reuse the kernel source and build it with different purposes over time (this assumes not just a single case of installation, e.g., developers working on kernels over time). You have the following content to be considered:
- Uncompiled pure kernel source.
- Configurations created by the developer.
- Intermediate object file output only used when creating some final file.
- Actual content which could be installed.
- Not exactly the above, but similar:
- Firmware, non-device tree.
- Firmware, device tree.
If you configured once, and then built from new source code with only that configuration, then there is not an issue. If things did build, then although not a guarantee, probably you also did not need to clean up or clear old source.
This applies to other kinds of build, but mainly this is in regards to building with the Kconfig dependency system (which is how the kernel is configured for what it intends to build and in what order). Most of what follows likely needs to be performed with the βO=/some/where
β if this was previously used (and this should be used). However, I am not listing βO=/some/where
β, but unless stated, you probably need to use that with each command that follows.
Using βmake mrproper
β, without βO=/some/where
β, works to clean up the original source code. This means 100% of any intermediate object files, firmware, device tree, configuration modification, so on, is gone. The source code is now pristine and untouched. This is a proper starting point before configuring. With the βO=/some/where
β this applies the the location of β/some/where
β. Keep in mind that if the original source tree (Iβll call β$TOP
β) is modified or configured in any way, that this will interfere with what goes on at β/some/where
β. If in doubt, then start with this.
The target βmake clean
β is similar to βmake mrproper
β. However, this leaves configuration in place. It does remove any intermediate object files, firmware, or device tree which has been created. βclean
β removes generated content (but not configuration content). If you run this, then you donβt need to reconfigure to build, e.g., if you already ran βmake tegra_defconfig
β, then this will leave βtegra_defconfig
β in place; if you then ran βmake modules_prepare
β (not everyone runs this, especially if you build the Image
itself, which does this as a side effect), then this should still be in place. An example of when to use this is that youβve configured, built, installed, and tested, but decide you need to make a change to a line in source code. To rebuild using the modified source code you would first clean, and then build again.
A good rule of thumb is to always install the source code itself to some location which is read-only except for user root
. This is the β$TOP
β. For example, you might install source code to β/usr/src/sources/kernel/kernel-4.9
β, and make sure anyone can read this, but nobody other than root
can write to it. Then, as root
(using sudo
), from β$TOP
β, run command βsudo make mrproper
β. From now on, so long as you donβt compile using sudo
, this is guaranteed quality source code (not modified by some accidental or forgotten step). Before any build you could βexport TOP=/usr/src/sources/kernel/kernel-4.9
β for this example, but use a separate location with βO=/some/where
β.
You would want to have a temporary location for intermediate output, plus configuration. An example is in your home directory you could create β~/intermediate
β (just an example name). This would mean all commands would use βO=~/intermediate
β. If you had configuration questions and donβt trust the configuration, or just wanted to start over, then you could recursively βrm -Rf ~/intermediate
β (be very careful about using recursive delete), then recreate it with βmkdir ~/intermediate
β. The use of βmake O=~/intermediate clean
β would do the same thing as βmake clean
β, except the action would be limited to β~/intermediate
β, and configuration would be left alone there; the use of βmake O=~/intermediate mrproper
β would be the same as βmake mrproper
β, but it would be limited to the location β~/intermediate
β (configuration would be removed there). Just make sure all of this is as a regular user and not with sudo
.
One target propagates configuration: βmodules_prepare
β. Not needed if you make target βImage
β, but if you have configured and then go to build modules, consider this step mandatory. Target βmrproper
β would remove anything done by βmodules_prepare
β, while βclean
β would not. Be sure to use βO=/some/where
β if the intermediate output location is what you want to use βmodules_prepare
β with.
There are build targets which place results somewhere convenient. One outputs modules to a tree which mirrors where it would go in the running system with this option: βINSTALL_MOD_PATH=/some/location
β in combination with target βmodules_install
β. An example is to create empty location β~/modules
β, and then build:
# Where to start:
cd $TOP
# Configure to ~/intermediate
make O=~/intermediate tegra_defconfig
# Make sure you've set CONFIG_LOCALVERSION; there is more than one way to do
# this.
# Pretend we are only building modules:
make O=~/intermediate modules_prepare
# Build modules, use 8 CPU cores:
make O=~/intermediate -j 8 modules
# Copy only the modules to a clean tree:
make O=~/intermediate INSTALL_MOD_PATH=~/modules modules_install
# Similar for device tree, though this won't be done very often:
mkdir ~/firmware
make O=~/intermediate dtbs
make O=~/intermediate INSTALL_FW_PATH=~/firmware
You might find it interesting to explore the example β~/modules
β and β~/firmware
β to see what is there. I like the command βtree
β (or βtree -d
β to limit to directories) to view such things (you probably would need βsudo apt-get install tree
β).