Creating bootable media for depthcharge based devices

From Gentoo Wiki
Jump to: navigation, search

Depthcharge, the ChromeOS bootloader[1], is one of the available payloads for coreboot (and also Libreboot) 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*

Create a filesystem on the root partition and mount it:

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 the bootable media's root filesystem:

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

Switch the bootable media’s Gentoo to unstable to ensure the availability of the latest version of sys-boot/vboot-utils 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 a 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 root filesystem:

root #umount /mnt

Create a cross-compiler

Important
This section can be skipped 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 by creating /etc/portage/repos.conf/crossdev.conf with the content shown below.

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[2] (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 and replace TUPLE again with the system tuple fitting the target architecture, e.g. arm-linux-gnueabihf. Mind the trailing "-".

user $export ARCH=TARGETARCH
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) that contains the CMDLINE parameters.

Important
The term "sd*" in the following file 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.

Important
The term "sd*" in the following command 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.

External resources

References