以下是我遵循的步骤。
1) 我运行的是4.15.0内核,所以我更新到了更新的内核。
wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.17.4.tar.xz
2) 使用提取内核源代码
sudo tar -xvf linux-4.17.4.tar.xz -C/usr/src/
3) 在cd /usr/src/linux-4.17.4/
中创建了一个名为的新目录
子
然后创建
subc
内部
子
目录。
在中
subc
我写的代码是从x中减去y if(y>x),否则返回0;这里x是整数,y是二重。
#include <linux/kernel.h>
asmlinkage int sys_sub(int x,double y)
{
printk("working...");
if(y>x){
return ((int)y-x);}
else
return 0;
}
4) 在同一子目录中创建了一个Makefile,并添加了obj-y := sub.o
5) 在中
/usr/src/linux-4.17.4
打开Makefile并将core-y行修改为
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ sub/
6) 然后在中
cd arch/x86/entry/syscalls/
我打开了
gedit syscall_64.tbl
并且作为第548次系统调用,我进入
548 64 hello sys_sub
7) 在中
cd include/linux/
我打开了
gedit系统调用.h
并添加
asmlinkage int sys_sub(int x,double y);
作为endif 前的最后一行
8) 我确保在中选择ext4
sudo使菜单配置
9)我使用编译了内核
sudo制作模块安装
10)执行
关闭-r现在
11)已检查
uname-r
以确保我正在运行
4.17.4
我确实是。
12) 我创建了一个C程序来检查系统调用
#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>
int main()
{
int res = syscall(548,10,44);
printf("System call sys_sub returned %d ", res);
return 0;
}
但它只返回
系统调用sys_sub返回0
和
dmesg
出于某种原因显示Hello World。请帮帮我。我做错了什么?
编辑:
我根据阅读的评论对代码进行了必要的更改。现在我的系统调用代码如下:
#include <linux/kernel.h>
asmlinkage long sys_sub(int a,int b)
{
printk("System call is working...n");
printk("Inputs are %d and %d",a,b);
if(b>a)
{
int c= b-a;
printk("Answer is %d",c);
return c;
}
printk("Answer is 0");
return 0;
}
我添加了一些print语句,以确保正确调用系统调用。我重新编译了内核并再次运行,现在我得到了
dmesg
输出为
系统调用正在工作。。。输入为1114685272和111468527答案是0
看起来内核得到的是随机垃圾值,而不是我传递的参数,这使得它总是使if循环失败。两个参数的随机值似乎总是相同的!我不知道我现在哪里错了。
在一篇互联网文章中提到编译整个内核,然后编译modules_install。此外,系统调用的返回必须是长的,而不是int。unistd.h文件需要对新的系统调用进行一些更改。这篇文章适用于2.6内核,但可以在http://www.tldp.org/HOWTO/html_single/Implement-Sys-Call-Linux-2.6-i386/