Jetson/Porting Arch
Contents
Introduction
This will go over the important steps of installing Arch Linux on the Jetston-TK1. Including installing the kernel, drivers, and configuration from the Linux for Tegra release provided by NVIDIA. It will also provide steps for testing that the NVIDIA drivers have been installed correctly and are working correctly.
The first step is to download the latest TK1 Driver Package: https://developer.nvidia.com/linux-tegra
Extract the Jetson TK1 Driver Packages, which should contain a top folder called "Linux_for_Tegra".
sudo tar jxpf <latest_l4t_driver_package>.tbz2 cd Linux_for_Tegra # We will refer to this directory as <path_to_L4T_TOP_DIR> cd rootfs # We will refer to this directory as <path_to_L4T_rootfs>
Obtaining Image
The first step is to obtain the image for Arch Linux ARM and create the root filesystem from it.
The list of all Downloads can be found on the Downloads page on the Arch ARM website [1]
Specifically you will want the armv7 multi platform version, latest is linked here
wget http://archlinuxarm.org/os/ArchLinuxARM-armv7-latest.tar.gz
Extract the tar into your rootfs directory.
cd <path_to_L4T_rootfs> sudo tar -xpf ArchLinuxARM-armv7-latest.tar.gz .
Changes to the Apply Binaries script
apply_binaries.sh is a script found in drivers tarball of the L4T drivers package, located at <path_to_L4T_TOP_DIR>
As the apply_binaries script (apply_binaries.sh) was written to work with Ubuntu, and Ubuntu stores its libraries in a different place than Arch Linux, the script will need to be updated to look in the correct place.
Find the section of the file that looks like the below script, and add the two lines indicated:
if [ -d "${LDK_ROOTFS_DIR}/usr/lib/arm-linux-gnueabihf/tegra" ]; then ARM_ABI_DIR="${LDK_ROOTFS_DIR}/usr/lib/arm-linux-gnueabihf" elif [ -d "${LDK_ROOTFS_DIR}/usr/lib/arm-linux-gnueabi/tegra" ]; then ARM_ABI_DIR="${LDK_ROOTFS_DIR}/usr/lib/arm-linux-gnueabi" elif [ -d "${LDK_ROOTFS_DIR}/usr/lib/aarch64-linux-gnu/tegra" ]; then ARM_ABI_DIR="${LDK_ROOTFS_DIR}/usr/lib/aarch64-linux-gnu" elif [ -d "${LDK_ROOTFS_DIR}/usr/lib/tegra" ]; then # Add this line ARM_ABI_DIR="${LDK_ROOTFS_DIR}/usr/lib" # and this one. else echo "Error: None of Hardfp/Softfp Tegra libs found" exit 4 fi
Next, to preserve Arch's symbolic directory paths, find any lines that look like:
tar xpfm #... tar jxpfm #...
And replace them so they look like:
tar --keep-directory-symlink -xpmf #... tar --keep-directory-symlink -jxpmf #...
Configuration Changes
Compared to Ubuntu a few configuration changes are needed as Arch Linux has a different directory structure and init program. This section outlines the changes that need to be made to the archives in nv_tegra folder of the driver package of Release. Many of the files / directories need to be relocated as the file system hierarchy differs between Arch Linux and Ubuntu.
Before making changes, extract the tars of the nv_tegra folder into directories of the same name:
cd <path_to_L4T_TOP_DIR>/nv_tegra sudo mkdir nvidia_drivers config nv_tools nv_sample_apps/nvgstapps sudo tar -xpjf nvidia_drivers.tbz2 -C nvidia_drivers/ sudo tar -xpjf config.tbz2 -C config/ sudo tar -xpjf nv_tools.tbz2 -C nv_tools/ sudo tar -xpjf nv_sample_apps/nvgstapps.tbz2 -C nv_sample_apps/nvgstapps/
Changes to nvidia_drivers Package
The lib folder will need to be moved into /usr
cd <path_to_L4T_TOP_DIR>/nv_tegra/nvidia_drivers sudo mv lib/* usr/lib/ sudo rm -r lib
Everything in usr/lib/arm-linux-gnueabihf will need to be moved into usr/lib
sudo mv usr/lib/arm-linux-gnueabihf/* usr/lib/ sudo rm -r usr/lib/arm-linux-gnueabihf
nv_tegra_release in etc/ will need to be updated to include the correct path to the tegra libraries.
The lines in nv_tegra_release need to be replaced to look as follows:
88cc04ed62acc205b2b0d415dddaeba5feac8262 */usr/lib/arm-linux-gnueabihf/tegra/libnvmm.so #Replace these paths
88cc04ed62acc205b2b0d415dddaeba5feac8262 */usr/lib/tegra/libnvmm.so # Correct new path
Update etc/ld.so.conf.d/nvidia-tegra.conf to point to the right directory and add the tegra-egl entry. The contents of nvidia-tegra.conf should look like this:
/usr/lib/tegra /usr/lib/tegra-egl
Changes to nv_tools Package
The tegrastats script should be moved from home/ubuntu into the /usr/bin directory. This removes the dependency on a user called ubuntu.
cd <path_to_L4T_TOP_DIR>/nv_tegra/nv_tools mkdir -p usr/bin mv home/ubuntu/tegrastats usr/bin/ rm -r home
Changes to nvgstapps Package
Move the contents of usr/sbin into usr/bin
cd <path_to_L4T_TOP_DIR>/nv_tegra/nv_sample_apps/nvgstapps/ sudo mv usr/sbin/* usr/bin sudo rm -r usr/sbin
Move the contents of usr/lib/arm-linux-gnueabihf to usr/lib
sudo mv usr/lib/arm-linux-gnueabihf/* usr/lib/ sudo rm -r usr/lib/arm-linux-gnueabihf
Finalizing Configuration Changes
When you have finished making all the listed changes, repackage the files:
cd <path_to_L4T_TOP_DIR>/nv_tegra cd nvidia_drivers sudo tar -cpjf ../nvidia_drivers.tbz2 * cd .. cd config sudo tar -cpjf ../config.tbz2 * cd .. cd nv_tools sudo tar -cpjf ../nv_tools.tbz2 * cd .. cd nv_sample_apps/nvgstapps sudo tar -cpjf ../nvgstapps.tbz2 * cd ../..
Changes to rootfs
The following are changes that will be made to contents in your rootfs directory.
Initialization Script
As Arch Linux uses systemd rather than upstart, the init script will need to be converted into a systemd service. Information on systemd and how to create services can be found on the Arch Linux Wiki page for systemd
To create the systemd service, we will need the service descriptor file, that tells systemd about the service. Hence need to create a service file as below in <path_to_L4T_TOP_DIR>/usr/lib/systemd/system/nvidia-tegra.service
##Location ## /usr/lib/systemd/system/nvidia-tegra.service [Unit] Description=The NVIDIA tegra init script [Service] type=oneshot RemainAfterExit=yes ExecStart=/usr/bin/nvidia-tegra-init-script [Install] WantedBy=multi-user.target
Similarly, create a new file at <path_to_L4T_TOP_DIR>/rootfs/usr/bin/nvidia-tegra-init-script, and place these contents inside.
<path_to_L4T_TOP_DIR>/rootfs/usr/bin/nvidia-tegra-init-script
#!/bin/bash # Nvidia tegra init script # adopted from nvidia_config /etc/init/nv.conf # # # power state if [ -e /sys/power/state ]; then chmod 0666 /sys/power/state fi # Set minimum cpu freq. if [ -e /sys/devices/soc0/family ]; then SOCFAMILY="`cat /sys/devices/soc0/family`" fi if [ "$SOCFAMILY" = "Tegra13" ] && [ -e /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq ]; then sudo bash -c "echo -n 510000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq" fi # CPU hotplugging if [ -d /sys/devices/system/cpu/cpuquiet/tegra_cpuquiet ] ; then echo 500 > /sys/devices/system/cpu/cpuquiet/tegra_cpuquiet/down_delay echo 1 > /sys/devices/system/cpu/cpuquiet/tegra_cpuquiet/enable elif [ -w /sys/module/cpu_tegra3/parameters/auto_hotplug ] ; then # compatibility for prior kernels without cpuquiet support echo 1 > /sys/module/cpu_tegra3/parameters/auto_hotplug fi # lp2 idle state if [ -e /sys/module/cpuidle/parameters/power_down_in_idle ] ; then echo "Y" > /sys/module/cpuidle/parameters/power_down_in_idle elif [ -e /sys/module/cpuidle/parameters/lp2_in_idle ] ; then # compatibility for prior kernels echo "Y" > /sys/module/cpuidle/parameters/lp2_in_idle fi # mmc read ahead size if [ -e /sys/block/mmcblk0/queue/read_ahead_kb ]; then echo 2048 > /sys/block/mmcblk0/queue/read_ahead_kb fi if [ -e /sys/block/mmcblk1/queue/read_ahead_kb ]; then echo 2048 > /sys/block/mmcblk1/queue/read_ahead_kb fi #FIXME remove once kernel CL merges into main Bug 1231069 for uartInst in 0 1 2 3 do uartNode="/dev/ttyHS$uartInst" if [ -e "$uartNode" ]; then ln -s /dev/ttyHS$uartInst /dev/ttyTHS$uartInst fi done # remove power to dc.0 for jetson-tk1 machine=`cat /sys/devices/soc0/machine` if [ "${machine}" = "jetson-tk1" ] ; then echo 4 > /sys/class/graphics/fb0/blank BoardRevision=`cat /proc/device-tree/chosen/board_info/major_revision` if [ "${BoardRevision}" = "A" ] || [ "${BoardRevision}" = "B" ] || [ "${BoardRevision}" = "C" ] || [ "${BoardRevision}" = "D" ]; then echo 0 > /sys/devices/platform/tegra-otg/enable_device echo 1 > /sys/devices/platform/tegra-otg/enable_host fi fi if [ -e /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors ]; then read governors < /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors case $governors in *interactive*) echo interactive > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor if [ -e /sys/devices/system/cpu/cpufreq/interactive ] ; then echo "1224000" >/sys/devices/system/cpu/cpufreq/interactive/hispeed_freq echo "95" >/sys/devices/system/cpu/cpufreq/interactive/target_loads echo "20000" >/sys/devices/system/cpu/cpufreq/interactive/min_sample_time fi ;; *) ;; esac fi echo "Success! Exiting" exit 0
Instructions on how to enable the script are in After First Boot section. If you wish to enable the script before flashing / first boot, create the following symbolic link to enable the service.
cd <path_to_L4T_rootfs>/etc/systemd/system/sysinit.target.wants/ ln -s ../../../../usr/lib/systemd/system/nvidia-tegra.service nvidia-tegra.service
This should be executed after apply_binaries, so the nvidia-tegra service is in place.
Pacman Configuration
As we have installed a custom kernel to boot linux on the Jetson-TK1, it is necessary to update pacman.conf to ignore updates to the kernel package.
To do so add linux as an ignored package to your <path_to_L4T_rootfs>/etc/pacman.conf as below:
IgnorePkg=linux
Alternatives Support
Arch Linux does not have a built in application for managing alternative versions of the same package as Debian/Ubuntu does.
It does however support having multiple packages installed at the same time, as long as their names are different.
A script can be created to automate the switching between which of the installed versions is treated as the default. As has been done with java [2].
Flashing Jetson TK1
The steps for flashing the Arch Linux image to the Jetson are no different than flashing the image for Ubuntu.
Run the following commands to apply the configuration, create the image, and flash it to the Jetson
# Apply the NVIDIA specific configuration, binaries, and the L4T kernel sudo ./apply_binaries.sh # Create the image from the rootfs directory and flash the image to the Jetson sudo ./flash.sh jetson-tk1 mmcblk0p1
Your device should reboot and prompt you to login. The default login for Arch Linux ARM is root/root.
After First Boot
Steps to perform after initial boot of Arch Linux
-
Enable the nvidia-tegra initialization script to start on boot.
systemctl enable nvidia-tegra.service
-
Optionally create a user account for yourself
# useradd -m -g [initial_group] -G [additional_groups] -s [login_shell] [username] useradd -m -g users -G wheel -s /bin/bash archie #set the password for archie passwd archie
More information about User and Group management can be found here.
-
Add your user account to the video group to allow access to the tegra devices
usermod -aG video archie
-
Sync your pacman repositories to have updated package lists
pacman -Syy
-
Install useful packages such as sudo.
pacman -S sudo
-
Allow members of the group wheel sudo access
Launch visudo to edit the sudo configuration file. Replace nano with your preferred text editor.
EDITOR=nano visudo
To allow members of the wheel group sudo access uncomment (add if it doesn't exist) the following line
%wheel ALL=(ALL) ALL
X11 Support
In order to configure X11 with the NVIDIA provided binaries, it is necessary to use an older version of xorg-server, as the NVIDIA drivers were compiled with ABI 15 support, eg xorg-xserver 15.
Older versions of packages xorg-server and xf86-input-evdev are required. Versions 1.15.2-1 and 2.8.4-1 respectively, work. They will have to be build however, information about the packages, including a download link, can be found here: xorg-server 1.15.2-1 and xf86-input-evdev 2.8.4-1.
You will need to build the packages for the arm architecture. Update the PKGBUILDs and add "armv7h" to the arch field.