feat(power): add reboot and shutdown syscalls and terminal commands

- REBOOT (0x1008): 8042 reset with PCI 0xCF9 fallback
- SHUTDOWN (0x1009): ACPI S5 writes to the common QEMU/Bochs/VBox
  PM1a control ports, then halt
- vpsdk.process.reboot()/shutdown()
- Terminal commands: reboot, shutdown (help updated)
This commit is contained in:
TermiNexus committed 2026-10-27 16:56:26 +08:00
1 parent f9cf26e59a
commit 925e0ffaea
4 files changed
+53 -6

No files matched your search

+4 -2
View File
@@ -345,7 +345,7 @@ export def _start() -> int:
term.delete(0, -1)
elif string.samestr(text, "help"):
term.insert("File: ls cd cat pwd mkdir rm touch")
term.insert("Sys: ver about sysinfo reboot")
term.insert("Sys: ver about sysinfo reboot shutdown")
term.insert("Util: echo clear help hexdump run runb")
elif string.samestr(text, "ver"):
term.insert("ViperOS Terminal v1.1")
@@ -370,7 +370,9 @@ export def _start() -> int:
elif string.samestr(text, "sysinfo"):
_cmd_sysinfo()
elif string.samestr(text, "reboot"):
process.exit(0)
process.reboot()
elif string.samestr(text, "shutdown"):
process.shutdown()
elif _startswith(text, "hexdump "):
_cmd_hexdump(text + 8)
elif _startswith(text, "run "):
+37 -2
View File
@@ -9,6 +9,7 @@ import mm.mm as mm
import paging.paging as paging
import execrunner.elf as elf
import drivers.devfs.devfs as devfs
import asm
# ============================================================================
@@ -46,14 +47,42 @@ enum Syscall:
OPENDIR = 0x1003 # TODO(linux):openat(O_DIRECTORY) + getdents64
READDIR = 0x1004 # TODO(linux):getdents64
CLOSEDIR = 0x1005 # TODO(linux):close
LOAD_SO = 0x1006 # TODO(用户层):动态库加载下沉
SO_CALL1 = 0x1007 # TODO(用户层):同上
LOAD_SO = 0x1006 # TODO(userspace): dynamic library loading
SO_CALL1 = 0x1007 # TODO(userspace): dynamic library call
REBOOT = 0x1008 # reboot()(本系统私有)
SHUTDOWN = 0x1009 # shutdown()(本系统私有)
define IA32_EFER = 0xC0000080
define IA32_STAR = 0xC0000081
define IA32_LSTAR = 0xC0000082
define IA32_FMASK = 0xC0000084
# Reset via the 8042 controller; PCI reset and halt are fallbacks.
def power_reboot():
serial.puts("[power] reboot\n")
asm.cli()
for _ in range(1000):
if (asm.inb(0x64) & 0x02) == 0: break
asm.outb(0x64, 0xFE)
asm.outb(0xCF9, 0x02)
asm.io_wait()
asm.outb(0xCF9, 0x06)
while True:
asm.cli()
asm.hlt()
# ACPI S5 on the common QEMU/Bochs/VirtualBox PM1a control ports.
def power_shutdown():
serial.puts("[power] shutdown\n")
asm.cli()
asm.outw(0x604, 0x3400)
asm.outw(0x604, 0x2000)
asm.outw(0xB004, 0x2000)
asm.outw(0x4004, 0x3400)
while True:
asm.cli()
asm.hlt()
def wrmsr(msr: uint32, val: uint64):
lo: uint32 = uint32(val & 0xFFFFFFFF)
hi: uint32 = uint32(val >> 32)
@@ -454,6 +483,12 @@ export def syscall_handler(num: uint64, arg1: uint64, arg2: uint64, arg3: uint64
path_ptr: str = str(arg1)
info_ptr: rawptr = rawptr(arg2)
return uint64(STAT(path_ptr, info_ptr))
elif n == int(Syscall.REBOOT):
power_reboot()
return uint64(0)
elif n == int(Syscall.SHUTDOWN):
power_shutdown()
return uint64(0)
elif n == int(Syscall.LOAD_SO):
path_ptr_so: rawptr = rawptr(arg1)
return LOAD_SO(path_ptr_so)
+8
View File
@@ -4,6 +4,14 @@ from . import syscall as syscall
def exit(code: int):
syscall._syscall1(uint64(syscall.Syscall.EXIT), uint64(code))
def reboot():
"""Reset the machine."""
syscall._syscall0(uint64(syscall.Syscall.REBOOT))
def shutdown():
"""Power off the machine (ACPI S5 / QEMU PM1a)."""
syscall._syscall0(uint64(syscall.Syscall.SHUTDOWN))
def thread_exit():
"""当前用户线程显式退出:内核回收其用户栈并标记线程结束(不返回)。"""
syscall._syscall0(uint64(syscall.Syscall.THREAD_EXIT))
+4 -2
View File
@@ -30,8 +30,10 @@ enum Syscall:
OPENDIR = 0x1003 # TODO(linux):openat(O_DIRECTORY) + getdents64
READDIR = 0x1004 # TODO(linux):getdents64
CLOSEDIR = 0x1005 # TODO(linux):close
LOAD_SO = 0x1006 # TODO(用户层):动态库加载下沉
SO_CALL1 = 0x1007 # TODO(用户层):同上
LOAD_SO = 0x1006 # TODO(userspace): dynamic library loading
SO_CALL1 = 0x1007 # TODO(userspace): dynamic library call
REBOOT = 0x1008
SHUTDOWN = 0x1009
# ---- mmap 的 prot / flags(与内核 VKernel/intr/syscall.vp 及各 Linux 同名常量一致)----
define PROT_NONE = 0x0