我开始使用内联汇编开发内核模块,我正在尝试执行 write 系统调用以便写入文件。它编译得很好(此外,在C程序中正常工作),但是当我加载模块时它会丢弃分段错误,当我查看诊断消息(dmesg)时,我看到以下内容:
[ 672.687568] BUG: stack guard page was hit at ffffb8a601d13fa8 (stack is ffffb8a601d14000..ffffb8a601d17fff)
[ 672.687577] kernel stack overflow (double-fault): 0000 [#1] SMP
...
[ 672.777032] [<ffffffffa50fda16>] ? SYSC_finit_module+0xc6/0xf0
[ 672.777396] [<ffffffffa55ebebb>] ? system_call_fast_compare_end+0xc/0x9b
[ 672.777765] Code: 48 89 e7 48 8b 74 24 78 48 c7 44 24 78 ff ff ff ff e8 28 09 a7 ff e9 53 02 00 00 0f 1f 00 0f 1f 00 66 0f 1f 44 00 00 48 83 c4 88 <e8> 7e 01 00 00 48 89 e7 48 8b 74 24 78 48 c7 44 24 78 ff ff ff
[ 672.779059] RIP [<ffffffffa55ed27d>] page_fault+0xd/0x30
[ 672.779481] RSP <ffffb8a601d13fb8>
[ 672.779901] fbcon_switch: detected unhandled fb_set_par error, error code -16
内核模块的代码如下:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
int example_init(void);
void example_exit(void);
module_init(example_init);
module_exit(example_exit);
int example_init(void) {
char *file = "/root/test2";
char *msg = "AAAAAA\n";
asm( "mov eax, 0x2;"
"mov rdi, %0;"
"mov rsi, 0x441;"
"xor rdx, rdx;"
"syscall;"
"mov rdi, rax;"
"mov eax, 0x1;"
"mov rsi, %1;"
"mov rdx, 7;"
"syscall;"
"mov eax, 0x3;"
"syscall;"
: "=m" (file), "=m" (msg)
);
printk("Example: module loaded.\n");
return 0;
}
void example_exit(void) {
printk("Example: module removed\n");
}
我知道失败在syscall指令中,因为我尝试了没有系统调用指令,汇编代码正常工作,只是在启动系统调用时出现分段错误。
答案 0 :(得分:1)
如comments中的@RossRidge所述,Linux内核不是为内核代码中使用的系统调用而设计的。因此,在内核代码中不应使用syscall
指令 。
syscalls获得的一些功能具有内核替代方案。例如,要在内核中打开文件,可以使用filp_open
,也可以使用vfs_write
来编写文件。有关在内核代码中使用文件的更多信息,请参阅that question。