mkinitrd: Difference between revisions

From vegard.wiki
Jump to navigation Jump to search
Content added Content deleted
(add mounting code)
(add ftrace link)
 
(One intermediate revision by the same user not shown)
Line 16: Line 16:
> initrd.gz
> initrd.gz
</source>
</source>

=== Mounting filesystems ===


Sometimes it can be useful to have <tt>/proc</tt>, <tt>/sys</tt>, <tt>/dev</tt>, etc. around:
Sometimes it can be useful to have <tt>/proc</tt>, <tt>/sys</tt>, <tt>/dev</tt>, etc. around:
Line 62: Line 64:
}
}
</source>
</source>

=== ftrace ===

To trace something with ftrace (and dump the trace), use something like:

<source lang="C">
#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);
}
}
</source>

See also: [[ftrace]].


[[Category:Linux kernel]]
[[Category:Linux kernel]]

Latest revision as of 14:36, 7 October 2022

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.