The first thing to consider is how the tablet stores and boots Android currently. I'll need to work with the standard bootloader that comes with the tablet, to reduce the chances of bricking the device completely. Whatever OS I choose to load on the tablet will need to be presented to the bootloader in the way it expects.
Factory Images
I'll start with Google's own Android factory images. Specifically, the KTU84P image. Unpacking the tarball, and further unzipping the zip file it contains, yields the following image files:
boot.img recovery.img system.img userdata.img cache.imgThese correspond to partitions on the device, which have been labelled in a way that the bootloader understands. With the fastboot tool, we're able to pass these image files to the bootloader on the device over USB, which can then unpack them and flash them to the identified partitions. Cool! Except that, this only works if the image files are in the format that bootloader expects.
The boot.img file is of particular interest, since this is the image file that is actually booted by the bootloader. We don't even have to flash the image file to boot it, fastboot allows us to download the image file to the device for a one-time boot:
$ fastboot boot boot.imgThe system.img file contains the contents of the Android system partition (mounted under /system on a running Android device), and the userdata.img file contains the contents of the user data partition (mounted under /data). Whilst it should be possible to split a new OS into this same system/data arrangement, I'm not going to explore that for now. So, I'm interested in which of these partitions is the larger. A simple task with adb shell:
shell@flo:/ $ df Filesystem Size Used Free Blksize /dev 902.9M 128.0K 902.8M 4096 /sys/fs/cgroup 902.9M 12.0K 902.9M 4096 /mnt/asec 902.9M 0.0K 902.9M 4096 /mnt/obb 902.9M 0.0K 902.9M 4096 /system 827.8M 719.3M 108.5M 4096 /cache 551.7M 9.9M 541.8M 4096 /data 11.9G 1.1G 10.9G 4096 /persist 14.5M 4.2M 10.2M 4096 /mnt/shell/emulated 11.9G 1.1G 10.9G 4096Yes, the 11.9GB user data partition seems like the best bet. So as well as boot.img, I'm also interested in userdata.img.
The Boot Image
So, how is the boot image file structured? This is documented in platform/system/core/mkbootimg/bootimg.h in the Android AOSP sources. The image contains a boot header, a Linux kernel image, a ramdisk image and an optional second stage. Amongst other things, the boot header contains the command line passed to the kernel on boot, which means that this can be configured from the boot image file.
OK, so how do we build the boot image file? Unsurprisingly, it is the mkbootimg tool in the AOSP which does this job. But it takes quite a few parameters, for which appropriate values are not entirely obvious. It would be good to determine the parameters that were passed to mkbootimg to construct the boot.img file provided in the KTU84P factory image. Happily, unmkbootimg is a tool (written by Pete Batard) which is able to do exactly this. Both unmkbootimg and a fixed up version of mkbootimg can be retrieved from Pete's bootimg-tools GitHub repository and built as follows:
$ git clone https://github.com/pbatard/bootimg-tools.git $ cd bootimg $ make $ cp mkbootimg/{mkbootimg,unmkbootimg} ~/binThen, turning unmkbootimg on the boot.img from the KTU84P factory image:
$ unmkbootimg -i boot.img kernel written to 'kernel' (6722240 bytes) ramdisk written to 'ramdisk.cpio.gz' (492556 bytes) To rebuild this boot image, you can use the command: mkbootimg --base 0 --pagesize 2048 --kernel_offset 0x80208000 --ramdisk_offset 0x82200000 --second_offset 0x81100000 --tags_offset 0x80200100 --cmdline 'console=ttyHSL0,115200,n8 androidboot.hardware=flo user_debug=31 msm_rtb.filter=0x3F ehci-hcd.park=3' --kernel kernel --ramdisk ramdisk.cpio.gz -o boot.imgThe ramdisk is clearly a gzipped CPIO archive, which suggests that it is used to populate an initramfs used by the kernel on boot. That's nice and standard! Also, the kernel image is nicely recognisable:
$ file kernel kernel: Linux kernel ARM boot executable zImage (little-endian)This should be enough information to allow me to deploy my own kernel image, and a non-Android initramfs ramdisk, to the tablet. But I'll still need to deploy a root filesystem as well.
The User Data Image
I'll use the user data partition to hold my root filesystem, at least initially. So now I need to figure out what format this image file uses. Looking around the AOSP tree some more, it appears to be platform/system/extras/ext4_utils/mkuserimg.sh that is responsible for building the user image file. This script is a wrapper around the make_ext4fs tool, whose source is provided in the same location. A bit more information is provided on this tutorial page, which suggests that the system, user data and cache image files uses a sparse image format, to ensure that fastboot can hold the image in device memory whilst flashing it to the appropriate partition. These image files are ext4 filesystem images, compressed into a sparse image format.
As with the boot image file, it is probably useful to try unpacking the user data image file from the KTU84P factory image. Under platform/system/core/libsparse in the AOSP is the source code to the simg2img tool, which appears to be able to translate a sparse image to a regular (non-sparse) image. This tool can be built as follows:
$ sudo apt-get install zlib1g-dev $ git clone https://android.googlesource.com/platform/system/core $ cd core/libsparse $ gcc -o simg2img -Iinclude simg2img.c sparse_crc32.c backed_block.c output_file.c sparse.c sparse_err.c sparse_read.c -lz $ cp simg2img ~/binTurning simg2img on the userdata.img from the KTU84P factory image:
$ simg2img ./userdata.img userdata-unpacked.img $ file userdata-unpacked.img userdata-unpacked.img: Linux rev 1.0 ext4 filesystem data, UUID=57f8f4bc-abf4-655f-bf67-946fc0f9f25b (extents) (large files) $ du -h userdata-unpacked.img 316M userdata-unpacked.imggives us an ext4 image that we can mount on loopback:
$ sudo mount -o loop userdata-unpacked.img /mnt $ df -m Filesystem 1M-blocks Used Available Use% Mounted on /dev/loop0 11464 29 11419 1% /mntSo, the user data image file contains an 11,464 MB ext4 filesystem. This shall define the upper bound of the user data image file that I try to produce later on. The filesystem is, however, completely empty:
$ ls -l /mnt total 12 drwxr-xr-x. 3 root root 4096 Jan 1 1970 . drwxr-xr-x 25 root root 4096 Sep 2 20:11 .. drwx------. 2 root root 4096 Jan 1 1970 lost+found
Next Time...
... will be my attempt at trying to boot a Linux kernel on the tablet, into a non-Android initramfs ramdisk.