mkinitrd
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
Mounting filesystems
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)");
}
...
}
ftrace
To trace something with ftrace (and dump the trace), use something like:
#define tracing_set(name, value) \
{ \
FILE *fp = fopen("/sys/kernel/tracing/" #name, "w"); \
if (!fp) \
error(EXIT_FAILURE, errno, "fopen(" #name ")"); \
fprintf(fp, "%s\n", #value); \
fclose(fp); \
}
int main(int argc, char *argv[])
{
// ...
tracing_set(current_tracer, function_graph);
tracing_set(tracing_on, 1);
// insert traced code here
tracing_set(tracing_on, 0);
// dump trace
{
FILE *fp = fopen("/sys/kernel/tracing/trace", "r");
while (fp && !feof(fp)) {
char buf[1024];
size_t len = fread(buf, 1, sizeof buf, fp);
fwrite(buf, 1, len, stdout);
}
fclose(fp);
}
}
See also: ftrace.