Difference between revisions of "Steam Link"

From Exploitee.rs
Jump to navigationJump to search
(Added TOC, About, and Purchase sections)
 
(10 intermediate revisions by 2 users not shown)
Line 14: Line 14:
== Specs ==
== Specs ==


* '''CPU:''' Marvell ARMv7 Processor (Can't find exact model)
* '''CPU:''' Marvell ARMv7 Processor (Can't find exact model) (Just now realized the hardware ID "MV88DE3108" is one number off from the [[Google Chromecast]] "MV88DE3100")
* '''RAM:''' 512MB (~256MB available after boot)
* '''RAM:''' 512MB (~256MB available after boot)
* '''Dimensions:''' 123.19 x 14.73 x 89.66 mm
* '''Dimensions:''' 123.19 x 14.73 x 89.66 mm
* '''WiFi:''' Marvell 88W8897
* '''Ports:''' 3 USB 2.0, HDMI 2.0, 10/100 Ethernet, Power
* '''Ports:''' 3 USB 2.0, HDMI 2.0, 10/100 Ethernet, Power


== Information ==
== Photos ==
 
[[File:Link PCB top.jpg|700px|frameless]]
 
[[File:Link PCB bottom.jpg|700px|frameless]]
 
== Information & Root Method ==
 
'''Note: As of the latest beta software for the Link, pulseaudio is no longer used. ALSA is used for everything including USB headsets and has a volume control option under Settings.
'''


Steam Link is running a custom Linux build by Valve. An SDK is provided to develop applications to run on the device itself. https://github.com/ValveSoftware/steamlink-sdk
Steam Link is running a custom Linux build by Valve. An SDK is provided to develop applications to run on the device itself. https://github.com/ValveSoftware/steamlink-sdk
Line 29: Line 39:
* /steamlink/config/system/update_branch.txt - Creating that file with one of their build numbers as the contents will make the Link download and install that particular version
* /steamlink/config/system/update_branch.txt - Creating that file with one of their build numbers as the contents will make the Link download and install that particular version


The best part? With SSH you get a root shell! Username: root password: steamlink (Change with passwd after first login)
The best part? With SSH you get a root shell! Username: root password: steamlink (or steamlink123). (Change with passwd after first login)


It comes with a surprising amount of regular utilities
It comes with a surprising amount of regular utilities
Line 35: Line 45:
  <nowiki>
  <nowiki>
# uname -a
# uname -a
Linux steamlink-87F1 3.8.13-mrvl #52 PREEMPT Thu Sep 1 11:23:18 PDT 2016 armv7l GNU/Linux
Linux steamlink-87F1 3.8.13-mrvl #60 PREEMPT Mon Dec 12 11:24:32 PST 2016 armv7l GNU/Linux
# cat /proc/cpuinfo
# cat /proc/cpuinfo
processor      : 0
processor      : 0
Line 53: Line 63:
pulseaudio 8.0
pulseaudio 8.0
# bluetoothctl --version
# bluetoothctl --version
5.35
5.43
# bluetoothctl
# bluetoothctl
[NEW] Controller E0:31:9E:0C:BA:0B BlueZ 5.35 [default]
[NEW] Controller E0:31:9E:0C:BA:0B BlueZ 5.35 [default]
Line 73: Line 83:
# df -h
# df -h
Filesystem                Size      Used Available Use% Mounted on
Filesystem                Size      Used Available Use% Mounted on
/dev/mtdblock9            1.0G    239.0M   785.0M 23% /
/dev/mtdblock9            1.0G    246.2M   777.8M 24% /
none                    131.4M   292.0K    131.1M   0% /dev
none                    131.4M     8.0K    131.4M   0% /dev
devtmpfs                131.4M   292.0K    131.1M   0% /dev
devtmpfs                131.4M     8.0K    131.4M   0% /dev
tmpfs                  131.4M    48.0K    131.3M   0% /tmp
tmpfs                  131.4M    20.0K    131.4M   0% /tmp
tmpfs                  131.4M        0    131.4M  0% /mnt
tmpfs                  131.4M        0    131.4M  0% /mnt
/dev/block/mtdblock4    32.0M      6.1M    25.9M  19% /mnt/factory_setting
/dev/block/mtdblock4    32.0M      6.1M    25.9M  19% /mnt/factory_setting
/dev/block/mtdblock10
/dev/block/mtdblock10
                           1.9G     32.2M     1.8G  2% /mnt/scratch
                           1.9G   785.5M     1.1G  41% /mnt/scratch
/dev/block/mtdblock3    512.0M   158.0M   354.0M  31% /mnt/config
/dev/block/mtdblock3    512.0M     26.5M   485.5M  5% /mnt/config
unionfs                512.0M   158.0M   354.0M  31% /etc
unionfs                512.0M     26.5M   485.5M  5% /etc
unionfs                512.0M   158.0M   354.0M  31% /var
unionfs                512.0M     26.5M   485.5M  5% /var
unionfs                512.0M   158.0M   354.0M  31% /home
unionfs                512.0M     26.5M   485.5M  5% /home/steam
unionfs                512.0M   158.0M   354.0M  31% /usr/local
unionfs                512.0M     26.5M   485.5M  5% /usr/local
tmpfs                  131.4M    20.0K    131.4M  0% /var/run
tmpfs                  131.4M    20.0K    131.4M  0% /var/run
/dev/loop0              975.9M    207.6M    717.1M  22% /home/apps
# mount
# mount
rootfs on / type rootfs (rw)
rootfs on / type rootfs (rw)
Line 102: Line 113:
unionfs on /etc type unionfs (rw,relatime,dirs=/mnt/config/overlay/etc=rw:/etc=ro)
unionfs on /etc type unionfs (rw,relatime,dirs=/mnt/config/overlay/etc=rw:/etc=ro)
unionfs on /var type unionfs (rw,relatime,dirs=/mnt/config/overlay/var=rw:/var=ro)
unionfs on /var type unionfs (rw,relatime,dirs=/mnt/config/overlay/var=rw:/var=ro)
unionfs on /home type unionfs (rw,relatime,dirs=/mnt/config/overlay/home=rw:/home=ro)
unionfs on /home/steam type unionfs (rw,relatime,dirs=/mnt/config/overlay/home/steam=rw:/home/steam=ro)
unionfs on /usr/local type unionfs (rw,relatime,dirs=/mnt/config/overlay/usr/local=rw:/usr/local=ro)
unionfs on /usr/local type unionfs (rw,relatime,dirs=/mnt/config/overlay/usr/local=rw:/usr/local=ro)
tmpfs on /var/run type tmpfs (rw,relatime)
tmpfs on /var/run type tmpfs (rw,relatime)
/dev/loop0 on /home/apps type ext4 (rw,relatime,data=ordered)
# busybox --help
# busybox --help
BusyBox v1.24.1 (2016-01-19 12:54:10 PST) multi-call binary.
BusyBox v1.24.1 (2016-01-19 12:54:10 PST) multi-call binary.
Line 207: Line 219:
(1/1) Updating the info directory file...
(1/1) Updating the info directory file...
</nowiki>
</nowiki>
== Compiling native applications ==
This can be a little tricky at times but is very fun when you get something running.
For best results look for a program using pure SDL2 for video/input handling (Bonus points if it uses the CMake compiling system). External libs are possible (you have to compile them, copy over the include files to the rootfs directory, and then when you package up a program include the .so files to use in an LD_PRELOAD)
Starting out is fairly straight forward
<nowiki>
git clone https://github.com/ValveSoftware/steamlink-sdk
cd steamlink-sdk/examples
</nowiki>
From here you can check out the included example applications and their respective build scripts. If we want to experiment with our own:
<nowiki>
git clone somesource
cd somesource
</nowiki>
First I'll cover a CMake project because these provide the best results (because of the included toolchain definition file)
<nowiki>
source ../../setenv.sh
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../../../toolchain/steamlink-toolchain.cmake ../
</nowiki>
If all goes well it should find any needed libraries and create the Makefile for you. (If it needs any other external libraries a quick rundown is to repeat the same steps as above to grab the source, hope it compiles, and copy over the include files to the rootfs/usr/include directory in the steamlink-sdk repo folder. This isn't guaranteed to work so your mileage may vary.)
Then you just compile it.
<nowiki>
make -j4
</nowiki>
For regular source installations (typical automake/Makefile) it can be a hit or miss whether compilation will work or not. The gist of it is:
<nowiki>
./automake #If needed
./configure --host=armv7a-cros-linux-gnueabi #and any other needed arguments
make -j4 #and pray...
</nowiki>
Once you end up with a compiled binary, you can scp it over to the Link and try to run it. If you had to compile any external libs (.so) be sure to include them in the transfer and use LD_PRELOAD=./ ./binaryname to test.
If everything went ok and the binary runs as expected and you are happy with the results, packaging it up for a USB install is dead simple
Create a folder named whatever you want (I typically use the program name all lowercase), and create these files in said folder as follows.
<nowiki>
toc.txt
    name=Whatever # This is what shows in the launcher
    icon=whatever-icon.png
    run=binary # Or a script name if you need to LD_PRELOAD. Just make sure the binary/script are executable for this line to work
whatever-icon.png # I haven't found exact specifications for this but I typically do a 128x128 icon
binary # Main program
binary-launch.sh # Only needed if you want to preload/pass special arguments
    #!/bin/sh
    LD_PRELOAD=./ ./binary
And any data files needed for it to run
</nowiki>
Next just back up a directory and tar up the folder
<nowiki>
tar zcvf programname.tgz foldername
</nowiki>
Now if you want to install this on the Link just copy that tgz to a flash drive at USB:/steamlink/apps/ and boot the Link with the drive plugged in. It will extract it and then boot to the launcher.

Latest revision as of 04:16, 15 August 2019

"Although the information we release has been verified and shown to work to the best our knowledge, we cant be held accountable for bricked devices or roots gone wrong."

Steam Link back.jpg

About

Steam Link is an in-home streaming appliance made by Valve.

Purchase

Support the Exploitee.rs network by using the following link to buy a Steam Link

Steam Link at Amazon

Specs

  • CPU: Marvell ARMv7 Processor (Can't find exact model) (Just now realized the hardware ID "MV88DE3108" is one number off from the Google Chromecast "MV88DE3100")
  • RAM: 512MB (~256MB available after boot)
  • Dimensions: 123.19 x 14.73 x 89.66 mm
  • WiFi: Marvell 88W8897
  • Ports: 3 USB 2.0, HDMI 2.0, 10/100 Ethernet, Power

Photos

Link PCB top.jpg

Link PCB bottom.jpg

Information & Root Method

Note: As of the latest beta software for the Link, pulseaudio is no longer used. ALSA is used for everything including USB headsets and has a volume control option under Settings.

Steam Link is running a custom Linux build by Valve. An SDK is provided to develop applications to run on the device itself. https://github.com/ValveSoftware/steamlink-sdk

Various functions can be enabled by putting a file in a certain location on a FAT32 USB drive and booting the Link with it plugged in. Create directories as needed.

  • /steamlink/config/system/enable_ssh.txt (Just create a blank file) - Enables SSH until next factory reset or removing /mnt/config/system/enable_ssh.txt
  • /steamlink/config/system/display_resolution.txt - Putting "720P" in that file will limit the Link to that resolution
  • /steamlink/config/system/update_branch.txt - Creating that file with one of their build numbers as the contents will make the Link download and install that particular version

The best part? With SSH you get a root shell! Username: root password: steamlink (or steamlink123). (Change with passwd after first login)

It comes with a surprising amount of regular utilities

# uname -a
Linux steamlink-87F1 3.8.13-mrvl #60 PREEMPT Mon Dec 12 11:24:32 PST 2016 armv7l GNU/Linux
# cat /proc/cpuinfo
processor       : 0
model name      : ARMv7 Processor rev 0 (v7l)
BogoMIPS        : 995.32
Features        : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x3
CPU part        : 0xc09
CPU revision    : 0

Hardware        : MV88DE3108
Revision        : 0000
Serial          : 0000000000000000\
# pulseaudio --version
pulseaudio 8.0
# bluetoothctl --version
5.43
# bluetoothctl
[NEW] Controller E0:31:9E:0C:BA:0B BlueZ 5.35 [default]
[bluetooth]# exit
[DEL] Controller E0:31:9E:0C:BA:0B BlueZ 5.35 [default]
# connmand --version
1.29
# connmanctl state
  State = online
  OfflineMode = False
  SessionMode = False
# connmanctl services
*AO ASUS_5G              wifi_e0319e0cba0a_415355535f3547_managed_psk

Valve's frontend actually interfaces with connman/bluetoothd for WiFi/Bluetooth connections.

# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/mtdblock9            1.0G    246.2M    777.8M  24% /
none                    131.4M      8.0K    131.4M   0% /dev
devtmpfs                131.4M      8.0K    131.4M   0% /dev
tmpfs                   131.4M     20.0K    131.4M   0% /tmp
tmpfs                   131.4M         0    131.4M   0% /mnt
/dev/block/mtdblock4     32.0M      6.1M     25.9M  19% /mnt/factory_setting
/dev/block/mtdblock10
                          1.9G    785.5M      1.1G  41% /mnt/scratch
/dev/block/mtdblock3    512.0M     26.5M    485.5M   5% /mnt/config
unionfs                 512.0M     26.5M    485.5M   5% /etc
unionfs                 512.0M     26.5M    485.5M   5% /var
unionfs                 512.0M     26.5M    485.5M   5% /home/steam
unionfs                 512.0M     26.5M    485.5M   5% /usr/local
tmpfs                   131.4M     20.0K    131.4M   0% /var/run
/dev/loop0              975.9M    207.6M    717.1M  22% /home/apps
# mount
rootfs on / type rootfs (rw)
/dev/mtdblock9 on / type yaffs2 (ro,relatime)
none on /dev type tmpfs (rw,relatime)
sys on /sys type sysfs (rw,relatime)
proc on /proc type proc (rw,relatime)
devtmpfs on /dev type tmpfs (rw,relatime)
devpts on /dev/pts type devpts (rw,relatime,mode=600)
tmpfs on /tmp type tmpfs (rw,relatime)
tmpfs on /mnt type tmpfs (rw,relatime)
/dev/block/mtdblock4 on /mnt/factory_setting type yaffs2 (ro,relatime)
/dev/block/mtdblock10 on /mnt/scratch type yaffs2 (rw,relatime)
/dev/block/mtdblock3 on /mnt/config type yaffs2 (rw,relatime)
unionfs on /etc type unionfs (rw,relatime,dirs=/mnt/config/overlay/etc=rw:/etc=ro)
unionfs on /var type unionfs (rw,relatime,dirs=/mnt/config/overlay/var=rw:/var=ro)
unionfs on /home/steam type unionfs (rw,relatime,dirs=/mnt/config/overlay/home/steam=rw:/home/steam=ro)
unionfs on /usr/local type unionfs (rw,relatime,dirs=/mnt/config/overlay/usr/local=rw:/usr/local=ro)
tmpfs on /var/run type tmpfs (rw,relatime)
/dev/loop0 on /home/apps type ext4 (rw,relatime,data=ordered)
# busybox --help
BusyBox v1.24.1 (2016-01-19 12:54:10 PST) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.

Usage: busybox [function [arguments]...]
   or: busybox --list[-full]
   or: busybox --install [-s] [DIR]
   or: function [arguments]...

        BusyBox is a multi-call binary that combines many common Unix
        utilities into a single executable.  Most people will create a
        link to busybox for each function they wish to use and BusyBox
        will act like whatever it was invoked as.

Currently defined functions:
        [, [[, acpid, add-shell, addgroup, adduser, adjtimex, arp, arping, ash, awk, base64, basename, beep, blkid, blockdev, bootchartd, brctl, bunzip2, bzcat, bzip2, cal, cat, catv, chat, chattr, chgrp, chmod, chown, chpasswd, chpst,
        chroot, chrt, chvt, cksum, clear, cmp, comm, conspy, cp, cpio, crond, crontab, cryptpw, cttyhack, cut, date, dc, dd, deallocvt, delgroup, deluser, depmod, devmem, df, dhcprelay, diff, dirname, dmesg, dnsd, dnsdomainname,
        dos2unix, du, dumpkmap, dumpleases, echo, ed, egrep, eject, env, envdir, envuidgid, ether-wake, expand, expr, fakeidentd, false, fatattr, fbset, fbsplash, fdflush, fdformat, fdisk, fgconsole, fgrep, find, findfs, flock, fold,
        free, freeramdisk, fsck, fsck.minix, fstrim, fsync, ftpd, ftpget, ftpput, fuser, getopt, getty, grep, groups, gunzip, gzip, halt, hd, hdparm, head, hexdump, hostid, hostname, httpd, hush, hwclock, id, ifconfig, ifdown,
        ifenslave, ifplugd, ifup, inetd, init, insmod, install, ionice, iostat, ip, ipaddr, ipcalc, ipcrm, ipcs, iplink, iproute, iprule, iptunnel, kbd_mode, kill, killall, killall5, klogd, last, less, linux32, linux64, linuxrc, ln,
        loadfont, loadkmap, logger, login, logname, logread, losetup, lpd, lpq, lpr, ls, lsattr, lsmod, lsof, lspci, lsusb, lzcat, lzma, lzop, lzopcat, makedevs, makemime, man, md5sum, mdev, mesg, microcom, mkdir, mkdosfs, mke2fs,
        mkfifo, mkfs.ext2, mkfs.minix, mkfs.vfat, mknod, mkpasswd, mkswap, mktemp, modinfo, modprobe, more, mount, mountpoint, mpstat, mt, mv, nameif, nanddump, nandwrite, nbd-client, nc, netstat, nice, nmeter, nohup, nslookup, ntpd,
        od, openvt, passwd, patch, pgrep, pidof, ping, ping6, pipe_progress, pivot_root, pkill, pmap, popmaildir, poweroff, powertop, printenv, printf, ps, pscan, pstree, pwd, pwdx, raidautorun, rdate, rdev, readahead, readlink,
        readprofile, realpath, reboot, reformime, remove-shell, renice, reset, resize, rev, rm, rmdir, rmmod, route, rpm, rpm2cpio, rtcwake, run-parts, runlevel, runsv, runsvdir, rx, script, scriptreplay, sed, sendmail, seq, setarch,
        setconsole, setfont, setkeycodes, setlogcons, setserial, setsid, setuidgid, sh, sha1sum, sha256sum, sha3sum, sha512sum, showkey, shuf, slattach, sleep, smemcap, softlimit, sort, split, start-stop-daemon, stat, strings, stty, su,
        sulogin, sum, sv, svlogd, swapoff, swapon, switch_root, sync, sysctl, syslogd, tac, tail, tar, tcpsvd, tee, telnet, telnetd, test, tftp, tftpd, time, timeout, top, touch, tr, traceroute, traceroute6, true, truncate, tty,
        ttysize, tunctl, ubiattach, ubidetach, ubimkvol, ubirmvol, ubirsvol, ubiupdatevol, udhcpc, udhcpd, udpsvd, uevent, umount, uname, unexpand, uniq, unix2dos, unlink, unlzma, unlzop, unxz, unzip, uptime, users, usleep, uudecode,
        uuencode, vconfig, vi, vlock, volname, wall, watch, watchdog, wc, wget, which, who, whoami, whois, xargs, xz, xzcat, yes, zcat, zcip
# free -m
             total       used       free     shared    buffers     cached
Mem:           262        119        143          0          0         71
-/+ buffers/cache:         47        215
Swap:            0          0          0

You only have sh/ash from Busybox BUT you can grab a static Bash binary and it works great. http://ftp.us.debian.org/debian/pool/main/b/bash/bash-static_4.4-1_armhf.deb (I just extracted the binary from this and placed it in /usr/local/bin on the Link)

And since we have Busybox we also have chroot! Extract http://os.archlinuxarm.org/os/ArchLinuxARM-armv7-latest.tar.gz to an EXT3 formatted flash drive and plug it into the Link.

# mount /dev/block/sda1 /mnt/usb
# mount -t proc proc /mnt/usb/proc/
# mount -t sysfs sys /mnt/usb/sys/
# mount -o bind /dev /mnt/usb/dev/
# mount -t devpts devpts /mnt/usb/dev/pts/
# chroot /mnt/usb /bin/bash
[root@steamlink-87F1 /]# 
[root@steamlink-87F1 /]# uname -a
Linux steamlink-87F1 3.8.13-mrvl #52 PREEMPT Thu Sep 1 11:23:18 PDT 2016 armv7l GNU/Linux
[root@steamlink-87F1 /]# useradd -m parker   
[root@steamlink-87F1 /]# passwd parker
New password: 
Retype new password: 
passwd: password updated successfully
[root@steamlink-87F1 /]# ls -a /home/parker/
.  ..  .bash_logout  .bash_profile  .bashrc
[root@steamlink-87F1 /]# pacman -Syu
:: Synchronizing package databases...
 core                                                                                                                211.8 KiB   963K/s 00:00 [######################################################################################] 100%
 extra                                                                                                                 2.3 MiB  4.85M/s 00:00 [######################################################################################] 100%
 community                                                                                                             3.8 MiB  4.73M/s 00:01 [######################################################################################] 100%
 alarm                                                                                                               110.2 KiB   648K/s 00:00 [######################################################################################] 100%
 aur                                                                                                                  29.3 KiB  7.15M/s 00:00 [######################################################################################] 100%
:: Starting full system upgrade...
resolving dependencies...
looking for conflicting packages...

Packages (8) curl-7.50.2-1  gawk-4.1.4-1  gcc-libs-6.2.1-1  gnutls-3.4.15-1  libutil-linux-2.28.2-1  linux-armv7-4.7.3-1  mkinitcpio-21-1  util-linux-2.28.2-1

Total Download Size:    56.39 MiB
Total Installed Size:  138.24 MiB
Net Upgrade Size:        0.18 MiB

:: Proceed with installation? [Y/n] 
:: Retrieving packages...
 gcc-libs-6.2.1-1-armv7h                                                                                              10.2 MiB  4.71M/s 00:02 [######################################################################################] 100%
 libutil-linux-2.28.2-1-armv7h                                                                                       252.0 KiB  1105K/s 00:00 [######################################################################################] 100%
 curl-7.50.2-1-armv7h                                                                                                776.2 KiB  4.62M/s 00:00 [######################################################################################] 100%
 gawk-4.1.4-1-armv7h                                                                                                 926.3 KiB  6.96M/s 00:00 [######################################################################################] 100%
 gnutls-3.4.15-1-armv7h                                                                                                2.0 MiB  2.38M/s 00:01 [######################################################################################] 100%
 util-linux-2.28.2-1-armv7h                                                                                         1687.2 KiB  4.25M/s 00:00 [######################################################################################] 100%
 mkinitcpio-21-1-any                                                                                                  38.0 KiB  3.71M/s 00:00 [######################################################################################] 100%
 linux-armv7-4.7.3-1-armv7h                                                                                           40.6 MiB  3.33M/s 00:12 [######################################################################################] 100%
(8/8) checking keys in keyring                                                                                                                [######################################################################################] 100%
(8/8) checking package integrity                                                                                                              [######################################################################################] 100%
(8/8) loading package files                                                                                                                   [######################################################################################] 100%
(8/8) checking for file conflicts                                                                                                             [######################################################################################] 100%
(8/8) checking available disk space                                                                                                           [######################################################################################] 100%
:: Processing package changes...
(1/8) upgrading gcc-libs                                                                                                                      [######################################################################################] 100%
(2/8) upgrading libutil-linux                                                                                                                 [######################################################################################] 100%
(3/8) upgrading curl                                                                                                                          [######################################################################################] 100%
(4/8) upgrading gawk                                                                                                                          [######################################################################################] 100%
(5/8) upgrading gnutls                                                                                                                        [######################################################################################] 100%
(6/8) upgrading util-linux                                                                                                                    [######################################################################################] 100%
(7/8) upgrading mkinitcpio                                                                                                                    [######################################################################################] 100%
(8/8) upgrading linux-armv7                                                                                                                   [######################################################################################] 100%
>>> Updating module dependencies. Please wait ...
:: Running post-transaction hooks...
(1/1) Updating the info directory file...

Compiling native applications

This can be a little tricky at times but is very fun when you get something running.

For best results look for a program using pure SDL2 for video/input handling (Bonus points if it uses the CMake compiling system). External libs are possible (you have to compile them, copy over the include files to the rootfs directory, and then when you package up a program include the .so files to use in an LD_PRELOAD)

Starting out is fairly straight forward

git clone https://github.com/ValveSoftware/steamlink-sdk
cd steamlink-sdk/examples

From here you can check out the included example applications and their respective build scripts. If we want to experiment with our own:

git clone somesource
cd somesource

First I'll cover a CMake project because these provide the best results (because of the included toolchain definition file)

source ../../setenv.sh
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../../../toolchain/steamlink-toolchain.cmake ../

If all goes well it should find any needed libraries and create the Makefile for you. (If it needs any other external libraries a quick rundown is to repeat the same steps as above to grab the source, hope it compiles, and copy over the include files to the rootfs/usr/include directory in the steamlink-sdk repo folder. This isn't guaranteed to work so your mileage may vary.)

Then you just compile it.

make -j4

For regular source installations (typical automake/Makefile) it can be a hit or miss whether compilation will work or not. The gist of it is:

./automake #If needed
./configure --host=armv7a-cros-linux-gnueabi #and any other needed arguments
make -j4 #and pray...

Once you end up with a compiled binary, you can scp it over to the Link and try to run it. If you had to compile any external libs (.so) be sure to include them in the transfer and use LD_PRELOAD=./ ./binaryname to test.

If everything went ok and the binary runs as expected and you are happy with the results, packaging it up for a USB install is dead simple

Create a folder named whatever you want (I typically use the program name all lowercase), and create these files in said folder as follows.

toc.txt
    name=Whatever # This is what shows in the launcher
    icon=whatever-icon.png 
    run=binary # Or a script name if you need to LD_PRELOAD. Just make sure the binary/script are executable for this line to work

whatever-icon.png # I haven't found exact specifications for this but I typically do a 128x128 icon

binary # Main program

binary-launch.sh # Only needed if you want to preload/pass special arguments
    #!/bin/sh
    LD_PRELOAD=./ ./binary

And any data files needed for it to run

Next just back up a directory and tar up the folder

tar zcvf programname.tgz foldername 

Now if you want to install this on the Link just copy that tgz to a flash drive at USB:/steamlink/apps/ and boot the Link with the drive plugged in. It will extract it and then boot to the launcher.