Jetson/Porting openSUSE

From eLinux.org
< Jetson
Revision as of 17:19, 19 August 2015 by Shervin.emami (talk | contribs) (Introduction: added link to home page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

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:

  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

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 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[1] 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 <openSUSE rootfs tar> -C <path_to_L4T_rootfs>

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 <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 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 <path_to_L4T_TOP_DIR>/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 <path_to_L4T_TOP_DIR>/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:

<path_to_L4T_TOP_DIR>/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 <path_to_L4T_TOP_DIR>/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 <path_to_L4T_TOP_DIR>/nv_tegra/config/etc/X11/
sudo mkdir xorg.conf.d
sudo <editor> 15-nvidia.conf

Create the 15-nvidia.conf file so it looks as follows <path_to_L4T_TOP_DIR>/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 <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 ../..

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.

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

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

# Apply the nvidia binaries + configuration
# rootfs dir defaults to rootfs/
# nv_tegra dir defaults to nv_tegra/
sudo ./apply_binaries.sh -r <rootfs dir>

# Flash the resulting image to the Jetson
sudo ./flash.sh -R <rootfs dir> jetson-tk1 mmcblk0p1

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