Linux kernel 关机的底层操作

本文深入探讨了Linux系统的关机命令实现原理,包括halt、shutdown、poweroff等命令如何通过调用内核中的reboot syscall来实现不同类型的关机操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Linux关机相关命令如:halt,shutdown,poweroff和reboot

其实它们底层都是调用名为reboot的system call,其具体实现是在内核目录的kernel/sys.c中的

SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, void __user *, arg)这个函数里,函数原型如下:

SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
		void __user *, arg)
{
	struct pid_namespace *pid_ns = task_active_pid_ns(current);
	char buffer[256];
	int ret = 0;

	/* We only trust the superuser with rebooting the system. */
	if (!ns_capable(pid_ns->user_ns, CAP_SYS_BOOT))
		return -EPERM;

	/* For safety, we require "magic" arguments. */
	if (magic1 != LINUX_REBOOT_MAGIC1 ||
	    (magic2 != LINUX_REBOOT_MAGIC2 &&
	                magic2 != LINUX_REBOOT_MAGIC2A &&
			magic2 != LINUX_REBOOT_MAGIC2B &&
	                magic2 != LINUX_REBOOT_MAGIC2C))
		return -EINVAL;

	/*
	 * If pid namespaces are enabled and the current task is in a child
	 * pid_namespace, the command is handled by reboot_pid_ns() which will
	 * call do_exit().
	 */
	ret = reboot_pid_ns(pid_ns, cmd);
	if (ret)
		return ret;

	/* Instead of trying to make the power_off code look like
	 * halt when pm_power_off is not set do it the easy way.
	 */
	if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
		cmd = LINUX_REBOOT_CMD_HALT;

	mutex_lock(&reboot_mutex);
	switch (cmd) {
	case LINUX_REBOOT_CMD_RESTART:
		kernel_restart(NULL);
		break;

	case LINUX_REBOOT_CMD_CAD_ON:
		C_A_D = 1;
		break;

	case LINUX_REBOOT_CMD_CAD_OFF:
		C_A_D = 0;
		break;

	case LINUX_REBOOT_CMD_HALT:
		kernel_halt();
		do_exit(0);
		panic("cannot halt");

	case LINUX_REBOOT_CMD_POWER_OFF:
		kernel_power_off();
		do_exit(0);
		break;

	case LINUX_REBOOT_CMD_RESTART2:
		if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) {
			ret = -EFAULT;
			break;
		}
		buffer[sizeof(buffer) - 1] = '\0';

		kernel_restart(buffer);
		break;

#ifdef CONFIG_KEXEC
	case LINUX_REBOOT_CMD_KEXEC:
		ret = kernel_kexec();
		break;
#endif

#ifdef CONFIG_HIBERNATION
	case LINUX_REBOOT_CMD_SW_SUSPEND:
		ret = hibernate();
		break;
#endif

	default:
		ret = -EINVAL;
		break;
	}
	mutex_unlock(&reboot_mutex);
	return ret;
}

其中针对cmd有多个case,经过我在imx6平台上测试发现:

poweroff,halt和shutdown都是调用的 case LINUX_REBOOT_CMD_POWER_OFF

而reboot则是调用case LINUX_REBOOT_CMD_RESTART

这里以poweroff为例,会依次进行如下调用:

-->kernel_power_off()                         //kernel/sys.c

     -->kernel_shutdown_prepare   

     -->migrate_to_reboot_cpu

     -->syscore_shutdown

     -->machine_power_off               // 该函数根据具体平台而定,arm平台在arch/arm/kernel/process.c文件中



详细可以参考这篇文章http://www.wowotech.net/linux_kenrel/reboot.html

<think>嗯,用户现在问的是嵌入式Linux系统应该如何关机。之前他们问过关于查看I2C次设备号的问题,可能是在开发或调试嵌入式设备,现在涉及到关机操作,说明他们可能在处理系统管理或电源管理方面的任务。需要考虑到嵌入式系统的特殊性,比如可能没有常规的电源按钮或者桌面环境,所以关机方法可能与普通Linux系统不同。 首先,用户可能对Linux系统有一定了解,但可能不熟悉嵌入式环境下的具体操作。需要给出几种不同的关机方法,涵盖命令行工具、直接调用底层接口、硬件方法以及注意事项,比如数据同步和权限问题。同时,可能需要解释为什么不能直接断电,避免数据丢失或硬件损坏。 还要考虑用户可能遇到的问题,比如没有shutdown命令,或者需要自定义关机脚本。另外,硬件相关的关机方法可能需要特定的电路设计,这部分用户可能需要参考硬件手册,但至少应该提到这些可能性。最后,确保回答结构清晰,步骤明确,方便用户按照指导操作。</think>在嵌入式Linux系统中实现安全关机需要特别注意硬件特性与数据完整性,以下是专业关机方法及注意事项: $$ \text{关机流程} = \text{终止进程} \rightarrow \text{同步存储} \rightarrow \text{卸载文件系统} \rightarrow \text{硬件断电} $$ 一、标准关机命令(推荐) ```bash # 立即关机 sudo shutdown -h now # 延迟60秒关机 sudo shutdown -h +1 # 调用halt指令 sudo halt -p ``` 二、底层系统调用 ```bash # 直接触发关机信号 sudo echo 1 > /proc/sysrq-trigger # 同步磁盘 sudo echo o > /proc/sysrq-trigger # 立即关机 ``` 三、硬件级关机(需电路支持) ```c #include <linux/reboot.h> syscall(SYS_reboot, LINUX_REBOOT_CMD_POWER_OFF); // 通过GPIO控制电源芯片 ``` 四、嵌入式特殊场景处理 1. 无文件系统时: ```bash sync # 强制写入存储介质 echo 0x4321fedc > /proc/sys/kernel/sysrq # 解锁 echo o > /proc/sysrq-trigger ``` 2. 无shutdown命令时: ```bash kill -TERM 1 # 向init进程发送终止信号 ``` 五、关键注意事项 1. 存储设备同步: $$ \text{数据安全} = \text{fsync()} + \text{umount} + \text{block\_device\_flush} $$ 必须确保完成: ```bash sync && echo 3 > /proc/sys/vm/drop_caches ``` 2. 硬件保护: - 先关闭PWM输出 - 断开外设电源(通过GPIO控制MOS管) - 保存FPGA配置状态 - 记录关机时间戳到RTC 3. 功耗管理: ```bash echo mem > /sys/power/state # 进入低功耗模式(需内核支持) ``` 六、调试技巧 1. 使用strace跟踪关机过程: ```bash strace -f shutdown -h now ``` 2. 查看内核日志: ```bash dmesg | grep -E 'shutdown|power' ``` 七、典型应用场景对比 | 场景 | 推荐方法 | 风险等级 | |-----------------------|-----------------------------|----------| | 正常关机 | shutdown命令 | ★☆☆☆☆ | | 快速关机 | sysrq触发 | ★★☆☆☆ | | 紧急断电 | GPIO硬件控制 | ★★★★☆ | | 低功耗设备 | ACPI电源管理 | ★★☆☆☆ | 建议优先使用系统提供的shutdown命令,在无可用命令时采用sysrq机制。对于定制硬件平台,建议开发专用关机驱动实现:$G_{shutdown} = f_{hw}(GPIO) \oplus f_{sw}(syscall)$
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值