Can not Build Kernel

Hello Sir,

I’m try to build the tx1 kernel(from r24.2.3-source.tbz2) with gcc-linaro-6.4.1-2017.08-x86_64_aarch64-linux-gnu,
But Get following error message:

martin@martin-VirtualBox:~/tx1/dev/sources/tmp/kernel$ make O=$TEGRA_KERNEL_OUT tegra21_defconfig
HOSTCC scripts/basic/fixdep
GEN /home/martin/tx1/dev/sources/tx1_out/Makefile
HOSTCC scripts/kconfig/conf.o
HOSTCC scripts/kconfig/zconf.tab.o
In file included from scripts/kconfig/zconf.tab.c:2544:0:
/home/martin/tx1/dev/sources/tmp/kernel/scripts/kconfig/menu.c: In function ‘get_symbol_str’:
/home/martin/tx1/dev/sources/tmp/kernel/scripts/kconfig/menu.c:567:18: warning: ‘jump’ may be used uninitialized in this function [-Wmaybe-uninitialized]
jump->offset = r->len - 1;
^
/home/martin/tx1/dev/sources/tmp/kernel/scripts/kconfig/menu.c:528:19: note: ‘jump’ was declared here
struct jump_key *jump;
^
HOSTLD scripts/kconfig/conf
warning: (PM_SLEEP_SMP) selects HOTPLUG_CPU which has unmet direct dependencies (SMP && HOTPLUG)
warning: (PM_SLEEP_SMP) selects HOTPLUG_CPU which has unmet direct dependencies (SMP && HOTPLUG)

configuration written to .config

martin@martin-VirtualBox:~/tx1/dev/sources/tmp/kernel$ make O=$TEGRA_KERNEL_OUT zImage
GEN /home/martin/tx1/dev/sources/tx1_out/Makefile
scripts/kconfig/conf --silentoldconfig Kconfig
warning: (PM_SLEEP_SMP) selects HOTPLUG_CPU which has unmet direct dependencies (SMP && HOTPLUG)
include/config/auto.conf:757:warning: symbol value ‘rtc1’ invalid for RTC_BACKUP_HCTOSYS_DEVICE
warning: (PM_SLEEP_SMP) selects HOTPLUG_CPU which has unmet direct dependencies (SMP && HOTPLUG)
Using /home/martin/tx1/dev/sources/tmp/kernel as source for kernel
GEN /home/martin/tx1/dev/sources/tx1_out/Makefile
CHK include/generated/uapi/linux/version.h
UPD include/generated/uapi/linux/version.h
CHK include/generated/utsrelease.h
UPD include/generated/utsrelease.h
make[2]: ‘include/generated/mach-types.h’ is up to date.
CC kernel/bounds.s
In file included from /home/martin/tx1/dev/sources/tmp/kernel/include/linux/compiler.h:54:0,
from /home/martin/tx1/dev/sources/tmp/kernel/include/uapi/linux/stddef.h:1,
from /home/martin/tx1/dev/sources/tmp/kernel/include/linux/stddef.h:4,
from /home/martin/tx1/dev/sources/tmp/kernel/include/uapi/linux/posix_types.h:4,
from /home/martin/tx1/dev/sources/tmp/kernel/include/uapi/linux/types.h:13,
from /home/martin/tx1/dev/sources/tmp/kernel/include/linux/types.h:5,
from /home/martin/tx1/dev/sources/tmp/kernel/include/linux/page-flags.h:8,
from /home/martin/tx1/dev/sources/tmp/kernel/kernel/bounds.c:9:
/home/martin/tx1/dev/sources/tmp/kernel/include/linux/compiler-gcc.h:106:30: fatal error: linux/compiler-gcc6.h: No such file or directory
#include gcc_header(GNUC)
^
compilation terminated.
/home/martin/tx1/dev/sources/tmp/kernel/./Kbuild:35: recipe for target ‘kernel/bounds.s’ failed
make[2]: *** [kernel/bounds.s] Error 1
/home/martin/tx1/dev/sources/tmp/kernel/Makefile:842: recipe for target ‘prepare0’ failed
make[1]: *** [prepare0] Error 2
Makefile:130: recipe for target ‘sub-make’ failed
make: *** [sub-make] Error 2

I’m not sure, but I suspect that compiler version is simply too new. In such cases there are usually some minor edits which can make it work, but it isn’t guaranteed. Are you compiling natively on a TX1? So far as I know the most recent native compiler on the TX1 is version 5.4.

Hi Sir,

Thanks for your quckly responce!
I just compile the kernel under X86 Host Desktop.
Can you please tell me which version to use?

Thanks,
Martin

Just Update, After with Toolchain gcc-4.8.5-aarch64, and following the wili link:

  1. Compile kernel, device tree and modules
    make O=$TEGRA_KERNEL_OUT zImage
    make O=$TEGRA_KERNEL_OUT dtbs
    make O=$TEGRA_KERNEL_OUT modules
    make O=$TEGRA_KERNEL_OUT modules_install INSTALL_MOD_PATH=$KERNEL_MODULES_OUT

I can run the command “make O=$TEGRA_KERNEL_OUT zImage” successfully.

But When run the command “make O=$TEGRA_KERNEL_OUT dtbs”, I get the following error message

martin@martin-VirtualBox:~/tx1/64_TX1/Linux_for_Tegra/kernel/kernel/kernel-4.4$ make O=$TEGRA_KERNEL_OUT dtbs
make[1]: Entering directory ‘/home/martin/tx1/64_TX1/Linux_for_Tegra/images’
cp -u arch/arm64/boot/dts/
cp: missing destination file operand after ‘arch/arm64/boot/dts/’
Try ‘cp --help’ for more information.
/home/martin/tx1/64_TX1/Linux_for_Tegra/kernel/kernel/kernel-4.4/arch/arm64/boot/dts/Makefile:97: recipe for target ‘dtbs’ failed
make[2]: *** [dtbs] Error 1
arch/arm64/Makefile:105: recipe for target ‘dtbs’ failed
make[1]: *** [dtbs] Error 2
make[1]: Leaving directory ‘/home/martin/tx1/64_TX1/Linux_for_Tegra/images’
Makefile:150: recipe for target ‘sub-make’ failed
make: *** [sub-make] Error 2

In the file “kernel-4.4/arch/arm64/boot/dts/Makefile” there are two line script code:
dtbs: $(DTB_OBJS) FORCE
cp -u $(DTB_OBJS) arch/arm64/boot/dts/

What is missing on my build steps?

Thanks,
Martin

I couldn’t say exactly, but the dtbs target (and kernel itself) depends on the configuration which exists prior to starting the build. There are also cases where old files left over from a previous build get in the way. I can only guess that the configuration had an issue.

Note that “make mrproper” cleans everything, including the “.config”. However, there is a catch…when using the NVIDIA source which refers (using relative path includes) files outside of the kernel source tree, then it is possible mrproper won’t clear those. You’ll see the directories I mean if you use the “Linux_for_Tegra/source_sync.sh” file to download kernel source…the kernel is actually a couple of subdirectories in and the other directories are referenced only for some configurations:

./source_sync.sh -k tegra-l4t-r24.2.3

I suggest all starting configuration is done via a copy of the “/proc/config.gz” file on a running TX1 where the system which is booted at the time is unmodified (the config.gz file is actually a pseudo file presented by the running kernel and is not a real file…other than CONFIG_LOCALVERSION this file is an exact match to the existing configuration…if you start with a modified kernel then this won’t be a good starting point).

FYI, there were a couple of corrections needed for the very earliest kernels. I am surprised you are using such an old kernel. One of the differences current documentation will not mention is that these earliest kernels required two cross-compilers. I don’t recall if R24.2.3 required this, but I suspect it does. If you get an error regarding kernel build of some 32-bit file names, then you will need a second compiler. For that case (and I don’t know for sure if this applies for you since R24.2 might have removed the requirement…definitely R24.1 had this requirement) see:
https://devtalk.nvidia.com/default/topic/936880/jetson-tx1/jetson-tx1-24-1-release-need-help-with-complier-directions-can-not-complie/post/4885136/#4885136

[url][/url] I re-install JetPack-L4T-3.2.1 .
Unfortunately, I get the same result.
I also take look into the file kernel-4.4/arch/arm64/boot/dts/Makefile and try to print some key variable
By add following code:

dtbs: $(DTB_OBJS) FORCE
echo DTB_OBJS = $(DTB_OBJS)
echo DTB_LIST = $(DTB_LIST)
echo dtb-y = $(dtb-y)
echo tegra-dtstree = $(tegra-dtstree)
echo dtstree=$(dtstree)
cp -u $(DTB_OBJS) arch/arm64/boot/dts/

The result show all variable DTB_OBJS,DTB_LIST,dtb-y is None.

Sorry, I don’t understand the code in the Makefile:

dtb-list will contain all dtb-y

DTB_LIST := $(dtb-y)
dtb-y :=
dts_makefile=$(foreach d,$(wildcard $1*), $(call dts_makefile,$(d)/,$(2)) $(if $(findstring Makefile,$(d)),$(d)))
dts_mfiles = $(call dts_makefile, $(tegra-dtstree)/platform/, Makefile)
ifneq ($(dts_mfiles),)
dts-include :=
include $(dts_mfiles)
dtb-y := $(addprefix $(tegra-rel-dtstree)/hardware/nvidia/,$(dtb-y))
ifneq ($(dts-include),)
DTC_FLAGS += $(addprefix -i $(tegra-dtstree)/,$(dts-include))
DTCCPP_FLAGS += $(addprefix -I$(tegra-dtstree)/,$(dts-include))
endif
endif

