universalisos/guests/linux-aarch64/initramfs/init.c
Fábio Coutada 5ab1b438b4 guests: add linux-aarch64 guest images and scripts
- initramfs.img, rootfs.img for AArch64 Linux guest
- mkdisk.py for disk image creation
- initramfs and rootfs directories
2026-07-15 15:32:04 +01:00

144 lines
3.9 KiB
C

/*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <sys/reboot.h>
#include <linux/reboot.h>
#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;
}