Git Product home page Git Product logo

u-root / u-root Goto Github PK

View Code? Open in Web Editor NEW
2.4K 96.0 392.0 104.26 MB

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.

Home Page: https://u-root.org

License: BSD 3-Clause "New" or "Revised" License

Shell 0.01% Go 99.62% Dockerfile 0.20% Assembly 0.14% Makefile 0.01% C 0.02%
embedded system tinycore kernel linux ramfs busybox initramfs coreboot linuxboot hacktoberfest

u-root's Introduction

u-root

Build Status codecov Go Report Card CodeQL GoDoc Slack License OpenSSF Best Practices

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 kexec to boot Linux or multiboot kernels such as ESXi, Xen, or tboot. They are meant to be used with LinuxBoot.

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-root
cd u-root
go install

Or install directly with go:

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

Note

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

Examples

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

git clone https://github.com/u-root/u-root
cd 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 commands
u-root core boot

# Generate an archive with only these given commands
u-root ./cmds/core/{init,ls,ip,dhclient,wget,cat,gosh}

# Generate an archive with all of the core tools with some exceptions
u-root core -cmds/core/{ls,losetup}

Important

u-root works exactly when go build and go list work as well.

Note

The u-root tool is the same as the mkuimage tool with some defaults applied.

In the near future, uimage will replace u-root.

Tip

To just build Go busybox binaries, try out gobusybox's makebb tool.

Multi-module workspace builds

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

$ 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/bb
lrwxrwxrwx   0 root     root            2 Jan  1  1970 bbin/cpud -> bb
lrwxrwxrwx   0 root     root            2 Jan  1  1970 bbin/gosh -> bb
lrwxrwxrwx   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, the goanywhere tool can create one on the fly. This works only 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 given modules, and then execs u-root 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 u-root tool is mkuimage 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 be included as well.

$ 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.6
lrwxrwxrwx   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.4
drwxr-xr-x   0 root     root            0 Jan  1  1970 lib64
lrwxrwxrwx   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

Init and Uinit

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

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

  • -uinitcmd is run by the default u-root init after some basic file system setup. There is no default, users should optionally supply their own. -uinitcmd 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 -defaultsh argument.

We expect most users to keep their -initcmd 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 -uinitcmd accepts command-line arguments, however. For example,

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/init

qemu-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 arguments to uinit via a flags file in /etc/uinit.flags, see Extra Files.

Additionally, you can pass arguments to uinit via the uroot.uinitargs kernel parameters, 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/init

qemu-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 will not work:

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

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/gosh

qemu-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 is started without a proper init.)

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:

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 is sufficient 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@latest

runvmtest -- bash -c "cp \$VMTEST_KERNEL ./kernel"

It may not have all features you require, however.

Framebuffer

For framebuffer support, append a VESA mode via the vga 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 the Linux kernel documentation.

Entropy / Random Number Generator

Some utilities, e.g., dhclient, require entropy to be present. For a speedy virtualized random number generator, the kernel should have the following:

CONFIG_VIRTIO_PCI=y
CONFIG_HW_RANDOM_VIRTIO=y
CONFIG_CRYPTO_DEV_VIRTIO=y

Then you can run your kernel in QEMU with a virtio-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 a distribution for LinuxBoot to create a system firmware + bootloader. All of these use kexec to boot. The commands are in cmds/boot. Parsers are available for GRUB, 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 a boot configuration which can be parsed as PXELinux or iPXE configuration files to get a boot program.

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

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

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

Compression

You can compress the initramfs. However, for xz compression, the kernel has some restrictions on the compression options and it is suggested to align the file to 512 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 the tcz command included in u-root, you can install tinycore linux packages 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 to tinycorelinux.net, or you want package fetching to be faster, you can run your own 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 the CONFIG_INITRAMFS_SOURCE config variable or coreboot config variable, and further embed the kernel image into firmware as a coreboot payload.

In the kernel and coreboot case, you may need to configure ethernet. We have a dhclient command that works for both ipv4 and ipv6. Since v6 does not yet work that 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 to include. See the gobusybox README for how it works. In this mode, u-root copies and rewrites the source of the tools you asked to include to be able to compile everything into one busybox-like binary.

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

Updating Dependencies

go get -u
go mod tidy
go mod vendor

Building without network access

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

Read more in the mkuimage README.

u-root also still supports GO111MODULE=off builds.

Hardware

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

Contributions

For information about contributing, including how we sign off commits, please see CONTRIBUTING.md.

Improving existing commands (e.g., additional currently unsupported flags) is very welcome. In this case it is not even required to build an initramfs, just enter the cmds/ directory and start coding. A list of commands that are on the roadmap can be found here.

u-root's People

Contributors

10000tb avatar ananya-joshi avatar bensallen avatar binjip978 avatar bkochendorfer avatar chengchiehhuang avatar chrimarme avatar floren avatar ganshun avatar hugelgupf avatar insomniacslk avatar jbeta51 avatar jensdrenhaus avatar johnnylinwiwynn avatar julienvdg avatar llogen avatar mdr164 avatar mpictor avatar orangecms avatar pallaud avatar risked avatar rjoleary avatar rminnich avatar rminnichcodeu avatar rojer9-fb avatar ryukinix avatar sipasing avatar thienhoang23 avatar tklauser avatar walterchris avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

u-root's Issues

Error handling in ramfs.go

Currently, ramfs.go uses log for errors and does not return them ex:

if config.Go == "" { log.Fatalf("Can't find a go binary! Is GOROOT set correctly?") }

Cp flags do not work

when I use cp - r I get error: flag provided but not defined: -r

similar to rm errors

How about a verbose mode on scripts/ramfs.go?

Disclaimer

At least on my machine (386), the ramfs.go now really take a good time to get into a u-root shell, about minutes. The debug mode has a lot of information, but is really annoying use this for anything instead debug.

Idea

How about create a -v option to put on stdout few information about what u-root are doing on ramfs.go? Is really scary don't know what he's doing on the normal mode. I think we don't need do too much, like a progressbar of compiling. Just print the sections of procedures to get into the ramfs would be good... searching libs,local variables, compiling source, preparing chroot and etc.

A minimal verbose mode. What you do think, guys?

installcommand does not compile command when passed --help

When sort is not yet compiled by installcommand, the output is:

% sort --help
Usage of sort:
  -ludicrous
    	print out ALL the output from the go build commands
  -v	print all build commands
wait: exit status 2:

The expect output is:

% sort --help
Usage of sort:
  -o string
    	Output file
  -r	Reverse
wait: exit status 2:

The flag.Parse() statement in installcommand exits early. Instead, if installcommand is accessed through symlink, we want to proceed as normal and pass --help into the compiled command.

Add ID command to uroot

The script to start sshd included by tinycore openssh relies on an id command. Since other packages may rely on this command as well, we should implement it.

Some commands with good code coverage show 0% coverage under `go test --cover`

At the moment, some of our tests with coverage are reported as 0% (ex: sort_test.go and uniq_test.go). The problem results from executing a process within the test via "go run" or "go build". The coverage tools aren't smart enough to descend into the child processes to count their coverage. Additionally, the child processes are not built with the proper instrumentation.

While a bit dated, the post here gives some useful background on the issue: https://blog.golang.org/cover

Things I've tried so far:

  • Executing the test within the test to create a subprocess. This technique is used by some tests in the go standard library. Unfortunately, the coverage array is not copied to the parent process.
  • Use the Go cover tool when building the child process's binary. Unfortunately, the coverage array is not copied to the parent process.

The only way I see of fixing this is using a function call rather than spawning a child process.

Relevant research:

rm: testing suite is incomplete

Many cases are not covered by rm_tests including - deleting empty directories - deleting files you do not have permission to and -deleting files that do not exist

Add utilities to flush out ip address?

Now we are working on utilities that get ipv4 or ipv6 address with dhcp. But do we need to add utilities so that we are able to flush out the address we add?

Travis build is broken due to `printenv_test.go`

Travis build is currently failing on the master branch: https://travis-ci.org/u-root/u-root/builds/196068822 . The cause is printenv_test.go.

The test works on my machine, but by taking a closer look, it is susceptible to a problem:

  • Environment variables containing a newline:

      export UHOH=$'ha\nha'
      go test
    

    This is guaranteed to fail the test.

