在内核模块

时间:2018-03-07 21:30:07

标签: assembly linux-kernel kernel-module

我开始使用内联汇编开发内核模块,我正在尝试执行 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指令中,因为我尝试了没有系统调用指令,汇编代码正常工作,只是在启动系统调用时出现分段错误。

1 个答案:

答案 0 :(得分:1)

comments中的@RossRidge所述,Linux内核不是为内核代码中使用的系统调用而设计的。因此,在内核代码中不应使用syscall指令

syscalls获得的一些功能具有内核替代方案。例如,要在内核中打开文件,可以使用filp_open,也可以使用vfs_write来编写文件。有关在内核代码中使用文件的更多信息,请参阅that question