User Tools

Site Tools


Sidebar

hardwarerelated:nintendo_switch

What is here?

Some notes regarding running Linux on the Nintendo Switch. First things first, thanks fail0verflow. I did just play a bit on the software side, but fail0verflow was one of the 2 groups who found the way to run Linux, and established all the chain to make this possible, including providing the patched Linux kernel. You guys rock!

20180527_200130_nintendo_switch.jpg

What works (not)?

distro wlan xorg plainxorg acceleratedaudio
Fedora28yes yes yesno
Arch Linux/KDE rootfsyesyesyesno
Ubuntu 18.04yes yes yesno
Fedora27 yes yes no no
Debian sid yes yes no no
opensuse Tumbleweedyes yes no no

Note: I am seeing crashes under high load. Building the mesa package, rpmbuild parallelizes for the 4 cores and one sees load ~4. After some time, the switch gets hot and turns off. Using this now in the specfile:

make_build MKDEP=/bin/true V=1 -j2

Note: As of today, the switch can not run Linux standalone. You need to shorten 2 pins (i.e. with a hardware device) and supply code to execute via USB using the RCM protocol. Note: There have been reports of hardware being sold, where the payload via USB can no longer be supplied after firmware update here are details.

hardware

First steps

At first, one should get preconfigured images from others to run. I followed https://gbatemp.net/threads/quick-tuto-how-to-boot-linux-on-your-switch.501918/ on a Fedora28 x86_64 host. Issue: Booting was not completing, message “Timeout waiting for hardware interrupt” was displayed. As hinted at https://github.com/fail0verflow/switch-linux/issues/1 , I had to revert patch https://github.com/fail0verflow/switch-linux/commit/e8a92bf5e6c022210cd7b661dc408153ba0e9015 and recompile the kernel, so my microsd-card got recognized. Wlan just works after a restart.

Installing Fedora

Installing Fedora for the switch on the microsd card, using a Fedora28 x86_64 as host. I created DOS style partitions on a 32GB card, and switch between the partitions in modifying the kernel command line.

For installing Fedora 28, images for several spins are available:

  • Fedora-Server-28-1.1.aarch64: unzipped 7.5GB, if using this you need to install packages NetworkManager-wifi and wpa_supplicant before wlan becomes usable.
  • Fedora-Workstation-28-1.1.aarch64: unzipped 10.7GB, quite fat, including many things I will not need.
  • Fedora-Minimal-28-1.1.aarch64: unzipped 5.4GB, seems like the best choice.
### preparing the new partition
mkfs.ext4 /dev/mmcblk0p4
mount /dev/mmcblk0p4 /mnt/tmp4

### deploying the image
xz -d Fedora-Minimal-28-1.1.aarch64.raw.xz
losetup -f Fedora-Workstation-28-1.1.aarch64.raw 
kpartx -av /dev/loop0 
vgscan 
mount /dev/mapper/loop0p5 /mnt/tmp
cd /mnt/tmp4
tar cfp - *|pv|(cd /mnt/tmp/4 && tar xfp -)

### preparations
vi /etc/fstab
# only need this: /dev/mmcblk0p4 / ext4 defaults 0 0

cd /mnt/tmp4
ln -s /etc/rc.local etc/rc.d/rc.local

# Remember that wlan just works after a soft reboot of Linux.
# As we can not type in 'reboot', we modify /etc/rc.local so
# it does a reboot for us.  Use the following code in /etc/rc.local:
------
#!/bin/bash

[ -f /etc/flagfile ] || {
        echo "/etc/flagfile does not exist apparently, touching it and rebooting in 10sec"
        touch /etc/flagfile
        dmesg >/var/log/dmesg1
        sync
        sleep 10
        reboot
}

echo "not rebooting.. and removing flagfile."
rm /etc/flagfile
------

chmod +x etc/rc.local

# set a root password, for example one from your /etc/shadow
vi etc/shadow

# disable console on tty1.  We have no input anyway, and can
# see debugmessages that way.
mv etc/systemd/system/getty.target.wants/getty@tty1.service root/

### prepare wlan
# copy wlan config file from an existing system
cp mynetwork etc/NetworkManager/system-connections/mynetwork
# required?  I created this while debugging nonworking network.
vi /etc/sysconfig/network-scripts/ifcfg-wlp1s0

# If you installed the Fedora server spin, fetch packages
# wpa_supplicant and NetworkManager-wifi and deploy them into 
# your image.  Either chrooting from a running aarch64 system,
# or using 
# rpm2cpio /tmp/wpa_supplicant-*.aarch64.rpm | \
#    cpio --extract --verbose --make-directories --preserve

# Now we can boot the system.  After the reboot, wlan should
# work.  Login via ssh into root, run dnf upgrade, and install
# the 2 packages cleanly so dnf is aware of them.
dnf update
dnf install NetworkManager-wifi langpacks-ja

systemctl disable auditd
systemctl disable smartd
systemctl disable pcscd

# if you want rpmfusion
dnf install \
  https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm \
  https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm

