【问题标题】:Adding new System Call to Linux Kernel 3.13 on 64 bit system在 64 位系统上向 Linux Kernel 3.13 添加新的系统调用
【发布时间】:2014-12-30 11:41:32
【问题描述】:

我正在尝试在 64 位系统上向 kernel 3.13.0-37-generic 添加一个简单的 helloworld 系统调用。

我将尝试一步一步地展示我到目前为止所做的事情:

1- 我已通过以下方式下载内核源代码:

sudo apt-get source linux-image-3.13.0-37-generic

之后,内核源文件解压到/usr/src/

2- 定义一个新的系统调用sys_hello():

我在/usr/src/linux-3.13/的内核源目录中创建了一个名称为hello的目录

我在hello 目录中创建了一个hello.c 文件,内容如下:

#include <linux/kernel.h>

asmlinkage long sys_hello(void)
{
        printk(“Hello world\n”);
        return 0;
}

然后我在 hello 目录中创建了一个Makefile,内容如下:

obj-y := hello.o

3- 将 hello 目录添加到内核的 Makefile 中

我在/usr/src/linux-3.13/Makefile 中更改了以下行:

core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/

到:

core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ hello/

4-将新的系统调用sys_hello()添加到系统调用表(syscall_64.tbl文件)

因为我使用的是 64 位系统,所以我需要更改 syscall_64.tbl 中的文件:

/usr/src/linux-3.13/arch/x86/syscalls/syscall_64.tbl

在文件末尾添加以下行:

-最后一行是313

314     common    hello    sys_hello

5-在系统调用头文件中添加新的系统调用sys_hello()

vim /usr/src/linux-3.13/include/linux/syscalls.h

我在文件末尾的最底部 #endif 语句之前添加了以下行:

asmlinkage long sys_hello(void);

6- 在我的系统上编译这个内核

为了配置内核,我尝试了以下命令:

sudo make menuconfig

执行上述命令后会弹出一个窗口,我确保选择了ext4,然后选择了save。

然后:

# cd /usr/src/linux-3.13/
# make

耗时 2~3 小时。

之后:

# make modules_install install

之后,我重新启动了我的系统。

7- 测试系统调用(问题来了)

重启后,我在主文件夹中创建了一个名为 hello.c 的文件,内容如下:

#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>
int main()
{
         long int amma = syscall(314); // 314 is the number of sys_hello line in `syscall_64.tbl`
         printf(“System call sys_hello returned %ld\n”, amma);
         return 0;
}

然后:

# gcc hello.c
# ./a.out

输出是:

System call sys_hello returned -1

问题正是-1。它必须返回0 而不是-1。

好像sys_hello 没有添加到内核系统调用中。

我做错了什么?

【问题讨论】:

  • 查看内核日志或检查 uname 以确保您正在运行新版本。也许检查 system.map 以查看您的添加是否包含在内核中。
  • 我无法通过uname 弄清楚,因为内核之前/之后是相同的(两者都是kernel 3.13.0-37-generic)。
  • dmesg没有与sys_hello系统调用相关的登录!
  • 你的内核输出不包括它的构建时间吗?我并不是建议您在那里寻找您的功能的证据,而是寻找您实际上正在运行您的新版本的证据。然后分别进行一些检查,看看您的新版本是否完全拾取了您的代码。
  • 了解make-kpkg 以构建内核,并在构建内核时将-j 4 传递给make-kpkg 或make。

标签: linux linux-kernel system-calls


【解决方案1】:

问题是从第 6 步到最后一步(编译内核)。

在第 5 步之后,我们必须执行以下步骤:

6- 在我的系统上编译这个内核

为了配置内核,我尝试了以下命令:

# make menuconfig

执行上述命令后会弹出一个窗口,我确保选择了 ext4 然后保存。

然后要从新内核创建DEB 文件,我们必须:

# make -j 5 KDEB_PKGVERSION=1.arbitrary-name deb-pkg

它将在/usr/src/ 中创建一些deb 文件。

之后我们需要安装它们:

# dpkg -i linux*.deb

它将在您的系统上安装新内核。

现在,重新启动您的系统。系统重新启动后,您可以查看是否安装了新内核:

$ uname -r

如果您想知道您的新系统调用是否添加到内核,只需键入:

$ cat /proc/kallsyms | grep <system call name>

就我而言:

$ cat /proc/kallsyms | grep hello

以下输出表明您的系统调用已成功添加到内核:

0000000000000000 T sys_hello

【讨论】:

  • 很好的提问和回答!
猜你喜欢
  • 1970-01-01
  • 2013-03-13
  • 2018-06-06
  • 2013-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-16
相关资源
最近更新 更多