u-root / u-root
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.
View on GitHubAI Architecture Analysis
This repository is indexed by RepoMind. By analyzing u-root/u-root in our AI interface, you can instantly generate complete architecture diagrams, visualize control flows, and perform automated security audits across the entire codebase.
Our Agentic Context Augmented Generation (Agentic CAG) engine loads full source files into context on-demand, avoiding the fragmentation of traditional RAG systems. Ask questions about the architecture, dependencies, or specific features to see it in action.
Repository Overview (README excerpt)
Crawler viewu-root Description u-root embodies four different projects. • Go versions of many standard Linux tools, such as ls, cp, or shutdown. See cmds/core for most of these. • A way to compile many Go programs into a single binary with busybox mode. • A way to create initramfs (an archive of files) to use with Linux kernels, embeddable into firmware. • Go bootloaders that use to boot Linux or multiboot kernels such as ESXi, Xen, or tboot. They are meant to be used with LinuxBoot. Requirements For u-root on Linux, certain Kconfig options are necessary. Basic defconfigs are in . See also the configs README. Demo Below is a demo of what it looks like, on OSX (but tested on Linux too). To recreate this demo: It goes by quickly, but the process of rewriting 115 commands into Go packages, via the Go AST package (i.e. compiler front end); and recompiling all that into one command and generating an initramfs, takes 7 seconds. For arm64 and riscv64, the time is also about 7 seconds. The entire set of commands, including VM boot and exit, is 31 seconds. Note: you do not need to supply an amd64, arm64, or riscv64 kernel; it is built-in to the package. GOARCH=arm64 and GOARCH=riscv64 work too. View Demo Usage Make sure your Go version is >= 1.21. Download and install u-root either via git: Or install directly with go: > [!NOTE] > The command will end up in , so you may > need to add to your . Examples Here are some examples of using the command to build an initramfs. > [!IMPORTANT] > > works exactly when and work as well. > > See also the section below discussing the > AMD64 architecture level. > [!NOTE] > > The tool is the same as the > mkuimage tool with some defaults > applied. > > In the near future, will replace . > [!TIP] > > To just build Go busybox binaries, try out > gobusybox's tool. Multi-module workspace builds There are several ways to build multi-module command images using standard Go tooling. When creating a new Go workspace is too much work, the tool can create one on the fly. This works **only with local file system paths**: creates a workspace in a temporary directory with the given modules, and then execs in the workspace passing along the command names. > [!TIP] > > While workspaces are good for local compilation, they are not meant to be > checked in to version control systems. > > For a non-workspace way of building multi-module initramfs images, read more > in the mkuimage README. (The > tool is with more defaults applied.) Extra Files You may also include additional files in the initramfs using the flag. If you add binaries with are listed, their ldd dependencies will be included as well by default. See below for how to disable. You can determine placement with colons: For example on Debian, if you want to add two kernel modules for testing, executing your currently booted kernel: Use 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 and command-line flags. • determines what is symlinked to. may be a u-root command name or a symlink target. • is run by the default u-root init after some basic file system setup. There is no default, users should optionally supply their own. may be a u-root command name with arguments or a symlink target with arguments. • After running a uinit (if there is one), init will start a shell determined by the argument. We expect most users to keep their as init, but to supply their own uinit for additional initialization or to immediately load another operating system. All three command-line args accept both a u-root command name or a target symlink path. **Only accepts command-line arguments, however.** For example, Passing command line arguments like above is equivalent to passing the arguments to uinit via a flags file in , see Extra Files. Additionally, you can pass arguments to uinit via the kernel parameters, for example: Note the order of the passed arguments in the above example. The command you name must be present in the command set. The following will *not work*: You can also refer to non-u-root-commands; they will be added as symlinks. We don'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. This will boot the same as the above. 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: (It fails to do that because some initialization is missing when the shell is started without a proper init.) AMD64 Architecture Level Before building an initramfs for AMD64 with , verify that the command prints . A setting of any higher version may produce such binaries that don't execute on old AMD64 processors (including the default CPU model of QEMU). can be reset to with one of the following methods: • through the environment variable: • through (only takes effect if the environment variable is not set): Cross Compilation (targeting different architectures and OSes) Cross-OS and -architecture compilation comes for free with Go. In fact, every PR to 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 several CI systems. If you need to add another CI system, processor or OS, please let us know. To cross compile for an ARM, on Linux: If you are on OSX, and wish to…