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.
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.
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):
- Power the Dot with the Action button held while plugging in — wait for a green LED (Amazon's factory fastboot mode).
./fastbrick.sh, confirm the detected device, typeYES.- 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.
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 slotsFlash 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.zipIts 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.
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 rebootTECHO5 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).
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 powershellinstall-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.staticmkimage.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.gzAnd 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-dotFour independent fixes, all in tools/install-dot.ps1:
-
Path separators. Several
Join-Pathcalls use a literal'tools\linux\...'style string.Join-Pathdoes not treat\as a separator on Linux, so these silently resolved to broken, literal filenames. Changed every internaltools\linux\...reference totools/linux/..., and the$SshKeydefault's'.ssh\id_ed25519.pub'to'.ssh/id_ed25519.pub'. -
Binary-safe partition backup. The per-partition backup step used
Start-Process -RedirectStandardOutputto captureadb exec-out cat <partition>. On PowerShell Core this redirection reads the child process's stdout as text, which corrupts arbitrary binary data (confirmed: thepreloaderpartition'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 aSystem.Diagnostics.Process+StandardOutput.BaseStream.CopyTo(...)raw byte copy, which is binary-safe cross-platform. -
Optional prebuilt rootfs. Added a
-PrebuiltRootfs <path>parameter. When given, the installer copies that file to the expected rootfs path instead of invokingmkrootfs.py, so a signed release tarball can be used directly instead of rebuilding an equivalent one from parts. -
Linux serial console lookup.
Find-LinuxPortusedGet-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 viaudevadm info -q property, applying the same matching logic (serial match, or the lone device if it reports the old placeholder serial).System.IO.Ports.SerialPortitself (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.
./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 python3Confirm 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.
Wow! That's a great write up for the install. I'm glad it worked for you!