apio
36fad85396
All checks were successful
continuous-integration/drone/push Build is passing
Still allow printing text to the console, but without text input or ANSI escape fancy stuff.
83 lines
1.9 KiB
C++
83 lines
1.9 KiB
C++
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/mount.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/syscall.h>
|
|
#include <unistd.h>
|
|
|
|
// FIXME: Make this configurable.
|
|
#define LUNA_ROOT_PARTITION "/dev/cd0p2"
|
|
|
|
static void mount_devfs()
|
|
{
|
|
if (mkdir("/dev", 0755) < 0 && errno != EEXIST && errno != EROFS) exit(255);
|
|
|
|
if (mount("/dev", "devfs", "devfs") < 0) exit(255);
|
|
}
|
|
|
|
static void open_std_streams()
|
|
{
|
|
stdin = fopen("/dev/null", "r");
|
|
stdout = fopen("/dev/kmsg", "w");
|
|
stderr = fopen("/dev/kmsg", "w");
|
|
}
|
|
|
|
static void fail(const char* message)
|
|
{
|
|
open_std_streams();
|
|
fprintf(stderr, "preinit: fatal error: %s\n", message);
|
|
exit(255);
|
|
}
|
|
|
|
static void fail_errno(const char* message)
|
|
{
|
|
int err = errno;
|
|
open_std_streams();
|
|
fprintf(stderr, "preinit: fatal error: %s (%s)\n", message, strerror(err));
|
|
exit(255);
|
|
}
|
|
|
|
static void mount_rootfs()
|
|
{
|
|
if (mkdir("/osroot", 0755) < 0 && errno != EEXIST) exit(255);
|
|
|
|
if (mount("/osroot", "ext2", LUNA_ROOT_PARTITION) < 0) fail_errno("Cannot mount the root partition");
|
|
}
|
|
|
|
int main()
|
|
{
|
|
if (getpid() != 1)
|
|
{
|
|
fprintf(stderr, "error: preinit must be run as the init process.\n");
|
|
return 1;
|
|
}
|
|
|
|
mount_devfs();
|
|
mount_rootfs();
|
|
|
|
struct stat st;
|
|
if (stat("/osroot/mnt", &st) < 0 || !S_ISDIR(st.st_mode)) fail("No suitable temporary mountpoint for pivot_root");
|
|
|
|
// Now that we have mounted the root file system, remove the /dev mount on the current ramfs root.
|
|
umount("/dev");
|
|
|
|
long rc = syscall(SYS_pivot_root, "/osroot", "/osroot/mnt");
|
|
if (rc < 0) exit(255);
|
|
|
|
chdir("/");
|
|
umount("/mnt");
|
|
|
|
// Now, mount the /dev file system on the new root.
|
|
mount_devfs();
|
|
|
|
char* argv[] = { "/usr/bin/init", nullptr };
|
|
char* envp[] = { nullptr };
|
|
execve(argv[0], argv, envp);
|
|
|
|
fail_errno("Failed to execute init");
|
|
|
|
return 255;
|
|
}
|