Fedora Xorg

ssh root@switch

dnf groupinstall Basic\ Desktop
dnf groupinstall 'LXDE Desktop'

# we will need a virtual keyboard.  This one is simple and small,
# florence is a further option.
dnf install xvkbd

# then, X can be started manually
startx

Fedora Xorg 3D support

At this point, X can be started, but has no 3D support. Fedora 28 and Fedora 29 (rawhide) do not have Tegra support in libdrm and mesa, lets rebuild it.

echo '%_topdir /root/rpmbuild' >~/.rpmmacros

dnf install rpm-build yum-utils rpmdevtools
rpmdev-setuptree

cd ~/rpmbuild
yumdownloader --source libdrm
rpm -ivh libdrm-2.4.92*fc28.src.rpm
cp SPECS/libdrm.spec SPECS/libdrm.spec.org
vi SPECS/libdrm.spec
# We are changing the release, so the Fedora version
# is not getting reinstalled.
# change 'Release:        1%{?dist}' into 'Release:        1.tegra%{?dist}'

# dependencies
dnf install -y docbook-style-xsl gcc kernel-headers \
  libatomic_ops-devel meson valgrind-devel
rpmbuild -ba --with tegra SPECS/libdrm.spec
# pay attention to:
# Message:   Tegra API      true

