【问题标题】:Trouble calling syscall by name按名称调用系统调用时遇到问题
【发布时间】:2015-05-03 09:08:23
【问题描述】:

我正在向 linux Kernel 3.19 添加系统调用。尝试以下方法在 Ubuntu 14.04 LTS 中为 x86 架构添加系统调用“添加”。 src=3.19 来源

  1. 向 src/arch/x86/syscalls/syscall_64.tbl 添加条目。

    323 common add sys_add
    
  2. 将系统调用原型添加到 src/include/syscalls.h。

    asmlinakge sys_add(int i,int j);
    
  3. fs目录中写add.c,在fs/Makefile中添加add.o .

  4. 在文件 src/include/uapi/asm-generic/unistd.h

添加的行

    #define __NR_add 323

  __SYSCALL(__NR_add, sys_add);
  1. 编译并构建了内核。这是成功的。 uname -r 的输出为 3.19。

  2. 创建了一个程序来测试新的系统调用。

    6.1 使用了函数syscall(323,10,15)。这是成功的,因为打印了 values(25) 的总和。

    6.2 当尝试按名称调用系统调用时,它给出了

      /tmp/ccpxRp8C.o: In function `main':
       testadd1.c:(.text+0x18): undefined reference to `add'
       collect2: error: ld returned 1 exit status
    

我错过了什么?

【问题讨论】:

    标签: linux ubuntu linux-kernel system-calls


    【解决方案1】:

    您缺少一小段汇编代码,在汇编时,它显示为 C 可链接符号。

    如果你这样做:

    ar t /usr/lib/libc.a | grep write.o
    

    您会看到(静态链接的)C 库有一个名为“write.o”的小文件。这包含一小段汇编代码,它定义了在write.o 之外可见的符号__libc_write。那一小段汇编代码将值 1 放入特定寄存器中,这是 Linux 和 Unix 内核称为“写入”系统调用的数字,非常小心地设置其他寄存器,然后执行 syscall 指令(在我的x86_64 机器)。

    您将不得不为您的“add”系统调用创建这样一段汇编代码。或者,您可以使用 syscall 系统调用,就像您一直在做的那样,编写一个普通的 C 函数,让它看起来像您有一个 add() 系统调用。

    您没有说明您使用的是什么架构(x86 或 x86_64),但这里是 write(2) 的 x86_64 实现。它确实正确设置了errno,并返回写入的字节数,但参数类型不正确。

    int
    linux_write(int fd, const void *data, unsigned long len)
    {
    
        long ret;
        asm volatile ("syscall" : "=a" (ret) : "a" (__NR_write),
                  "D" (fd), "S" (data), "d" (len) :
                  "cc", "memory", "rcx",
                  "r8", "r9", "r10", "r11" );
        if (ret < 0)
        {
            errno = -ret;
            ret = -1;
        }
        return (int)ret;
    }
    

    【讨论】:

    • 您好,感谢您的回复。上面的代码是在内核本身完成的吗?还有,step 4有什么用?
    • @AsishKSahadevan - 不,它驻留在单独的文件中,并自行编译。此时,您已经有了一个可以与缺少符号的 C 程序链接的目标文件(.o 文件)。目标文件提供符号和执行syscall 的代码,将您的程序带入内核。第 4 步是这样您就可以使用syscall() 通用系统调用执行功能。如果您正在编写自己的程序集存根,则无需执行第 4 步。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-01
    • 1970-01-01
    相关资源
    最近更新 更多