From 3974452284ba7f46c94f025ae5ee38a9068c50a4 Mon Sep 17 00:00:00 2001 From: Albert Slepak Date: Fri, 28 Aug 2026 14:16:40 -0700 Subject: [PATCH 1/2] feat(syscall): implemented the reboot syscall --- kernel/arch/aarch64/syscall/linux_syscalls.h | 1 + kernel/arch/x86_64/syscall/linux_syscalls.h | 1 + kernel/syscall/handlers/sys_power.cpp | 49 ++++++++++++++++++++ kernel/syscall/handlers/sys_power.h | 8 ++++ kernel/syscall/syscall_table.cpp | 2 + 5 files changed, 61 insertions(+) create mode 100644 kernel/syscall/handlers/sys_power.cpp create mode 100644 kernel/syscall/handlers/sys_power.h diff --git a/kernel/arch/aarch64/syscall/linux_syscalls.h b/kernel/arch/aarch64/syscall/linux_syscalls.h index cadf7f20..9c1a807f 100644 --- a/kernel/arch/aarch64/syscall/linux_syscalls.h +++ b/kernel/arch/aarch64/syscall/linux_syscalls.h @@ -47,6 +47,7 @@ constexpr uint64_t RT_SIGACTION = 134; constexpr uint64_t RT_SIGPROCMASK = 135; constexpr uint64_t RT_SIGPENDING = 136; constexpr uint64_t RT_SIGRETURN = 139; +constexpr uint64_t REBOOT = 142; constexpr uint64_t SETPGID = 154; constexpr uint64_t GETPGID = 155; constexpr uint64_t UNAME = 160; diff --git a/kernel/arch/x86_64/syscall/linux_syscalls.h b/kernel/arch/x86_64/syscall/linux_syscalls.h index 4cafca27..82165439 100644 --- a/kernel/arch/x86_64/syscall/linux_syscalls.h +++ b/kernel/arch/x86_64/syscall/linux_syscalls.h @@ -70,6 +70,7 @@ constexpr uint64_t SETPGID = 109; constexpr uint64_t GETPGID = 121; constexpr uint64_t RT_SIGPENDING = 127; constexpr uint64_t ARCH_PRCTL = 158; +constexpr uint64_t REBOOT = 169; constexpr uint64_t GETTID = 186; constexpr uint64_t TKILL = 200; constexpr uint64_t FUTEX = 202; diff --git a/kernel/syscall/handlers/sys_power.cpp b/kernel/syscall/handlers/sys_power.cpp new file mode 100644 index 00000000..9b45714c --- /dev/null +++ b/kernel/syscall/handlers/sys_power.cpp @@ -0,0 +1,49 @@ +#include "syscall/handlers/sys_power.h" + +#include "power/power.h" +#include "hw/cpu.h" +#include "common/logging.h" + +// Linux reboot(2) magic values, required so a stray syscall with a +// garbage number cannot take the machine down by accident. +constexpr uint32_t REBOOT_MAGIC1 = 0xFEE1DEAD; +constexpr uint32_t REBOOT_MAGIC2 = 672274793; +constexpr uint32_t REBOOT_MAGIC2A = 85072278; +constexpr uint32_t REBOOT_MAGIC2B = 369367448; +constexpr uint32_t REBOOT_MAGIC2C = 537993216; + +// Linux reboot(2) commands +constexpr uint32_t REBOOT_CMD_RESTART = 0x01234567; +constexpr uint32_t REBOOT_CMD_HALT = 0xCDEF0123; +constexpr uint32_t REBOOT_CMD_POWER_OFF = 0x4321FEDC; + +DEFINE_SYSCALL3(reboot, magic1, magic2, cmd) { + if (static_cast(magic1) != REBOOT_MAGIC1) { + return syscall::EINVAL; + } + + uint32_t m2 = static_cast(magic2); + if (m2 != REBOOT_MAGIC2 && m2 != REBOOT_MAGIC2A && + m2 != REBOOT_MAGIC2B && m2 != REBOOT_MAGIC2C) { + return syscall::EINVAL; + } + + switch (static_cast(cmd)) { + case REBOOT_CMD_RESTART: + log::info("power: restarting system"); + power::reboot(); + return syscall::EOPNOTSUPP; + case REBOOT_CMD_POWER_OFF: + log::info("power: powering off"); + power::shutdown(); + return syscall::EOPNOTSUPP; + case REBOOT_CMD_HALT: + log::info("power: system halted"); + cpu::irq_disable(); + while (true) { + cpu::halt(); + } + default: + return syscall::EINVAL; + } +} diff --git a/kernel/syscall/handlers/sys_power.h b/kernel/syscall/handlers/sys_power.h new file mode 100644 index 00000000..aee493e3 --- /dev/null +++ b/kernel/syscall/handlers/sys_power.h @@ -0,0 +1,8 @@ +#ifndef STELLUX_SYSCALL_HANDLERS_SYS_POWER_H +#define STELLUX_SYSCALL_HANDLERS_SYS_POWER_H + +#include "syscall/syscall_table.h" + +DECLARE_SYSCALL(reboot); + +#endif // STELLUX_SYSCALL_HANDLERS_SYS_POWER_H diff --git a/kernel/syscall/syscall_table.cpp b/kernel/syscall/syscall_table.cpp index 99a56d21..12abdcad 100644 --- a/kernel/syscall/syscall_table.cpp +++ b/kernel/syscall/syscall_table.cpp @@ -21,6 +21,7 @@ #include "syscall/handlers/sys_pipe.h" #include "syscall/handlers/sys_uname.h" #include "syscall/handlers/sys_futex.h" +#include "syscall/handlers/sys_power.h" namespace syscall { @@ -85,6 +86,7 @@ __PRIVILEGED_CODE void init_syscall_table() { REGISTER_SYSCALL(linux_nr::CLOCK_GETRES, clock_getres); REGISTER_SYSCALL(linux_nr::GETTIMEOFDAY, gettimeofday); REGISTER_SYSCALL(linux_nr::UNAME, uname); + REGISTER_SYSCALL(linux_nr::REBOOT, reboot); REGISTER_SYSCALL(linux_nr::SOCKET, socket); REGISTER_SYSCALL(linux_nr::SOCKETPAIR, socketpair); From c1bca21b5e20b33af1991b2d6c86fccfed3f605a Mon Sep 17 00:00:00 2001 From: Albert Slepak Date: Fri, 28 Aug 2026 14:16:51 -0700 Subject: [PATCH 2/2] feat(userland): added reboot and shutdown apps --- userland/apps/Makefile | 3 ++- userland/apps/reboot/Makefile | 2 ++ userland/apps/reboot/src/reboot.c | 13 +++++++++++++ userland/apps/shutdown/Makefile | 2 ++ userland/apps/shutdown/src/shutdown.c | 18 ++++++++++++++++++ 5 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 userland/apps/reboot/Makefile create mode 100644 userland/apps/reboot/src/reboot.c create mode 100644 userland/apps/shutdown/Makefile create mode 100644 userland/apps/shutdown/src/shutdown.c diff --git a/userland/apps/Makefile b/userland/apps/Makefile index a21af18d..1f069776 100644 --- a/userland/apps/Makefile +++ b/userland/apps/Makefile @@ -5,7 +5,8 @@ APP_DIRS := init hello shell ls cat rm stat touch sleep true false clear ptytest date \ clockbench stlxdm stlxterm doom ping ifconfig nslookup arp udpecho tcpecho \ fetch polltest sigtest dropbear blackjack wordle hangman snake tetris \ - grep wc head threadtest pthreadtest uname kill cxxtest synctest python vim stlxtop + grep wc head threadtest pthreadtest uname kill cxxtest synctest python vim stlxtop \ + reboot shutdown APP_COUNT := $(words $(APP_DIRS)) all: diff --git a/userland/apps/reboot/Makefile b/userland/apps/reboot/Makefile new file mode 100644 index 00000000..91b3c4d6 --- /dev/null +++ b/userland/apps/reboot/Makefile @@ -0,0 +1,2 @@ +APP_NAME := reboot +include ../../mk/app.mk diff --git a/userland/apps/reboot/src/reboot.c b/userland/apps/reboot/src/reboot.c new file mode 100644 index 00000000..86c7080a --- /dev/null +++ b/userland/apps/reboot/src/reboot.c @@ -0,0 +1,13 @@ +#include +#include + +int main(void) { + printf("Restarting system...\n"); + fflush(stdout); + + reboot(RB_AUTOBOOT); + + // Only reachable when the kernel could not restart the machine + perror("reboot"); + return 1; +} diff --git a/userland/apps/shutdown/Makefile b/userland/apps/shutdown/Makefile new file mode 100644 index 00000000..2a2e858f --- /dev/null +++ b/userland/apps/shutdown/Makefile @@ -0,0 +1,2 @@ +APP_NAME := shutdown +include ../../mk/app.mk diff --git a/userland/apps/shutdown/src/shutdown.c b/userland/apps/shutdown/src/shutdown.c new file mode 100644 index 00000000..f7018e83 --- /dev/null +++ b/userland/apps/shutdown/src/shutdown.c @@ -0,0 +1,18 @@ +#include +#include + +int main(void) { + printf("Powering off...\n"); + fflush(stdout); + + reboot(RB_POWER_OFF); + + // Only reachable when the platform could not power off, so stop + // the machine in a state that is safe to switch off by hand. + printf("Power off unsupported, halting instead.\n"); + fflush(stdout); + reboot(RB_HALT_SYSTEM); + + perror("shutdown"); + return 1; +}