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:
1 parent
f9cf26e59a
commit
925e0ffaea
4 files changed
+53
-6
No files matched your search
@@ -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 "):
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Reference in new issue
Block a user