Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A fully Go userland with Linux bootloaders! u-root can create a one-binary root file system (initramfs) containing a busybox-like set of tools written in Go.

License

NotificationsYou must be signed in to change notification settings

u-root/u-root

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Build StatuscodecovGo Report CardCodeQLGoDocSlackLicenseOpenSSF Best Practices

Description

u-root embodies four different projects.

  • Go versions of many standard Linux tools, such asls,cp, orshutdown. Seecmds/core for most of these.

  • A way to compile many Go programs into a single binary withbusybox mode.

  • A way to create initramfs (an archive of files) to use with Linux kernels,embeddable into firmware.

  • Gobootloaders that usekexec to boot Linux or multibootkernels such as ESXi, Xen, or tboot. They are meant to be used withLinuxBoot.

Requirements

For u-root on Linux, certain Kconfig options are necessary. Basic defconfigs areinconfigs/. See also theconfigs README.

Usage

Make sure your Go version is >= 1.21.

Download and install u-root either via git:

git clone https://github.com/u-root/u-rootcd u-rootgo install

Or install directly with go:

go install github.com/u-root/u-root@latest

Note

Theu-root command will end up in$GOPATH/bin/u-root, so you mayneed to add$GOPATH/bin to your$PATH.

Examples

Here are some examples of using theu-root command to build an initramfs.

git clone https://github.com/u-root/u-rootcd u-root# Build an initramfs of all the Go cmds in ./cmds/core/... (default)u-root# Generate an archive with bootloaders## core and boot are templates that expand to sets of commandsu-root core boot# Generate an archive with only these given commandsu-root ./cmds/core/{init,ls,ip,dhclient,wget,cat,gosh}# Generate an archive with all of the core tools with some exceptionsu-root core -cmds/core/{ls,losetup}

Important

u-root works exactly whengo build andgo list work as well.

See also the section below discussing theAMD64 architecture level.

Note

Theu-root tool is the same as themkuimage tool with some defaultsapplied.

In the near future,uimage will replaceu-root.

Tip

To just build Go busybox binaries, try outgobusybox'smakebb tool.

Multi-module workspace builds

There are several ways to build multi-module command images using standard Gotooling.

$ mkdir workspace$cd workspace$ git clone https://github.com/u-root/u-root$ git clone https://github.com/u-root/cpu$ go work init ./u-root$ go work use ./cpu$ u-root ./u-root/cmds/core/{init,gosh} ./cpu/cmds/cpud$ cpio -ivt< /tmp/initramfs.linux_amd64.cpio...-rwxr-x---   0 root     root      6365184 Jan  1  1970 bbin/bblrwxrwxrwx   0 root     root            2 Jan  1  1970 bbin/cpud -> bblrwxrwxrwx   0 root     root            2 Jan  1  1970 bbin/gosh -> bblrwxrwxrwx   0 root     root            2 Jan  1  1970 bbin/init -> bb...# Works for offline vendored builds as well.$ go work vendor# Go 1.22 feature.$ u-root ./u-root/cmds/core/{init,gosh} ./cpu/cmds/cpud

When creating a new Go workspace is too much work, thegoanywhere tool cancreate one on the fly. This worksonly with local file system paths:

$ go install github.com/u-root/gobusybox/src/cmd/goanywhere@latest$ goanywhere ./u-root/cmds/core/{init,gosh} ./cpu/cmds/cpud -- u-root

goanywhere creates a workspace in a temporary directory with the givenmodules, and then execsu-root in the workspace passing along the commandnames.

Tip

While workspaces are good for local compilation, they are not meant to bechecked in to version control systems.

For a non-workspace way of building multi-module initramfs images, read morein themkuimage README. (Theu-roottool ismkuimage with more defaults applied.)

Extra Files

You may also include additional files in the initramfs using the-files flag.

If you add binaries with-files are listed, their ldd dependencies will beincluded as well by default. See below for how to disable.

$ u-root -files /bin/bash$ cpio -ivt< /tmp/initramfs.linux_amd64.cpio...-rwxr-xr-x   0 root     root      1277936 Jan  1  1970 bin/bash...drwxr-xr-x   0 root     root            0 Jan  1  1970 lib/x86_64-linux-gnu-rwxr-xr-x   0 root     root       210792 Jan  1  1970 lib/x86_64-linux-gnu/ld-linux-x86-64.so.2-rwxr-xr-x   0 root     root      1926256 Jan  1  1970 lib/x86_64-linux-gnu/libc.so.6lrwxrwxrwx   0 root     root           15 Jan  1  1970 lib/x86_64-linux-gnu/libtinfo.so.6 -> libtinfo.so.6.4-rw-r--r--   0 root     root       216368 Jan  1  1970 lib/x86_64-linux-gnu/libtinfo.so.6.4drwxr-xr-x   0 root     root            0 Jan  1  1970 lib64lrwxrwxrwx   0 root     root           42 Jan  1  1970 lib64/ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2...

