diff options
| -rwxr-xr-x | rushmore-linux/rl.sh | 10 | ||||
| -rw-r--r-- | rushmore-linux/rlinit/rlinit.c | 92 | ||||
| -rw-r--r-- | rushmore-linux/rlwsd/rlwsd.c | 56 |
3 files changed, 116 insertions, 42 deletions
diff --git a/rushmore-linux/rl.sh b/rushmore-linux/rl.sh index 39614bc..a9c024d 100755 --- a/rushmore-linux/rl.sh +++ b/rushmore-linux/rl.sh @@ -7,7 +7,7 @@ BUILD_DIR="$ROOT/build" ROOTFS_DIR="$ROOT/rootfs" mkdir -p "$BUILD_DIR" -mkdir -p "$ROOTFS_DIR/proc" "$ROOTFS_DIR/sys" "$ROOTFS_DIR/dev" +mkdir -p "$ROOTFS_DIR" echo "Compiling rlinit" musl-gcc -static -O2 -s rlinit/rlinit.c -o "$BUILD_DIR/init" @@ -23,4 +23,10 @@ echo "Building initramfs" (cd "$ROOTFS_DIR" && find . -print0 | cpio --null -ov --format=newc) > "$BUILD_DIR/initramfs.cpio" echo "Running QEMU (do CTRL+A then X to quit)" -qemu-system-x86_64 -kernel linux/arch/x86/boot/bzImage -initrd "$BUILD_DIR/initramfs.cpio" -append "console=ttyS0" -nographic
\ No newline at end of file +qemu-system-x86_64 \ + -kernel linux/arch/x86/boot/bzImage \ + -initrd "$BUILD_DIR/initramfs.cpio" \ + -append "console=ttyS0 video=vesafb:1024x768-32" \ + -serial mon:stdio \ + -vga std \ + -display sdl
\ No newline at end of file diff --git a/rushmore-linux/rlinit/rlinit.c b/rushmore-linux/rlinit/rlinit.c index 4ab06db..ce3da40 100644 --- a/rushmore-linux/rlinit/rlinit.c +++ b/rushmore-linux/rlinit/rlinit.c @@ -2,56 +2,77 @@ #include <fcntl.h> #include <unistd.h> #include <sys/mount.h> +#include <sys/stat.h> #include <sys/uio.h> #include <sys/wait.h> +#include <stdio.h> -static void write_str(int fd, const char* str) -{ - write(fd, str, __builtin_strlen(str)); -} +// ref: https://git.suckless.org/sinit/file/sinit.c.html -static void error(const char* message) +static void panic(const char* message) { // Attempt to spew to kernel log int kmfd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC); + int fd = (kmfd >= 0) ? kmfd : 2; + + struct iovec msgvec[] = { +#define STRVEC(str) { .iov_base = (void*)(str), .iov_len = __builtin_strlen(str) } + STRVEC("rlinit: "), + STRVEC(message), + STRVEC("\n") +#undef STRVEC + }; + writev(fd, msgvec, sizeof(msgvec) / sizeof(*msgvec)); + if (kmfd >= 0) { - write_str(kmfd, message); close(kmfd); } - _exit(1); // Kernel panic + _exit(1); // Triggers a kernel panic since we're PID 1 } -#define ERROR(message) error("[rlinit] " message) -static bool mount_required(const char* src, const char* tgt, const char* fs) +static bool mkdir_if_missing(const char* path, mode_t mode) { - // EBUSY means already mounted, which is ok - return mount(src, tgt, fs, 0, 0) >= 0 || errno == EBUSY; + return mkdir(path, mode) == 0 || errno == EEXIST; } int main(void) { -#if 0 - // First, spew a message to tty to signal we at least made it this far - { - const char* hello = "rlinit: Initialization started\n"; - write(1, hello, __builtin_strlen(hello)); + if (getpid() != 1) { + panic("PID is not 1. Aborting."); } -#endif - // Mount /dev first, as /dev/kmsg is useful for debugging errors + // Set up filesystem in descending priority + // // @@ include errno in error messages - if (!mount_required("devtmpfs", "/dev", "devtmpfs")) { - ERROR("Failed to mount /dev\n"); + + if (!mkdir_if_missing("/dev", 0755)) { + panic("Failed to create /dev"); + } + if (mount("devtmpfs", "/dev", "devtmpfs", MS_NOSUID, 0) < 0) { + panic("Failed to mount /dev"); } - if (!mount_required("proc", "/proc", "proc")) { - ERROR("Failed to mount /proc\n"); + + if (!mkdir_if_missing("/proc", 0555)) { + panic("Failed to create /proc"); + } + if (mount("proc", "/proc", "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV, 0) < 0) { + panic("Failed to mount /proc"); + } + + if (!mkdir_if_missing("/sys", 0555)) { + panic("Failed to create /sys"); } - if (!mount_required("sysfs", "/sys", "sysfs")) { - ERROR("Failed to mount /sys\n"); + if (mount("sysfs", "/sys", "sysfs", MS_NOSUID | MS_NOEXEC | MS_NODEV, 0) < 0) { + panic("Failed to mount /sys"); } - // Write to kernel log + if (!mkdir_if_missing("/tmp", 0777)) { + panic("Failed to create /tmp"); + } + chmod("/tmp", 01777); + + // Test write to kernel log { int kmfd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC); if (kmfd >= 0) { @@ -61,16 +82,19 @@ int main(void) } } - // pid_t pid = fork(); - // if (pid == 0) { - // char *argv[] = { (char*)"/rlwsd", 0 }; - // execv(argv[0], argv); - // _exit(127); - // } + pid_t child = fork(); + switch(child) { + case 0: { + char* const argv[] = { "/rlwsd", 0 }; + execv(argv[0], argv); + panic("execvp failed"); + } break; + case -1: { + panic("Failed to fork()"); + } break; + } - // int st = 0; - // waitpid(pid, &st, 0); - // write(1, "rlinit: rlwsd exited\n", 21); + // @@ reap child processes for (;;) pause(); } diff --git a/rushmore-linux/rlwsd/rlwsd.c b/rushmore-linux/rlwsd/rlwsd.c index 94ebd87..0c96881 100644 --- a/rushmore-linux/rlwsd/rlwsd.c +++ b/rushmore-linux/rlwsd/rlwsd.c @@ -1,11 +1,55 @@ +#include <errno.h> +#include <fcntl.h> +// #include <linux/fb.h> +#include <stdarg.h> +#include <string.h> +#include <stdio.h> +#include <sys/uio.h> #include <unistd.h> +static const char* tmp_fmt(const char* fmt, ...) +{ + static char msg[1024] = { 0 }; + va_list va; va_start(va, fmt); + vsnprintf(msg, sizeof(msg), fmt, va); + va_end(va); + return msg; +} + +static void spew(const char* message) +{ + // Kernel log is available after init + int kmfd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC); + + struct iovec msgvec[] = { +#define STRVEC(str) { .iov_base = (void*)(str), .iov_len = __builtin_strlen(str) } + STRVEC("rlwsd: "), + STRVEC(message), + STRVEC("\n") +#undef STRVEC + }; + writev(kmfd, msgvec, sizeof(msgvec) / sizeof(*msgvec)); + + close(kmfd); +} + +static void panic(const char* message) +{ + spew(message); + _exit(1); // Triggers a kernel panic since we're PID 1 +} + int main(void) { - const char* msg = "[rlwsd] HELLO!\n"; - write(1, msg, __builtin_strlen(msg)); - for (;;) - { - pause(); - } + int fd = open("/dev/fb0", O_RDWR | O_CLOEXEC); + if (fd < 0) { + panic(tmp_fmt("Failed to open /dev/fb0: %s", strerror(errno))); + } + + const char* msg = "[rlwsd] HELLO!\n"; + write(1, msg, __builtin_strlen(msg)); + for (;;) + { + pause(); + } } |