Create bootable media for depthcharge based devices

From Gentoo Wiki
Jump to: navigation, search

Depthcharge[1], the ChromeOS bootloader, is one of coreboot’s (and also libreboot’s) available payloads[2] and as such mostly found on chromebooks. This guide shows how to create bootable media, e.g. an installation media USB drive, for those devices.

Note
So far these instructions have only been tested with the ARMv7-A based target device Asus Chromebook C201.


Installing required tools

The guide assumes that the current platform is a Gentoo Linux one. The majority of steps however can be performed from any distribution, just translate the Gentoo-specific way of doing things (such as installing software) to the other distribution's practices.

Note
Throughout this guide this current platform will be referred to as the host system whereas the device that shall be booted will be referred to as the target device.

Install dev-embedded/u-boot-tools, sys-apps/dtc, sys-block/parted and sys-boot/vboot-utils

root #emerge –ask dev-embedded/u-boot-tools sys-apps/dtc sys-block/parted sys-boot/vboot-utils

Some drivers might also require proprietary firmware available from sys-kernel/linux-firmware.

Preparing the partitions

This is the recommended partition layout and size:

/dev/sd*1 kernel partition (similar to a traditional boot partition) 64MiB
/dev/sd*2 root partition available space
Important
The term "sd*" in the following commands needs to be replaced with the term currently corresponding to the bootable media – in case of a SD Card something like "mmcblkXp". In any case the "*" represents a letter and the "X" represents a number.
Warning
This will delete all data on /dev/sd*
root #parted /dev/sd* mklabel gpt
root #parted -a optimal /dev/sd* unit mib mkpart Kernel 1 65
root #parted -a optimal /dev/sd* unit mib mkpart Root 65 100%

Depthcharge requires some specific parameters to be set. These signal the bootloader the presence of a valid kernel partition:

root #cgpt add -i 1 -t kernel -S 1 -T 5 -P 15 /dev/sd*

Preparing the root partition

root #mkfs.ext4 /dev/sd*2
root #mount /dev/sd*2 /mnt

Install a Gentoo rootfs

Get a stage3 tarball from the main website's download section that is suitable for the architecture (e.g. ARMv7a|HardFP) of the target device and extract it to /mnt/

root #tar xvpf /PATH/TO/STAGE3-TARBALL -C /mnt/

Switch the bootable media’s Gentoo to unstable to ensure the availability of the latest versions of sys-boot/vboot-utils and dev-embedded/u-boot-tools and speed up the bootable media. Replace TARGETARCH with the target device's architecture, e.g. arm for ARMv7-A based devices.

root #echo "ACCEPT_KEYWORDS=\"~TARGETARCH\"" >> /mnt/etc/portage/make.conf
root #echo "MAKEOPTS=\"-j4\"" >> /mnt/etc/portage/make.conf

Set the bootable media’s root password to “gentoo”, cf. Setting the default root password

root #sed -i 's/root\:\*/root\:\$6\$I9Q9AyTL\$Z76H7wD8mT9JAyrp\/vaYyFwyA5wRVN0tze8pvM\.MqScC7BBm2PU7pLL0h5nSxueqUpYAlZTox4Ag2Dp5vchjJ0/' /mnt/etc/shadow

Finish this step by unmounting the bootable media’s rootfs

root #umount /mnt

Create a cross-compiler

Important
You can skip this section if the host system's architecture is the same as the target system's. These steps are only necessary if the host system is not based on the same architecture as the target device.
Note
The instructions for setting up a cross-compilation toolchain are very specific to Gentoo, i.e. if the host system runs a different Linux distribution the respective distribution’s documentation on cross-compilation should be consulted instead.

Create a local overlay for the cross toolchain, cf. Custom repository for crossdev:

root #mkdir -p /usr/local/portage-crossdev/{profiles,metadata}
root #echo 'crossdev' > /usr/local/portage-crossdev/profiles/repo_name
root #echo 'masters = gentoo' > /usr/local/portage-crossdev/metadata/layout.conf
root #chown -R portage:portage /usr/local/portage-crossdev

Then instruct Portage and sys-devel/crossdev to use this overlay:

FILE /etc/portage/repos.conf/crossdev.conf
[crossdev]
location = /usr/local/portage-crossdev
priority = 10
masters = gentoo
auto-sync = no

Install sys-devel/crossdev and create the cross toolchain. Replace TUPLE with the system tuple fitting the target architecture, e.g. arm-linux-gnueabihf for ARMv7-A based target devices with at least VFPv3-D16[3] (also commonly referred to as hardfloat, HardFP or hf).

