2012-03-15 4 views
2

カーネルの土地でIRQを処理する際に再起動する必要があります。IRQスコープの非モノリシックカーネルモジュールからソフトリブートする方法はありますか?

私は/sbin/rebootバイナリに電話しますが、IRQスコープのため制限があります。

コードは次のとおりです。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); 
} 

私は/bin/rm /tmp/its-not-working/sbin/rebootを交換する場合でも、printk(...)を見ることができます。私はmvBoardReset()machine_halt()arm_pm_restart()pm_power_off()kill(1, SIGTSTP)reboot()handle_sysrq('b')のように再起動を行うには、他の方法をテストした

、私はいつも私がIRQの範囲外ではありませんエラーを持っています。

私は本当に/sbin/rebootに電話したいと思っています。それはで、ソフトリセットです。

ありがとうございます。

答えて

5

ジャストアイデア:あなたはカーネルスレッドに自分のものを(/sbin/rebootを実行したり、何でもしたい)やる、wait_event()で寝wake_up()によってIRQハンドラで、それをウェイクアップするためにそれを置く、kthread_run()によってカーネルスレッドを開始することができます。このような何か(完全にテストされていない):

#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

関連する問題