操作系统Linux:增加系统调用

一、系统调用简介

Linux内核中设置了一组用于实现各种系统功能的子程序,称为系统调用。用户可以通过系统调用命令在自己的应用程序中调用它们。从某种角度来看,系统调用和普通的函数调用非常相似。区别仅仅在于,系统调用由操作系统核心提供,运行于核心态;而普通的函数调用由函数库或用户自己提供,运行于用户态。二者在使用方式上也有相似之处。
一般的,进程是不能访问内核的。它不能访问内核所占内存空间也不能调用内核函数。CPU硬件决定了这些(这就是为什么它被称作"保护模式")。系统调用是这些规则的一个例外。其原理是进程先用适当的值填充寄存器,然后调用一个特殊的指令,这个指令会跳到一个事先定义的内核中的一个位置。进程可以跳转到的内核位置叫做sysem_call。这个过程检查系统调用号,这个号码告诉内核进程请求哪种服务。然后,它查看系统调用表(sys_call_table)找到所调用的内核函数入口地址。接着,就调用函数,等返回后,做一些系统检查,最后返回到进程(或到其他进程,如果这个进程时间用尽)。

二、准备工作

1.在VMware Workstation下安装Linux(Ubuntu)系统

我就是按这个安装的
https://blog.csdn.net/u014337397/article/details/80751753

2.Ubuntu下安装VMware Tools

推荐按这个安装
https://blog.csdn.net/Franticquanshi/article/details/81348796

3.下载Linux系统内核

下载网址 https://www.kernel.org/
点击下载按钮,接下来选择保存文件。
(好像用虚拟机里面的火绒浏览器下载速度会更快一点!反正慢慢等待吧。)
操作系统Linux:增加系统调用

三、系统调用的实现

1、获取root权限

单击鼠标右键,点击“打开终端”,输入sudo su,回车后,输入用户名的密码,按回车键即可。(注意:密码不会显示,并且整个过程必须在root权限下完成!!!)
操作系统Linux:增加系统调用

2、安装相关编译程序

依次输入
sudo apt-get install build-essential kernel-package libncurses5-dev
sudo apt-get install libncurses5-dev libssl-dev
sudo apt-get install build-essential openssl
sudo apt-get install zlibc minizip
sudo apt-get install libidn11-dev libidn11
sudo apt-get install bison flex

3、获取内核

将下载好的linux-5.1.tar.xz拖到桌面上
在终端输入sudo mv /home/hejiaxing/桌面/linux-5.1.tar.xz /usr/src/
(建议在文件属性里复制文件名和文件地址,以免出错,.tar.xz后有一个空格不要漏敲!)
操作系统Linux:增加系统调用

4、解压内核

在终端依次输入:
cd /usr/src
sudo tar -xvf /usr/src/linux-5.1.tar.xz

5、进入解压文件目录,安装vim编辑器

在终端依次输入:
cd /usr/src/linux-5.1/kernel
sudo apt-get install vim

6、编辑sys.c文件

(1)进入sys.c

在终端输入 vim sys.c

(2)在文件的末尾加入函数(这个函数自己写)

asmlinkage long sys_hejxtest(void){
printk(“Good evening!”);
return 1;
}
操作系统Linux:增加系统调用
vim快捷键: i进入编辑,esc退出编辑状态, G跳到末尾, gg进入开头, :wq保存退出,:q不保存退出)

7、syscalls.h中加入声明

(1)进入syscalls.h

在终端依次输入:
cd /usr/src/linux-5.1/arch/x86/include/asm/
vim syscalls.h

(2)添加声明

在文件最末尾添加
asmlinkage long sys_hejxtest(void);
操作系统Linux:增加系统调用

8、添加系统调用id

(1)进入syscalls._64.tbl

在终端依次输入:
cd /usr/src/linux-5.1/arch/x86/entry/syscalls
vim syscall_64.tbl

(2)编辑

在文件如图位置添加
335 64 hejxtest sys_hejxtest
(335是系统调用号,hejxtest函数名)
使用esc + :wq命令保存退出操作系统Linux:增加系统调用

9、配置内核

在终端依次输入:
cd /usr/src/linux-5.1
sudo make mrproper
sudo make clean
sudo make menuconfig

将General setup内的Local version修改成新的名称,比如我的hejxtest,保存后自动退出(保存依次点击Exit,出现ok点击即可)。
操作系统Linux:增加系统调用
操作系统Linux:增加系统调用
操作系统Linux:增加系统调用

10、编译内核

根据自己处理器的最大线程数目来编译。
输入 make -j4
(虚拟机中处理器的核总数为4个,耗时较长,我花了将近3个小时,耐心等待!)
操作系统Linux:增加系统调用

11、安装内核

在终端依次输入:
make modules_install
make install
成功后重启虚拟机。
操作系统Linux:增加系统调用

12、调用系统指令验证

在桌面打开终端,进入root权限。

(1)在终端输入 uname -r

查看使用的内核,结果显示使用的正是自己刚刚编译好的内核,表示Ubuntu系统的内核编译成功,并且内核成功更换为刚编译的内核。
操作系统Linux:增加系统调用

(2)输入指令 vim hejx.cpp

输入i编辑代码
#include
#include<linux/kernel.h>
#include<syscall.h>
#include<unistd.h>
using namespace std;
int main()
{
cout<<“System call sys_hejxtest has been used.”<<endl;
long int a=syscall(335);
cout<<"System call sys_xutest return : "<<a<<endl;
syscall(335);
return 0;
}
使用esc + :wq命令保存退出操作系统Linux:增加系统调用

(3)输入指令 g++ hejx.cpp

会在如下文件夹中生成hejx.cpp和a.out文件
操作系统Linux:增加系统调用

(4)输入指令 ./a.out

操作系统Linux:增加系统调用

(5)输入指令 dmesg

最后一行出输出"Good evening!",系统调用函数成功实现了。
操作系统Linux:增加系统调用
至此,系统调用完全实现了!!!

四、感想

第一次写博客,可能意思表达不太清楚,如果有错误的地方,欢迎大家指正!
能够完成这次任务,十分感谢学长@King_LJames的耐心指导,他也发表了一篇博客[https://blog.csdn.net/qq_41175905/article/details/80529245],对我启发很大。
这次在配置和编译内核时,容易出现缺少某个软件包的问题,按照错误里提示缺什么包就下载什么包,基本上就可以解决问题了。
在做这方面的题目时,应该多看看大牛的博客,耐心请教。再自己尝试去动手编译,这样才能培养自己的动手能力。