github.com/insomniacslk/u-root@v0.0.0-20200717035308-96b791510d76/README.md (about) 1 # u-root 2 3 [![Build Status](https://circleci.com/gh/u-root/u-root/tree/master.png?style=shield&circle-token=8d9396e32f76f82bf4257b60b414743e57734244)](https://circleci.com/gh/u-root/u-root/tree/master) 4 [![Go Report Card](https://goreportcard.com/badge/github.com/u-root/u-root)](https://goreportcard.com/report/github.com/u-root/u-root) 5 [![GoDoc](https://godoc.org/github.com/u-root/u-root?status.svg)](https://godoc.org/github.com/u-root/u-root) 6 [![Slack](http://slack.u-root.com/badge.svg)](http://slack.u-root.com) 7 [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://github.com/u-root/u-root/blob/master/LICENSE) 8 9 # Description 10 11 u-root embodies four different projects. 12 13 * Go versions of many standard Linux tools, such as [ls](cmds/core/ls/ls.go), 14 [cp](cmds/core/cp/cp.go), or [shutdown](cmds/core/shutdown/shutdown.go). See 15 [cmds/core](cmds/core) for most of these. 16 17 * A way to compile many Go programs into a single binary with 18 [busybox mode](pkg/bb/README.md). 19 20 * A way to create initramfs (an archive of files) to use with Linux kernels. 21 22 * Go bootloaders that use `kexec` to boot Linux or multiboot kernels such as 23 ESXi, Xen, or tboot. They are meant to be used with 24 [LinuxBoot](https://www.linuxboot.org). With that, parsers for 25 [GRUB config files](pkg/boot/grub) or 26 [syslinux config files](pkg/boot/syslinux) are to make transition to 27 LinuxBoot easier. 28 29 # Usage 30 31 Make sure your Go version is 1.13. Make sure your `GOPATH` is set up correctly. 32 33 Download and install u-root: 34 35 ```shell 36 go get github.com/u-root/u-root 37 ``` 38 39 You can now use the u-root command to build an initramfs. Here are some 40 examples: 41 42 ```shell 43 # Build an initramfs of all the Go cmds in ./cmds/core/... (default) 44 u-root 45 46 # Generate an archive with bootloaders 47 # 48 # core and boot are templates that expand to sets of commands 49 u-root core boot 50 51 # Generate an archive with only these given commands 52 u-root ./cmds/core/{init,ls,ip,dhclient,wget,cat,elvish} 53 54 # Generate an archive with a tool outside of u-root 55 u-root ./cmds/core/{init,ls,elvish} github.com/u-root/cpu/cmds/cpud 56 ``` 57 58 The default set of packages included is all packages in 59 `github.com/u-root/u-root/cmds/core/...`. 60 61 In addition to using paths to specify Go source packages to include, you may 62 also use Go package import paths (e.g. `golang.org/x/tools/imports`) to include 63 commands. Only the `main` package and its dependencies in those source 64 directories will be included. For example: 65 66 You can build the initramfs built by u-root into the kernel via the 67 `CONFIG_INITRAMFS_SOURCE` config variable or you can load it separately via an 68 option in for example Grub or the QEMU command line or coreboot config variable. 69 70 ## Extra Files 71 72 You may also include additional files in the initramfs using the `-files` flag. 73 If you add binaries with `-files` are listed, their ldd dependencies will be 74 included as well. As example for Debian, you want to add two kernel modules for 75 testing, executing your currently booted kernel: 76 77 > NOTE: these files will be placed in the `$HOME` dir in the initramfs. 78 79 ```shell 80 u-root -files "$HOME/hello.ko $HOME/hello2.ko" 81 qemu-system-x86_64 -kernel /boot/vmlinuz-$(uname -r) -initrd /tmp/initramfs.linux_amd64.cpio 82 ``` 83 84 To specify the location in the initramfs, use `<sourcefile>:<destinationfile>`. 85 For example: 86 87 ```shell 88 u-root -files "root-fs/usr/bin/runc:usr/bin/run" 89 ``` 90 91 ## Init and Uinit 92 93 u-root has a very simple (exchangable) init system controlled by the `-initcmd` 94 and `-uinitcmd` command-line flags. 95 96 * `-initcmd` determines what `/init` is symlinked to. `-initcmd` may be a 97 u-root command name or a symlink target. 98 * `-uinitcmd` is run by the default u-root [init](cmds/core/init) after some 99 basic file system setup. There is no default, users should optionally supply 100 their own. `-uinitcmd` may be a u-root command name with arguments or a 101 symlink target with arguments. 102 * After running a uinit (if there is one), [init](cmds/core/init) will start a 103 shell determined by the `-defaultsh` argument. 104 105 We expect most users to keep their `-initcmd` as [init](cmds/core/init), but to 106 supply their own uinit for additional initialization or to immediately load 107 another operating system. 108 109 All three command-line args accept both a u-root command name or a target 110 symlink path. **Only `-uinitcmd` accepts command-line arguments, however.** For 111 example, 112 113 ```bash 114 u-root -uinitcmd="echo Go Gopher" ./cmds/core/{init,echo,elvish} 115 116 cpio -ivt < /tmp/initramfs.linux_amd64.cpio 117 # ... 118 # lrwxrwxrwx 0 root root 12 Dec 31 1969 bin/uinit -> ../bbin/echo 119 # lrwxrwxrwx 0 root root 9 Dec 31 1969 init -> bbin/init 120 121 qemu-system-x86_64 -kernel $KERNEL -initrd /tmp/initramfs.linux_amd64.cpio -nographic -append "console=ttyS0" 122 # ... 123 # [ 0.848021] Freeing unused kernel memory: 896K 124 # 2020/05/01 04:04:39 Welcome to u-root! 125 # _ 126 # _ _ _ __ ___ ___ | |_ 127 # | | | |____| '__/ _ \ / _ \| __| 128 # | |_| |____| | | (_) | (_) | |_ 129 # \__,_| |_| \___/ \___/ \__| 130 # 131 # Go Gopher 132 # ~/> 133 ``` 134 135 The command you name must be present in the command set. The following will *not 136 work*: 137 138 ```bash 139 u-root -uinitcmd="echo Go Gopher" ./cmds/core/{init,elvish} 140 # 2020/04/30 21:05:57 could not create symlink from "bin/uinit" to "echo": command or path "echo" not included in u-root build: specify -uinitcmd="" to ignore this error and build without a uinit 141 ``` 142 143 You can also refer to non-u-root-commands; they will be added as symlinks. We 144 don't presume to know whether your symlink target is correct or not. 145 146 This will build, but not work unless you add a /bin/foobar to the initramfs. 147 148 ```bash 149 u-root -uinitcmd="/bin/foobar Go Gopher" ./cmds/core/{init,elvish} 150 ``` 151 152 This will boot the same as the above. 153 154 ```bash 155 u-root -uinitcmd="/bin/foobar Go Gopher" -files /bin/echo:bin/foobar ./cmds/core/{init,elvish} 156 ``` 157 158 This will bypass the regular u-root init and just launch a shell: 159 160 ```bash 161 u-root -initcmd=elvish ./cmds/core/{elvish,ls} 162 163 cpio -ivt < /tmp/initramfs.linux_amd64.cpio 164 # ... 165 # lrwxrwxrwx 0 root root 9 Dec 31 1969 init -> bbin/elvish 166 167 qemu-system-x86_64 -kernel $KERNEL -initrd /tmp/initramfs.linux_amd64.cpio -nographic -append "console=ttyS0" 168 # ... 169 # [ 0.848021] Freeing unused kernel memory: 896K 170 # failed to put myself in foreground: ioctl: inappropriate ioctl for device 171 # ~/> 172 ``` 173 174 (It fails to do that because some initialization is missing when the shell is 175 started without a proper init.) 176 177 ## Cross Compilation (targeting different architectures and OSes) 178 179 Cross-OS and -architecture compilation comes for free with Go. In fact, every PR 180 to the u-root repo is built against the following architectures: amd64, x86 181 (i.e. 32bit), mipsle, armv7, arm64, and ppc64le. 182 183 Further, we run integration tests on linux/amd64, freebsd/amd64 and linux/arm64, 184 using several CI systems. If you need to add another CI system, processor or OS, 185 please let us know. 186 187 To cross compile for an ARM, on Linux: 188 189 ```shell 190 GOARCH=arm u-root 191 ``` 192 193 If you are on OSX, and wish to build for Linux on AMD64: 194 195 ```shell 196 GOOS=linux GOARCH=amd64 u-root 197 ``` 198 199 ## Testing in QEMU 200 201 A good way to test the initramfs generated by u-root is with qemu: 202 203 ```shell 204 qemu-system-x86_64 -nographic -kernel path/to/kernel -initrd /tmp/initramfs.linux_amd64.cpio 205 ``` 206 207 Note that you do not have to build a special kernel on your own, it is 208 sufficient to use an existing one. Usually you can find one in `/boot`. 209 210 If you quickly need to obtain a kernel, for example, when you are on a non-Linux 211 system, you can assemble a URL to download one through Arch Linux's 212 [iPXE menu file](https://www.archlinux.org/releng/netboot/archlinux.ipxe). It 213 would download from `${mirrorurl}iso/${release}/arch/boot/x86_64/vmlinuz`, so 214 just search for a mirror URL you prefer and a release version, for example, 215 `http://mirror.rackspace.com/archlinux/iso/2019.10.01/arch/boot/x86_64/vmlinuz`. 216 217 ### Framebuffer 218 219 For framebuffer support, append a VESA mode via the `vga` kernel parameter: 220 221 ```shell 222 qemu-system-x86_64 \ 223 -kernel path/to/kernel \ 224 -initrd /tmp/initramfs.linux_amd64.cpio \ 225 -append "vga=786" 226 ``` 227 228 For a list of modes, refer to the 229 [Linux kernel documentation](https://github.com/torvalds/linux/blob/master/Documentation/fb/vesafb.rst#how-to-use-it). 230 231 ### Entropy / Random Number Generator 232 233 Some utilities, e.g., `dhclient`, require entropy to be present. For a speedy 234 virtualized random number generator, the kernel should have the following: 235 236 ``` 237 CONFIG_VIRTIO_PCI=y 238 CONFIG_HW_RANDOM_VIRTIO=y 239 CONFIG_CRYPTO_DEV_VIRTIO=y 240 ``` 241 242 Then you can run your kernel in QEMU with a `virtio-rng-pci` device: 243 244 ```sh 245 qemu-system-x86_64 \ 246 -device virtio-rng-pci \ 247 -kernel vmlinuz \ 248 -initrd /tmp/initramfs.linux_amd64.cpio 249 ``` 250 251 In addition, you can pass your host's RNG: 252 253 ```sh 254 qemu-system-x86_64 \ 255 -object rng-random,filename=/dev/urandom,id=rng0 \ 256 -device virtio-rng-pci,rng=rng0 \ 257 -kernel vmlinuz \ 258 -initrd /tmp/initramfs.linux_amd64.cpio 259 ``` 260 261 ## SystemBoot 262 263 SystemBoot is a set of bootloaders written in Go. It is meant to be a 264 distribution for LinuxBoot to create a system firmware + bootloader. All of 265 these use `kexec` to boot. The commands are in [cmds/boot](cmds/boot). 266 267 * `pxeboot`: a network boot client that uses DHCP and HTTP or TFTP to get a 268 boot configuration which can be parsed as PXELinux or iPXE configuration 269 files to get a boot program. 270 271 * `boot`: finds all bootable kernels on local disk, shows a menu, and boots 272 them. Supports (basic) GRUB, (basic) syslinux, (non-EFI) BootLoaderSpec, and 273 ESXi configurations. 274 275 * `fbnetboot`: a network boot client that uses DHCP and HTTP to get a boot 276 program based on Linux, and boots it. To be merged with `pxeboot`. 277 278 * `localboot`: a tool that finds bootable kernel configurations on the local 279 disks and boots them. 280 281 * `systemboot`: a wrapper around `fbnetboot` and `localboot` that just mimicks 282 a BIOS/UEFI BDS behaviour, by looping between network booting and local 283 booting. Use `-uinitcmd` argument to the u-root build tool to make it the 284 boot program. 285 286 This project started as a loose collection of programs in u-root by various 287 LinuxBoot contributors, as well as a personal experiment by 288 [Andrea Barberio](https://github.com/insomniacslk) that has since been merged 289 in. It is now an effort of a broader community and graduated to a real project 290 for system firmwares. 291 292 More detailed information about the build process for a full LinuxBoot firmware 293 image using u-root/systemboot and coreboot can be found in the 294 [LinuxBoot book](https://github.com/linuxboot/book) chapter about 295 [LinuxBoot using coreboot, u-root and systemboot](https://github.com/linuxboot/book/blob/master/coreboot.u-root.systemboot/README.md). 296 297 You can build systemboot like this: 298 299 ```sh 300 u-root -build=bb -uinitcmd=systemboot core github.com/u-root/u-root/cmds/boot/{systemboot,localboot,fbnetboot} 301 ``` 302 303 ## Compression 304 305 You can compress the initramfs. However, for xz compression, the kernel has some 306 restrictions on the compression options and it is suggested to align the file to 307 512 byte boundaries: 308 309 ```shell 310 xz --check=crc32 -9 --lzma2=dict=1MiB \ 311 --stdout /tmp/initramfs.linux_amd64.cpio \ 312 | dd conv=sync bs=512 \ 313 of=/tmp/initramfs.linux_amd64.cpio.xz 314 ``` 315 316 ## Getting Packages of TinyCore 317 318 Using the `tcz` command included in u-root, you can install tinycore linux 319 packages for things you want. 320 321 You can use QEMU NAT to allow you to fetch packages. Let's suppose, for example, 322 you want bash. Once u-root is running, you can do this: 323 324 ```shell 325 % tcz bash 326 ``` 327 328 The tcz command computes and fetches all dependencies. If you can't get to 329 tinycorelinux.net, or you want package fetching to be faster, you can run your 330 own server for tinycore packages. 331 332 You can do this to get a local server using the u-root srvfiles command: 333 334 ```shell 335 % srvfiles -p 80 -d path-to-local-tinycore-packages 336 ``` 337 338 Of course you have to fetch all those packages first somehow :-) 339 340 ## Build an Embeddable U-root 341 342 You can build this environment into a kernel as an initramfs, and further embed 343 that into firmware as a coreboot payload. 344 345 In the kernel and coreboot case, you need to configure ethernet. We have a 346 `dhclient` command that works for both ipv4 and ipv6. Since v6 does not yet work 347 that well for most people, a typical invocation looks like this: 348 349 ```shell 350 % dhclient -ipv4 -ipv6=false 351 ``` 352 353 Or, on newer linux kernels (> 4.x) boot with ip=dhcp in the command line, 354 assuming your kernel is configured to work that way. 355 356 ## Build Modes 357 358 u-root can create an initramfs in two different modes: 359 360 * source mode includes Go toolchain binaries + simple shell + Go source files 361 in the initramfs archive. Tools are compiled from source on the fly by the 362 shell. 363 364 When you try to run a command that is not built, it is compiled first and 365 stored in tmpfs. From that point on, when you run the command, you get the 366 one in tmpfs. Don't worry: the Go compiler is pretty fast. 367 368 * bb mode: One busybox-like binary comprising all the Go tools you ask to 369 include. See [here for how it works](pkg/bb/README.md). 370 371 In this mode, u-root copies and rewrites the source of the tools you asked 372 to include to be able to compile everything into one busybox-like binary. 373 374 ## Updating Dependencies 375 376 ```shell 377 # The latest released version of dep is required: 378 curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh 379 dep ensure 380 ``` 381 382 # Hardware 383 384 If you want to see u-root on real hardware, this 385 [board](https://www.pcengines.ch/apu2.htm) is a good start. 386 387 # Contributions 388 389 For information about contributing, including how we sign off commits, please 390 see [CONTRIBUTING.md](CONTRIBUTING.md). 391 392 Improving existing commands (e.g., additional currently unsupported flags) is 393 very welcome. In this case it is not even required to build an initramfs, just 394 enter the `cmds/` directory and start coding. A list of commands that are on the 395 roadmap can be found [here](roadmap.md).