/* * Minimal /init for UniversalisOS initramfs. * * This is the first userspace program executed by Linux after mounting * the rootfs. It demonstrates that the hypervisor can boot a real Linux * kernel to userspace via virtio-blk. * * Features: * - Mounts /proc, /sys, /dev (tmpfs) * - Prints system information from /proc/cpuinfo * - Runs a minimal shell loop (echo + wait) * - Demonstrates the full hypervisor -> Linux -> userspace path */ #include #include #include #include #include #include #include #include #include #define BANNER \ "\r\n" \ "============================================\r\n" \ " UniversalisOS Linux Guest Boot Successful!\r\n" \ "============================================\r\n" \ "\r\n" static void mount_proc(void) { mkdir("/proc", 0755); if (mount("proc", "/proc", "proc", 0, NULL) == 0) { printf("[init] /proc mounted\r\n"); } else { printf("[init] /proc mount failed\r\n"); } } static void mount_sys(void) { mkdir("/sys", 0755); if (mount("sysfs", "/sys", "sysfs", 0, NULL) == 0) { printf("[init] /sys mounted\r\n"); } else { printf("[init] /sys mount failed\r\n"); } } static void mount_dev(void) { mkdir("/dev", 0755); if (mount("tmpfs", "/dev", "tmpfs", 0, "size=64M") == 0) { printf("[init] /dev mounted (tmpfs)\r\n"); } else { printf("[init] /dev mount failed\r\n"); } } static void print_cpuinfo(void) { FILE *f = fopen("/proc/cpuinfo", "r"); if (f) { char line[256]; printf("[init] CPU info:\r\n"); while (fgets(line, sizeof(line), f)) { if (strncmp(line, "Processor", 9) == 0 || strncmp(line, "model name", 10) == 0 || strncmp(line, "CPU implementer", 14) == 0 || strncmp(line, "CPU variant", 10) == 0 || strncmp(line, "BogoMIPS", 8) == 0) { printf(" %s", line); } } fclose(f); } } static void print_uptime(void) { FILE *f = fopen("/proc/uptime", "r"); if (f) { double uptime; if (fscanf(f, "%lf", &uptime) == 1) { printf("[init] System uptime: %.1f seconds\r\n", uptime); } fclose(f); } } static void print_memory(void) { FILE *f = fopen("/proc/meminfo", "r"); if (f) { char line[256]; printf("[init] Memory info:\r\n"); while (fgets(line, sizeof(line), f)) { if (strncmp(line, "MemTotal", 8) == 0 || strncmp(line, "MemFree", 7) == 0 || strncmp(line, "MemAvailable", 12) == 0) { printf(" %s", line); } } fclose(f); } } int main(void) { printf(BANNER); printf("[init] UniversalisOS Linux Guest Init\r\n"); printf("[init] PID=%d\r\n", getpid()); /* Mount essential filesystems */ mount_dev(); mount_proc(); mount_sys(); /* Create basic device nodes */ mknod("/dev/console", 0600 | S_IFCHR, makedev(5, 1)); mknod("/dev/null", 0666 | S_IFCHR, makedev(1, 3)); mknod("/dev/zero", 0666 | S_IFCHR, makedev(1, 5)); /* Print system information */ print_cpuinfo(); print_uptime(); print_memory(); /* Print mount info */ FILE *f = fopen("/proc/mounts", "r"); if (f) { char line[256]; printf("[init] Mounts:\r\n"); while (fgets(line, sizeof(line), f)) { printf(" %s", line); } fclose(f); } printf("\r\n[init] System ready. Entering idle loop.\r\n"); printf("[init] To shutdown: echo 1 > /proc/sys/kernel/sysrq && echo o > /proc/sysrq-trigger\r\n"); /* Idle loop — in a real system this would run a shell or service manager */ while (1) { sleep(10); printf("[init] heartbeat\r\n"); } return 0; }