免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7674 | 回复: 1
打印 上一主题 下一主题

[操作系统] busybox reboot 跟踪一下 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-12-14 17:02 |只看该作者 |倒序浏览
reboot 进入busybox,  busybox-1.01/init/reboot.c
  1. extern int reboot_main(int argc, char **argv)
  2. {
  3. char *delay; /* delay in seconds before rebooting */
  4. if(bb_getopt_ulflags(argc, argv, "d:", &delay)) {
  5.   sleep(atoi(delay));
  6. }
  7. #ifndef CONFIG_INIT
  8. #ifndef RB_AUTOBOOT
  9. #define RB_AUTOBOOT  0x01234567     /*与kernel 中定义相同*/
  10. #endif
  11. return(bb_shutdown_system(RB_AUTOBOOT));
  12. #else
  13. return kill_init(SIGTERM);
  14. #endif
  15. }
复制代码

busybox-1.01/init/init_shared.c,向init或linuxrc进程发送SIGTRRM,
  1. extern int kill_init(int sig)
  2. {
  3. #ifdef CONFIG_FEATURE_INITRD
  4. /* don't assume init's pid == 1 */
  5. long *pid = find_pid_by_name("init");
  6. if (!pid || *pid<=0) {
  7.   pid = find_pid_by_name("linuxrc");
  8.   if (!pid || *pid<=0)
  9.    bb_error_msg_and_die("no process killed");
  10. }
  11. return(kill(*pid, sig));
  12. #else
  13. return(kill(1, sig));
  14. #endif
  15. }
复制代码

init_main()中得到信号:

  1. extern int init_main(int argc, char **argv)
  2. {
  3.   ...
  4. signal(SIGTERM, reboot_signal);
  5. ...
  6. }
复制代码
  1. static void reboot_signal(int sig)
  2. {
  3. shutdown_system();
  4. message(CONSOLE | LOG, "Please stand by while rebooting the system.");
  5. sync();
  6. /* allow time for last message to reach serial console */
  7. sleep(2);
  8. init_reboot(RB_AUTOBOOT);
  9. loop_forever();
  10. }
复制代码
  1. static void init_reboot(unsigned long magic)
  2. {
  3. pid_t pid;
  4. /* We have to fork here, since the kernel calls do_exit(0) in
  5.   * linux/kernel/sys.c, which can cause the machine to panic when
  6.   * the init process is killed.... */
  7. if ((pid = fork()) == 0) {
  8.   reboot(magic);
  9.   _exit(0);
  10. }
  11. waitpid (pid, NULL, 0);
  12. }
复制代码

reboot的定义在库里面,用的是交叉编程库为uclinux,在其库中找到linux/common/reboot.c,

  1. #include "syscalls.h"
  2. #include <sys/reboot.h>
  3. #define __NR__reboot __NR_reboot
  4. static inline _syscall3(int, _reboot, int, magic, int, magic2, int, flag);
  5. int reboot(int flag)
  6. {
  7.     return (_reboot((int) 0xfee1dead, 672274793, flag));
  8. }
复制代码


include/linux/reboot.h 中定义:
  1. #define LINUX_REBOOT_CMD_RESTART 0x01234567
复制代码

进入kernel/sys.c,

  1. asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user * arg)
  2. {
  3.         char buffer[256];

  4.         /* We only trust the superuser with rebooting the system. */
  5.         if (!capable(CAP_SYS_BOOT))
  6.                 return -EPERM;

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

  14.         lock_kernel();
  15.         switch (cmd) {
  16.         case LINUX_REBOOT_CMD_RESTART:
  17.                 kernel_restart(NULL);
  18.                 break;

  19.         case LINUX_REBOOT_CMD_CAD_ON:
  20.                 C_A_D = 1;
  21.                 break;

  22.         case LINUX_REBOOT_CMD_CAD_OFF:
  23.                 C_A_D = 0;
  24.                 break;

  25.         case LINUX_REBOOT_CMD_HALT:
  26.                 kernel_halt();
  27.                 unlock_kernel();
  28.                 do_exit(0);
  29.                 break;

  30.         case LINUX_REBOOT_CMD_POWER_OFF:
  31.                 kernel_power_off();
  32.                 unlock_kernel();
  33.                 do_exit(0);
  34.                 break;

  35.         case LINUX_REBOOT_CMD_RESTART2:
  36.                 if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) {
  37.                         unlock_kernel();
  38.                         return -EFAULT;
  39.                 }
  40.                 buffer[sizeof(buffer) - 1] = '\0';

  41.                 kernel_restart(buffer);
  42.                 break;

  43.         case LINUX_REBOOT_CMD_KEXEC:
  44.                 kernel_kexec();
  45.                 unlock_kernel();
  46.                 return -EINVAL;

  47. #ifdef CONFIG_SOFTWARE_SUSPEND
  48.         case LINUX_REBOOT_CMD_SW_SUSPEND:
  49.                 {
  50.                         int ret = software_suspend();
  51.                         unlock_kernel();
  52.                         return ret;
  53.                 }
  54. #endif

  55.         default:
  56.                 unlock_kernel();
  57.                 return -EINVAL;
  58.         }
  59.         unlock_kernel();
  60.         return 0;
  61. }
复制代码

系统重启:
  1. void kernel_restart(char *cmd)
  2. {
  3. kernel_restart_prepare(cmd);
  4. if (!cmd) {
  5.   printk(KERN_EMERG "Restarting system.\n");
  6. } else {
  7.   printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd);
  8. }
  9. printk(".\n");
  10. machine_restart(cmd);
  11. }
复制代码


进入arch/mips/kernel/reset.c, _machine_restart为一个函数指针:
  1. void (*_machine_restart)(char *command);
  2. void machine_restart(char *command)
  3. {
  4. _machine_restart(command);
  5. }
复制代码


用的cpu为ar7240,在arch/mips/ar7240下的指定
  1. void __init plat_setup(void)
  2. {
  3.     .....
  4.     _machine_restart    =  ar7240_restart;
  5.     _machine_halt       =  ar7240_halt;
  6.     _machine_power_off  =  ar7240_power_off;
  7.    ....
  8. }
复制代码

对cpu reset reg进行写值,操作完成
  1. void
  2. ar7240_restart(char *command)
  3. {
  4.     for(;;) {
  5.         ar7240_reg_wr(AR7240_RESET, AR7240_RESET_FULL_CHIP);
  6.     }
  7. }
复制代码

[ 本帖最后由 s.t_seeyou 于 2009-12-14 17:13 编辑 ]

评分

参与人数 1可用积分 +30 收起 理由
T-Bagwell + 30 原创内容

查看全部评分

论坛徽章:
0
2 [报告]
发表于 2009-12-15 17:18 |只看该作者
好文:
最后调用到,ar7240_reg_wr(AR7240_RESET, AR7240_RESET_FULL_CHIP);

世界清静了。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP