Skip to content

Instantly share code, notes, and snippets.

@proffalken
Created September 17, 2026 10:48
Show Gist options
  • Select an option

  • Save proffalken/377ae50146affe1886dddaaacb87926b to your computer and use it in GitHub Desktop.

Select an option

Save proffalken/377ae50146affe1886dddaaacb87926b to your computer and use it in GitHub Desktop.
Install Techno5-dot via Linux

Installing TECHO5 Dot from Linux

This documents a working end-to-end path from a stock Amazon Echo Dot 2nd generation ("biscuit") to TECHO5 Dot, done entirely from a Linux PC (Linux Mint 22.2 / Ubuntu 24.04 base, no Windows or WSL involved). tools/install-dot.ps1 is written for Windows; the changes needed to run it on Linux are described at the end, alongside the unlock steps that get a stock unit to the installer's starting point.

1. Identify the hardware

Confirm the unit is a 2nd-gen Echo Dot ("biscuit", model AEOBC, MediaTek MT8163) before using any of this — TECHO5 Dot and its unlock tooling target this generation specifically.

2. Unlock the bootloader (amonet, no disassembly needed)

TECHO5 Dot's own prerequisite is a unit "already unlocked with amonet and sitting in TWRP, or running Fire OS 6 with root adb". Unlocking is amonet's job, not this project's:

  • amonet: https://github.com/R0rt1z2/amonet (branch mt8163-biscuit)
  • Community guide: XDA thread "[UNLOCK][ROOT][TWRP][UNBRICK] Amazon Echo Dot 2nd Gen / 2016 (biscuit)"

