无法按名称调用syscall

时间:2015-03-02 07:26:38

标签: linux ubuntu linux-kernel system-calls

我正在向linux Kernel 3.19添加系统调用。尝试在Ubuntu 14.04 LTS中为x86 arch添加系统调用'add'。 src = 3.19 source

  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

  5. 添加了行

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

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

      6.1使用系统调用(323,10,15)功能。这是成功的,因为印刷了价值总和(25)。

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

        /tmp/ccpxRp8C.o: In function `main':
         testadd1.c:(.text+0x18): undefined reference to `add'
         collect2: error: ld returned 1 exit status
      
    3. 我错过了什么?

1 个答案:

答案 0 :(得分:1)

您缺少一小段汇编代码,汇编后会显示为C-linkable符号。

如果你这样做:

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

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

您必须为“添加”系统调用创建这样的汇编代码。或者,就像你一直在做的那样,你可以进行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;
}