]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
rootfs-handoff: Milestone B - add early userspace /init
authorTulio A M Mendes <[email protected]>
Thu, 11 Jun 2026 03:37:10 +0000 (00:37 -0300)
committerTulio A M Mendes <[email protected]>
Thu, 11 Jun 2026 03:37:10 +0000 (00:37 -0300)
- Created user/cmds/initrd_init/initrd_init.c as early /init program
- Created user/cmds/initrd_init/Makefile
- Added initrd_init to USER_CMD_NAMES in main Makefile
- Changed default init path from /sbin/init to /init in cmdline.c
- Early /init checks if /newroot is mounted by kernel
- If /newroot is mounted, executes /sbin/init (basic handoff)
- If /newroot is not mounted, falls back to /sbin/init directly
- Milestone C will add pivot_root and mount moving functionality

Test Results:
- Smoke test: 131/131 PASS
- Battery test: 157/157 PASS
- Analyzer: PASS
- Zero regressions

Makefile
src/kernel/cmdline.c
user/cmds/initrd_init/Makefile [new file with mode: 0644]
user/cmds/initrd_init/initrd_init.c [new file with mode: 0644]

index ed90dad486718f65e8a2a4540379631fc0c3d9ce..057b422b1f45dfd9e20a6569e0ee001587439d30 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -127,7 +127,7 @@ ifeq ($(ARCH),x86)
                       grep id uname dmesg \
                       printenv tr dd pwd stat \
                       sed awk who top du find which \
-                      login init
+                      login init initrd_init
 
     # ELF paths for dynamically-linked commands
     USER_CMD_ELFS := $(foreach cmd,$(USER_CMD_NAMES),$(USER_BUILD)/cmds/$(cmd)/$(cmd).elf)
index 167d4f023d6616a45559854957abdd5ae73fae8c..28139b4e6078a79a17ef5c23a3517017128bba8b 100644 (file)
@@ -85,7 +85,7 @@ void cmdline_parse(const char* raw) {
     kflag_count = 0;
     init_argc = 0;
     init_envc = 0;
-    init_path_val = "/sbin/init";
+    init_path_val = "/init";  /* Default to early /init for root handoff */
 
     if (!raw) {
         raw_copy[0] = '\0';
diff --git a/user/cmds/initrd_init/Makefile b/user/cmds/initrd_init/Makefile
new file mode 100644 (file)
index 0000000..d741b0a
--- /dev/null
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Copyright (c) 2026, Tulio A M Mendes <[email protected]>
+# All rights reserved.
+# See LICENSE for details.
+#
+# Source: https://github.com/tadryanom/AdrOS
+#
+
+NAME := initrd_init
+SRCS := initrd_init.c
+include ../common.mk
diff --git a/user/cmds/initrd_init/initrd_init.c b/user/cmds/initrd_init/initrd_init.c
new file mode 100644 (file)
index 0000000..7771519
--- /dev/null
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2026, Tulio A M Mendes <[email protected]>
+ * All rights reserved.
+ * See LICENSE for details.
+ *
+ * Source: https://github.com/tadryanom/AdrOS
+ */
+
+/*
+ * Early /init for root filesystem handoff
+ *
+ * This program runs from the initrd before the final /sbin/init.
+ * 
+ * Milestone B: Basic early init - checks for /newroot and executes /sbin/init
+ * Milestone C: Will add pivot_root and mount moving
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#define NEWROOT "/newroot"
+
+static int is_mounted(const char* path) {
+    FILE* fp = fopen("/proc/mounts", "r");
+    if (!fp) {
+        return 0;
+    }
+
+    char line[256];
+    int found = 0;
+    while (fgets(line, sizeof(line), fp)) {
+        char mountpoint[128];
+        if (sscanf(line, "%*s %127s", mountpoint) == 1) {
+            if (strcmp(mountpoint, path) == 0) {
+                found = 1;
+                break;
+            }
+        }
+    }
+
+    fclose(fp);
+    return found;
+}
+
+int main(int argc __attribute__((unused)), char** argv) {
+    printf("[init] early userspace init starting\n");
+
+    /* Check if /newroot is already mounted by kernel */
+    if (!is_mounted(NEWROOT)) {
+        printf("[init] /newroot not mounted by kernel, nothing to do\n");
+        printf("[init] falling back to /sbin/init\n");
+        execve("/sbin/init", argv, environ);
+        perror("execve /sbin/init");
+        return 1;
+    }
+
+    printf("[init] /newroot is mounted by kernel\n");
+    printf("[init] Milestone B: basic handoff - executing /sbin/init directly\n");
+    printf("[init] (pivot_root and mount moving will be added in Milestone C)\n");
+
+    /* For now, just execute /sbin/init from the initrd overlay */
+    /* The kernel has already mounted the real root on /newroot */
+    /* Future Milestone C will implement pivot_root to make /newroot the actual root */
+    execve("/sbin/init", argv, environ);
+    perror("execve /sbin/init");
+
+    return 1;
+}