root #emerge --ask sys-devel/crossdev
root #crossdev --stable --target TUPLE


Finally prepare cross-compiling the kernel.

Replace TARGETARCH with the target device's architecture, e.g. arm for ARMv7-A based devices.

user $export ARCH=TARGETARCH

Replace TUPLE again with the system tuple fitting the target architecture, e.g. arm-linux-gnueabihf. Mind the trailing "-".

user $export CROSS_COMPILE=TUPLE-

Configuring the Linux kernel

If all necessary drivers are built into the kernel (i.e. no loadable modules are needed to boot the target device) there's no need to have an initramfs, which keeps things simple. Especially if the host system's architecture differs from the target device's architecture creating an initramfs would at least involve cross-compiling busybox. With that in mind configure sys-kernel/gentoo-sources as usual, cf. Configuring the Linux kernel.

Build the kernel and device tree binaries:

user $make -j5 zImage dtbs

From the kernel build directory, copy the zImage and the target device's device tree binary to the desired working directory. Replace DTBINARY with the filename of the target device's device tree binary, e.g. rk3288-veyron-speedy.dtb for the Asus Chromebook C201 (which is based on Rockchip's RK3288 SoC and a board with the codename "Veyron Speedy").

user $cp -a arch/arm/boot/zImage /PATH/TO/ARBITRARY_WORKING_DIRECTORY
user $cp -a arch/arm/boot/dts/DTBINARY /PATH/TO/ARBITRARY_WORKING_DIRECTORY

Change to the desired working directory:

user $cd /PATH/TO/ARBITRARY_WORKING_DIRECTORY


Create the configuration file ("gentoo.its") for the FIT image with the following content. Again replace DTBINARY with the filename of the target device's device tree binary, e.g. rk3288-veyron-speedy.dtb for the Asus Chromebook C201.

FILE gentoo.its
/dts-v1/;

/ {
    description = "Linux kernel image with one or more FDT blobs";
    #address-cells = <1>;
    images {
        kernel@1{
            description = "vmlinuz";
            data = /incbin/("zImage");
            type = "kernel_noload";
            arch = "arm";
            os = "linux";
            compression = "none";
            hash@1{
                algo = "sha1";
            };
        };
        fdt@1{
            description = "dtb";
            data = /incbin/("DTBINARY");
            type = "flat_dt";
            arch = "arm";
            compression = "none";
            hash@1{
                algo = "sha1";
            };
        };
    };
    configurations {
        default = "conf@1";
        conf@1{
            kernel = "kernel@1";
            fdt = "fdt@1";
        };
    };
};

Pack the FIT image:

user $sync
user $mkimage -f gentoo.its gentoo.itb

Create a file ("kernel.flags") for the CMDLINE parameters:

Important
The term "sd*" needs to be replaced with the term corresponding to the bootable media in future, i.e. when booting on the target system. This depends on the target device, but "sda" or "sdb" respectively "mmcblk0p" or "mmcblk1p" are good guesses.
FILE kernel.flags
console=tty1 root=/dev/sd*2 rootfstype=ext4 rootwait rw

Sign and pack the kernel:

user $sync
user $futility --debug vbutil_kernel --arch arm --version 1 --keyblock /usr/share/vboot/devkeys/kernel.keyblock --signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk --bootloader kernel.flags --config kernel.flags --vmlinuz gentoo.itb --pack vmlinuz.signed


Install the kernel to the kernel partition. Now the term "sd*" needs to be replaced with the term currently corresponding to the bootable media – in case of a SD Card something like "mmcblkXp". In any case the "*" represents a letter and the "X" represents a number.

root #dd vmlinuz.signed of=/dev/sd*1

Finalizing

Now boot the target device from the created media, log in and configure the network. Once the network connection is working prepare Portage:

root #emerge-webrsync

Finally install required tools, dev-embedded/u-boot-tools, sys-apps/dtc, sys-block/parted and sys-boot/vboot-utils:

root #emerge --ask dev-embedded/u-boot-tools sys-apps/dtc sys-block/parted sys-boot/vboot-utils
Note
If the created bootable media is to be used on a day-to-day base, i.e. as a regular system, it is highly recommended to read the Gentoo Handbook and work through the steps not covered by this guide.

References

  1. Depthcharge source code, Git at Google. Retrieved on February 25th, 2019
  2. Depthcharge payload, Coreboot payloads. Retrieved on February 25th, 2019
  3. ARM architecture - Floating-point (VFP), Wikipedia. Retrieved February 26th, 2019