我一直在使用下面列出的内核 5.4.0-77,您遇到的问题是因为存在引用错误,并且编译器无法找到特定定义的代码。执行下面提到的步骤并尝试看看它们是否能解决您的问题。
jack@blr:~$ uname -a
Linux blr 5.4.0-77-generic #86-Ubuntu SMP Thu Jun 17 02:35:03 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
在你的主源代码文件夹中添加一个文件夹 printmsg,例如:
jack@blr:/working/focal/printmsg$ ls
Makefile printmsg.c
创建列出的两个文件,如下图:
Printmsg.c
#include <linux/kernel.h>
#include <linux/syscalls.h>
SYSCALL_DEFINE0(printmsg)
{
printk("printmsg SYSTEM CALL IS ALIVE\n");
return 0;
}
生成文件
obj-y := printmsg.o
现在我们必须将系统调用引用添加到我们的 syscalls.h 和 syscall_64.tbl 文件中,如下所示。
root@blr:/working/focal# vi include/linux/syscalls.h
asmlinkage long sys_printmsg(void); - add this before the last #endif
root@blr:/working/focal# vi arch/x86/entry/syscalls/syscall_64.tbl
548 common printmsg __x64_sys_printmsg
– 确保您在此处使用制表符而不是空格,并按照文件中遵循的任何格式保持原样,并将新文本与其余代码对齐。
返回到主源文件夹,你应该有一个 Makefile - 在该文件中编辑以下行,添加我们的代码所在的文件夹,以便可以在内核构建期间对其进行编译。
jack@blr:/working/focal$ cat Makefile |grep core-y
core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ printmsg/
编译代码后,您可以通过编写一个简单的 userspcae 程序来检查代码是否工作,如下所示:
jack@blr:~/kerndev/asg3$ cat printmsg.c
#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <linux/unistd.h>
#include <unistd.h>
#include <errno.h>
int main()
{
long amma = syscall(548);
int errnum =errno;
if(amma==-1)
{ perror("Error is :" );
printf("System call sys_jackall returned %ld and error is %d\n",amma,errnum);
}
else
printf("System call PRINTMSG was called sussefully\n");
return 0;
}
编译运行程序:
jack@blr:~/kerndev/asg3$ gcc printmsg.c
jack@blr:~/kerndev/asg3$ ./a.out
System call PRINTMSG was called sussefully