Jetson/Porting Arch

= 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 .tbz2 cd Linux_for_Tegra    # We will refer to this directory as  cd rootfs             # We will refer to this directory as 

= 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 

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  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 

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 /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 /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 /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 /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 /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 /usr/lib/systemd/system/nvidia-tegra.service


 * 1) Location
 * 2) /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 /rootfs/usr/bin/nvidia-tegra-init-script, and place these contents inside.

/rootfs/usr/bin/nvidia-tegra-init-script if [ -e /sys/power/state ]; then chmod 0666 /sys/power/state fi
 * 1) !/bin/bash
 * 2) Nvidia tegra init script
 * 3) adopted from nvidia_config /etc/init/nv.conf
 * 4) power state
 * 1) power state
 * 1) power state

if [ -e /sys/devices/soc0/family ]; then SOCFAMILY="`cat /sys/devices/soc0/family`" fi
 * 1) Set minimum cpu freq.

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

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
 * 1) CPU hotplugging

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
 * 1) lp2 idle state

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
 * 1) mmc read ahead size

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 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
 * 1) FIXME remove once kernel CL merges into main Bug 1231069
 * 1) remove power to dc.0 for jetson-tk1

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 /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 /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.

= 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

sudo ./apply_binaries.sh
 * 1) Apply the NVIDIA specific configuration, binaries, and the L4T kernel

sudo ./flash.sh jetson-tk1 mmcblk0p1
 * 1) Create the image from the rootfs directory and flash the image to the Jetson

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

 <li> Enable the nvidia-tegra initialization script to start on boot. systemctl enable nvidia-tegra.service </li> <li> Optionally create a user account for yourself

useradd -m -g users -G wheel -s /bin/bash archie
 * 1) useradd -m -g [initial_group] -G [additional_groups] -s [login_shell] [username]

passwd archie
 * 1) set the password for archie

More information about User and Group management can be found here.

</li> <li> Add your user account to the video group to allow access to the tegra devices usermod -aG video archie </li> <li> Sync your pacman repositories to have updated package lists pacman -Syy </li> <li> Install useful packages such as sudo. pacman -S sudo </li> <li> 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 </li> </ul>

= 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.