diff options
Diffstat (limited to 'README')
-rw-r--r-- | README | 342 |
1 files changed, 342 insertions, 0 deletions
@@ -0,0 +1,342 @@ +Debian on ASUS C101PA Chromebook +=============================== + + +Overview +-------- + +This document contains instructions to install the Debian Linux distribution +on the internal eMMC of the ASUS C101PA Chromebook. It concerns the stable +distribution at the time of this writing (9.0 stretch), but that can easily +be changed to testing or unstable. + +It is assumed the device still runs the ChromeOS operating system. The +procedure erases all data on the internal eMMC, so save any relevant files +before starting. + +The installation steps are : + - Enable boot from external device + - Prepare rootfs image + - Build Linux kernel packages + - Create bootable external device as rescue (DESTRUCTIVE) + - Deploy to internal eMMC (DESTRUCTIVE) + +Hardware required : + - x86 machine running Debian + - Bootable device (USB drive or microSD card) + - Networking (wireless / USB-Ethernet adapter) + +This procedure is destructive and intended for advanced users. Be very careful +not to destroy your own data by mistake. Make back-up copies if unsure. + +The kernel configuration in this repository was crafted to be close to the +original Debian kernel configuration, without modules which may not ever +be useful on the Chromebook, and with more specific options targetting +a low latency laptop with energy saving needs. It also works around some +defects in the ChromeOS branch, such as modules that must be built in the +kernel instead of as loadable modules. + +The procedure is intended to get a system as close to Debian as possible. +In particular, with actual kernel packages and a careful kernel configuration, +it's very easy to get additional features such as an encrypted root file +system, because Debian handles the generation of the initramfs image. + +The kernel/deploy.sh script, installed at /root/kernel/deploy.sh and +linked at /etc/kernel/postinst.d/zz-deploy, is run when updating the kernel +or adding packages that trigger a regeneration of the initramfs. It's the +responsibility of the user to understand what this script does, and adjust +it, as well as the files it uses, as necessary. + + +Enable boot from external device +-------------------------------- + +First, enable Developer Mode : while the laptop is off, hold down the ESC and +Refresh (F3) keys and start it. + +From now on, the firmware presents a recovery screen saying "OS verification +is OFF". Press Ctrl-D to boot from the internal eMMC or Ctrl-U to boot from +an external USB drive / microSD card. Until the external "rescue" bootable +system is available, you can only boot ChromeOS from the internal eMMC. + +Once in ChromeOS : + - Press Ctrl-Alt-T to open the crosh shell + - Type the "shell" command to start a real Unix shell + - Type "sudo -s" to gain root privileges + - Type "crossystem dev_boot_usb=1 dev_boot_signed_only=0" to enable booting + from an external device + + +Prepare rootfs image +-------------------- + +There are several ways to do this, notably with the debootstrap tool, but +this procedure uses a fully emulated Qemu virtual machine to achieve it. The +idea is to use the arm64 Debian installer in the virtual machine, and +extract the resulting root file system from it. Note that, because it's +currently required to completely emulate the arm64 machine, this method is +quite long. Reserve around an hour for it, depending on your host hardware +and your Internet connection. + +First, prepare a disk image. This image can be the same for both the rescue +device as well as the internal eMMC. It is suggested to use a small disk +size, and resize later to the maximum size permitted by the device. Run +the following command : + +qemu-img create disk.img 4G + +The procedure also requires the Debian installer, which you can find on any +Debian mirror, such as http://ftp.fr.debian.org/. The two files required are +the kernel image, named "linux", and the initrd containing the installer, +named "initrd.gz". Those files are in the netboot directory of the installer +of the version you want to install. Here is an example URL for the stretch +stable release : + +http://ftp.fr.debian.org/debian/dists/stretch/main/installer-arm64/current/images/netboot/debian-installer/arm64 + +Move those files next to the disk image, then run the following command +to start the installation in the virtual machine : + +qemu-system-aarch64 \ + -nographic \ + -M virt \ + -m 1G \ + -cpu cortex-a53 \ + -kernel linux \ + -initrd initrd.gz \ + -drive media=disk,if=virtio,index=0,format=raw,file=disk.img + +These installation instructions assume the default single-partition guided +format, with the /boot directory inside the root file system. Once installed, +the root file system can be extracted by mounting the disk image as a loop +device, and simply copying the relevant partition into a new file. + +As root, on the host : + +# Allocate a loop device, attach the disk image to it, and probe partitions +losetup -f -P disk.img + +# Identify the root file system device +losetup -a +lsblk + +# This assumes the allocated device is /dev/loop0 and the root file system +# is in the second partition +dd if=/dev/loop0p2 of=rootfs.img bs=1M + +# Once done, detach the disk image. +losetup -d /dev/loop0 + + +Build Linux kernel packages +--------------------------- + +The kernel packages are pretty easy to build, thanks to the deb-pkg make +target built in the Linux build system. While it's possible to build the +kernel on the Chromebook, this procedure cross-compiles them from the x86 +host system, mostly for better performance. + +As root, on the host : + +# Install build dependencies +apt build-dep linux + +# Install the AArch64 GCC toolchain +# XXX This seems to be in conflict with gcc-multilib +apt install gcc-aarch64-linux-gnu + +As a non-privileged user, on the host : + +# Prepare the kernel build +cp linux_config chromeos-kernel/.config +cd chromeos-kernel +make ARCH=arm64 oldconfig + +# Build the kernel +# Replace -j6 with the number of processors on your machine +make ARCH=arm64 -j6 deb-pkg + +The two packages required on the Chromebook are : + - linux-image + - linux-firmware-image + + +Create bootable external device as rescue +----------------------------------------- + +For this, you need a USB drive or a microSD card. This procedure assumes a +USB drive at /dev/sdc on the host, and /dev/sda on the target. Locating the +USB drive on both the x86 host and the Chromebook is the responsibility of +the user. Use a combination of lsblk and dmesg to make sure you're accessing +the correct device, hereafter called the "rescue device". + +The idea is to create a ChromeOS-compatible GPT partition table on the +rescue device, with two entries (one for the "kernel" and another for the +root file system), and then write the kernel and the root file system into +their respective partitions. Creating the partitions and writing the root +file system is done from the host system, whereas installing the kernel +and copying it to the kernel partition is done from the target system, +either the original ChromeOS on the Chromebook (easier) or a QEMU virtual +machine. + +Note that the Linux framebuffer console apparently suffers from a small bug +that freezes it after input inactivity. + +As root, on the host : + +# Install partitioning tools +apt install parted cgpt + +# Create the partition table +parted --script /dev/sdc mklabel gpt + +# You may check your partition table at any time with +cgpt show /dev/sdc + +# Create the kernel partition +# +# This line names the partition "kernel" (-l is label) starting at +# sector 64 with a size of 131072 sectors (1 sector == 512 bytes, +# making the partition size 64M). +cgpt add -t kernel -l kernel -b 64 -s 131072 /dev/sdc + +# Set priority and "successful" counters for the kernel partition +# This is required by the boot loader. Refer to the documentation of +# cgpt for more details. +cgpt add -i 1 -P 10 -S 1 /dev/sdc + +# Create the root file system partition +# +# After creating the kernel partition, print the partition table, and look +# for a line similar to : +# 15261663 32 Sec GPT table +# The first value on this line is the last sector. To maximize your root +# file system partition size, subtract its first sector from this size. +# The first sector is the last sector of the kernel partition, so in +# this example, it's 64 + 131072, so 131136, and 15261663 - 131136 is +# 15130527. +cgpt add -t data -l / -b 131136 -s 15130527 /dev/sdc + +# Write the root file system into the root file system partition +dd if=rootfs.img of=/dev/sdc2 bs=1M + + ---- These steps are similar for the deployment on the ---- + ---- internal eMMC, with /dev/mmcblk0p1 as the kernel ---- + ---- partition and /dev/mmcblk0p2 as the root file system ---- + ---- partition. ---- + +# Extend the root file system to the maximum available size +e2fsck -fp /dev/sdc2 +resize2fs /dev/sdc2 + +# Mount the root file system +mount /dev/sdc2 /mnt + +# Copy the required kernel packages to the root file system +cp <linux-firmware-pkg> <linux-image-pkg> /mnt/root + +# Copy the files used to generated a signed kernel image from this repository +# to the rescue device +cp -r kernel /mnt/root + +# Unmount the root file system +umount /mnt + +Installing the kernel is done on the target device, either the original +ChromeOS system, or a QEMU virtual machine. Refer to enabling developer mode +for a procedure to gain root privileges on ChromeOS. + +With QEMU, make the rescue device available to the virtual machine using a +line such as -drive media=disk,if=virtio,index=1,format=raw,file=/dev/sdc to +the qemu-system-aarch64 command line used when preparing the root file system. +From the installer, when asked for the root password, select "Go back", then +select "Detect disks", and then start a root shell in the environment of the +installer. + +# Once you have a root shell on the target system, with networking configured, +# mount the root file system, and chroot into it +mount /dev/sda2 /mnt +chroot /mnt +mount -t proc none /proc +mount -t sysfs none /sys +mount -t devtmpfs none /dev + +# Copy the host /etc/resolv.conf to the chroot if needed + +# Install the packages required for partitioning and generating the kernel +# image in the format expected by the boot loader +apt install parted cgpt vboot-utils vboot-kernel-utils u-boot-tools + +# Copy the firmware blobs to /lib/firmware +mkdir -p /lib/firmware +cp -a /root/kernel/firmware/* /lib/firmware + +# Adjust the kernel image generation files in /root/kernel to refer to the +# correct kernel partition (the relevant files are deploy.sh and kernel args). +# One the Chromebook, the USB drive is /dev/sda, whereas the external microSD +# card is /dev/mmcblk1. The files to adjust are deploys.sh and kernel.args. + +# Create a link to the deploy.sh script so that every time a kernel is +# installed, a signed kernel image is generated and written to the kernel +# partition (note that the link must not end with .sh for this to work). +ln -s /root/kernel/deploy.sh /etc/kernel/postinst.d/zz-deploy + +# Install the kernel packages +dpkg -i <linux-firmware-pkg> <linux-image-pkg> + +# Depending on how you installed Debian, the previous operation may fail +# because it can't find a symlink to the kernel. Solve this with the +# linux-update-symlinks command, e.g. +linux-update-symlinks install 4.4.121-c101pa+ /boot/vmlinuz-4.4.121-c101pa+ + +# Once done, you may remove the Debian kernel +apt purge linux-image-4.9.0-6-arm64 linux-image-arm64 + +# It's recommended to install software to configure wireless networking, +# such as wicd +apt install wicd-curses + +# Don't forget to properly unmount after leaving chroot, as this makes +# sure all the written data is actually on disk afterwards. +umount /mnt/dev +umount /mnt/sys +umount /mnt/proc +umount /mnt + + +Deploy to internal eMMC +----------------------- + +Once the rescue device boots, deploying to the internal eMMC is quite simple. +Make sure not to leave any data of value on the Chromebook since this is a +destructive operation. Also, make sure to set up networking on the rescue +device so that additional software can easily be installed. + +The idea is to boot from the rescue device (Ctrl-U from the boot screen), +repartition the internal eMMC, write the root file system to the data +partition, mount it and chroot inside, and install the kernel from there. + +Depending on the rescue device capacity, you may store the root file system +image and kernel packages and generation files inside, on an additional +USB drive (if booting from a microSD card) or microSD card (if booting from +a USB drive), or you may fetch them through the network. + +As root, on the target, after booting on the rescue device : + +# Create the partition table +parted --script /dev/mmcblk0 mklabel gpt + +# Create the kernel partition +cgpt add -t kernel -l kernel -P 10 -S 1 -b 64 -s 131072 /dev/mmcblk0 + +# Create the root file system partition +# Compute the sizes from cgpt show /dev/mmcblk0 as for the rescue device +cgpt add -t data -l / -b 131136 -s 30646175 /dev/mmcblk0 + +# Write the root file system into the root file system partition + +The rest is very similar to the rescue device, with the exception that +the target device is /dev/mmcblk0, with /dev/mmcblk0p1 being the kernel +partition and /dev/mmcblk0p2 the root file system partition. + +Once done, boot from the internal eMMC with Ctrl-D from the boot screen. |