This guide will help installing the InkBox open-source operating system on the Kobo Clara HD (N249).
- 1 Compiling the bootloader
- 2 Building the rootfs
- 3 Building the kernel
- 4 Signing overlaymount-rootfs
- 5 Creating the boot script image
- 6 Installing InkBox
- 7 Post-install
Start by creating a new home directory for the build process and cloning the InkBox repository in it.
sudo mkdir -p /home/build/inkbox/kernel
sudo chown -R "$USER:$(id -gn)" /home/build
git clone [email protected]:Kobo-InkBox/kernel.git /home/build/inkbox/kernel
Note: the
/home/build/inkbox
path is hardcoded in the make process, avoid changing it.
cd /home/build/inkbox/kernel
env TOOLCHAINDIR=$PWD/toolchain/arm-kobo-linux-gnueabihf TARGET=arm-kobo-linux-gnueabihf THREADS=$(($(nproc)*2)) scripts/build_u-boot.sh n249
You should see the built bootloader in bootloader/out/u-boot_inkbox.n249.imx
.
Get the rootfs, but clone it as root to avoid permissions problems later on the Kobo, then build it.
cd /home/build/inkbox
sudo git clone https://github.com/Kobo-InkBox/rootfs
cd rootfs
sudo env GITDIR=$PWD ./release.sh
Create your RSA key pair and sign the rootfs with your private key.
cd /home/build/inkbox
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -out public.pem -outform PEM -pubout
openssl dgst -sha256 -sign private.pem -out rootfs.squashfs.dgst rootfs.squashfs
First, we need to put our public RSA key in a trusted kernel space, then compile the kernel image.
The key is located inside a squashfs, we need to unsquash it, update the key and put it back in place.
cd /home/build/inkbox
sudo unsquashfs kernel/initrd/n249/opt/key.sqsh
cp public.pem squashfs_root
mksquashfs squashfs-root kernel/initrd/n249/opt/key.sqsh -noappend
Note: unsquashing with
sudo
is required to preserve x-attrs.
Note: don't
mv
yourpublic.pem
file to the unsquashed directory, otherwise file ownership will be ovewritten.
You can now check if the squashfs contains your public.pem
by mounting it.
sudo mount -t squashfs kernel/initrd/n249/opt/key.sqsh /mnt
Before compiling the kernel, a specific initrd
is needed. Let's clone it and compile it.
git clone [email protected]:Kobo-InkBox/inkbox-os-init.git /home/build/inkbox/os-init
cd /home/build/inkbox/os-init
/home/build/inkbox/kernel/toolchain/armv7l-linux-musleabihf-cross/bin/armv7l-linux-musleabihf-gcc init.c -o init -static -D_GNU_SOURCE
/home/build/inkbox/kernel/toolchain/armv7l-linux-musleabihf-cross/bin/armv7l-linux-musleabihf-strip init
Then we'll overwrite the original init
file with the compilation output.
cp /home/build/inkbox/os-init/init /home/build/inkbox/kernel/initrd/common/init
To compile the kernel, just move to the kernel directory and run the build script as follows.
cd /home/build/inkbox/kernel
env GITDIR=$PWD TOOLCHAINDIR=$PWD/toolchain/armv7l-linux-musleabihf-cross/ THREADS=$(($(nproc)*2)) TARGET=armv7l-linux-musleabihf scripts/build_kernel.sh n249 root
You should see the built kernel in kernel/out/n249/zImage-root
.
InkBox has a reproducible image builder. Download it and sign the overlaymount-rootfs.squashfs
file using your private key.
cd /home/build/inkbox
git clone [email protected]:Kobo-InkBox/imgtool.git
openssl dgst -sha256 -sign private.pem -out imgtool/sd/overlaymount-rootfs.squashfs.dgst imgtool/sd/overlaymount-rootfs.squashfs
Create the boot.scr
U-Boot image to automate the execution of the uboot-script.sh
script.
mkimage -A arm -O linux -T script -n postmarketOS -d uboot-script.sh boot.scr
Perform a backup, we will start from the bootloader.
Write the bootloader on the whole device.
dd if=bootloader/out/u-boot_inkbox.n249.imx of=/dev/<microsd> bs=1K seek=1
Create an environment u-boot-env.txt
for the bootloader.
mkenvimage -p 0 -s 8192 -o u-boot-env.bin u-boot-env.txt
dd if=u-boot-env.bin of=/dev/<microsd> bs=4096 seek=192
Run the partition script as follows.
sudo sfdisk /dev/<microsd> < partition-script.txt
You can check the partition table by running sudo fdisk -l /dev/<microsd>
, it should have the same structure as below.
Device Boot Start End Sectors Size Id Type
/dev/<microsd>1 49152 79871 30720 15M 83 Linux
/dev/<microsd>2 104448 1128447 1024000 500M 83 Linux
/dev/<microsd>3 1128448 1390591 262144 128M 83 Linux
/dev/<microsd>4 1390592 8388607 6998016 3.3G 83 Linux
Note: the last partition may be larger or smaller depending on the microSD card size.
Format the four partitions in ext4.
for partition in 1 2 3 4; do sudo mkfs.ext4 /dev/<microsd>${partition}; done
Mount the third partition and copy the signed rootfs and overlaymount-rootfs to it.
mount /dev/<microsd>3 /mnt
cp rootfs.squashfs* /mnt
cp imgtool/sd/overlaymount-rootfs.squashfs* /mnt
Unmount the third partition, mount the second partition and copy the overlaymount-rootfs to it.
mount /dev/<microsd>2 /mnt
cp imgtool/sd/overlaymount-rootfs.squashfs* /mnt
Unmount the second partition, mount the first partition and copy the DTB, the zImage and the boot script to it.
mount /dev/<microsd>1 /mnt
cp kernel/kernel/out/n249/zImage-root /mnt
cp kernel/kernel/linux-5.16-n249/arch/arm/boot/dts/imx6sll-kobo-clarahd.dtb /mnt
cp boot.scr /mnt
Write the Root kernel flag to a specific sector of the microSD card, which will allow us to interface with the device via USBNet, SSH, etc. and have root access.
printf "rooted\n" | sudo dd of=/dev/<microsd> bs=512 seek=79872
Unmount the microSD from your computer, put it inside the e-reader, establish a serial connection and boot the device.