mou*_*oul 2 linux kernel reboot irq linux-kernel
我需要重新启动处理内核中的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);
}
Run Code Online (Sandbox Code Playgroud)
我可以看到printk(...)IRQ被触发的时间,但是我有一些错误,即使我替换/sbin/reboot了/bin/rm /tmp/its-not-working.
我测试了其他办法可以做到像重启mvBoardReset(),machine_halt(),arm_pm_restart(),pm_power_off(),kill(1, SIGTSTP),reboot(),handle_sysrq('b'),我总是说我没有IRQ范围之外的错误.
我真的很想打电话/sbin/reboot,因为它确实可以清除软复位.
感谢您的时间.
只是一个想法:你可以启动内核线程kthread_run(),让它睡眠wait_event(),在IRQ处理程序中唤醒它,在内核线程中wake_up()执行你的东西(运行/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);
}
Run Code Online (Sandbox Code Playgroud)
不要忘记在内核线程被发送到睡眠之前__exit中断时处理模块和情况.
| 归档时间: |
|
| 查看次数: |
1497 次 |
| 最近记录: |