Running Nix on a Jailbroken Kindle

Collin Dewey

05/14/2025



Fastfetch running through Nix on a jailbroken Amazon Kindle

Kindle

The Amazon Kindle is an e-reader, meant for e-reading purposes. I’ve loved getting to read books, textbooks, and papers on it. Much easier on my eyes. It’s also a good way to have a distraction-free environment where I don’t have a good way to get sidetracked. Let’s ruin that by jailbreaking it and installing software.


Jailbreak

To get more out of your Kindle, you’ll want to jailbreak it. This lets you install and run non-Amazon software. If you’re interested, there’s an available jailbreak at the Kindle Modding Wiki.

One of the nicest tools to install is KOReader, an ebook reading software. It also supports starting an SSH server, which can make setup easier. You’ll also want to install Kterm so you can use a terminal on the Kindle itself.


What does Nix offer you?

Nix can be used as a package manager, allowing us to install up-to-date software on the Kindle without trampling over old libraries or accidently bricking the Kindle’s operating system. It also lets us easily cross compile lots of software, since the Kindle isn’t made to be a compilation power-house.


TL;DR How do I install it? How do I install software?

Run the kindle-nix-installer.sh script from my GitHub on your Kindle, either through Kterm or through SSH. Here’s the command.

curl -fsSLO https://github.com/CollinDewey/kindle-nix/releases/latest/download/kindle-nix-installer.sh && bash kindle-nix-installer.sh && rm kindle-nix-installer.sh

To install software, on a computer with Nix installed, add this as a shell alias

alias kindle-send='f(){ p=nixpkgs#pkgsCross.armv7l-hf-multiplatform.$2 && nix build $p && for c in $(nix path-info $p); do nix-copy-closure --to $1 $c && ssh $1 "nix-env -i $c"; done; }; f'

and send over software like

kindle-send root@<KINDLE_IP> htop

How does this work?

The regular Nix installer will fail on the Kindle due to missing features in bash and user management tools. So let’s install it ourselves.

Preparing files to transfer over

The Kindle’s processor architecture is not one with a lot of support - armv7l-hf. Because of this, we need to cross compile the packages to be installed over onto the Kindle, including Nix itself and it’s dependencies.

# Compiles Nix for the armv7l-hf architecture
nix build nixpkgs#pkgsCross.armv7l-hf-multiplatform.nixVersions.latest

This will give us a folder called result that has the files for the latest Nix on armv7l. However, it does not have all of the dependencies, you can see that list if you query the Nix store for that.

nix-store --query --requisites result

Which gives you an output of the many files that need to be copied over.

/nix/store/g1y29dris8086r03fbpx4yb9p9icv1yf-glibc-armv7l-unknown-linux-gnueabihf-2.40-66
/nix/store/29mvl137lnza2kkv177w8394r0da50jh-armv7l-unknown-linux-gnueabihf-gcc-14.2.1.20250322-lib
/nix/store/q982119q5fdcmja5idjg5fnw9xbjh3cv-bzip2-armv7l-unknown-linux-gnueabihf-1.0.8
/nix/store/zf0v7yc6nrjdjrk317mf4dj6qygkj4md-zlib-armv7l-unknown-linux-gnueabihf-1.3.1
/nix/store/kzrykpkyyrb500blfrniz41i46x26diy-aws-sdk-cpp-armv7l-unknown-linux-gnueabihf-1.11.448
/nix/store/vijan3j8kyw12n7x3nn1sg3zp1p187zv-sqlite-armv7l-unknown-linux-gnueabihf-3.48.0
/nix/store/yvqsjp82nc56zrd8xm1im2lk68hk5jvf-editline-armv7l-unknown-linux-gnueabihf-1.17.1
/nix/store/480ql4g8prnq39lvbw4x9nm7ajpq1avp-nix-armv7l-unknown-linux-gnueabihf-2.28.3

All of these folders need to be placed into a tarball to be sent over and extracted on the Kindle itself once the Nix store is ready.

Internal Storage

The Kindle’s internal storage is setup rather strangely. There is a small root partition with the operating system, and a bigger partition for userdata (/mnt/base-us/), which is formatted as FAT32. FAT32 comes with some annoying restrictions, such as a filesize limit of 4GB and lacking symbolic links. This partition is also mounted with the noexec option, requiring a remount to be able to execute applications. Since there isn’t enough space to store the Nix store elsewhere, we need to store it in this userdata partition. While we still have the limit of 4GB, we can create a file, format it as ext4, and mount that, getting past some of the FAT32 restrictions.

# Create folders for disk location and mountpoint, create the disk, mount it
mkdir -p /mnt/base-us/system/nix /nix
fallocate -l 4095M /mnt/base-us/system/nix/nix.ext4
mkfs.ext4 /mnt/base-us/system/nix/nix.ext4
mount -o loop -t ext4 /mnt/base-us/system/nix/nix.ext4 /nix

Automounting /nix

Different Linux distributions use different init systems. The init system is one of the first things run by the Linux kernel and is generally in charge of mounting desired filesystem and starting services. The Kindle uses upstart for it’s init manager. Upstart was created for Ubuntu in 2006, and replaced by systemd in 2014. So using upstart is a rather weird choice. The upstart configuration files are placed in /etc/upstart. We want to mount the filesystem after the userstore is mounted, and unmount it when the system is shutting down.

/etc/upstart/nix-daemon.conf

start on started filesystems_userstore
stop on stopping filesystems

pre-start script
    mount -o loop -t ext4 /mnt/base-us/system/nix/nix.ext4 /nix
end script

script
    /bin/nix daemon
end script

post-stop script
    umount /nix
end script

Setting up the Nix store

After we have the store mounted, we need to set the permissions and extract the files needed to go in the store for the nix binary.

# Creates folders and sets permissions, extracts store.tar
install -dv -m 0755 /nix /nix/var /nix/var/log /nix/var/log/nix /nix/var/log/nix/drvs /nix/var/nix{,/db,/gcroots,/profiles,/temproots,/userpool,/daemon-socket} /nix/var/nix/{gcroots,profiles}/per-user
install -dv -m 0555 /etc/nix
install -dv -m 1775 /nix/store
tar -xf ./store.tar -C /

Nix configuation

Nix by default wants a bunch of users to be created for it to use as build users, but modern Nix has an experimental feature called “auto-allocate-uids”, which will create users when needed. I had to give it a group to use, so I just picked one.

/etc/nix/nix.conf

extra-experimental-features = nix-command flakes auto-allocate-uids
auto-allocate-uids = true
build-users-group = javausers

Putting Nix in the right spot

Now that we have Nix setup, we need to put it in the right place to invoke it. We can just create a link to where Nix is from /bin/nix, and then all of the other variants of nix-something to /bin/nix.

ln -sf /nix/store/XXXXXXXXXXX-nix-armv7l-unknown-linux-gnueabihf-2.28.3/bin/nix /bin/nix
ln -sf /bin/nix /bin/nix-build
ln -sf /bin/nix /bin/nix-channel
ln -sf /bin/nix /bin/nix-collect-garbage
ln -sf /bin/nix /bin/nix-copy-closure
ln -sf /bin/nix /bin/nix-daemon
ln -sf /bin/nix /bin/nix-env
ln -sf /bin/nix /bin/nix-hash
ln -sf /bin/nix /bin/nix-instantiate
ln -sf /bin/nix /bin/nix-prefetch-url
ln -sf /bin/nix /bin/nix-shell
ln -sf /bin/nix /bin/nix-store

And to stop Nix from garbage collecting itself when nix-collect-garbage is run, let Nix know to keep itself around.

nix-env -i /nix/store/XXXXXXXXXXX-nix-armv7l-unknown-linux-gnueabihf-2.28.3

Installing other applications

Nix has a binary cache for the populat platforms aarch64 and x86_64. This is not the case for armv7l, so software will need to be compiled from source. Nix makes this very easy to do, but the Kindle is lacking a little bit in power and RAM. So to compile software, we can do it on a computer similar to how we compiled Nix itself earlier. For example, let’s install htop. First we need to compile it on our stronger machine, transfer over the files over SSH, and then install the package with nix-env to make it available to run.

# Build the application, get the full path of the package, and send it over
nix build nixpkgs#pkgsCross.armv7l-hf-multiplatform.htop

# You can see the path using path-info
nix path-info nixpkgs#pkgsCross.armv7l-hf-multiplatform.htop
nix-copy-closure --to root@<KINDLE_IP> <THE_PATH_FROM_PATH_INFO>

Then SSH into the Kindle and install it with nix-env

nix-env -i <THE_PATH_FROM_PATH_INFO>

But we still can’t run the application when typing in htop.

Using Nix-installed applications

To use applications we’re installing with Nix, we need to add a snippet to the shell profile to set all of the proper shell variables. The default shell is Busybox’s version of ash, which doesn’t look in /etc/profile.d by default, so we need to edit /etc/profile instead, just adding this to the end.

/etc/profile

# Put Nix stuff in the PATH
if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then
    . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'
fi

Start a new shell and now you’re ready to use your newly installed applications.

For some reason Kterm seems to not source /etc/profile. You can fix this by just running

. /etc/profile

Every time you start the shell.

Uninstalling Nix

Remove the part in /etc/profile, remove the upstart config, unmount /nix and delete the virtual drive.

Automating all of this

I used a tool called makeself to pack all of the files into one file which you can just run on the Kindle which includes all of the files you need. It’s similar to one of those self-extracting archive Windows software installers. It goes through the process of preparing all of the files to be put in the Nix store, and to pack all of the scripts. The files get extracted into /mnt/base-us/system/nix-installer, which includes an uninstaller script if you wish to use that. Check it out on my GitHub at CollinDewey/kindle-nix.