I don’t know why the DTB_OBJS,DTB_LIST,dtb-y is None.
Do you guess there are the issues on the kernel config file ? I just run the command “make O=$TEGRA_KERNEL_OUT tegra21_defconfig”

Also,I didn’t run the command ./source_sync.sh to get the kernel source code.
I just use the following way to download kernel source code:

Download kernel sources from next link:
https://developer.nvidia.com/embedded/dlc/sources-r2821#Getting_kernel
Untar the sources and copy kernel_src.tbz2 to $HOME/JetPack-L4T-3.2.1/64_TX2/Linux_for_Tegra/sources
tar -xf public_sources.tbz2
cd public_release/
cp kernel_src.tbz2 $HOME/JetPack-L4T-3.2.1/64_TX2/Linux_for_Tegra/sources
cd $HOME/JetPack-L4T-3.2.1/64_TX2/Linux_for_Tegra/sources
tar -xf kernel_src.tbz2

Can you please check there are any issues on the following wiki link:

Thanks,
Martin

The first thing I see wrong with the Link is that it is for TX2 instead of TX1. The release mentioned is R28.2.1, and this release is only for a TX2. The release you are using is R24.2.3, and instructions are far different between these (in some cases for building, and in other cases for installing).

FYI, a dtsi file is just an “include” file to a “dts” device tree source file. Which ones get included and which ones are even ignored depends on configuration. Any tegra21_defconfig will be vastly wrong if mixed…the two kernel versions themselves are quite different. However, if you are using the R24.2.3 source, then the tegra21_defconfig would be valid (and even more valid is the “/proc/config.gz” from the unmodified running system).

The kernel you’ve downloaded simply isn’t compatible with the older release.

Is there a reason why you can’t upgrade to R28.1? Many problems were eliminated after the R24.x series, and in a lot of cases there was improved performance. You would of course need the BSP from RidgeRun if you use one of their carrier boards.

Thsnks for your replay!
No problem, Let me upgrade to R28.1.
One question, I ‘m a little confusd the version between R28.1 and Jetpack-L4T version, can you explain it?
I also check the version Jetack-L4t-3.2.1 and follow the link but still the same result.
Also, with R28.1, can you please give me details instructions on building kernel?

Thanks
Martin

About JetPack and Driver Packages…

JetPack is just a front end and either acts like a download manager or else runs the actual flash software (depending on if you are flashing or adding packages). In the following URLs you may have to log in and then hit the URL again before the page shows up correctly, but if you go to a JetPack page for a particular version from here:
https://developer.nvidia.com/embedded/jetpack-archive
…and then drill down to the JetPack3.1 listing to go here:
https://developer.nvidia.com/embedded/jetpack-3_1
…you will see “JetPack 3.1 introduces L4T 28.1”.

Note that R28.1 is actually flashed via command line software available directly as the “driver package”. Going here for a list of driver packages:
https://developer.nvidia.com/embedded/linux-tegra-archive
…you will find R28.1 is here:
https://developer.nvidia.com/embedded/linux-tegra-r281

This latter R28.1 URL lists everything associated with that particular release, whereas JetPack is a container for downloading those components related to R28.1. JetPack3.1 actually downloads the R28.1 driver package, R28.1 documentation, R28.1 sample rootfs, and most anything from the R28.1 URL. When you tell JetPack to flash a Jetson, what it does is to run something like this on command line (this assumes the Jetson is in recovery mode with the micro-B USB connected):

sudo ./flash.sh jetson-tx1 mmcblk0p1

A variation on this to use the most possible eMMC:

sudo ./flash.sh <b>-S 14580MiB</b> jetson-tx1 mmcblk0p1

The part where JetPack is most convenient is that it downloads a manifest of URLs and software compatible with either your desktop PC or the Jetson for that release. It then gives a list of possible compatible components for you to choose from, and will basically use a combination of wget and ssh download and install those components over ethernet.

The individual URLs for various components are not published separately. You can run JetPack, and then if you know which files to look in, you can manually run wget. You’d also have to know about install order of packages if you want to avoid frustration.

