mkinitrd

From vegard.wiki
Revision as of 06:15, 15 December 2019 by Vegard (talk | contribs) (add mounting code)
Jump to navigation Jump to search

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)");
        }

        ...
}