# Then install the rebuild package.
rpm -Fvh RPMS/aarch64/*2.4.92*
rpm -ql libdrm|grep tegra
/usr/lib64/libdrm_tegra.so.0
/usr/lib64/libdrm_tegra.so.0.0.0

# Now, Fedora28 has only mesa-18.0.1, but we need the current
# pre-18.2 version for tegra support.
# rawhide has mesa-18.1.0-rc3, rebuilding that might work,
# that version has tegra support:
# http://ftp.riken.jp/Linux/fedora/development/rawhide/Everything/source/tree/Packages/m/
# Instead, I used the specfile from rawhides mesa-18.1.0-rc3,
# and compiled the current git version of mesa-18.2-pre.

# Install build dependencies of the mesa-18.0.1 Fed28 package
dnf install -y autoconf automake bison clang-devel \
  elfutils-libelf-devel expat-devel flex gcc-c++ libXdamage-devel \
  libXext-devel libXfixes-devel libXi-devel libXmu-devel \
  libXxf86vm-devel libclc-devel libomxil-bellagio-devel \
  libselinux-devel libtool libudev-devel libva-devel \
  libvdpau-devel libxshmfence-devel llvm-devel makedepend \
  opencl-filesystem python2-libxml2 python2-mako python3-mako \
  xorg-x11-proto-devel libglvnd-devel wayland-protocols

### The custom Ubuntu packages use these options:
# ./configure --prefix=/usr/ --without-dri-drivers \
#  --disable-gallium-llvm --with-gallium-drivers=nouveau,tegra \
#  --enable-gbm --enable-egl --with-egl-platforms=drm,x11 \
#  --enable-gles1 --enable-gles2 --enable-opengl --enable-osmesa \
#  --enable-shared-glapi --enable-dri3 --enable-glx --enable-glx-tls \
#  --enable-texture-float

rpm -ivh mesa-18.1.0-0.2.rc3.fc29.src.rpm
cd /root/rpmbuild
git clone git://anongit.freedesktop.org/git/mesa/mesa
mv mesa mesa-18.2.0-git02c7916298
tar cf mesa-18.2.0-git02c7916298.tar mesa-18.2.0-rc
mv mesa-18.2.0-git02c7916298.tar SOURCES
mv SPECS/mesa.spec SPECS/mesa.spec.org
cd SPECS
wget https://fluxcoil.net/files/tmp/mesa-18.2.0-git02c7916298.spec

rpmbuild -bb mesa-18.2.0-git02c7916298.spec
cd ../RPMS/aarch64/
rpm -Fvh mesa*18.2.0*

# Then start X, and try somesoftware:
startx
glxgears

graphical demos/games

  • 'dnf -y install glmark2 extremetuxracer' is a good start
  • 'dnf install freedoom2' also runs nicely: 'prboom -window -iwad <wadfile>'. Explicit OpenGL rendering with '-vidmode gl'.
  • GZDoom can be compiled, but can not be started for me. Neither current, nor older 3.x version. Version 2.x can not be compiled.
  • Amiga emulator https://fs-uae.net/ : packages just build for x86_64. Rebuilding fails, need to try to build directly.

Debian

This is bootstrapped from an installed Fedora27.

dnf -y install debootstrap
mkfs.ext4 /dev/mmcblk0p3
mount /dev/mmcblk0p3 /mnt/mmcblk0p3

debootstrap sid /mnt/mmcblk0p3/ http://ftp.jp.debian.org/debian/
cd /mnt/mmcblk0p3/
echo "proc sid-root/proc proc defaults 0 0" >> etc/fstab 
echo "sysfs /sys sysfs defaults 0 0" >> etc/fstab
echo "/dev/mmcblk0p3 / ext4 defaults 0 0" >> etc/fstab
mount proc proc/ -t proc
mount sysfs sys -t sysfs
cp /etc/hosts etc/
cp /etc/hostname etc/
export LC_ALL=en_US.utf8
chroot . /bin/bash

# now in the debian filesystem
apt-get update
# if it fails, mktemp might be missing, can be copied in from host
cp /usr/bin/mktemp /mnt/mmcblk0p3/usr/bin/

mount -t devpts devpts /dev/pts
echo 'deb http://ftp.jp.debian.org/debian sid main contrib non-free' \
  >>/etc/apt/sources.list
echo 'export PATH=/bin:/sbin:$PATH' >>/root/.bashrc
echo 'alias ll="ls -al"' >>/root/.bashrc

apt-get install locales locales-all
apt-get install openssh-server linux-image-arm64 binutils
apt-get install wpasupplicant network-manager
cp /etc/NetworkManager/system-connections/mynet \
  /mnt/mmcblk0p3/tc/NetworkManager/system-connections/

# now set a password
passwd
# pubkeys should be same as for host
cp -r /root/.ssh/mnt/mmcblk0p3/root/

reboot
# modify your switch linux loader, so partition 3 gets started:
# grep mmcblk0p ./shofel2/usb_loader/switch.scr
setenv bootargs 'root=/dev/mmcblk0p3 rw fbcon=rotate:3 rootwait'

ping switch
# login, and do a first functionality test
ssh root@switch
apt-get update; apt-get install bb
/usr/games/bb

Debian Xorg

apt-get install lxde fonts-ipafont-mincho fonts-ipafont-gothic \
  fonts-nanum xfsprogs mesa-utils xfonts-100dpi xfonts-75dpi \
  xfonts-scalable xinput xinit
  
# now we can bring up X
startx

apt-get install firefox fonts-stix fonts-lmodern xvkbd

Debian compiling dri/mesa

apt-get install git autoconf xutils-dev wget
apt-get install libtool make flex bison build-essential
apt-get build-dep libdrm mesa

git clone git://anongit.freedesktop.org/mesa/drm
cd drm
./autogen.sh
./configure --enable-tegra-experimental-api --prefix=/usr
make
make install
cd ..

git clone git://anongit.freedesktop.org/git/mesa/mesa
cd mesa
./autogen.sh
# https://github.com/NVIDIA/tegra-rootfs-scripts/blob/master/build-mesa
./configure --prefix=/usr/ --without-dri-drivers \
  --disable-gallium-llvm --with-gallium-drivers=nouveau,tegra \
  --enable-gbm --enable-egl --with-egl-platforms=drm,x11 \
  --enable-gles1 --enable-gles2 --enable-opengl --enable-osmesa \
  --enable-shared-glapi --enable-dri3 --enable-glx --enable-glx-tls \
  --enable-texture-float

openSUSE Tumbleweed

# suse has by default no symlink to default.target in /etc/systemd/system .
# It runs the graphical target by default, you need to create the
# link for the plain multiuser target
ln -s /usr/lib/systemd/system/multi-user.target \
  /etc/systemd/system/default.target
  
# We also need to setup rc-local compat
ln -s /usr/lib/systemd/system/rc-local.service \
  /etc/systemd/system/multi-user.target.wants/rc-local.service
  
# Also, no /etc/rc.local, but:
mv /etc/rc.local /etc/init.d/boot.init
# We can use the same rc.local/boot.init code as for Fedora.

# By default, Suse tries to start wicked and NetworkManager.
# So if you copy your wlan file to 
# /etc/NetworkManager/system-connections/ , you are fine.

# then, start the image, login and..

hostnamectl set-hostname switch.local
zypper update
zypper install xvkbd qsynergy rss-glx

# X can be started, but pointer detection and screen are not aligned.
# Be sure to _not_ use kernel option fbcon=rotate:X to have them aligned.

rpm -ql rss-glx|grep bin
# these screensavers are usable for me

generic xorg hints

touchscreen detection not in sync

The touchscreen driver will work in horizontal mode by default, but the xorg screen might come up in vertical mode. You can use one of the following 2 things to fix:

  • Modify the touchscreen config to vertical:
cat <<EOT >/etc/udev/rules.d/01-nintendo-switch-libinput-matrix.rules
ATTRS{name}=="stmfts", ENV{LIBINPUT_CALIBRATION_MATRIX}="0 1 0 -1 0 1"
EOT
  • or rotate the screen to vertical. For example on lxde, this can be used:
mkdir -p ~/.config/autostart
cat <<EOT >~/.config/autostart/.desktop 
[Desktop Entry] 
Type=rotater
Exec=xrandr --output DSI-1 --rotate left
EOT

missing tegra driver

gbm: Last dlopen error: /usr/lib/dri/tegra_dri.so: 
cannot open shared object file: No such file or directory
failed to load driver: tegra
EGL_MESA_drm_image required.

Compile libdrm and mesa with tegra support.

hardwarerelated/nintendo_switch.txt · Last modified: 2018/11/11 00:37 by chris