An account of how to create a USB disk that will boot a Linux 4.19 kernel (based off Chrome OS' most recent working kernel) on an Asus C100PA with a Debian ("buster") root file system. This may also work on other veyron-*
devices.
In this first step we will create a Chrome OS GPT partition table on USB drive that looks like this:
start size part contents
0 1 PMBR
1 1 Pri GPT header
2 32 Pri GPT table
34 65536 1 Label: "kernel"
Type: ChromeOS kernel
UUID: NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN
Attr: priority=0 tries=0 successful=0
65570 65536 2 Label: "alt-kernel"
Type: ChromeOS kernel
UUID: NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN
Attr: priority=0 tries=0 successful=0
131106 7690173 3 Label: "root"
Type: Linux data
UUID: NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN
7821279 32 Sec GPT table
7821311 1 Sec GPT header
If you already know how to do this, then skip the steps given below. (The numbers in the first column are for a specific USB drive. Some of them could be different for you.) Basically, partition 1 will hold the Chrome OS "style" kernel image, partition 3 will have the root file system for Debian. Partition 2 will be useful if one wants to test alternative kernels.
- Go to file manager and eject the USB drive if it is mounted.
Note: The commands below need to run as root on Chrome OS. This means that you need to be in developer mode (it is complicated to explain how to do this here). I also prefer to work within crouton
in developer mode since it is a familiar Debian environment; in the latter case you need to install fdisk
and cgpt
with apt-get install fdisk cgpt
.
-
From
/proc/partitions
figure out the drive name. We will assume that it is/dev/sda
. -
Run
fdisk /dev/sda
and typeg
followed byw
to create a new GPT partition table. Or, if you prefer a complete command-line approach runecho label: gpt | sfdisk /dev/sda
; alternatively,parted --script /dev/sda mklabel gpt
. -
Run
cgpt create /dev/sda
to setup the Chrome OS extensions to the GPT partition table. -
Now we create partitions in succession:
a.
cgpt add -b 34 -s 65536 -t kernel -l "kernel" /dev/sda
will create partition 1 of size 32M.b.
cgpt add -b 65570 -s 65536 -t kernel -l alt-kernel /dev/sda
will create partition 2. Note that 65570 = 34 + 65536!c. Use
cgpt show /dev/sda
to get the available size for partition 3. Ifn
is the first number in the second last row of the output, then the size ism
=n
-131106. Note that 131106=65570+65536!d.
cgpt add -b 131106 -s <m> -t data -l root /dev/sda
will create the root partition.
Note: At this point (and various other points!) the Chrome OS utility cros-disks
may mount your partitions, you will need to unmount them from the file manager to avoid silly errors.
This step will create a Debian (buster) root file system on /dev/sda3
(the chosen partition for this) using debootstrap
. If you already know how to do this, then you can skip the following steps.
We assume that you want to create a Debian root file system on /dev/sda3
, and that this file system is not mounted, and that you have root access.
-
Create a blank
ext4
file system on the partition withmkfs.ext4 /dev/sda3
. -
Mount it in some empty directory. In Debian (and Crouton)
/mnt
is usually available for such temporary mounts, so you domount /dev/sda3 /mnt
. -
Get a copy of the
debootstrap
package and install it somewhere. In Debian (and Crouton) this is as easy asapt-get install debootstrap
. -
Run
debootstrap --arch=armhf --foreign buster /mnt
to create the Debian buster root file system on the partition mounted at/mnt
. -
If the above steps were not run on your Chromebook, then you need to eject your drive and get it to your Chromebook. As usual you need to have root on your Chromebook at the partition needs to be mounted somewhere. Since I worked with Crouton, I didn't have to do anything, the partition continued to be mounted at
/mnt
. -
Run the second stage of the installation process with
chroot /mnt /debootstrap/debootstrap --second-stage
. -
At this stage, it is probably a good idea to "expand"
/mnt/etc/apt/sources.list
to include security and other updates. (Why not?!) So it should look like:
deb http://deb.debian.org/debian/ buster main non-free contrib
deb http://deb.debian.org/debian/ buster-updates main non-free contrib
deb http://deb.debian.org/debian-security buster/updates main non-free contrib
- Run
chroot /mnt apt-get update
andchroot /mnt apt-get upgrade
just to get your (minimal) Debian root up-to-date. This also checks that you can connect to the Debian repositories within the chroot. (If you get a name lookup error, you may need to copy/etc/resolv.conf
into/mnt/etc/resolv.conf
.)
We assume that your Debian root file system is mounted at /mnt
and install things required to build the Linux kernel.
-
Probably a good idea to mount some of the utility filesystems at this point with
mount --bind /dev /mnt/dev
,chroot /mnt mount -t proc proc /proc
andchroot /mnt mount -t sysfs sysfs /sys
. -
You need to run
chroot /mnt apt-get install <pkg>
for the packagesbuild-essential
,libncurses5-dev
,libssl-dev
,bc
,bison
,flex
,git
,initramfs-tools
.
The build process is based on the current stable channel
version of Chrome OS. The following steps need to be carried out in the Chrome OS root.
-
Run
modprobe configs
to get the running configuration of the Chrome OS kernel in/proc/config.gz
. Copy this file to some location accessible to your Crouton. -
Run
tar -czf /tmp/extras.tar.gz /lib/firmware /opt/google/touch
and copy this file to some location accessible to your Crouton. -
grep CHROMEOS_RELEASE_BUILDER_PATH /etc/lsb-release
should give you something likeveyron_minnie-release/R83-13020.87.0
. The relevant portion of that isR83-13020
-
uname -r
should give you something like4.19.113-08544-ge67503bc40df
. The relevant parts of that are4.19
ande67503bc40df
(which is the tail following theg
--- for Google?). -
Browse the Google Chromium Source tree at https://chromium.googlesource.com/chromiumos/third_party/kernel/+/refs/heads/release-R83-13020.B-chromeos-4.19. Note how we used the
R83-13020
and4.19
. At the top of the page againstcommit
you will see a hexadecimal number which starts withe67503bc40df
(our last relevant part!). This shows that you have the correct source for the kernel that is running on your Chromebook! -
Click on the
tgz
link, or copy the link and download it usingcurl
orwget
. It should give you a file calledrelease-R83-13020.B-chromeos-4.19.tar.gz
-
Make this file accessible to your Crouton if necessary. Now assume that you are in the same situation as the previous step and have your Debian root file system mounted at
/mnt
. -
Make a directory to unpack this archive
mkdir -p /mnt/usr/src/linux-chromeos-4.19/
. -
Unpack the archive with
tar -xf release-R83-13020.B-chromeos-4.19.tar.gz -C /mnt/usr/src/linux-chromeos-4.19/
-
Copy the
config.gz
from (1) above to/mnt/root/chromeos.config.gz
and unzip it withgunzip /mnt/root/chromeos.config.gz
. -
Unpack
extras.tar.gz
from (2) above usingtar -xf extras.tar.gz -C /mnt
so that the files are in/lib/firmware
and/opt
within the Debian file system.
Assume that the root of the Debian file system is mounted at /mnt
and this has the /dev
, /proc
and /sys
mounts as above as well.
Enter this with chroot /mnt
before running the next steps.
-
Run
cd /usr/src/linux-chromeos-4.19/
to enter the kernel sources. -
Copy the running (Chrome OS) kernel configuration with
cp /root/chromeos.config .config
-
Enable a few flags in this configuration file.
./scripts/config --enable CONFIG_VT
./scripts/config --enable CONFIG_FRAMEBUFFER_CONSOLE
./scripts/config --enable CONFIG_DRM_FBDEV_EMULATION
The above three are probably essential as a replacement for Chrome OS' use of frecon
. The next ones are not very clear. Some experimentation is required to see if they are all required!
./scripts/config --enable CONFIG_DRM_MALI_DISPLAY
./scripts/config --enable CONFIG_ROCKCHIP_LVDS
./scripts/config --enable CONFIG_ROCKCHIP_RGB
./scripts/config --enable CONFIG_DRM_PANEL_LVDS
The following is a way to reduce the size of the kernel and also its debug-ability! You may or may not want to do this!
./scripts/config --disable CONFIG_DEBUG_INFO
-
Finally, make this into a proper
.config
withmake ARCH=arm -j6 olddefconfig
. -
Now run
make ARCH=arm -j6 <target>
for the targetszImage
,modules
,dtbs
,modules_install
anddtbs_install
. -
Before installing the kernel one needs to run
ln -s /dev/sda3 /dev/root
so that Debian'supdate-initramfs
is able to guess the root file system to build theinitrd.img
. After this you can runmake ARCH=arm -j6 zinstall
. Then you can remove the/dev/root
link. Don't worry too much about the failure to build theinitrd.img
as we will not use it to boot the system at this point.
At this point you are in the Debian chroot where, in /boot
you have your vmlinuz-4.19.113
, System.map-4.19.113
and initrd.img-4.19.113
and in /boot/dtbs/4.19.113
you will have the file rk3288-veyron-minnie.dtb
.
-
Install the tools needed to install the kernel with
apt-get install vim vboot-utils vboot-kernel-utils u-boot-tools
-
Create the file
/boot/kernel.its
with the following contents.
/dts-v1/;
/ {
description = "Kernel image with one or more FDT blobs";
images {
kernel@1{
description = "kernel";
data = /incbin/("vmlinuz-4.19.113");
type = "kernel_noload";
arch = "arm";
os = "linux";
compression = "none";
hash@1{
algo = "sha1";
};
};
fdt@1{
description = "device_tree";
data = /incbin/("dtbs/4.19.113/rk3288-veyron-minnie.dtb");
type = "flat_dt";
arch = "arm";
compression = "none";
hash@1{
algo = "sha1";
};
};
};
configurations {
default = "conf@1";
conf@1{
kernel = "kernel@1";
fdt = "fdt@1";
};
};
};
-
Use this to create the FIT image that can be loadedby
u-boot
with the commandmkimage -f /boot/kernel.its /boot/kernel.itb
-
Create a file
/boot/cmdline
with the contents
cros_secure console=tty1 noinitrd nosplash root=/dev/sda3 rootfstype=ext4 rw rootwait lsm.module_locking=0 vt.global_cursor_default=1
It is not clear that all these options are required. Some experimentation is needed! Note that /dev/sda3
should probably be replaced with a "UUID" or a label or something.
-
Create an empty
/boot/bootloader.bin
file. (Why? No idea!) The command isdd if=/dev/zero of=/boot/bootloader.bin bs=512 count=1
-
Create the image for the kernel partition with the command
vbutil_kernel --pack /boot/image.kpart --version 1 --arch arm \
--vmlinuz /boot/kernel.itb --bootloader /boot/bootloader.bin --config /boot/cmdline \
--keyblock /usr/share/vboot/devkeys/kernel.keyblock \
--signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk
-
Install this kernel in
/dev/sda1
withdd if=/boot/image.kpart of=/dev/sda1
-
Activate this for booting with
cgpt add -i 1 -P 1 -T 1 -S 1 /dev/sda
At this point your system should be ready! Unmount /dev
, /proc
and /sys
and exit from the "chroot". Then unmount the partition umount /dev/sda3
.
Before rebooting ensure that you have enabled USB booting and disabled verified boot with crossystem dev_boot_usb=1
and crossystem dev_boot_signed_only=0
. It should be possible to make sure that only certain signatures are accepted even with these settings according to some docs, but, for now, your system is "wide open" for anyone to install anything! Security has been over-ridden!
After this you can shut down your system and hit Ctrl+U
at the usual developer splash screen. If all went well then your Debian system should boot up!
This is still not a self-hosting system! One needs to install software to get the network going etc. One can look at links like http://galexander.org/chromebook for this.
Followed the above instructions to install on a C100PA on an SD card (
mmcblk0
in my case). When I reboot and hold downCTRL-U
it fails to boot with "The device you inserted does not contain Chrome OS". I was able to boot ArchLinux on the same device earlier but it has too many problems with the OS installation side that I decided to search for a Debian Howto.The
/boot/
directory contains:I flashed
image.kpart
to/dev/mmcblk0p1
and thedtbs
directory has./4.19.122/rk3288-veyron-minnie.dtb
Any pointers where I might start troubleshooting?