我尝试在64位系统上向helloworld
添加一个简单的kernel 3.13.0-37-generic
系统调用。
我会尝试逐步展示我的目标:
1-我已经通过以下方式下载了内核源代码:
sudo apt-get source linux-image-3.13.0-37-generic
之后,将内核源文件解压缩到/usr/src/
2-定义新系统调用sys_hello()
:
我在hello
/usr/src/linux-3.13/
的目录
我在hello.c
目录中创建了一个hello
文件,内容如下:
#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
没有添加到内核系统调用。
我做错了什么?
答案 0 :(得分:7)
问题是从第6步到最后一步(编译内核)。
在第5步之后,我们必须执行以下步骤:
6-在我的系统上编译此内核
要配置内核,我尝试了以下命令:
# make menuconfig
在上面的命令之后出现一个弹出窗口,我确保选择了ext4,然后保存。
然后从新内核创建DEB
文件,我们必须:
# make -j 5 KDEB_PKGVERSION=1.arbitrary-name deb-pkg
它会在deb
中创建一些/usr/src/
个文件。
之后我们需要安装它们:
# dpkg -i linux*.deb
它将在您的系统上安装新内核。
现在,重新启动系统。系统重启后,您可以查看是否安装了新内核:
$ uname -r
如果你想知道你的新系统调用是否已添加到内核中,或者只是输入:
$ cat /proc/kallsyms | grep <system call name>
就我而言:
$ cat /proc/kallsyms | grep hello
以下输出表明您的系统调用已成功添加到内核:
0000000000000000 T sys_hello