2012-03-15 66 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