You can determine placement with colons:

$ u-root -files"/bin/bash:sbin/sh"$ cpio -ivt< /tmp/initramfs.linux_amd64.cpio...-rwxr-xr-x   0 root     root      1277936 Jan  1  1970 sbin/sh...

For example on Debian, if you want to add two kernel modules for testing,executing your currently booted kernel:

$ u-root -files"$HOME/hello.ko:etc/hello.ko" -files"$HOME/hello2.ko:etc/hello2.ko"$ qemu-system-x86_64 -kernel /boot/vmlinuz-$(uname -r) -initrd /tmp/initramfs.linux_amd64.cpio

Use-skip-ldd to not automatically include ldd dependencies for binary files. This can be useful for

  • Reproducible Builds: Ensures builds don't depend on the host system's libraries
  • Cross-compilation: When host libraries are incompatible with target architecture
  • Controlled Dependencies: When you want to manually specify exact library versions

Init and Uinit

u-root has a very simple (exchangable) init system controlled by the-initcmdand-uinitcmd command-line flags.

  • -initcmd determines what/init is symlinked to.-initcmd may be au-root command name or a symlink target.

  • -uinitcmd is run by the default u-rootinit after somebasic file system setup. There is no default, users should optionally supplytheir own.-uinitcmd may be a u-root command name with arguments or asymlink target with arguments.

  • After running a uinit (if there is one),init will start ashell determined by the-defaultsh argument.

We expect most users to keep their-initcmd asinit, but tosupply their own uinit for additional initialization or to immediately loadanother operating system.

All three command-line args accept both a u-root command name or a targetsymlink path.Only-uinitcmd accepts command-line arguments, however. Forexample,

u-root -uinitcmd="echo Go Gopher" ./cmds/core/{init,echo,gosh}cpio -ivt< /tmp/initramfs.linux_amd64.cpio# ...# lrwxrwxrwx   0 root     root           12 Dec 31  1969 bin/uinit -> ../bbin/echo# lrwxrwxrwx   0 root     root            9 Dec 31  1969 init -> bbin/initqemu-system-x86_64 -kernel$KERNEL -initrd /tmp/initramfs.linux_amd64.cpio -nographic -append"console=ttyS0"# ...# [    0.848021] Freeing unused kernel memory: 896K# 2020/05/01 04:04:39 Welcome to u-root!#                              _#   _   _      _ __ ___   ___ | |_#  | | | |____| '__/ _ \ / _ \| __|#  | |_| |____| | | (_) | (_) | |_#   \__,_|    |_|  \___/ \___/ \__|## Go Gopher# ~/>

Passing command line arguments like above is equivalent to passing the argumentsto uinit via a flags file in/etc/uinit.flags, seeExtra Files.

Additionally, you can pass arguments to uinit via theuroot.uinitargs kernelparameters, for example:

u-root -uinitcmd="echo Gopher" ./cmds/core/{init,echo,gosh}cpio -ivt< /tmp/initramfs.linux_amd64.cpio# ...# lrwxrwxrwx   0 root     root           12 Dec 31  1969 bin/uinit -> ../bbin/echo# lrwxrwxrwx   0 root     root            9 Dec 31  1969 init -> bbin/initqemu-system-x86_64 -kernel$KERNEL -initrd /tmp/initramfs.linux_amd64.cpio -nographic -append"console=ttyS0 uroot.uinitargs=Go"# ...# [    0.848021] Freeing unused kernel memory: 896K# 2020/05/01 04:04:39 Welcome to u-root!#                              _#   _   _      _ __ ___   ___ | |_#  | | | |____| '__/ _ \ / _ \| __|#  | |_| |____| | | (_) | (_) | |_#   \__,_|    |_|  \___/ \___/ \__|## Go Gopher# ~/>

Note the order of the passed arguments in the above example.

The command you name must be present in the command set. The following willnotwork:

u-root -uinitcmd="echo Go Gopher" ./cmds/core/{init,gosh}# 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

You can also refer to non-u-root-commands; they will be added as symlinks. Wedon't presume to know whether your symlink target is correct or not.

This will build, but not work unless you add a /bin/foobar to the initramfs.

u-root -uinitcmd="/bin/foobar Go Gopher" ./cmds/core/{init,gosh}

This will boot the same as the above.

u-root -uinitcmd="/bin/foobar Go Gopher" -files /bin/echo:bin/foobar -files your-hosts-file:/etc/hosts ./cmds/core/{init,gosh}

The effect of the above command:

  • Sets up the uinit command to be /bin/foobar, with 2 arguments: Go Gopher
  • Adds /bin/echo as bin/foobar
  • Adds your-hosts-file as etc/hosts
  • builds in the cmds/core/init, and cmds/core/gosh commands.

This will bypass the regular u-root init and just launch a shell:

u-root -initcmd=gosh ./cmds/core/{gosh,ls}cpio -ivt< /tmp/initramfs.linux_amd64.cpio# ...# lrwxrwxrwx   0 root     root            9 Dec 31  1969 init -> bbin/goshqemu-system-x86_64 -kernel$KERNEL -initrd /tmp/initramfs.linux_amd64.cpio -nographic -append"console=ttyS0"# ...# [    0.848021] Freeing unused kernel memory: 896K# failed to put myself in foreground: ioctl: inappropriate ioctl for device# ~/>

(It fails to do that because some initialization is missing when the shell isstarted without a proper init.)

AMD64 Architecture Level

Before building an initramfs for AMD64 withu-root, verify that the command

go env GOAMD64

printsv1. AGOAMD64 settingof any higher version may produce such binaries that don't execute on old AMD64processors (including the default CPU model of QEMU).

GOAMD64 can be reset tov1 with one of the following methods:

  • through theGOAMD64 environment variable:

    export GOAMD64=v1
  • throughgo env (only takes effect if theGOAMD64 environment variableis not set):

    go env -w GOAMD64=v1

Cross Compilation (targeting different architectures and OSes)

Cross-OS and -architecture compilation comes for free with Go. In fact, every PRto the u-root repo is built against the following architectures: amd64, x86(i.e. 32bit), mipsle, armv7, arm64, and ppc64le.

Further, we run integration tests on linux/amd64, and linux/arm64, using severalCI systems. If you need to add another CI system, processor or OS, please let usknow.

To cross compile for an ARM, on Linux:

GOARCH=arm u-root

If you are on OSX, and wish to build for Linux on AMD64:

GOOS=linux GOARCH=amd64 u-root

Testing in QEMU

A good way to test the initramfs generated by u-root is with qemu:

qemu-system-x86_64 -nographic -kernel path/to/kernel -initrd /tmp/initramfs.linux_amd64.cpio

Note that you do not have to build a special kernel on your own, it issufficient to use an existing one. Usually you can find one in/boot.

If you don't have a kernel handy, you can also get the one we use for VM testing:

go install github.com/hugelgupf/vmtest/tools/runvmtest@latestrunvmtest -- bash -c"cp\$VMTEST_KERNEL ./kernel"

It may not have all features you require, however.

Framebuffer

For framebuffer support, append a VESA mode via thevga kernel parameter:

qemu-system-x86_64 \  -kernel path/to/kernel \  -initrd /tmp/initramfs.linux_amd64.cpio \  -append"vga=786"

For a list of modes, refer to theLinux kernel documentation.

Entropy / Random Number Generator

Some utilities, such asdhclient, require entropy to be present. Withoutsufficient entropy, they may take a while to succeed, possibly half a minute.

If your platform has a hardware random number generator, enable it withCONFIG_ARCH_RANDOM and trust it withCONFIG_RANDOM_TRUST_CPU.Otherwise, adduroot.nohwrng to your kernel command line so u-root uses anon-blocking software random number generator implementation.

For a speedy virtualized random number generator, the kernel should have thefollowing:

CONFIG_VIRTIO_PCI=yCONFIG_HW_RANDOM_VIRTIO=yCONFIG_CRYPTO_DEV_VIRTIO=y

Then you can run your kernel in QEMU with avirtio-rng-pci device:

qemu-system-x86_64 \    -device virtio-rng-pci \    -kernel vmlinuz \    -initrd /tmp/initramfs.linux_amd64.cpio

In addition, you can pass your host's RNG:

qemu-system-x86_64 \    -object rng-random,filename=/dev/urandom,id=rng0 \    -device virtio-rng-pci,rng=rng0 \    -kernel vmlinuz \    -initrd /tmp/initramfs.linux_amd64.cpio

SystemBoot

