Linux电源管理(二)系统reboot/shutdown过程
来源:互联网 发布:oecd数据公布 编辑:程序博客网 时间:2024/06/06 05:10
概述
计算机包括嵌入式设备,关机和重启是常见的两个操作。本文主要主要描述这两个动作背后和流程和实现。
下机我们先看一下,linux支持的类似关机重启这样的命令的其它相关命令。
/* * Commands accepted by the _reboot() system call. * * RESTART Restart system using default command and mode. * HALT Stop OS and give system control to ROM monitor, if any. * CAD_ON Ctrl-Alt-Del sequence causes RESTART command. * CAD_OFF Ctrl-Alt-Del sequence sends SIGINT to init task. * POWER_OFF Stop OS and remove all power from system, if possible. * RESTART2 Restart system using given command string. * SW_SUSPEND Suspend system using software suspend if compiled in. * KEXEC Restart system using a previously loaded Linux kernel */#define LINUX_REBOOT_CMD_RESTART 0x01234567 //重启命令#define LINUX_REBOOT_CMD_HALT 0xCDEF0123 #define LINUX_REBOOT_CMD_CAD_ON 0x89ABCDEF#define LINUX_REBOOT_CMD_CAD_OFF 0x00000000#define LINUX_REBOOT_CMD_POWER_OFF 0x4321FEDC//关机命令#define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4#define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2#define LINUX_REBOOT_CMD_KEXEC 0x45584543
reboot/shutdown流程
在Linux操作系统中,可以通过reboot、halt、poweroff等命令,发起reboot,具体的操作流程如下:
- 一般的Linux操作系统,在用户空间都提供了一些工具集合(如常在嵌入式系统使用的Busybox),这些工具集合包含了reboot、halt和poweroff三个和Reboot相关的命令。读者可以参考man帮助文档,了解这些命令的解释和使用说明
- 用户空间程序通过reboot系统调用,进入内核空间
- 内核空间根据执行路径的不同,提供了kernel_restart、kernel_halt和kernel_power_off三个处理函数,响应用空间的reboot请求
- 这三个处理函数的处理流程大致相同,主要包括:向关心reboot过程的进程发送Notify事件;调用drivers核心模块提供的接口,关闭所有的外部设备;调用drivers syscore模块提供的接口,关闭system core;调用Architecture相关的处理函数,进行后续的处理;最后,调用machine相关的接口,实现真正意义 Reboot
- 另外,借助TTY模块提供的Sysreq机制,内核提供了其它途径的关机方法,如某些按键组合、向/proc文件写入命令等。
实现流程分析
系统调用入口
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;}
重启函数入口
void kernel_restart(char *cmd){ kernel_restart_prepare(cmd); //通知链通知,关闭所有设备(bus,driver的shutdown接口) migrate_to_reboot_cpu();// syscore_shutdown(); //系统核心器件关闭(例如中断等) if (!cmd) printk(KERN_EMERG "Restarting system.\n"); else printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd); kmsg_dump(KMSG_DUMP_RESTART); //向世界发出最后的声音 machine_restart(cmd); //由machine-core的代码,接管后续的处理}
关机接口
void kernel_power_off(void){ kernel_shutdown_prepare(SYSTEM_POWER_OFF); if (pm_power_off_prepare) pm_power_off_prepare(); migrate_to_reboot_cpu(); syscore_shutdown(); printk(KERN_EMERG "Power down.\n"); kmsg_dump(KMSG_DUMP_POWEROFF); machine_power_off();}
驱动需要实现什么?
实现各自的shutdown接口,以正确关闭对应的设备
参考资料
<1>.http://www.wowotech.net/pm_subsystem/reboot.html
阅读全文
0 0
- Linux电源管理(二)系统reboot/shutdown过程
- Linux电源管理(3)_Generic PM之Reboot过程
- Linux电源管理(3)_Generic PM之Reboot过程
- Linux电源管理(3)_Generic PM之Reboot过程
- Linux电源管理(3)_Generic PM之Reboot过程
- Linux电源管理(3)_Generic PM之Reboot过程
- Linux系统下的shutdown和reboot
- Linux学习笔记_系统操作、优化相关命令复习(shutdown,reboot,yum)
- Linux电源管理(一)电源管理系统架构
- linux 用户空间电源管理 (二)
- 七、Linux常用命令之系统操作篇(write、wall、ping、ifconfig、shutdown、reboot、alias、unalias、<、>、2>、|、``、mount)
- Linux电源管理系统架构和驱动(1)-Linux电源管理全局架构
- Linux电源管理系统架构和驱动(1)-Linux电源管理全局架构
- linux下shutdown, halt, reboot的区别
- Linux开关机命令(shutdown,reboot,halt,init)
- Linux关机命令:halt shutdown reboot init
- Linux 常用基本命令 reboot shutdown init
- Linux功耗管理(3)_Generic PM之Reboot过程
- 在Ubuntu下用APT去安装FLASH插件
- PHP 7 新特性
- 异常
- 百度地图学习总结(1)—前置准备,申请key
- CF687A NP-Hard Problem(二分图判断)
- Linux电源管理(二)系统reboot/shutdown过程
- java后端题目常见
- 元组:戴上了枷锁的列表
- 栈的应用4--中缀表达式转换为后缀表达式
- 网络编程(python)
- apt-get安装软件Unable to locate package错误解决办法
- NYOJ201
- plan(Tag,ToDo/Doing),在路上的思考
- C++ MFC / VS2013 之六 (对话框:创建对话框类和添加控件变量)