The no-disassembly path (fastbrick.sh, from the release ZIP attached to that XDA thread, not the bare git repo):

  1. Power the Dot with the Action button held while plugging in — wait for a green LED (Amazon's factory fastboot mode).
  2. ./fastbrick.sh, confirm the detected device, type YES.
  3. A successful run reports Exploit most likely successful!, then the device reboots into TWRP (white LED). Do not interrupt this.

Recovery re-entry after this point (needed throughout the rest of the process): unplug power, hold Volume Up, reapply power, wait for white LED.

3. Flash Fire OS 6 (the exact build TECHO5 Dot was tested against)

Get Fire OS 6574.1 for biscuit (NS6574, build 7623, version code 13121734532) — this is the build TECHO5 Dot's own bench unit ran. A newer build works for the unlock and boot-root steps but its live filesystem's SELinux policy isn't in boot-root.zip's bundled policy database, which manifested as a boot loop; downgrading to this exact build fixed it (boot-root.zip's install log should complete with no SELinux warning as the confirmation).

From TWRP, with the file pushed to the device:

adb shell twrp wipe cache
adb shell twrp wipe data
adb push update-kindle-biscuit_puffin-NS6574_user_7623_0013121734532.bin /sdcard/update.zip
adb shell twrp install /sdcard/update.zip
adb reboot recovery                      # switches to the other A/B slot
adb shell twrp install /sdcard/update.zip # flash the same build again, for both slots

4. Root (boot-root.zip)

Flash the boot-root.zip attached to the same XDA thread, the same way:

adb push boot-root.zip /sdcard/
adb shell twrp install /sdcard/boot-root.zip

Its log should end cleanly (SELinux, adbd, fstab and OTA all patched, no "no selinux policy bundled" warning) — that warning is the signal of a Fire OS build mismatch; if it appears, use the exact build in step 3 instead.

5. Trust adb's key for a normal (non-TWRP) boot

Rooted Fire OS still requires the standard Android adb RSA key authorization, which normally means tapping "Allow" on an on-screen prompt — impossible on a screen-less device. The fix, done once from TWRP before the first normal boot:

adb push ~/.android/adbkey.pub /sdcard/adbkey.pub
adb shell "mkdir -p /data/misc/adb && cp /sdcard/adbkey.pub /data/misc/adb/adb_keys && \
  chown 1000:2000 /data/misc/adb/adb_keys && chmod 640 /data/misc/adb/adb_keys"

A file created this way through TWRP is mislabeled for SELinux (system_data_file instead of adb_keys_file), which silently blocks adbd from trusting it once Fire OS boots normally (adb devices shows unauthorized even though the key file is correct). Fix the label before rebooting:

adb shell restorecon -v /data/misc/adb/adb_keys
adb reboot

6. Join Wi-Fi once under Fire OS

TECHO5 Dot's installer reads Wi-Fi credentials Fire OS already saved; it needs the Dot joined to a network at least once. Complete the Alexa app's Wi-Fi step (declining/skipping further Alexa account setup is fine — boot-root.zip already disabled OTA updates, so this doesn't risk an update overwriting root).

7. Set up the Linux PC toolchain

Install PowerShell Core, adb, Python 3 and git. On a distro whose /etc/os-release doesn't match Microsoft's package list exactly (e.g. Linux Mint reports its own VERSION_ID), use the underlying Ubuntu version instead of trusting $VERSION_ID (check UBUNTU_CODENAME in /etc/os-release):

wget -q https://packages.microsoft.com/config/ubuntu/24.04/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get update && sudo apt-get install -y powershell

8. Get the build inputs — from the published release, not from source

install-dot.ps1 normally builds the root filesystem from source (the daemon, wmtup, btbridge, bluez-alsa, and an assembled Alpine rootfs). All of that is already built and published as a signed release asset, so it's simpler and just as legitimate to use it directly:

gh release download <latest-tag> --repo HuskerMinion/techo5-dot \
  --pattern "manifest.json" --pattern "techo5-dot-rootfs.tar.gz"

Extract the individual binaries the boot image (not the rootfs) still needs from that tarball — mkimage.py, which builds the per-unit boot image, needs wmtup and busybox.static regardless of whether the rootfs itself is prebuilt or not:

tar -xzf techo5-dot-rootfs.tar.gz -O usr/local/bin/wmtup    > wmtup
tar -xzf techo5-dot-rootfs.tar.gz -O usr/local/bin/echod    > echod-dot
tar -xzf techo5-dot-rootfs.tar.gz -O usr/local/bin/btbridge > btbridge
tar -xzf techo5-dot-rootfs.tar.gz -O usr/bin/bluealsa        > bluealsa
tar -xzf techo5-dot-rootfs.tar.gz -O bin/busybox.static      > busybox.static
chmod +x wmtup echod-dot btbridge bluealsa busybox.static

mkimage.py (boot image) also needs the Alpine armv7 minirootfs as a base, independent of the main rootfs:

wget -q https://dl-cdn.alpinelinux.org/alpine/v3.24/releases/armv7/alpine-minirootfs-3.24.1-armv7.tar.gz

And two empty directories, so the installer's (unused, in this path) apk-scanning code doesn't error under its strict error mode:

mkdir -p apks-dot apks-bt-dot

9. Patch install-dot.ps1 for Linux

Four independent fixes, all in tools/install-dot.ps1:

  1. Path separators. Several Join-Path calls use a literal 'tools\linux\...' style string. Join-Path does not treat \ as a separator on Linux, so these silently resolved to broken, literal filenames. Changed every internal tools\linux\... reference to tools/linux/..., and the $SshKey default's '.ssh\id_ed25519.pub' to '.ssh/id_ed25519.pub'.

  2. Binary-safe partition backup. The per-partition backup step used Start-Process -RedirectStandardOutput to capture adb exec-out cat <partition>. On PowerShell Core this redirection reads the child process's stdout as text, which corrupts arbitrary binary data (confirmed: the preloader partition's backup came out with the wrong md5 every time, while a plain shell > redirect of the exact same read matched the device perfectly). Replaced it with a System.Diagnostics.Process + StandardOutput.BaseStream.CopyTo(...) raw byte copy, which is binary-safe cross-platform.

  3. Optional prebuilt rootfs. Added a -PrebuiltRootfs <path> parameter. When given, the installer copies that file to the expected rootfs path instead of invoking mkrootfs.py, so a signed release tarball can be used directly instead of rebuilding an equivalent one from parts.

  4. Linux serial console lookup. Find-LinuxPort used Get-CimInstance Win32_PnPEntity (Windows CIM/WMI) to find the Windows COM port assigned to the device's post-reboot USB serial console, matched by USB serial number. Replaced with a Linux-native version that globs /dev/ttyACM* and reads each one's USB vendor/product/serial via udevadm info -q property, applying the same matching logic (serial match, or the lone device if it reports the old placeholder serial). System.IO.Ports.SerialPort itself (used afterwards to talk to the console) works unmodified on PowerShell Core/Linux once given a /dev/ttyACM* path instead of a COM port name.

10. Run it

./tools/install-dot.ps1 -Serial <adb serial> -DryRun \
  -BackupRoot  <path>/backups \
  -Inputs      <path>/inputs \
  -Daemon      <path>/build/echod-dot \
  -Wmtup       <path>/build/wmtup \
  -Btbridge    <path>/build/btbridge \
  -Bluealsa    <path>/build/bluealsa \
  -PrebuiltRootfs <path>/techo5-dot-rootfs.tar.gz \
  -Python python3

Confirm the dry run completes cleanly (all partitions backed up and md5-verified, boot image and rootfs sizes printed, no errors), then drop -DryRun and add -Name "<whatever you want to call it>" for the real install. It backs up every boot-critical partition, builds the per-unit boot image from the unit's own recovery backup, writes it to recovery, unpacks the rootfs into slot a, reboots, and waits on the unit's USB serial console until it reports healthy.

@HuskerMinion

Copy link
Copy Markdown

Wow! That's a great write up for the install. I'm glad it worked for you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment