User Tools

Site Tools



Boot order for Linux@switch

  1. As first step, the switch needs to be booted into RCM, an early debug mode. For doing this for the first time, pins on the switch need to be crossed, for example using this RCM jig device. When this succeeded one time, you can use Hekate to set 'autorcm', the switch will then after resets always enter RCM instead of booting Nintendos Horizon.
  2. With the switch being in RCM, it will do nothing, the screen will be black. At this state, payload code to be run needs to be supplied via USB. The code can be supplied from Android (via NXLoader) or a Linux box via Fusee launcher.
  3. What to run as first level payload?
    • Hekate could be used, offered via Fusee launcher. Hekate can then
      • configure 'autorcm'
      • it can verify the switches battery charge state
      • it can run Linux kernels from microsd-cards in the switch (using coreboot)
      • it can poweroff the switch
    • Shovel2 can be used to upload Linux kernels via USB, coreboot is also here used. Userland to be booted could be on the microsd card, or supplied via NFS.
    • ArgonNX has more eyecandy than hekate.
  4. Which kernel to run? There are basically 2 levels of kernel patches.
    • mid-2018 kernel, using the initial patches from Fail0verflow: no audio, problems charging the switch, resets when load is high (compile things only with 'make -j1'), wlan only works after one reset of the system. Yet, on this kernel one can see Linux console output directly on the screen after booting. This kernel is great for initially running for example Fedora30, Opensuse or Debian userlands: because you can use the screen to get debugging output, until you get the userland appropriately configured to log into wlan after booting. From that state on you can work via SSH.
    • mid-2019 kernel from the L4T distro with nvidia patches: audio, charging and wlan work, no resets under high load. But no initial console output. Lakka and the L4T distro use this kernel. The Lakka bootchain.
  5. Which userland to run? L4T and Lakka come with kernel/userland together. The kernels with switch patches can be used on other userlands though, like Fedora30, SuSE, Debian.

Fedora 30 boot order

2 variants can be used:

  1. loading kernel/initrd from sdcard
  2. or via USB.

I use USB so far, it's easier to exchange kernels. Single steps (nicely summed up here):

  • Switch booting into to Tegra RCM flashing mode over USB
  • ShofEL2 boots Coreboot
  • Coreboot initializes hardware and launches U-Boot as its payload
  • U-Boot starts SDP flashing mode over USB
  • imx-usb-loader loads Linux kernel, device tree, and U-Boot script via SDP
  • U-Boot script decompresses (if comressed kernel) and boots Linux

Installing Fedora 30

I am installing Fedora for the switch on the microsd card, using a Fedora30 x86_64 as host. I created DOS style partitions on a 32GB card, and switch between the partitions in modifying the kernel command line. First, I installed L4T on the card, this did setup partitions 1 (vfat) and 2 (ext4, L4T). After increasing the second partition to 16GB, I created a third partition and installed Fedora 30 there.

L4T is booting the linux kernel from the card, but I am booting Fedora with kernel/initrd supplied via USB. For this, I have compiled shovel2/coreboot from this guide. I also compiled the kernel as per these instructions, but it has many downsides over the L4T kernel. I am booting Fedora with the L4T kernel. Details on how I boot kernels are here

For installing the Fedora30 aarch64 userland for the switch, I used Fedora-Server-30-1.2.aarch64.raw.xz. Despite being the server spin, it comes with packages wpa_supplicant and Networkmanager-wifi.

### preparing the new partition
mkfs.ext4 /dev/mmcblk0p3
mount /dev/mmcblk0p3 /mnt/tmp3

### deploying the image
xz -d Fedora-Server-30-1.2.aarch64.raw.xz
kpartx -av Fedora-Server-30-1.2.aarch64.raw
vgchange -ay
mount /dev/fedora/root /mnt/tmp
cd /mnt/tmp
tar cfp - *|pv|(cd /mnt/tmp3 && tar xfp -)

### preparations
cd /mnt/tmp3
vi etc/fstab
# only need this: /dev/mmcblk0p3 / ext4 defaults 0 0

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

echo switch.local >etc/hostname
echo '   switch.local switch' >>etc/hosts

# disable console on tty1.  We have no input anyway, and can
# see debugmessages that way - via HDMI
mv etc/systemd/system/ root/

### prepare wlan
# I have my wlan already setup on my Fedora30 host system,
# so I can simply copy over the files
cp /etc/sysconfig/network-scripts/keys-mynetwork \
   /etc/sysconfig/network-scripts/ifcfg-mynetwork \

# Now we can boot the system.  After the reboot, wlan should
# work.  Login via ssh into root, run dnf upgrade,
# remove and install packages
dnf remove iscsi-initiator-utils-iscsiuio iscsi-initiator-utils \
  clevis-luks atmel-firmware
dnf install -y langpacks-ja upower screen
dnf update -y

for i in auditd smartd pcscd ModemManager multipathd mdmonitor \
         dmraid-activation initial-setup lvm2-monitor zram-swap \
         plymouth-start lm_sensors udisks2 ; do
    systemctl disable $i

### tuning, seen in the L4T scripts
cat >/etc/rc.local<<EOT
echo 2048 > /sys/block/mmcblk0/queue/read_ahead_kb
echo 0 > "/proc/sys/vm/lazy_vfree_pages"
chmod +x /etc/rc.local
ln -s /etc/rc.local /etc/rc.d/rc.local

### if you want rpmfusion
dnf install \$(rpm -E %fedora).noarch.rpm \$(rpm -E %fedora).noarch.rpm

Fedora Xorg/LXDM autologin

ssh root@switch

# Install the basic environment.
dnf -y groupinstall 'Basic Desktop' 'LXDE Desktop'

# Install
# - xvkbd, a virtual keyboard.  'florence' is a further option.
# - synergy, so I can use mouse/keyboard of my linux box
# - f29-backgrounds, because they are awesome :)
dnf install -y xvkbd synergy f29-backgrounds-base mplayer

# Now copying drivers from an L4T installation on partition2:
mount /dev/mmcblk0p2 /mnt/tmp2/
cd /mnt/tmp2

cp usr/lib/xorg/modules/drivers/ \
cp usr/lib/xorg/modules/extensions/ \
cp /mnt/tmp2/usr/bin/dock-hotplug /usr/bin

mkdir -p /usr/lib/aarch64-linux-gnu
cp -r usr/lib/aarch64-linux-gnu/tegra-egl \
ln -s /usr/lib/aarch64-linux-gnu/tegra-egl/ \
cp -r usr/lib/aarch64-linux-gnu/tegra \
ln -s /usr/lib/aarch64-linux-gnu/tegra/ \


cp -r lib/firmware/tegra21x lib/firmware/gm20b /lib/firmware/
cp lib/firmware/bcm4354.hcd /lib/firmware/

# special xorg config
cat >/etc/X11/xorg.conf<<EOT
Section "Module"
    Disable     "dri"
    SubSection  "extmod"
        Option  "omit xfree86-dga"

Section "Device"
    Identifier  "Tegra0"
    Driver      "nvidia"
    # Allow X server to be started even if no display devices are connected.
    Option      "AllowEmptyInitialConfiguration" "true"
    Option      "Rotate" "CW"

Section "InputClass"
    Identifier "evdev touchscreen catchall"
    MatchIsTouchscreen "on"
    MatchDevicePath "/dev/input/event*"
    Driver "evdev"
    Option "InvertX" "no"
    Option "InvertY" "no"
    Option "SwapAxes" "no"
    Option "Calibration" "0 1279 0 719"

Section "Monitor"
    Identifier "DFP-0"
    Option "Rotate" "left"

# MYUSER="lxde"
useradd -m $MYUSER

mkdir -p /home/$MYUSER/.config/lxsession/LXDE
cat >/home/$MYUSER/.config/lxsession/LXDE/autostart<<EOT
@lxpanel --profile LXDE
@pcmanfm --desktop --profile LXDE
@synergy-core --client
chown -R $MYUSER /home/$MYUSER/.config

# configure autologin
vi /etc/lxdm/lxdm.conf
# autologin=username  # <- insert the username which you use
# session=/usr/bin/startlxde

# We need to ensure that our user later appears in the 'who' output.
# That is important for the /usr/bin/dock-hotplug script, for
# switching screens.
echo 'sessreg -a -l $DISPLAY -x /etc/X11/xdm/Xservers $USER &' >> \
echo 'sessreg -d -l $DISPLAY -x /etc/X11/xdm/Xservers $USER &' >> \

rm -f /etc/systemd/system/display-manager.service
systemctl enable --now lxdm
systemctl set-default

Fedora sound

# Now copying drivers from an L4T installation on partition2.
mount /dev/mmcblk0p2 /mnt/tmp2/
cd /mnt/tmp2

dnf install -y alsa-ucm alsa-plugins-pulseaudio alsa-utils \
  pulseaudio pulseaudio-module-x11 pulseaudio-utils pavucontrol
cp -r usr/share/alsa/ucm/tegra-snd-t210ref-mobile-rt565x/ /usr/share/alsa/ucm/
cp usr/share/alsa/cards/tegra-hda.conf /usr/share/alsa/cards

cp -r opt/nvidia/ /opt/
cp usr/sbin/nv* usr/sbin/brcm* /usr/sbin/
cp -r etc/nv* /etc/
cp etc/systemd/nv* /etc/systemd
cp etc/systemd/system/nv*service /etc/systemd/system/

cp etc/asound.conf.* /etc/

# ensure that /etc/asound.conf is linked to
# the appropriate file, depending on whether we are docked or not
cat >/etc/udev/rules.d/92-dp-switch.rules<<EOT
SUBSYSTEM!="switch", GOTO="dp_end"
KERNEL!="dp", GOTO="dp_end"
ATTRS{state}=="1", TEST=="/proc/asound/tegrahda", RUN+="/bin/ln -sf /etc/asound.conf.tegrahda /etc/asound.conf"
ATTRS{state}=="1", TEST=="/usr/bin/dock-hotplug", RUN+="/usr/bin/dock-hotplug"
ATTRS{state}=="0", TEST=="/usr/bin/dock-hotplug", RUN+="/usr/bin/dock-hotplug"
ATTRS{state}=="0", TEST=="/proc/asound/tegrasndt210ref", RUN+="/bin/ln -sf /etc/asound.conf.tegrasndt210ref /etc/asound.conf"

# reboot

# for playing via alsa, this has to be active:
alsamixer # I2S1 Mux -> ADMAIF1

# we should now be able to start X, and have sound output:
mplayer <something> 

# When the switch is docked, the screen should switch to HDMI
# output automatically, via profile switch in /usr/bin/dock-hotplug .
# The profile can also be selected via 'pavucontrol' from X.

# also for output testing: 
# speaker-test –channels 2 –rate 48000 –device hw:0,3​
software/switch/fedora_30_install.txt · Last modified: 2021/03/23 12:22 (external edit)