This may not be the cause of the test failure under Travis, but is my best hunch.

Things to fix:

  • Verbose output in Travis
  • To ensure consistency, the test should unset all unwanted environment variables.
  • Using newlines as a separator is part of a much larger problem.

RUN_ME_FIRST error

Hi, I was trying to run the RUN_ME_FIRST file but I got these errors.

errorreadme

This is the output
% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 318 0 0 0 0 0 0 --:--:-- 0:00:06 --:--:-- 0 100 4682 100 4682 0 0 450 0 0:00:10 0:00:10 --:--:-- 2428 2016/06/07 23:41:45 Using /usr/local/go from the environment as the GOROOT 2016/06/07 23:42:23 Go get failed: err exit status 1, output [103 111 32 105 110 115 116 97 108 108 32 114 117 110 116 105 109 101 47 105 110 116 101 114 110 97 108 47 115 121 115 58 32 111 112 101 110 32 47 117 115 114 47 108 111 99 97 108 47 103 111 47 112 107 103 47 108 105 110 117 120 95 97 109 100 54 52 47 114 117 110 116 105 109 101 47 105 110 116 101 114 110 97 108 47 115 121 115 46 97 58 32 112 101 114 109 105 115 115 105 111 110 32 100 101 110 105 101 100 10] 2016/06/07 23:44:33 Go get failed: err exit status 1, output [103 111 32 105 110 115 116 97 108 108 32 114 117 110 116 105 109 101 47 105 110 116 101 114 110 97 108 47 115 121 115 58 32 111 112 101 110 32 47 117 115 114 47 108 111 99 97 108 47 103 111 47 112 107 103 47 108 105 110 117 120 95 97 109 100 54 52 47 114 117 110 116 105 109 101 47 105 110 116 101 114 110 97 108 47 115 121 115 46 97 58 32 112 101 114 109 105 115 115 105 111 110 32 100 101 110 105 101 100 10]

Can you guide me to solve this?

Thanks.

add insmod, lsmod, rmmod

See summary. A cursory look at init-tools source indicates that it may be enough to just wrap SYS_INIT_MODULE and SYS_DELETE_MODULE. lsmod should only need to look at /proc/modules.

slack channel problems

Joining u-root.slack.com indicates one must have a Princeton or MIT email address. Can this be opened?

ps.go broken: bug between walk at /proc and reading stats of process

Sometimes when process disappears at the middle of operations in walking and reading stats, we got that weird error:

2016/03/09 19:53:37 /proc/7020: lstat /proc/7020: no such file or directory
--- FAIL: TestPsExecution (0.01s)
    ps_test.go:18: Loading Table fails on some point; lstat /proc/7020: no such file or directory
FAIL
FAIL    github.com/u-root/u-root/cmds/ps    0.008s

The most probable functions whose may be the guilty of this are:

rm -r flag does not work

I wanted to remove multiple files

I ran rm -r to remove all files in a directory and got the following error: flag provided but not defined: -r
Usage: rm [-Rrvi] file...:
wait:exit status 2
NOTE: this is going to fail right now

Enable website: why not?

We need just this to enable our website and get visible.

mv website docs

And activate gh-pages by:

docs

I think we can create a more friendly documentation on README.md too.

Improper lexical parsing for bb cmd

  1. An error is not thrown if there is an error in lexical parsing
  2. Multiple whitespaces between the arguments are not condensed
  3. A space in a filename is counted as two different files

TCZ: Automount existing TCZ packages

We should include a feature of TCZ or a command that will mount all the existing TCZ packages.

This would prevent us from having to individually tcz each package by name between each power on. Adding this functionality would make the time from boot to running packages much quicker. Furthermore, it would be a useful feature to include in a future library of init scripts.

Multiple DHCPv6 Servers in the same network

Now the DHCPv6 client just handles the first DHCPv6 packet it gets after it sends out a request. even if there are multiple DHCPv6 servers in the same network. It is okay if both servers reply with a valid IPv6 address.

However, if one server does not have available address for the client whereas the other has, and the former one replies faster than latter, the client will miss the DHCPv6 address that is assigned to it.

I don't know how possible such scenario happens in real world. If so then perhaps we have to fix it right away.

