2012-03-15 58 views
2

我需要在处理内核中的IRQ时重新启动。如何从IRQ范围内的非单片内核模块进行软重启?

我想调用/sbin/reboot二进制文件,但由于IRQ范围,我受到了限制。

代码如下:

#define MY_IRQ_ID  42 

void __init    rebootmodule_init(void) { 
    request_any_context_irq(MY_IRQ_ID, rebootmodule_irq_handler, IRQF_TRIGGER_FALLING, "irq-name", NULL); 
} 

irqreturn_t    rebootmodule_irq_handler(int irq, void *dev_id) { 
    my_reboot(); 
    return IRQ_HANDLED; 
} 

void     my_reboot(void) { 
    int     ret; 
    char    *argv[2], *envp[4]; 

    argv[0] = "/sbin/reboot"; 
    argv[1] = NULL; 
    envp[0] = "HOME=/"; 
    envp[1] = "PWD=/"; 
    envp[2] = "PATH=/sbin"; 
    envp[3] = NULL; 
    ret = call_usermodehelper(argv[0], argv, envp, 0); 
    printk(KERN_INFO "trying to reboot (ret = %d)", ret); 
} 

我可以看到printk(...)的IRQ被触发,但我有一些错误的时候,即使我通过/bin/rm /tmp/its-not-working更换/sbin/reboot

我测试的其他办法做到像重新启动,我没有IRQ范围之外mvBoardReset()machine_halt()arm_pm_restart()pm_power_off()kill(1, SIGTSTP)reboot()handle_sysrq('b'),我总是有误差。

我真的想打电话/sbin/reboot,因为它确实干净软复位。

谢谢你的时间。

回答

5

只是一个想法:您可以通过kthread_run()启动内核线程,把它放在wait_event()睡觉,由wake_up()唤醒它在IRQ处理程序,做你的东西(运行/sbin/reboot或任何你想要)在内核线程。像这样的东西(没有经过充分测试):

#define MY_IRQ_ID 42 

static DECLARE_WAIT_QUEUE_HEAD(wq); 
static volatile int showtime = 0; 

void my_reboot(void) { 
    int ret; 
    char *argv[2], *envp[4]; 

    argv[0] = "/sbin/reboot"; 
    argv[1] = NULL; 
    envp[0] = "HOME=/"; 
    envp[1] = "PWD=/"; 
    envp[2] = "PATH=/sbin"; 
    envp[3] = NULL; 
    ret = call_usermodehelper(argv[0], argv, envp, 0); 
    printk(KERN_INFO "trying to reboot (ret = %d)", ret); 
} 

static int my_thread(void *arg) { 
    wait_event(&wq, showtime); 
    my_reboot(); 
    return 0; 
} 

irqreturn_t rebootmodule_irq_handler(int irq, void *dev_id) { 
    showtime = 1; 
    wake_up(&wq); 
    return IRQ_HANDLED; 
} 

void __init rebootmodule_init(void) { 
    kthread_run(my_thread, NULL, "my_module"); 
    request_any_context_irq(MY_IRQ_ID, rebootmodule_irq_handler, IRQF_TRIGGER_FALLING, "irq-name", NULL); 
} 

不要忘了处理模块__exit和内核线程被送到睡觉的时候中断了来之前的情况。

+0

我修正了它的方式:) https://github.com/moul/junk/blob/master/kernel/irq_reboot.c – moul 2012-03-16 03:04:50