The final step in getting a Linux distro is to build our root filesystem on a USB flash drive.
- Format flash drive as ext2/ext3/ext4
- Dump Ubuntu rootfs on to the flash drive
- Minor configuration
- Rebuild Linux kernel with new options
The first thing we will want to be doing is formatting a flash drive to a Linux partition type. I am going to be using an ext3 partition on a 64GB USB 3.0 flash drive. I'd recommend at least an 8GB flash drive, anything smaller may have issues with fitting everything on to it.
Once you're done flashing your drive you'll need to download an Ubuntu Core image for AArch64/ARM64/ARMv8.
Download the Ubuntu Core 14.04.1 image*Here
. Make sure to grab the 'arm64' tar.gz file, not the 'amd64' file.
Once you have the flash drive formatted and mounted, extract the ubuntu core image to the flash drive.
Configuring the Ubuntu Core image for the Nexus 9
sudo tar zxf ubuntu-core-14.04.1-core-arm64.tar.gz -C Mount/
- Terminal over UART configuration
- DNS configuration
- Firmware files
- Add user
In order to properly get a terminal instance over the UART we have to add a package to the base Ubuntu core image.
This is a small package that all it does is open a new terminal instance over the configured getty instance. The package can be found*Here
To install it to the root filesystem just unpack it to the root filesystem on the USB flash drive
sudo tar xf console.tar -C Mount/
We need to set up a DNS server so that the filesystem will be able to resolve addresses via DNS.
Let's just set it to Google's DNS.
sudo echo 'nameserver 18.104.22.168' >> Mount/etc/resolv.conf
We've got to grab the firmware files from the Nexus 9 in order for the device to stop spamming warnings at us in the console.
These are used for multiple things, so it is a good idea to grab them. You can grab these either from a factory image or directly from the Nexus 9. I chose to grab mine directly from the Nexus 9.
sudo mkdir Mount/lib/firmware
sudo mkdir Mount/etc/wifi
sudo adb pull /vendor/firmware Mount/lib/firmware/
sudo adb pull /system/etc/wifi/bcmdhd.cal Mount/etc/wifi/
We need to add a user to the root filesystem. This is a fairly annoying step because we actually need to chroot in to the filesystem.
There is a really nice guide to doing this on a ARMv7 filesystem*Here
. This won't work for our system because we are working with ARMv8 instead.
So we are going to use that guide as a base but change it over to support what we need to do for AArch64.
First thing we've got to do is build qemu as a static binary for AArch64
This is fairly straight forward.
git clone git://git.qemu-project.org/qemu.git
sudo apt-get build-dep qemu
./configure --target-list=aarch64-linux-user *--static --disable-werror
This will get us a binary in the aarch64-linux-user folder called 'qemu-aarch64'
We will need to rename this to 'qemu-arm64-static' and move it in to the '/usr/bin/' folder inside of our root partition
Once qemu is inside of the root partition, we will be able to chroot in to it and add our user.
So go in to the root directory of our filesystem we are generating, and run a few basic commands.
Set up some mounts inside of the chroot
for m in `echo 'sys dev proc'`; do sudo mount /$m ./$m -o bind; done
*Chroot in to the root filesystem
sudo LC_ALL=C chroot . /bin/bash
Now we are inside of the root filesystem, we can add the new user to it.
Let's just add a new user named 'ubuntu'. The first command will ask for a password for your user. The rest will add it to some default groups to make sure it can do things.
addgroup ubuntu adm
addgroup ubuntu sudo
Once the user is added you can exit the root filesystem with a regular exit command, then we have to make sure to unmount all of the mounts we did prior to chrooting in to the filesystem.
for m in `echo 'sys dev proc'`; do sudo umount ./$m; done
Make sure to cleanly unmount the flash drive so everything is written to it.
Reconfigure the kernel to boot from flash drive instead of initramfs
*Go in to the kernel configuration
Change the configuration to remove the initramfs
General Setup->Initial RAM filesystem and RAM disk (initramfs/initrd) support (Disable it)
Then exit the menu and rebuild the kernel
Running the Ubuntu Core Image
So with the device sitting at the bootloader we will need to boot the new kernel
fastboot -c "fbcon=rotate:1 root=/dev/sda1 rootwait rw" boot arch/arm64/boot/Image.gz-dtb
This will boot the kernel and then it'll wait until you plug in the flash drive to continue booting.
So plug the USB hub in to the USB OTG cable. Then plug your USB flash drive and USB keyboard in to the USB hub.
After that plug the USB OTG cable in to the tablet and it will continue booting.
Give it roughly 20-60 seconds and it will show a login prompt on the devices screen.
You'll be able to login to the core image with the user you created earlier.
With some packages installed like the xubuntu-desktop environment you can have a full desktop available.