首先,我做这个只是为了好玩,所以请不要批评我。
我的做法是将一个函数指针从用户空间传递到内核,使用copy_from_user将函数体复制到内核中的静态数组中,并开始跳转到该数组中执行。
在内核中:
static char handler_text[PAGE_SIZE] __page_aligned_data;
copy_from_user((void *)handler_text , (const void __user *)my_handler , PAGE_SIZE);
((void (*)())(handler_text))();
在用户空间,这个函数的作用非常简单,如下所示。
void my_handler(){
volatile unsigned long * p = (volatile unsigned long *)0xF0000c10;
*p = 0x0000000;
}
10000938 <my_handler>:
10000938: 3d 20 f0 00 lis r9,-4096
1000093c: 39 40 00 00 li r10,0
10000940: 61 29 0c 10 ori r9,r9,3088
10000944: 91 49 00 00 stw r10,0(r9)
10000948: 4e 80 00 20 blr
1000094c: 00 01 88 08 .long 0x18808
问题是第一次执行此操作时总会产生Oops。但第二次和之后再执行,问题就消失了,不再出现任何Oops。通过读取内存,我可以清楚地看到该函数是由内核执行的。我正在运行一个PowerPc目标,因此Oops显示异常为700,即程序异常。从Oops中,我可以看到指令转储,其中nip(之后)正好是与my_handler相同的指令。
Instruction dump:
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 <3d20f000> 39400000 61290c10 91490000
我无法理解它的意义。有人能理解吗?谢谢。