R21.5 was almost exactly the same as R21.6, but there were new bluetooth vulnerabilities discovered, and thus R21.6 had security patches. R21.6 is still advised, but if you don’t use bluetooth, then it might not matter. I suggest you flash R21.6 before starting…clone first if you want. You can keep going on R21.5 and chances are it won’t hurt anything, but I’m using R21.6 here so for example a file download name might differ slightly, plus I sometimes rename files with a version number…many files (perhaps even including the kernel) are exact matches between the two.
R21.6 URL: https://developer.nvidia.com/linux-tegra-r216
R21.5 URL: https://developer.nvidia.com/linux-tegra-r215
Instead of cross compiling I am going to suggest to simplify your life and do the build directly on the Jetson. Cross compiling is an extension to this (everything here still applies). If you don’t have enough disk space you might want to consider doing this on an SD card formatted to ext4 and mounted somewhere for temporary disk space, but normally this isn’t an issue. You can see what disk space you have for a partition from “df -H”…if you run “df -H .” from the location you want to add source (note that “.” is short for “the current directory”, and “…” is short for “the parent of the current directory”) and compile you’ll know how much space you have there. Normally this isn’t a problem, but I don’t know what you have on your system or if it was flashed to use the full eMMC.
Before you start you probably want to make sure you can run some of the terminal-based config utilties. For that reason you need to install package “libncurses5-dev”:
sudo apt-get install libncurses5-dev
You can login and run as non-root (no sudo) until it comes time to actually install something. Unless I use sudo below this is logged in as user “ubunut”. I have “/usr/src/kernels/” set up as owned by user “ubuntu” (if it isn’t there “sudo mkdir /usr/src/kernels; sudo chown ubuntu.ubuntu /usr/src/kernels”). I downloaded the kernel source there from the R21.6 URL (which happens to be “kernel-3.10.40_R21-4_src.tbz2”), and unpacked it, then renamed it for that version:
tar xvfj kernel-3.10.40_R21-4_src.tbz2
mv kernel kernel-3.10.40
I then set up by starting with an exact copy of my current config:
cp /proc/config.gz .
mv config config-3.10-40-original
I made temporary output locations for intermediate results…this could be put on an SD card instead if you are worried about space (adjust what follows to some other temporary location if you want to do this):
If you are just building the kernel, and not modules, then you don’t need “kernel_modules”. If you are not building firmware (and for your purposes you don’t need this…but it is listed in case others want this information), then you don’t need “kernel_firmware”. It doesn’t hurt to have the directories in place.
Set up some environment variables for convenience ("
pwd" in the back quotes echoes the current directory…if you cd to that directory first and then use pwd for setup you are guaranteed to typographic errors):
Just for reference, if you run “uname -r” you will see something like “3.10.40-gb271e8f”. The 3.10.40 is the version of the kernel source, the “-gb271e8f” is from a kernel option “CONFIG_LOCALVERSION”. CONFIG_LOCALVERSION is usually based on some unique value for the configuration used on that kernel…it’s entirely up to the person compiling…this does not cause a change in the kernel other than changing what the “uname -r” will respond to. This is important because the kernel modules will be searched for in “/lib/modules/$(uname -r)/”…which means if you compile a new kernel and “uname -r” differs, then the kernel won’t find any of its existing modules. Keeping “uname -r” the same implies you can re-use modules. However, if you change the config in the wrong way, your existing modules will become invalid…you would want to change “uname -r” in this case and avoid using old modules. In the case of this kernel the “-gb271e8f” is from the git source code unique identifier. You want to match it for this case.
The patch listed does not change the kernel, it changes the device tree. You should build the kernel just to be sure it is configured correctly (some device tree details will change depending on configuration), but technically speaking, “uname -r” won’t matter and only the device tree will be used. Remember though that if you don’t succeed at a build stage, then it is a sign something isn’t right…build the kernel and modules first just to see if you got it right before you use the new device tree (.dtb file). The dtb file will be built as a side-effect anyway.
The following does not include the device tree changes…see if you can build first without the changes. Then do the same thing with the changes.
Now for some actual work (note that in command line “bash” that a line starting with “#” is a comment…also sometimes a comment on the right of an actual command):
# Make sure the exist kernel is completely pristine...not necessary after unpacking,
# but not a bad idea either.
# Make sure the output location is pristine:
make O=$TEGRA_KERNEL_OUT mrproper
# Set up config to match the existing system:
cp -f $SRC/../config-3.10.40 $TEGRA_KERNEL_OUT/.config
make O=$TEGRA_KERNEL_OUT menuconfig
One of several menu editors will open. Because the “.config” file was in place at $TEGRA_KERNEL_OUT it will reflect that existing config. All you will need to do is edit CONFIG_LOCALVERSION. To do this navigate to “General setup —>”, move down one line to “Local version - append to…”, hit the enter key, type in “-gb271e8f” (the suffix of “uname -r”), and hit the enter key. Now cursor to the right and hit “Save”, let it save to the default “.config”, and exit. Your kernel now matches exactly your running system. Try it out:
make -j4 O=$TEGRA_KERNEL_OUT zImage
# This builds the files from the device tree...this is what the patch will involve:
make -j4 O=$TEGRA_KERNEL_OUT dtbs
The “find” command will come in useful. Basically:
find TheStartDirectory -name "NameOrPatternToFind"
So to find the zImage you built:
find $TEGRA_KERNEL_OUT -name zImage
See all of the dtb files built:
find $TEGRA_KERNEL_OUT -name '*.dtb'
Each dtb file is built from a number of others and may or may not matter to you.
If this succeeded, then anything else you might build should probably work. You don’t need modules or firmware for this purpose, the dtb file relevant to the patch will be built after zImage…I’ll go back and tell you how to do that instead, but first I’ll add the last steps for building everything in case someone needs it.
make -j4 O=$TEGRA_KERNEL_OUT modules
make O=$TEGRA_KERNEL_OUT modules_install INSTALL_MOD_PATH=$TEGRA_MODULES_OUT
# modules will be found in $TEGRA_MODULES_OUT/lib/modules/3.10-40-gb271e8f/
Without the “INSTALL_MOD_PATH=$TEGRA_MODULES_OUT” you would be putting the modules directly on the running system in “/lib/modules/<kernel_versionCONFIG_LOCALVERSION>/”. If you are just building a module and installing it to the existing system this might be what you want.
Firmware can be installed to $TEGRA_FIRMWARE_OUT via:
make O=$TEGRA_KERNEL_OUT firmware_install INSTALL_FW_PATH=$TEGRA_FIRMWARE_OUT
Without “INSTALL_FW_PATH” this would go directly into the operating system. Building as user “ubuntu” keeps you from doing this by accident since the paths are owned by root.
Back to the dtb patch! The original names a git repository, but we do not have that. Notice though that it names this path:
The “a/” implies one set of source code, yours might be a “b/”. It’s symbolic…think of “a/” as original, and “$SRC/something/” as your version. In this case we are looking at files specific to the 32-bit ARM architecture, or just “arm”. Go there now in your source:
You could use patch tools to apply the patch if you had a valid patch/diff file (copy and paste from that web site leaves a file in need of edits), but I’ll just go through the edits and do what the patch tool would do. You’ll need a text editor, e.g., “sudo apt-get install nano” and then “nano tegra124-jetson_tk1-gpio-pm375-0000-c00-00.dtsi”. Unfortunately this doesn’t list line numbers…I like vi, but this has a very steep learning curve. If you have a GUI, you might want “sudo apt-get install geany”, then:
geany tegra124-jetson_tk1-gpio-pm375-0000-c00-00.dtsi &
The patch starts with “@@ -36,10 +36,7 @@”, implying go to line 36, refer to 10 lines following, and when done, there will be 7 lines representing the first original 10 lines. Lines surrounding this are “context” lines to make it possible to be sure you have the right lines. The “-” lines are lines to remove, the “+” lines are lines to insert. So for example, I see line 36 in my source matches the patch context lines, and that the line with content “TEGRA_GPIO(U, 3)”, and two other lines, are to be deleted. Do so. Save the file.
The next file is named via “diff --git a/arch/arm/boot/dts/tegra124-platforms/tegra124-jetson_tk1-pinmux-pm375-0000-c00-00.dtsi b/arch/arm/boot/dts/tegra124-platforms/tegra124-jetson_tk1-pinmux-pm375-0000-c00-00.dtsi”…this is the same directory and file as before, but from the start (if you have the editor still open just keep using it):
geany tegra124-jetson_tk1-pinmux-pm375-0000-c00-00.dtsi &
The lines have changed, indicated by “@@ -1015,10 +1015,10 @@”. If you hadn’t deleted the 3 lines earlier the correct line is 1015, and the context lines surrounding the edits would verify this. Since you are missing 3 lines you will need to adjust. Replace the line with “nvidia,function = “gmi”;” to instead be “nvidia,function = “pwm0”;”…the same with the line three lines down…“nvidia,enable-input = <TEGRA_PIN_ENABLE>” is edited to instead be “nvidia,enable-input = <TEGRA_PIN_DISABLE>;”. Save the file.
There are four more lines to edit, the reference is via “@@ -1031,18 +1031,18 @@”. So line 1031 is the starting location if the file were the original…you must adjust for the three lines previously deleted. Within the pu5 block replace “nvidia,function = “gmi”;” with “nvidia,function = “pwm2”;”. Three lines down replace “nvidia,enable-input = <TEGRA_PIN_ENABLE>;” with “nvidia,function = “pwm2”;”. Within the pu6 block, in a similar fashion, edit those two lines…remove the “-” lines and insert the “+” lines. Save and exit.
The next patch edits “arch/arm/mach-tegra/board-ardbeg-panel.c b/arch/arm/mach-tegra/board-ardbeg-panel.c”. The procedure is the same.
If you had valid diff files then something like “patch -p1 <patch_file.diff” would apply patches for you. I’ve had issues with copy and paste from that web site so I did it the hard way.
I have not used this particular patch. One or more of the dtb files produced will be the correct file after you run the “make O=$TEGRA_KERNEL_OUT dtbs” command while the source is edited:
find $TEGRA_KERNEL_OUT -name '*.dtb'
However, if you look at “/boot/extlinux/extlinux.conf” you will see a line with a key/value pair, “FDT”. This is the device tree file. On mine it says:
…so if the edits propagate into this file:
find $TEGRA_KERNEL_OUT -name tegra124-jetson_tk1-pm375-000-c00-00.dtb
…then this is the file you use from the $TEGRA_KERNEL_OUT to replace the one in “/boot”.
An alternative if you have serial console is to make an alternate boot entry and put the new file in with an alternate name…leave the original…and put the name edit in the FDT entry.