Build

How to build the stick image from source. If you already have the image, go to Install.

What you need

  • A copy of the tvOS 16.5 OTA for AppleTV6,2 (20L563).
  • A build machine with Linux, python3, hfsprogs (mkfs.hfsplus, fsck.hfsplus), Theos ($THEOS, for its toolchain and ldid), and what hakios/ needs to build the kernel (make doctor there).

Build steps

1. The kernel and the loader

cd hakios && make kernel
cd .. && twloader/build.sh

2. The tvOS system volume

From the unpacked OTA (AssetData/payloadv2/payload.000 ...):

python3 tools/ota-yaa.py work/tvos/rootfs AssetData/payloadv2/payload.0*
mv work/tvos/rootfs/.manifest work/tvos/ota.manifest
python3 tools/tvos-meta.py work/tvos/ota.manifest work/tvos
python3 hakios/tools/apfs/mkapfs.py -z -o out/tvos-system.apfs \
    System=work/tvos/rootfs,manifest=work/tvos/system.manifest

3. The Wi-Fi and Bluetooth chip's firmware

From the chip's firmware file, wifi_w2_fw_usb.bin:

python3 tools/w2-fw.py wifi_w2_fw_usb.bin work/w2fw/bin

4. The stick

Either an image file to write with dd or any imaging tool, or the stick itself. Everything on the stick is lost.

An 8 GB image file, out/twilight-usb.img:

tools/twl-release.sh

A bigger /private/var:

SIZE=16G tools/twl-release.sh

Straight onto the stick. It must be removable and not mounted:

sudo tools/twl-release.sh /dev/sdX

Options

Set these as environment variables.

NETWORK=file
Join a Wi-Fi network at the start: its name on the first line of the file, its passphrase on the second. Without it, choose the network in Settings.
SSH=1
sshd for root with your public key (SSH_KEY, default ~/.ssh/id_ed25519.pub) and the package manager's prefix /var/jb. Run tools/twl-jb.sh first.
ARGS="..."
More boot arguments.

The stick

Partition 1: FAT32, 256 MB
aml_autoscript, cfgload and twl.img: the loader, the kernel and the small root image. U-Boot reads this one.
Partition 2: APFS
The tvOS system volume, read-only.
Partition 3: HFS+, journaled, case-sensitive
/private/var: settings, apps and their data.

To update, write a new twl.img to partition 1. Building the stick again also works, but that erases /private/var.