Made by REMIXXYH
所使用的实验环境:
操作系统:OpenEuler22.03
内核版本:5.18.14
在进行实验三之前,请先确认已经完成实验一。
在进行本次实验之前,你需要先知道什么是系统调用。
关于系统调用,库函数,SHELL的转摘,,,-阿里云开发者社区https://developer.aliyun.com/article/42076
系统调用是用户身份访问内核的唯一方法。
- 编写新添系统调用代码
vim /opt/linux-5.18.14/kernel/sys.c 根据你的实际安装目录来
在文件的开头添加:
#include<linux/linkage.h>
在文件的末尾添加:
/*A new syscall example!*/
SYSCALL_DEFINE0(mysyscall)
{
printk(“Hello, this is REMIXXYH first systemcall!\n”);
return 0;
}
注意:DEFINE后面是0 ,表示函数只有一个参数
- 分配系统调用号,修改系统调用表
cd /opt/linux-5.18.14/
vim arch/x86/entry/syscalls/syscall_64.tbl
在common部分的最后添加,请和上面对齐
451 64 mysyscall sys_mysyscall
请记住此时的系统调用号
- 添加系统调用函数声明
vim /opt/linux-5.18.14/include/linux/syscalls.h
在文件中如图位置添加:
/* This is a new syscall */
asmlinkage long compat_sys_mysyscall(void);
asmlinkage long sys_mysyscall (void);
其中asmlinkage是一个编译指令,通知编译器仅从栈中提取该函数的参数。所有的系统调用都需要这个限定词。
- 重新编译源码
make -j8
make modules_install
make install
reboot
- 以用户态测试系统调用
编写测试程序test.c:
cat> test.c <<EOF
#include <syscall.h>
#include <stdio.h>
#include <linux/unistd.h>
#define __NR_hello 451
int main()
{
syscall(__NR_hello);
return 0;
}
EOF
gcc -o test test.c -g
注意:编译前要注意修改系统调用号,之前提示记住系统调用号,在这里就要使用
运行,在终端输入dmesg -c可显示函数的输出内容
首先执行下面的命令清除启动过程中内核产生的信息
dmesg -c
执行测试程序并查看结果:
./test
dmesg