Jetson/Porting openSUSE

= Introduction =

This guide will go over the steps needed to get openSUSE for ARM running on the Jetson TK1 after installing the board support package (config, kernel, drivers, etc.) This guide was written for porting the Linux for Tegra board support package to work with an openSUSE root filesystem, instead of the provided Ubuntu root filesystem.

Here are the general steps to follow for porting the openSUSE distribution to work on Jetson TK1:

The first step is to download the latest TK1 Driver Package: https://developer.nvidia.com/linux-tegra
 * 1) Download the Jetson-TK1 Driver Packages - https://developer.nvidia.com/embedded/linux-tegra
 * 2) Download an openSUSE arm rootfs - openSUSE 13.1 ARM JeOS
 * 3) Make configuration changes to the packages in the nv_tegra folder
 * 4) Make compatibility changes to the apply binaries script
 * 5) Run the apply binaries script
 * 6) Flash the root filesystem to the Jetson TK1

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 the Image = Next we need to obtain the image for openSUSE ARM and create the root filesystem from it.

The list of all ARM openSUSE images can be found at Download the rootfs version.

As an example, here is a compatible version of openSUSE that was tested to work on the Jetson-TK1 wget http://download.opensuse.org/ports/armv7hl/distribution/13.1/appliances/openSUSE-13.1-ARM-JeOS.armv7-rootfs.armv7l-1.12.1-Build37.1.tbz Extract the tar into the Linux_for_Tegra/rootfs directory.

sudo tar -xpf  -C 

= Configuration Changes = Compared to Ubuntu a few configuration changes are needed as openSUSE Linux has a different directory structure and init program. 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 nv_drivers Package
openSUSE does not handle multiarch in the same way as Ubuntu, so all binaries are expected at /usr/lib instead of /usr/lib/arm-linux-gnueabihf

cd /nv_tegra/nvidia_drivers/usr/lib sudo mv arm-linux-gnueabihf/*. sudo rm -r arm-linux-gnueabihf/

Next, we must modify nvidia_tegra.conf to reflect our changes thus far. Find this file in the path /nv_tegra/nvidia_drivers/etc/ld.so.conf.d, and modify nvidia-tegra.conf to reflect the location of the tegra and tegra-egl folders so that it looks like this:

/nv_tegra/nvidia_drivers/etc/ld.so.conf.d/nvidia-tegra.conf /usr/lib/tegra /usr/lib/tegra-egl

Changes to nv_sample_apps Package
Similar to nv_drivers, we must change the hierarchy for nv_sample_apps.

cd /nv_tegra/nv_sample_apps/nvgstapps/usr/lib sudo mv arm-linux-gnueabihf/*. sudo rm -r arm-linux-gnueabihf/

Changes to config Package
openSUSE does not seem to pay attention to the xorg.conf file, so the Tegra device must be added to xorg.conf.d cd /nv_tegra/config/etc/X11/ sudo mkdir xorg.conf.d sudo 15-nvidia.conf

Create the 15-nvidia.conf file so it looks as follows /nv_tegra/config/etc/X11/xorg.conf.d/15-nvidia.conf Section "Device" Identifier "Tegra0" Driver "nvidia" EndSection

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

= Adding Initialization Script = Because openSUSE uses systemd instead than upstart we need to add an init script for systemd to use. To create the systemd service, we will need the service descriptor file, that tells systemd about the service. Create the file "nvidia-tegra.service" at the path below and copy the contents here.

/rootfs/etc/systemd/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

= Changes to the Apply Binaries script = The apply binaries script (apply_binaries.sh) needs a bit of modification before it will work properly.

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

= Flashing Jetson TK1 =

The steps for flashing the openSUSE Linux image to the Jetson is 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 -r
 * 1) Apply the nvidia binaries + configuration
 * 2) rootfs dir defaults to rootfs/
 * 3) nv_tegra dir defaults to nv_tegra/

sudo ./flash.sh -R jetson-tk1 mmcblk0p1
 * 1) Flash the resulting image to the Jetson

Your device should reboot and start YAST for account set up.

= Running openSUSE =

The first time you boot into openSUSE, you are presented with the YAST setup screen to create a root password, a user account, and a few other basic setup tasks.

After completing the YAST setup, openSUSE is ready to use, but there are a few additional configuration steps that are helpful listed below

Configure the Network
While logged in as root or with sudo, open the YAST menu with the command yast


 * 1) Go to Network Devices => Network Settings
 * 2) Select the PCI Express Gigabit Ethernet controller, enp1s0
 * 3) Edit (alt+i or F4)
 * 4) Select Dynamic Address DHCP (alt+y)
 * 5) Hit next (alt+n or F10)
 * 6) Hit OK (alt+o or F10)
 * 7) exit YAST

Install sudo
While logged in as root, enter the following command to add sudo zypper in sudo

Installing XFCE
This section will allow you to install a basic xfce session setup as a GUI using lightdm as the display manager.

While logged in as root or with sudo, install the following programs: sudo zypper in xorg-x11-server xfce4-session xfce4-terminal lightdm

Run lightdm as root to start the xfce session.

Ensure that /usr/lib/xorg/modules/extensions/libglx.so points to /usr/lib/tegra/libglx.so after installation cd /usr/lib/xorg/modules/extensions ln -sf /usr/lib/tegra/libglx.so libglx.so

To set lightdm as your default display manager, modify the file /etc/sysconfig/displaymanager DISPLAYMANAGER="lightdm"

Launch Graphical Desktop
Start your GUI enabled desktop, by running the lightdm program lightdm