mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 10:15:03 +00:00
feat: 完善sys_reboot (#1084)
* fix(process): 修复copy_process的一些bug & 支持默认init进程传参 - 修复`copy_process`函数对标志位处理不正确的bug - init进程搜索列表中,支持为默认init程序传入参数 Signed-off-by: longjin <longjin@DragonOS.org> * feat: 完善sys_reboot - 校验magic number - 支持多个cmd (具体内容未实现) Signed-off-by: longjin <longjin@DragonOS.org> --------- Signed-off-by: longjin <longjin@DragonOS.org>
This commit is contained in:
parent
55d7280a51
commit
5b4d581e92
@ -1,2 +1,4 @@
|
||||
pub mod events;
|
||||
pub mod ksysfs;
|
||||
pub mod reboot;
|
||||
pub mod syscall;
|
||||
|
154
kernel/src/misc/reboot.rs
Normal file
154
kernel/src/misc/reboot.rs
Normal file
@ -0,0 +1,154 @@
|
||||
use core::hint::spin_loop;
|
||||
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{arch::cpu::cpu_reset, libs::mutex::Mutex, syscall::user_access::check_and_clone_cstr};
|
||||
|
||||
static SYSTEM_TRANSITION_MUTEX: Mutex<()> = Mutex::new(());
|
||||
|
||||
const LINUX_REBOOT_MAGIC1: u32 = 0xfee1dead;
|
||||
const LINUX_REBOOT_MAGIC2: u32 = 672274793;
|
||||
const LINUX_REBOOT_MAGIC2A: u32 = 85072278;
|
||||
const LINUX_REBOOT_MAGIC2B: u32 = 369367448;
|
||||
const LINUX_REBOOT_MAGIC2C: u32 = 537993216;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum RebootCommand {
|
||||
/// 重启系统,使用默认命令和模式
|
||||
Restart,
|
||||
/// 停止操作系统,并将系统控制权交给ROM监视器(如果有)
|
||||
Halt,
|
||||
/// Ctrl-Alt-Del序列导致执行RESTART命令
|
||||
CadOn,
|
||||
/// Ctrl-Alt-Del序列向init任务发送SIGINT信号
|
||||
CadOff,
|
||||
/// 停止操作系统,如果可能的话从系统中移除所有电源
|
||||
PowerOff,
|
||||
/// 使用给定的命令字符串重启系统
|
||||
Restart2,
|
||||
/// 使用软件挂起(如果编译在内)挂起系统
|
||||
SoftwareSuspend,
|
||||
/// 使用预先加载的Linux内核重启系统
|
||||
Kexec,
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for RebootCommand {
|
||||
type Error = SystemError;
|
||||
|
||||
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
0x01234567 => Ok(RebootCommand::Restart),
|
||||
0xCDEF0123 => Ok(RebootCommand::Halt),
|
||||
0x89ABCDEF => Ok(RebootCommand::CadOn),
|
||||
0x00000000 => Ok(RebootCommand::CadOff),
|
||||
0x4321FEDC => Ok(RebootCommand::PowerOff),
|
||||
0xA1B2C3D4 => Ok(RebootCommand::Restart2),
|
||||
0xD000FCE2 => Ok(RebootCommand::SoftwareSuspend),
|
||||
0x45584543 => Ok(RebootCommand::Kexec),
|
||||
_ => Err(SystemError::EINVAL),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RebootCommand> for u32 {
|
||||
fn from(val: RebootCommand) -> Self {
|
||||
match val {
|
||||
RebootCommand::Restart => 0x01234567,
|
||||
RebootCommand::Halt => 0xCDEF0123,
|
||||
RebootCommand::CadOn => 0x89ABCDEF,
|
||||
RebootCommand::CadOff => 0x00000000,
|
||||
RebootCommand::PowerOff => 0x4321FEDC,
|
||||
RebootCommand::Restart2 => 0xA1B2C3D4,
|
||||
RebootCommand::SoftwareSuspend => 0xD000FCE2,
|
||||
RebootCommand::Kexec => 0x45584543,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 系统调用reboot的实现
|
||||
///
|
||||
/// 参考:https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/reboot.c#700
|
||||
pub(super) fn do_sys_reboot(
|
||||
magic1: u32,
|
||||
magic2: u32,
|
||||
cmd: u32,
|
||||
arg: usize,
|
||||
) -> Result<(), SystemError> {
|
||||
if magic1 != LINUX_REBOOT_MAGIC1
|
||||
|| (magic2 != LINUX_REBOOT_MAGIC2
|
||||
&& magic2 != LINUX_REBOOT_MAGIC2A
|
||||
&& magic2 != LINUX_REBOOT_MAGIC2B
|
||||
&& magic2 != LINUX_REBOOT_MAGIC2C)
|
||||
{
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
let command = RebootCommand::try_from(cmd)?;
|
||||
let _guard = SYSTEM_TRANSITION_MUTEX.lock();
|
||||
log::debug!(
|
||||
"do_sys_reboot: magic1={}, magic2={}, cmd={:?}",
|
||||
magic1,
|
||||
magic2,
|
||||
command
|
||||
);
|
||||
match command {
|
||||
RebootCommand::Restart => kernel_restart(None),
|
||||
RebootCommand::Halt => kernel_halt(),
|
||||
RebootCommand::CadOn => {
|
||||
// todo: 支持Ctrl-Alt-Del序列
|
||||
return Ok(());
|
||||
}
|
||||
RebootCommand::CadOff => {
|
||||
// todo: 支持Ctrl-Alt-Del序列
|
||||
return Ok(());
|
||||
}
|
||||
RebootCommand::PowerOff => kernel_power_off(),
|
||||
RebootCommand::Restart2 => {
|
||||
let s = check_and_clone_cstr(arg as *const u8, Some(256))?;
|
||||
let cmd_str = s.to_str().map_err(|_| SystemError::EINVAL)?;
|
||||
kernel_restart(Some(cmd_str));
|
||||
}
|
||||
RebootCommand::SoftwareSuspend => {
|
||||
log::warn!("do_sys_reboot: SoftwareSuspend not implemented");
|
||||
return Err(SystemError::ENOSYS);
|
||||
}
|
||||
RebootCommand::Kexec => {
|
||||
log::warn!("do_sys_reboot: Kexec not implemented");
|
||||
return Err(SystemError::ENOSYS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// kernel_restart - 重启系统
|
||||
///
|
||||
/// ## 参数
|
||||
/// - cmd: 指向包含重启命令的缓冲区的指针,或者 None
|
||||
///
|
||||
/// 关闭所有东西并执行一个干净的重启。
|
||||
/// 在中断上下文中调用这是不安全的。
|
||||
///
|
||||
/// todo: 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/reboot.c#265
|
||||
pub fn kernel_restart(cmd: Option<&str>) -> ! {
|
||||
if let Some(cmd) = cmd {
|
||||
log::warn!("Restarting system with command: '{}'", cmd);
|
||||
} else {
|
||||
log::warn!("Restarting system...");
|
||||
}
|
||||
unsafe { cpu_reset() }
|
||||
}
|
||||
|
||||
/// todo: 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/reboot.c#678
|
||||
pub fn kernel_power_off() -> ! {
|
||||
log::warn!("Power down");
|
||||
log::warn!("Currently, the system cannot be powered off, so we halt here.");
|
||||
loop {
|
||||
spin_loop();
|
||||
}
|
||||
}
|
||||
|
||||
/// todo: 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/reboot.c#293
|
||||
pub fn kernel_halt() -> ! {
|
||||
log::warn!("System halted.");
|
||||
loop {
|
||||
spin_loop();
|
||||
}
|
||||
}
|
11
kernel/src/misc/syscall.rs
Normal file
11
kernel/src/misc/syscall.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::syscall::Syscall;
|
||||
|
||||
use super::reboot::do_sys_reboot;
|
||||
|
||||
impl Syscall {
|
||||
pub fn reboot(magic1: u32, magic2: u32, cmd: u32, arg: usize) -> Result<usize, SystemError> {
|
||||
do_sys_reboot(magic1, magic2, cmd, arg).map(|_| 0)
|
||||
}
|
||||
}
|
@ -63,7 +63,6 @@ pub fn kernel_wait4(
|
||||
|
||||
// 判断pid类型
|
||||
let pidtype: PidType;
|
||||
|
||||
if pid == -1 {
|
||||
pidtype = PidType::MAX;
|
||||
} else if pid < 0 {
|
||||
|
@ -24,7 +24,7 @@ use num_traits::FromPrimitive;
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
arch::{cpu::cpu_reset, interrupt::TrapFrame, MMArch},
|
||||
arch::{interrupt::TrapFrame, MMArch},
|
||||
filesystem::vfs::{
|
||||
fcntl::{AtFlags, FcntlCommand},
|
||||
file::FileMode,
|
||||
@ -232,7 +232,13 @@ impl Syscall {
|
||||
Self::sbrk(increment).map(|vaddr: VirtAddr| vaddr.data())
|
||||
}
|
||||
|
||||
SYS_REBOOT => Self::reboot(),
|
||||
SYS_REBOOT => {
|
||||
let magic1 = args[0] as u32;
|
||||
let magic2 = args[1] as u32;
|
||||
let cmd = args[2] as u32;
|
||||
let arg = args[3];
|
||||
Self::reboot(magic1, magic2, cmd, arg)
|
||||
}
|
||||
|
||||
SYS_CHDIR => {
|
||||
let r = args[0] as *const u8;
|
||||
@ -1253,9 +1259,4 @@ impl Syscall {
|
||||
print!("\x1B[38;2;{fr};{fg};{fb};48;2;{br};{bg};{bb}m{s}\x1B[0m");
|
||||
return Ok(s.len());
|
||||
}
|
||||
|
||||
pub fn reboot() -> Result<usize, SystemError> {
|
||||
log::info!("reboot");
|
||||
unsafe { cpu_reset() };
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ source = "git"
|
||||
source-path = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/NovaShell.git"
|
||||
# git标签或分支
|
||||
# 注意: branch和revision只能二选一,且source要设置为"git"
|
||||
revision = "feaebefaef"
|
||||
revision = "d7d2136c5a"
|
||||
# 构建相关信息
|
||||
[build]
|
||||
# (可选)构建命令
|
||||
|
Loading…
x
Reference in New Issue
Block a user