summaryrefslogtreecommitdiff
path: root/README
diff options
context:
space:
mode:
Diffstat (limited to 'README')
-rw-r--r--README342
1 files changed, 342 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..03021e5
--- /dev/null
+++ b/README
@@ -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.