JetPack works only from an Ubuntu PC host. Command line flash works from any 64-bit Linux distribution. I normally use Fedora, so this is where I live. Sometimes I run JetPack from an old dual core Atom laptop, and then copy the files with URLs to my host where I manually run various package downloads or installs (I initially run from the laptop, it is more convenient…but I save those extra files and can later avoid using the laptop…it has a massive 10.1" screen).

About Kernel Building In the Early Days of R24.x…Skip this if You Don’t Have Time for a Story

First, the Image file is used with R28.1 (not the zImage). When you build zImage it first builds Image, and then creates a compressed zImage version. It doesn’t hurt to build zImage, but it is wasted space.

Second, you can use the configuration tegra21_defconfig, but you are better off not trusting this to be the same as your installed system. It might be the same, but you don’t know. On an unmodified system always start with the “/proc/config.gz” being copied somewhere safe for permanent reference. Also write down the result of “uname -r” for that config. If you build with that config and CONFIG_LOCALVERSION set to match the suffix of “uname -r”, then you have an exact 100% match for your starting configuration. If you build another configuration, then you might be building something completely unrelated and there is no base for knowing if the error is due to a configuration or due to some bug.

Any R24.x release should be suspect as to why it is being used. The R24.x series was the very first TX1 series. There was a transition going on at the time from 32-bit to 64-bit, and there wasn’t much (if any) previous 64-bit code or experience to go by. This was new. Additionally, the first R24.x was 64-bit only in kernel space…user space was still 32-bit. A 64-to-32-bit conversion was going on while user space packages were being updated from antique armhf software. The result is that the building of kernels had some differences. R24.1 for sure required both a 64-bit compiler and a 32-bit compiler simultaneously during a kernel build. At some point the requirement for the 32-bit compiler was removed (I’m not sure at which point…perhaps R24.2.1 did not need this, but I can’t say for sure). Here is an example of kernel build (cross-compile) from R24.1:
https://devtalk.nvidia.com/default/topic/936880/jetson-tx1/jetson-tx1-24-1-release-need-help-with-complier-directions-can-not-complie/post/4885136/#4885136

In those instructions for R24.1 you will note that this is being set to a 32-bit cross compiler:

export CROSS32CC=

The earliest of R24.x had some bug fixes as well, but I think those were not needed for R24.2.1 (I can’t swear to it though).

Explaining why two compilers were required isn’t really what you’ve asked, but it is still useful to know what you are getting into if you run R24.x series. And to start that it is easier to explain a difference from desktop PC history. So hopefully you will forgive me for going so seeming far from the topic with what follows.

In the desktop PC world everything used to be 32-bit. Basically i386 through i686, sometimes just labelled x86. Compilers were dedicated to this one architecture in the PC world. Then came 64-bit, and things got more complicated. 64-bit CPUs were backwards compatible in the ability to execute 32-bit code. This new CPU’s native instruction set was the 64-bit x86_64. Previous compilers in the 32-bit days were natively 32-bit. On a 64-bit system the backwards compatibility to x86 32-bit required a cross-compiler as native compile was a different x86_64 architecture. This backwards compatible 32-bit architecture is foreign on a 64-bit system despite the 64-bit system’s ability to execute the code. However, all of the newer Pentium and further 64-bit systems supported this backwards compatible 32-bit code, and so the compilers for both native 64-bit and for foreign 32-bit existed in the same compiler.

ARM architecture has a similar story when going from 32-bit to 64-bit, but the compilers are not integrated together in a single package. Furthermore, the 32-bit compatibility mode is absolutely terrible in performance even if there is no conversion back and forth between 64-bit kernels and 32-bit applications…a desktop PC also has a conversion penalty, but the penalty much more harsh in the ARM world.

On the desktop PC, if one wants to run a 64-bit app, then the 64-bit linker is used, and the 64-bit libraries can be dynamically used in combination. When a 32-bit application runs, then you need a second linker for 32-bit…and you need a bunch of compat libraries which are 32-bit. This was really common in the PC world, but ARM does not do this. Embedded systems are much smaller and what the PC essentially did of installing two operating systems for the user space 32-bit and 64-bit world isn’t practical on tiny embedded devices. Installing compat 32-bit (armhf/ARMv7-a with NEON and hardware floating point) plus native 64-bit (ARMv8-a/arm64/aarch64) was never set up for the two to exist simultaneously. The two can coexist, but it is a very manual and tedious operation to put both on the same system at the same time. It isn’t something a sane person wants to do unless it is mandatory (or if the sane person wants to go insane…sort of like that commercial where some people like paper cuts on the tongue and so they do this on purpose).

Back to Kernel Build…

Do you really need to stick to the R24.x install? Is there any chance you could flash to R28.1? The only reason I know of that anyone sticks to these earlier installs is if there is some special 32-bit program compatibility which is mandatory. The earlier URL on R24.1 will tell you about how to compile from that series, but probably the bugs listed won’t need fix (or some might), and maybe (not sure) R24.2.1 won’t need the second compiler (if you get a “vdso” error, then this is probably a 32-bit issue). However, the rest of that URL is still the explanation of building for that kernel.