mkinitrd: Difference between revisions
Jump to navigation
Jump to search
Content added Content deleted
(add mounting code) |
(add ftrace example) |
||
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 60: | Line 62: | ||
... |
... |
||
} |
|||
</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> |
</source> |
Revision as of 06:27, 15 December 2019
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);
}
}