本来以为是很简单随便水一水的课程设计,没想到是这里踩了一个坑那里踩了一个坑一直弄了快十个小时才全部解决。
安装OpenEuler虚拟机环境
openEuler镜像仓列表 | openEuler下载 | openEuler社区
在镜像仓列表随意选择一个适配操作系统的ISO镜像下载即可,如图选择Index of /openeuler/openEuler-22.03-LTS/ISO/下的x86_64进行下载。

下载好了之后用VMware安装即可,内存、磁盘与处理器最好多分配一些,不然后续编译内核可能会出现空间不够编译失败,或者速度很慢非常花时间。
安装好虚拟机后发现这命令行不能选择不能粘贴的,推荐ssh连接,后续配环境,改代码都会很方便。
下载内核源码并完成添加系统调用的代码部分
yum group install -y "Development Tools"
yum install -y bc
yum install -y openssl-devel
逐行输入配置后续开发环境。
git clone https://gitee.com/openeuler/kernel.git
从网上下一份源代码,用于后续修改,整个包有两三个G。
哪怕添加一个最简单仅仅输出字符串的系统调用,仍需要完成三个任务。
- 注册系统调用号

在kernel/arch/x86/entry/syscalls/syscall_64.tbl文件中添加系统调用号,在网上搜到的教程挺多都是以sys_mysyscall的形式添加,或者干脆没有这一步。值得注意的是在4.17之后的版本,添加的系统调用必须以__x64_sys_为开头,也是因为这个坑而白白编译了数次。
arch/x86/entry/syscall_64.o:(.rodata+0xa78): undefined reference to `sys_get_pid_info‘-CSDN博客
- 声明系统调用函数

在kernel/arch/x86/include/asm/syscalls.h中声明函数原型,如果参数不填入void后续会出现函数无返回值的报错。
- 添加调用函数的定义

在kernel/kernel/sys.c中添加如下代码,其中SYSCALL_DEFINE0表示这个函数没有参数,printk用于在日志中打印。
SYSCALL_DEFINE0(sys_mysyscall){
printk("Hello");
return 1;
}
完成上述三步,代码层面的添加系统调用便完成了,后续需要进行编译和安装。
编译与安装
于kernel目录下依顺序执行
配置内核:
make menuconfig

保存config后直接退出即可。
编译内核:
make -j64
-j64表示64线程进行编译,如果真有这么多资源的话可以加速编译过程,编译过程需要较长时间。
编译模块:
make modules
安装模块:
make modules_install
安装内核:
make install
完成后会在终端提示版本号,记住后执行reboot重启,选择对应操作系统启动。
验证是否添加成功
#include<linux/kernel.h>
#include<sys/syscall.h>
#include<unistd.h>
#include<stdio.h>
int main(void)
{
long res = 0;
res = syscall(548);
if(res == 1)
{
printf("Success!");
}
return 0;
}
编译并执行,通过dmesg -c清空日志后执行程序再dmesg查看日志,若出现Hello即为添加成功。
到此,添加一个系统调用的任务就完成了,笔者在完成这个课程设计的过程中踩了非常多的坑,有VMware网络配置问题,vscode的SSH连接问题,系统调用不同版本的注册问题,编译过程缺库、安装过程缺文件的问题,做的时候多少带点怨气,做完想想其实是自己其他方面的经验不足。

Comments 2 条评论
😋
@1254551681 😋