A possible solution would be: keep client in the loop until it receives a DHCPv6 reply that has a valid IPv6 address, or time runs out.

standardize our file layout

the scripts/ and bb/ directories are historical. To fit Go guidelines, we need a
cmd/bb
cmd/ramfs
cmd/whatever

directory layout, so that go get builds the commands when we do a go get.

Doing this right is a little tricky and you want to do it one command at a time, not all commands at once. Consider starting with making scripts/ramfs.go be cmd/ramfs/ramfs.go instead.

Implement rm force flag

Right now, the rm command does not have a force flag. This could come in handy when you may not have permissions needed to remove a file without prompting.

TCZ does not work

  1. It downloads tcz packages that already exist
  2. It will mount on top of older versions
  3. It does not create tcloop directories correctly
    • It spltis on "." instead of removing ".tcz" from the command names
    • This causes packages to be mounted in the same place i.e. "Xorg-7.7.tcz" and "Xorg-7.7-bin.tcz" both mount to "Xorg-7"
  4. It needs a debug flag "-d" to enable/disable print statements

Naive attempt to test u-root, problem with cpio

2016/10/16 12:44:57 exit status 1
2016/10/16 12:44:57 External cpio is done
2016/10/16 12:44:57 Done all cpio operations
2016/10/16 12:44:57 Creating initramf file
2016/10/16 12:44:57 Run &{/usr/bin/sudo [sudo cpio -H newc -o -A -F /tmp/initramfs.linux_386.cpio] [] /tmp/u-root247321542 0x1862c748 0x185260e0 0x185260e8 [] <nil> <nil> <nil> <nil> <nil> false [] [] [] [] <nil> <nil>} @ /tmp/u-root247321542
2016/10/16 12:44:57 Finished sending file list for initramfs cpio
sudo: cpio: command not found
2016/10/16 12:44:57 exit status 1
2016/10/16 12:44:57 cpio for initramfs is done
2016/10/16 12:44:57 Run &{/usr/bin/sudo [sudo cpio -i] [] /tmp/u-root247321542 0x1862c870 0x185260e0 0x185260e8 [] <nil> <nil> <nil> <nil> <nil> false [] [] [] [] <nil> <nil>} @ /tmp/u-root247321542
sudo: cpio: command not found
2016/10/16 12:44:57 exit status 1
exit status 1

I got this after execute go run scripts/ramfs.go -test -d. Maybe we need put cpio as dependency on docs?

Faster Go Compiling

I got tipped off by this comment: https://www.reddit.com/r/golang/comments/476pae/how_to_speed_up_go_compiler_and_many_other_go/

The idea is to run the compiler's garbage collector less frequently because we know the compiler is alive for only a few seconds and all the piled-up memory can be quickly freed at the end.

I tested it out on the busybox (with go1.7.4):

~/go/src/github.com/u-root/u-root/bb$ /usr/bin/time -p go run *.go
real 3.88s
user 7.95s
sys 0.81s
maxresident 95088KiB

~/go/src/github.com/u-root/u-root/bb$ GOGC=2000 /usr/bin/time -p go run *.go
real 3.29s
user 4.29s
sys 0.66s
maxresident 151800KiB

By setting this flag, bb can be compiled 15% faster, but at the cost of 56712KiB of memory (60% increase). Testing various individual commands shows an increase of 10%-30%.

I propose it is reasonable to increase the value of GOGC passed into go build by installcommand. The environment variable affects the compilation time and not the compiled binary. When the environment variable is not set, its value defaults to 100. Any concerns?

Side note: I've already started implementing a Go version of time, so we can measure the value within the ramfs.

Add switch root script

Currently there is no "switch_root" command that allows u-root to switch from the RAM file system to another device.

Set up an easy-to-use qemu test harness

What we'd like is an easy to use qemu setup. You'll need to find a good place to get a kernel (remember, this test should work on OSX, so using /boot/whatever is not fair!). The steps would be something like

  1. go run script/initramfs.go for the architecture you want to test on
  2. get a kernel for that architecture that has network, and graphics
  3. run qemu-xx-yy with the right arguments

This script should be written in Go, not bash, zsh, or whatever.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.