1mkroot - simple linux system builder 2 3Compiles a toybox-based root filesystem and kernel that can boot under qemu. 4 5Prebuilt binaries available from http://landley.net/bin/mkroot/latest 6launched via ./run-qemu.sh (which assumes you have QEMU installed, KVM 7works in a pinch), and then run "exit" to shut down the emulated system. 8 9This project is a successor to https://landley.net/aboriginal/about.html 10and shares most of the same goals, with a much simpler implementation. 11 12--- Quick Start 13 14To install the build prerequisites: download toybox source, linux kernel source, 15and one or more musl cross compiler toolchain(s) in the "ccc" directory: 16 17 $ cd toybox 18 $ git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux 19 $ wget https://landley.net/bin/toolchains/latest/i686-linux-musl-cross.tar.xz 20 $ mkdir ccc 21 $ tar xvJCf ccc i686-linux-musl-cross.tar.xz 22 23Then invoke mkroot like: 24 25 $ mkroot/mkroot.sh CROSS=i686 LINUX=linux 26 $ root/i686/run-qemu.sh 27 28This project is a successor to https://landley.net/aboriginal/about.html 29and shares most of the same goals, with a much simpler implementation. 30 31--- Building without a cross compiler (warning: glibc sucks) 32 33Running ./mkroot.sh with no arguments and no $CROSS_COMPILE environment 34variable builds a statically linked root filesystem with the host's compiler. 35 36 $ mkroot/mkroot.sh 37 38You can then chroot into it like this: 39 40 $ sudo chroot output/host/root /init 41 $ ls -l 42 $ exit 43 44Unfortunately, glibc doesn't properly support static linking, so if your host 45Linux uses glibc the build will spit out a bunch of warnings indicating 46all sorts of glibc features won't work (DNS lookups always fail, ls -l can't 47read names out of /etc/password, etc). This is a known problem with glibc, 48because ex-maintainer Ulrich Drepper had a strong personal dislike of static 49linking and actively sabotaged it. 50 51If building on a non-glibc system, such as Alpine Linux, you're fine. 52Otherwise, you'll probably want to cross compile with a musl-libc toolchain 53to avoid glibc's very long list of static linking bugs. (The resulting root 54filesystem is also significantly smaller: a stripped statically linked 55"hello world" binary for x86-64 is 5420 bytes with musl-libc, and 682,696 bytes 56with glibc.)</p> 57 58--- Building with a cross compiler. 59 60The variable $CROSS_COMPILE indicates the toolchain prefix to apply to 61commands such as "cc" and "ld". Since prefixed cross compiler names tend 62to look like "armv5l-cc" this prefix tends to end with a dash. 63 64 $ mkroot/mkroot.sh CROSS_COMPILE=armv5l- 65 66If you haven't added the cross compiler to your $PATH, you can specify 67a path as part of the prefix: 68 69 $ mkroot/mkroot.sh CROSS_COMPILE=~/x86_64-linux-musl-cross/bin/x86_64-linux-musl-cross- 70 71Don't forget the trailing dash. 72 73Alternately, the variable $CROSS (as used in the Quick Start above) tells 74mkroot to look in the "ccc" directory for a cross compiler starting with 75a short name: 76 77 $ mkroot/mkroot.sh CROSS=s390x 78 79That would look (using wildcards) for ccc/s390x-*cross/bin/s390x*-cc and 80if found, work out the appropriate $CROSS_COMPILER prefix to use for the 81corresponding other tools. Use "CROSS=help" to see the list of cross compilers 82currently available in the ccc directory. 83 84You only need to set one of $CROSS or $CROSS_COMPILE, the other gets derived 85from the one you provided. 86 87The downloadable toolchains were built with toybox's scripts/mcm-buildall.sh 88running in a fresh checkout of https://github.com/richfelker/musl-cross-make 89and are available as prebuilt binaries from https://landley.net/bin/toolchains 90(The "native" compilers run _on_ the target system, as well as producing 91binaries for them. Those are packaged as squashfs filesystems, to be loopback 92mounted within qemu.) 93 94--- Adding a kernel 95 96On the mkroot command line add LINUX= pointing to a kernel source directory: 97 98 $ mkroot/mkroot.sh CROSS=sh4 LINUX=~/linux 99 100This will build a kernel for the appropriate target, package the filesystem 101as cpio.gz for use by initramfs, and create a run-qemu.sh script to invoke 102qemu. This results in the following files under root/$CROSS: 103 104 initramfs.cpio.gz - the "fs" dir packaged for initramfs, plus any $MODULES 105 linux-kernel - the compiled kernel 106 linux.dtb - The device tree binary (if this target requires one) 107 run-qemu.sh - the qemu invocation to run it all 108 109And also: 110 111 fs/ - the generated root filesystem (you can chroot here) 112 docs/ - Additional information not needed to run qemu. 113 114The run-qemu.sh script will connect together the appropriate -kernel, -initrd, 115and -dtb arguments to consume the provided files, as well as -m board and 116-append "kernel command line arguments". The KARGS environment variable is 117added to the kernel command line arguments, and any additional arguments 118provided to the script are passed through to qemu, so you can do: 119 120 $ KARGS="rdinit=/bin/sh" ./run-qemu.sh -hda blah.img 121 122Running the script should boot the kernel to a command prompt, with the 123serial console connected to stdin and stdout of the qemu process so you can 124just type into it and see the output. The generated kernel config should 125provide basic NAT network support (as if behind a router) and block device 126support. 127 128--- Environment variables 129 130Any "name=value" argument provided on the mkroot.sh command line will set 131an environment variable, and any string without an = indicates a package 132script to run before building toybox (explained below). This is why CROSS= 133CROSS_COMPILE= and LINUX= were all set on the command line above. 134 135For portability reasons, mkroot.sh clears all environment variables at the 136start of its run, with the following exceptions: 137 138LINUX - Linux kernel source directory. 139CROSS_COMPILE - Cross compiler prefix (sets $CROSS from prefix before first -) 140CROSS - Short target name (sets $CROSS_COMPILE from ccc) 141HOME - Absolute path to user's home directory. 142PATH - Executable path to find binaries. 143NOCLEAR - Don't clear environment variables. (Can't set on command line.) 144 145Other interesting variables to set on the command line include: 146 147NOAIRLOCK - don't do a hermetic build, just use the $PATH's tools. 148NOLOGPATH - don't use the command line recording wrapper 149NOLOG - don't record build output to root/build/log/$CROSS.[yn] 150NOTOYBOX - don't build toybox 151PENDING - extra commands to enable out of toys/pending 152KEXTRA - Additional kernel symbols to enable (in short CSV format) 153MODULES - Kernel modules to build (in short CSV format) 154 155--- Adding build modules 156 157You can run additional build scripts from the mkroot/packages directory by 158listing them on the command line: 159 160 $ mkroot/mkroot.sh dropbear overlay OVERLAY=~/blah 161 162Any "name=value" argument provided on the command line will set an environment 163variable in mkroot (explained above), and any string that without an = 164indicates a package script to run before building toybox. 165 166The provided build scripts mostly download source tarballs, cross compile them, 167and install them into the root filesystem. Additional package build instructions 168are available from the "Linux From Scratch" (http://linuxfromscratch.org/lfs) 169and "Beyond Linux From Scratch" (http://linuxfromscratch.org/blfs) projects. 170 171If you specify any packages, the "plumbing" package is automatically read first 172to provide the download, setupfor, and cleanup shell functions to fetch and 173manage source tarballs, and set the $DOWNLOAD variable (defaulting to store 174downloaded tarballs in "./root_download"). 175 176The "overlay" script copies the $OVERLAY directory (default "./overlay") 177into the root filesystem, so you can add arbitrary additional files. 178 179The "dynamic" script attempts to copy dynamic libraries out of the 180toolchain, to allow a dynamically linked root filesystem. It's a work in 181progress. (A debian host toolchain can have multiple gigabytes of shared 182libraries.) 183 184The "tests" script copies the toybox test suite into the new filesystem, 185downloads some test files, and adds some test modules to the kernel build. 186 187--- Creating new build modules 188 189Build scripts run after creating the directory layout and writing 190the the init script and etc files (resolv.conf/passwd/group), but before 191building toybox. 192 193These scripts are sourced, not run, so environment variables you set remain 194in force. The following variables can affect the remaining mkroot.sh build: 195 196NOTOYBOX - if set, toybox will not be installed into the new root filesystem 197KEXTRA - additional kernel symbols to enable (in same CSV format as $KCONF) 198QEMU_MORE - Additional qemu command line arguments added to run-qemu.sh 199 200To append instead of replacing (in case they're already set), you can use 201QEMU_MORE="$QEMU_MORE --blah" and KEXTRA="${KEXTRA+$KEXTRA,}"BLAH,BLAH,BLAH 202 203If you check your own build scripts into mkroot/packages without touching 204any existing files, you should be able to "git pull --ff" to update your tree 205without conflicts. Alternately, you can add your script directory to the start 206of the $PATH and bash's "source" command will fall back to looking there next. 207