I was really hoping this would be easier than it was. Most (all?) of the pieces needed are upstream, with a minor patch for das U-boot needed to make it all work with L4T. I’m going to provide links to my u-boot images and kernel packages, but first I wanted to go over what I’ve done and why.
My Jetson TK1 still has L4T installed on the internal eMMC device. I used that to debug and build a few minor tools. My target was Debian 8 on an SSD attached to the SATA port. In order to make life easier, I just copy the boot files (kernel, initramfs, dtb) to the eMMC:/boot directory and then add an entry to the extlinux.conf to boot them.
- It takes about 30s for the kernel, SATA interface, and my SSD to get their act together on boot. I had the same problem when trying to mount the SSD from L4T. I had hoped a new kernel would help this, it did not. Everything works, and it’s stable but you get a LOT of SATA error messages on boot once it tries to mount the filesystem from the SATA SSD.
- I didn’t bother to try and bring the binary nvidia drivers over, I’m just using the open source stuff (this is a compile box for me and runs headless anyway)
- No network boot support in das U-boot (this is a mystery to me as to how to fix this, if anyone knows please reach out)
Why the heck did I even build my own kernel? An excellent question, it was mostly to satisfy these requirements:
- XFS filesystem support
- systemd support (the L4T kernel will fail to boot Debian 8 properly)
- LXC support (running build and test targets in containers, and many of the required features were not in 3.10)
- LVM support
- More advanced networking options (nftables, etc)
Getting a kernel build was interesting, and learning what features were required for LXC was also more involved than I would have liked. I also learned from the #tegra channel on freenode that I was also going to need to update das U-boot as well. So, let’s get started.
I built against the 2016.01 release. Pretty much everything is built in, and you can generate a mostly working build with the following command from the official source tree:
However, this build will fail to boot L4T or any of the default nvidia 3.10 kernels because the command line length is too short (512B allowed, the default command line is 518B). So, this is the change I made (this patch will not apply with a cut and paste due to formatting issues, I’ve linked it below in the files section):
diff --git a/include/configs/tegra-common.h b/include/configs/tegra-common.h index ba819c4..b448b4b 100644 --- a/include/configs/tegra-common.h +++ b/include/configs/tegra-common.h @@ -76,7 +76,7 @@ * Increasing the size of the IO buffer as default nfsargs size is more * than 256 and so it is not possible to edit it */ -#define CONFIG_SYS_CBSIZE (256 * 2) /* Console I/O Buffer Size */ +#define CONFIG_SYS_CBSIZE (256 * 4) /* Console I/O Buffer Size */ /* Print Buffer Size */ #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ sizeof(CONFIG_SYS_PROMPT) + 16
At that point, everything started to work. I was able to generate and flash the image to the Jetson TK1 board using the tegra-uboot-flasher-scripts provided by nvidia on a separate host. Follow the directions there, and know that you will need the Das U-Boot source, and the cboot-image-configs from nvidia, a device-tree-compiler, and a cross-compiler toolchain if the other host is also not an ARM. On a Debain 8 amd64 host, I installed these packages and used these commands:
sudo apt-get install gcc-arm-none-eabi binutils-arm-none-eabi device-tree-compiler export CROSS_COMPILE="arm-none-eabi-" git clone git://git.denx.de/u-boot.git git clone https://github.com/NVIDIA/tegra-uboot-flasher-scripts.git git clone https://github.com/NVIDIA/cbootimage-configs.git git clone https://github.com/NVIDIA/tegrarcm.git cd u-boot git checkout tag/v2016.01 patch -p1 < ~/u-boot-tegra-commandline.patch cd ../tegra-uboot-flasher-scripts ./build --socs tegra124 --boards jetson-tk1 build sudo ./tegra-uboot-flasher flash jetson-tk1
The resulting image is linked below if you want to skip all that crap and just flash it directly.
Linux Kernel 4.4
At the time I built it, the 4.4 kernel was the latest stable. Getting started was similar to Das U-Boot:
Gets you to a state where most of the options you need to just get the darned thing to boot are turned on. I also used the LXC Kernel Requirements list and the lxc-checkconfig tool to ensure all the options I needed for LXC were turned on. There were many more than I expected. It also turns out you need to pass a command line argument of “cgroup_enable=memory” in order for everything to work correctly. Along with a few other tweaks, this was my final kernel config, which generated the following DEB using make-kpkg. You also need to “make dtb” in the kernel directory to get the required dtb for booting out. Then I copied the kernel, generated initramfs, and dtb to the eMMC partition and added the following kernel config to eMMC:/boot/extlinux/extlinux.conf
LABEL debian MENU LABEL debian 8 on sda1 with 4.4 kernel and ramdisk LINUX /boot/vmlinuz-4.4.0 FDT /boot/dtb/tegra124-jetson-tk1.dtb APPEND initrd=/boot/initrd.img-4.4.0 console=ttyS0,115200n8 console=tty1 ignore_loglevel earlyprintk cgroup_enable=memory root=/dev/sda1
Here are all the files needed and their SHA256 checksums:
f7ffbfe4f3a10b6c91f41963957360190c0102daafc731f1d805950c5fdd9cda tegra124-jetson-tk1.dtb a96b9a0e779f0f1abe4e5f85e146ef9a71c409ebfbb937a00eb8a2c303d0ab16 linux-image-4.4.0_5_armhf.deb 843ae0cce792966395083fbd7590993410d94f8bd34e07953ce236239a0e5323 config-4.4.0 e29210c3fef917f8c89a83fb00b43f80a9c8b9ede46284a3b5c8421805f9a57a jetson-tk1-emmc.img 75bfde768022e83e5995000291ff97217d11cd6e59673a4124d881992d2edd47 u-boot-tegra-commandline.patch
Hope this helps others trying to build a mainline kernel for the Jetson TK1. Please feel free to contact me if you have questions!