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).