mkinitrd
A handy way to run a program as init without a filesystem:
#! /bin/bash
set -e
set -u
set -x
rm -rf initrd/
mkdir initrd/
g++ -static [...] -o initrd/init main.cc
(cd initrd/ && (find | cpio -o -H newc)) \
| gzip -c \
> initrd.gz
Sometimes it can be useful to have /proc, /sys, /dev, etc. around:
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <error.h>
#include <unistd.h>
static void mkdirp(const char *name)
{
if (mkdir(name, 0777) == -1 && errno != EEXIST)
error(EXIT_FAILURE, errno, "mkdir()");
}
int main(int argc, char *argv[])
{
pid_t self = getpid();
if (getpid() == -1)
error(EXIT_FAILURE, errno, "getpid()");
if (self == 1) {
// We're init! Do some basic setup.
mkdirp("/proc");
if (mount("nodev", "/proc", "proc", 0, "") == -1)
error(EXIT_FAILURE, errno, "mount(/proc)");
mkdirp("/sys");
if (mount("nodev", "/sys", "sysfs", 0, "") == -1)
error(EXIT_FAILURE, errno, "mount(/sys)");
mkdirp("/dev");
if (mount("nodev", "/dev", "devtmpfs", 0, "") == -1)
error(EXIT_FAILURE, errno, "mount(/dev)");
if (mount("nodev", "/sys/kernel/tracing", "tracefs", 0, "") == -1)
error(EXIT_FAILURE, errno, "mount(/sys/kernel/tracing)");
}
...
}