SystemBoot is a set of bootloaders written in Go. It is meant to be adistribution for LinuxBoot to create a system firmware + bootloader. All ofthese usekexec to boot. The commands are incmds/boot.Parsers are available forGRUB,syslinux,and other config files to make the transition to LinuxBoot easier.

  • pxeboot: a network boot client that uses DHCP and HTTP or TFTP to get aboot configuration which can be parsed as PXELinux or iPXE configurationfiles to get a boot program.

  • boot: finds all bootable kernels on local disk, shows a menu, and bootsthem. Supports (basic) GRUB, (basic) syslinux, (non-EFI) BootLoaderSpec, andESXi configurations.

More detailed information about the build process for a full LinuxBoot firmwareimage using u-root/systemboot and coreboot can be found in theLinuxBoot book chapter aboutLinuxBoot using coreboot, u-root and systemboot.

This project started as a loose collection of programs in u-root by variousLinuxBoot contributors, as well as a personal experiment byAndrea Barberio that has since been mergedin. It is now an effort of a broader community and graduated to a real projectfor system firmwares.

Compression

You can compress the initramfs. However, for xz compression, the kernel has somerestrictions on the compression options and it is suggested to align the file to512 byte boundaries:

xz --check=crc32 -9 --lzma2=dict=1MiB \   --stdout /tmp/initramfs.linux_amd64.cpio \| dd conv=sync bs=512 \   of=/tmp/initramfs.linux_amd64.cpio.xz

Getting Packages of TinyCore

Using thetcz command included in u-root, you can install tinycore linuxpackages for things you want.

You can use QEMU NAT to allow you to fetch packages. Let's suppose, for example,you want bash. Once u-root is running, you can do this:

% tcz bash

The tcz command computes and fetches all dependencies. If you can't get totinycorelinux.net, or you want package fetching to be faster, you can run yourown server for tinycore packages.

You can do this to get a local server using the u-root srvfiles command:

% srvfiles -p 80 -d path-to-local-tinycore-packages

Of course you have to fetch all those packages first somehow :-)

Build an Embeddable u-root

You can build the cpio image created by u-root into a Linux kernel via theCONFIG_INITRAMFS_SOURCE config variable or coreboot config variable, andfurther embed the kernel image into firmware as a coreboot payload.

In the kernel and coreboot case, you may need to configure ethernet. We have adhclient command that works for both ipv4 and ipv6. Since v6 does not yet workthat well for most people, a typical invocation looks like this:

% dhclient -ipv4 -ipv6=false

Or, on newer linux kernels (> 4.x) boot with ip=dhcp in the command line,assuming your kernel is configured to work that way.

Build Modes

u-root can create an initramfs in two different modes, specified by-build:

  • gbb mode: One busybox-like binary comprising all the Go tools you ask toinclude.Seethe gobusybox README for how it works.In this mode, u-root copies and rewrites the source of the tools you askedto include to be able to compile everything into one busybox-like binary.

  • binary mode: each specified binary is compiled separately and all binariesare added to the initramfs.

Updating Dependencies

go get -ugo mod tidygo mod vendor

Building without network access

The u-root command supports building with workspace vendoring and modulevendoring. In both of those cases, if all dependencies are found in the vendoreddirectories, the build happens completely offline.

Read more in themkuimage README.

u-root also still supportsGO111MODULE=off builds.

Hardware

If you want to see u-root on real hardware, thisboard is a good start.

Using with Plan 9

U-root works with Plan 9. The best distro to use for it is 9front, as the9front cpiofs works with newc-format cpio (the format of Linux initramfs, whichu-root generates).

Here is a script for Plan 9. Once this script runs, all the u-root commandsappear in /bin. You will need to have go1.22 installed on Plan 9; orcreate the u-root initramfs on some other system and copy it to Plan 9.

#!/bin/rcu-root'-defaultsh=''-initcmd=''-shellbang=true'fs/cpiofs /tmp/initram*cpiobind -a /n/tapefs /bind -a /bbin /bin

Contributions

For information about contributing, including how we sign off commits, pleaseseeCONTRIBUTING.md.

Improving existing commands (e.g., additional currently unsupported flags) isvery welcome. In this case it is not even required to build an initramfs, justenter thecmds/ directory and start coding. A list of commands that are on theroadmap can be foundhere.

Website

The sources ofu-root.org are inside thedocs/ directory andare deployed to the gh-pages branch. The CNAME file is currently not part of the CIwhich deploys to the branch which shall be evaluated if this makes futures deployments easier.

About

A fully Go userland with Linux bootloaders! u-root can create a one-binary root file system (initramfs) containing a busybox-like set of tools written in Go.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors183

Languages


[8]ページ先頭

©2009-2025 Movatter.jp