mkdepthcharge(1)
๐ mkdepthcharge(1) ยท depthcharge-tools ๐
โจ NAME โจ
mkdepthcharge โ build boot images for the ChromeOS bootloader ๐
๐ธ SYNOPSIS ๐ธ
mkdepthcharge -o FILE [options] [VMLINUZ] [INITRAMFS ...] [DTB ...]
๐ซ DESCRIPTION ๐ซ
okay bestie, here's the vibe: mkdepthcharge is basically the ultimate glow-up wrapper around mkimage(1) and vbutil_kernel(1). it takes those two and hands them reasonable defaults so your inputs get packaged into the exact format the ChromeOS bootloader is expecting. no cap. ๐
and it doesn't stop there โ it also automates all the preprocessing steps and initramfs support hacks that you'd otherwise be doing manually or writing a whole script for. it's giving "I got you, girl". โจ
so who are the players?
VMLINUZโ should be a kernel executable ๐งINITRAMFSโ should be a ramdisk image that the kernel should be able to use on its own ๐DTBfiles โ should be device-tree binary files appropriate for the kernel ๐ธ
mkdepthcharge tries to figure out the type of each input file by some heuristics on their contents (detective energy ๐), but if that fails? it just assumes a file is whatever's missing in the VMLINUZ, INITRAMFS, DTB order. Alternatively, these files can be specified as options instead of positional arguments. your call, main character. ๐
๐ OPTIONS ๐
๐ Input files ๐
-d VMLINUZ,--vmlinuz VMLINUZโ the kernel executable. If a compressed file is given here, it is decompressed and its contents are used in its place. ๐ฅ-i INITRAMFS [INITRAMFS ...],--initramfs INITRAMFS [INITRAMFS ...]โ ramdisk image. If multiple files are given (e.g. for CPU microcode updates ๐), they are concatenated and used as a single file. teamwork!-b DTB [DTB ...],--dtbs DTB [DTB ...]โ device-tree binary files. ๐
๐ฆ Global options ๐ฆ
-A ARCH,--arch ARCHโ architecture to build the images for. The following architectures are understood:arm,arm64,aarch64for ARM boards;x86,x86_64,amd64for x86 boards. If not given, the build architecture of theVMLINUZfile is used. โจ--format FORMATโ kernel image format to use, eitherfitorzimage. If not given, architecture-specific defaults are used.fitโ this is the default on ARM boards. TheVMLINUZand the optionalINITRAMFS,DTBfiles are packaged into the Flattened Image Tree (FIT) format usingmkimage(1)and that is passed tovbutil_kernel(1). ๐ณzimageโ this is the default for x86 boards. TheVMLINUZis passed mostly unmodified tovbutil_kernel(1), except for decompression and padding for self-decompression. TheINITRAMFSfile is passed as the--bootloaderargument and the kernel header is modified to point to where it will be in memory. It does not support packagingDTBfiles. ๐ซ
-h,--helpโ show a help message and exit. bye bestie ๐--kernel-start ADDRโ start of the Depthcharge kernel buffer in memory. Depthcharge loads the packed data to a fixed physical address in memory, and some initramfs support hacks require this value to be known. This is exactly the board-specificCONFIG_KERNEL_STARTvalue in the Depthcharge source code and defaults to0x100000for the x86 architecture. ๐-o FILE,--output FILEโ write the image toFILE. The image isn't generated at the output, but copied to it from a temporary working directory. This option is mandatory. ๐--pad-vmlinuz,--no-pad-vmlinuzโ pad theVMLINUZfile so that the kernel's self-decompression has enough space to avoid overwriting theINITRAMFSfile during boot. This has different defaults and behaviour depending on the image format, see explanations in their respective sections. ๐ซถ--tmpdir DIRโ create and keep temporary files inDIR. If not given, a temporarymkdepthcharge-*directory is created in/tmpand removed at exit. ๐๏ธ-v,--verboseโ print info messages,mkimage(1)output andvbutil_kernel(1)output to stderr. โจ-V,--versionโ print program version and exit. ๐ซ
๐ง FIT image options ๐ง
-C TYPE,--compress TYPEโ compress theVMLINUZbefore packaging it into a FIT image, either withlz4orlzma.noneis also accepted, but does nothing. ๐คท-n DESC,--name DESCโ description of theVMLINUZto put in the FIT image. ๐ท๏ธ--pad-vmlinuz,--no-pad-vmlinuzโ pad theVMLINUZfile so that the kernel's self-decompression has enough space to avoid overwriting theINITRAMFSfile during boot. The necessary padding is calculated based on compressed and decompressed kernel sizes and the--kernel-startargument. ๐
On earliest boards U-Boot moves the INITRAMFS away to a safe place before running the VMLINUZ, and on ARM64 boards Depthcharge itself decompresses the VMLINUZ to a safe place. But 32-bit ARM boards with Depthcharge lack FIT ramdisk support and run the VMLINUZ in-place, so this initramfs support hack is necessary on those. ๐ค
This option is enabled by default when --patch-dtbs is given, use the --no-pad-vmlinuz argument to disable it. ๐ซถ
--patch-dtbs,--no-patch-dtbsโ addlinux,initrd-startandlinux,initrd-endproperties to theDTBfiles'/chosennodes. Their values are based on the--kernel-startor the--ramdisk-load-addressargument, one of which is required if this argument is given. ๐ฉน
These properties are normally added by Depthcharge, but 32-bit ARM Chromebooks were released with versions before FIT ramdisk support was introduced, so this initramfs support hack is necessary on those. ๐
--ramdisk-load-address ADDRโ add aloadproperty to the FIT ramdisk subimage section. The oldest ARM Chromebooks use an old custom U-Boot that implements the same verified boot flow as Depthcharge. Its FIT ramdisk support requires an explicit load address for the ramdisk, which can be provided with this argument. ๐บ๏ธ
๐ zImage image options ๐
--pad-vmlinuz,--no-pad-vmlinuzโ pad theVMLINUZfile so that the kernel's self-decompression has enough space to avoid overwriting theINITRAMFSfile during boot. The necessary padding is calculated based on values in the zImage header and the--kernel-startargument. ๐
If the VMLINUZ and INITRAMFS are small enough (about 16 MiB in total) they may fit between --kernel-start and the start of the decompression buffer. In this case the padding is unnecessary and not added. ๐ฆ
The padding is usually larger than the decompressed version of the kernel, so it results in unbootable images for older boards with small image size limits. For these, it is usually necessary to use --set-init-size, or custom kernels to make the parts fit as described above. ๐ญ
This is disabled by default in favour of --set-init-size, use the --pad-vmlinuz argument to enable it. ๐
--set-init-size,--no-set-init-sizeโ increase theinit_sizekernel boot parameter so that the kernel's self-decompression does not overwrite theINITRAMFSfile during boot. The modified value is calculated based on values in the zImage header and the--kernel-startargument. ๐งฎ
This only works if the kernel has KASLR enabled (as is the default), because then the kernel itself tries to avoid overwriting the INITRAMFS during decompression. However it does not do this when first copying the VMLINUZ to the end of the decompression buffer. Increasing init_size shifts copy this upwards to avoid it overlapping INITRAMFS. ๐คน
If the VMLINUZ and INITRAMFS are small enough, they may fit before the first compressed copy's start. In this case changing the value is unnecessary and skipped. โจ
This is enabled by default, use the --no-set-init-size argument to disable it. ๐ซถ
๐ Depthcharge image options ๐
--bootloader FILEโ bootloader stub for the very first Chromebooks that use H2C as their firmware. Beyond those, this field is ignored on the firmware side except as a ramdisk for the multiboot and zbi formats. ๐ค
If an INITRAMFS is given for the zimage format, it is placed here as part of an initramfs support hack for x86 boards. Otherwise, an empty file is used. ๐ซ
-c CMD [CMD ...],--cmdline CMD [CMD ...]โ command-line parameters for the kernel. Can be used multiple times to append new values. If not given,--is used. ๐ฃ๏ธ
The ChromeOS bootloader expands any instance of %U in the kernel command line with the PARTUUID of the ChromeOS kernel partition it has chosen to boot, e.g. root=PARTUUID=%U/PARTNROFF=1 will set the root partition to the one after the booted partition. ๐
As knowing the currently booted partition is generally useful, mkdepthcharge prepends kern_guid=%U to the given kernel command line parameters to capture it. Use --no-kern-guid to disable this. ๐ก
--kern-guid,--no-kern-guidโ prependkern_guid=%Uto kernel command-line parameters. This is enabled by default, use the--no-kern-guidargument to disable it. ๐--keydir KEYDIRโ directory containing verified boot keys to use. Equivalent to using--keyblock KEYDIR/kernel.keyblock,--signprivate KEYDIR/kernel_data_key.vbprivk, and--signpubkey KEYDIR/kernel_subkey.vbpubk. ๐--keyblock FILE,--signprivate FILE,--signpubkey FILEโ ChromiumOS verified boot keys. More specifically: kernel key block, private keys in.vbprivkformat, and public keys in.vbpubkformat. ๐๏ธ
If not given, defaults to files set in depthcharge-tools configuration. If those are not set, mkdepthcharge searches for these keys in /etc/depthcharge-tools and /usr/share/vboot/devkeys directories, the latter being test keys that may be distributed with vbutil_kernel(1). ๐ง
You can set these in depthcharge-tools configuration by the vboot-keyblock, vboot-private-key and vboot-public-key options under a depthcharge-tools config section. ๐
๐ EXIT STATUS ๐
In general, exits with zero on success and non-zero on failure. simple as that bestie ๐
๐ FILES ๐๏ธ
/etc/depthcharge-tools/config,/etc/depthcharge-tools/config.d/*โ the depthcharge-tools config files bestie ๐ . These can be used to say where your ChromiumOS verified boot keys live, like, as system configuration. Very "set it and forget it" of them./etc/depthcharge-toolsโ this is the depthcharge-tools config directory, the home base ๐ .mkdepthchargegoes digging around in here looking for verified boot keys./usr/share/vboot/devkeysโ a directory stuffed with test keys that should have been installed byvbutil_kernel(1). Should have. ๐KEYDIR/kernel.keyblockโ the default kernel key block file, aka the one used for signing the image โ๏ธ.KEYDIR/kernel_subkey.vbpubkโ the default public key, the one that verifies signed images โ .KEYDIR/kernel_data_key.vbprivkโ the default private key used for signing the image ๐. Guard it with your life, bestie.
๐ธ EXAMPLES ๐ธ
Okay this is the part where it gets real fun, because these are actual things you can type and the vibes are immaculate. Let's go ๐ฆ
โจ The bare minimum, no thoughts just vibes
mkdepthcharge -o depthcharge.img /boot/vmlinuz
This is the simplest invocation that exists, periodt. But heads up: if you try this on an ARM board, the firmware might straight up refuse to boot the output image because it's got no dtb for the board ๐ญ. And even if the firmware does run the /boot/vmlinuz binary, it might not actually boot correctly for non-firmware reasons โ like a kernel panic because there's no root. Not the move. ๐
โจ The Samsung Chromebook Plus (v1) moment
mkdepthcharge -o system.img --cmdline "root=/dev/mmcblk0p2" --compress lz4 -- /boot/vmlinuz.gz /boot/initrd.img rk3399-gru-kevin.dtb
This is what someone on a Samsung Chromebook Plus (v1) might run on their board to make a bootable image for the system they're actually running. Main character energy, lowkey iconic ๐
โจ The veyron board situation
mkdepthcharge -o veyron.img -c "root=LABEL=ROOT gpt" --kernel-start 0x2000000 --patch-dtbs -- /boot/vmlinuz /boot/initramfs-linux.img /boot/dtbs/rk3288-veyron-*.dtb
Build an image meant to work on veyron boards โ think ASUS Chromebook C201PA and Chromebook Flip C100PA ๐. Here's the tea: the stock Depthcharge on these boards does not process the FIT ramdisk, so the dtbs needs to be patched for it to boot with initramfs. No patch, no boot, no cap. ๐ง
โจ The peach-pit plot twist
mkdepthcharge -o peach-pit.img -c "console=null" --ramdisk-load-address 0x44000000 -- vmlinuz initramfs exynos5420-peach-pit.dtb exynos5420-peach-pit.dtb
Build an image meant to work on a Samsung Chromebook 2 (11" ). This board runs a custom U-Boot, so it needs an explicit ramdisk load address, okay?? And its firmware has a bug when loading the device-tree file โ so you gotta list that file twice for the result to actually be bootable. Yes, twice. Same file. That's not a typo, that's a workaround, and it's giving "firmware said I'm quirky" ๐ ๐ซถ
๐ SEE ALSO ๐
That's the whole page bestie, you made it to the end and I'm so proud of you ๐ฅน๐. This was v0.6.2, dated 2023-06-30, and yeah, mkdepthcharge(1) really said "here's everything you need, now go make a bootable image." Slay. โจ๐๐
๐ฆ where this page comes from
- ubuntu resolute: depthcharge-tools 0.6.2-4 ยท GPL-2.0-or-later
- ubuntu stonking: depthcharge-tools 0.6.2-5 ยท GPL-2.0-or-later
- ๐ the page's license: GPL-2.0-or-later
- Copyright (C) 2019-2022 Alper Nebi Yasak <alpernebiyasak@gmail.com>
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms