[保姆级教程] 如何在 Linux Kernel (V5.17.7) 中添加一个系统调用(System call)
最近在学习 《linux Kernel Development》,本书用的linux kernel 是v2.6 版本的。看完”系统调用“一节后,想尝试添加一个系统调用,然后重编一个kernel。经过几个小时的尝试,实现了这个小功能,其中也遇到了不少坑,本文主要是记录分享下如何在Linux Kernel (V5.17.7) 中添加一个系统调用(System call)。
编kernel之前需要注意:
1、修改的kernel是目前最新的release 版本(V5.17.7), 书中v2.6版本的kernel太老了,gcc需要降到4.8版本,否则无法编过。 kernel 发布地址:https://www.kernel.org/
2、需要选用大内存,多核的机器编kernel,否则会出现各种异常问题,而且编kernel 很费时间。15GB内存的机器,编不过kernel。换用100GB内存的机器就好了
本文主要包含以下几点内容:
1、环境准备
2、修改kernel
3、rebuild kernel 以及安装kernel
4、测试结果
1、环境准备
我编kernel的机器是:Ubuntu 20.04.1 LTS,内存180GB, cores: 88
1.1 更新系统的源
sudo apt update && sudo apt upgrade -y
1.2 安装编译kernel 需要的依赖
sudo apt install build-essential libncurses-dev libssl-dev libelf-dev bison flex -y
我这里用的vim,没有的话也需要安装:
sudo apt install vim -y
1.3 清除已经安装的packages
sudo apt clean && sudo apt autoremove -y
1.4 下载kernel code
wget -P ~/ https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.17.7.tar.xz
tar -xvf ~/linux-5.17.7.tar.xz -C ~/
2、修改kernel
2.1 检查你自己当前系统的kernel 版本
uname -r
5.11.0-36-generic
重新安装kernel之后,这个版本号会被修改。
2.2 切换到工作目录中,然后创建自己的系统调用
cd ~/linux-5.17.7/
mkdir hello
2.3 创建自己的系统调用
vim hello/hello.c
添加代码。
#include <linux/kernel.h>
#include <linux/syscalls.h>
SYSCALL_DEFINE0(hello)
{
printk("hello_system_call.\n");
return 0;
}
2.4 为你的系统调用创建 Makefile
vim hello/Makefile
添加下面内容:
obj-y := hello.o
2.5 将你的系统调用添加到Kernel 的makefile中
vim Makefile
搜索 core-y, 完成如下添加:

2.6 将系统调用的相应函数原型添加到系统调用的头文件中
vim include/linux/syscalls.h
添加:
asmlinkage long sys_hello(void);

2.7 在system_table 中为你的系统调用开辟一个新的系统调用号。
vim arch/x86/entry/syscalls/syscall_64.tbl

3、编译kernel 并安装
前面的步骤都很简单,这一步可能会出现各种问题,而且很耗时。
3.1 创建你的.config
这里一路默认设置就好。
make menuconfig
3.2 查询你的机器logicl cores 有多少个
nproc
3.3 编译安装你的kernel
make -j32
echo $? // make 结束之后记得检查一下 状态
###if output is 0 then
sudo make modules_install -j32
echo $?
make install -j32
3.4 查看kernel 是否安装进去了
sudo update-grub
sudo reboot

4、测试结果
4.1 首先check 你的kernel 换好没
uname -r
4.2 编一个code 调用你的系统调用
由于系统调用不像普通函数那样,需要通过sys_call 以及系统调用号才能实现系统调用。创建一个test.c
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#define __NR_hello 451
long hello_syscall(void)
{
return syscall(__NR_hello);
}
int main(int argc, char *argv[])
{
long activity;
activity = hello_syscall();
if(activity < 0)
{
perror("Sorry, xxx. Your system call appears to have failed.");
}
else
{
printf("Congratulations, xxx! Your system call is functional. Run the command dmesg in the terminal and find out!\n");
}
return 0;
}
4.3 测试结果
gcc -o test test.c
./test
dmesg // 后面也能看到系统调用打印的信息
Congratulations, yaran! Your system call is functional. Run the command dmesg in the terminal and find out!
[保姆级教程] 如何在 Linux Kernel (V5.17.7) 中添加一个系统调用(System call)的更多相关文章
- [Linux学习--用户管理]centos中添加一个新用户,并授权
前言 有时候给root用户不太方便,新建一个用于并赋予权限这个做法相对好些 创建新用户 创建一个用户名为:cmj [root@localhost ~]# adduser cmj 为这个用户初始化密码, ...
- 保姆级教程——Ubuntu16.04 Server下深度学习环境搭建:安装CUDA8.0,cuDNN6.0,Bazel0.5.4,源码编译安装TensorFlow1.4.0(GPU版)
写在前面 本文叙述了在Ubuntu16.04 Server下安装CUDA8.0,cuDNN6.0以及源码编译安装TensorFlow1.4.0(GPU版)的亲身经历,包括遇到的问题及解决办法,也有一些 ...
- 自建本地服务器,自建Web服务器——保姆级教程!
搭建本地服务器,Web服务器--保姆级教程! 本文首发于https://blog.chens.life/How-to-build-your-own-server.html. 先上图!大致思路就是如此. ...
- RocketMQ保姆级教程
大家好,我是三友~~ 上周花了一点时间从头到尾.从无到有地搭建了一套RocketMQ的环境,觉得还挺easy的,所以就写篇文章分享给大家. 整篇文章可以大致分为三个部分,第一部分属于一些核心概念和工作 ...
- Eclipse for C/C++ 开发环境部署保姆级教程
Eclipse for C/C++ 开发环境部署保姆级教程 工欲善其事,必先利其器. 对开发人员来说,顺手的开发工具必定事半功倍.自学编程的小白不知道该选择那个开发工具,Eclipse作为一个功能强大 ...
- 强大博客搭建全过程(1)-hexo博客搭建保姆级教程
1. 前言 本人本来使用国内的开源项目solo搭建了博客,但感觉1核CPU2G内存的服务器,还是稍微有点重,包括服务器内还搭建了数据库.如果自己开发然后搭建,耗费时间又比较多,于是乎开始寻找轻量型的博 ...
- 保姆级教程!手把手教你使用Longhorn管理云原生分布式SQL数据库!
作者简介 Jimmy Guerrero,在开发者关系团队和开源社区拥有20多年的经验.他目前领导YugabyteDB的社区和市场团队. 本文来自Rancher Labs Longhorn是Kubern ...
- ElasticSearch入门篇(保姆级教程)
本章将介绍:ElasticSearch的作用,搭建elasticsearch的环境(Windows/Linux),ElasticSearch集群的搭建,可视化客户端插件elasticsearch-he ...
- 保姆级教程!使用k3d实现K3s高可用!
你是否曾经想尝试使用K3s的高可用模式?但是苦于没有3个"备用节点",或者没有设置相同数量的虚拟机所需的时间?那么k3d这个方案也许你十分需要噢! 如果你对k3d尚不了解,它的名字 ...
随机推荐
- 简易shell脚本启动jar包
可参考博客: Shell脚本中$0.$?.$!.$$.$*.$#.$@等的意义 https://blog.csdn.net/csgd2000/article/details/80396996 s ...
- jsp报错问题之“使用jstl的c标签choose报错Illegal text inside "c:choose" tag问题”
一.报错 [bessky_it][ERROR][2022-03-25 17:19:07] | PLATFORM | ):[c]鍜孾/com.bessky.pss.portal/purchase/sam ...
- c++中的左值和右值的理解
1.左值和右值的概念 C++中左值(lvalue)和右值(rvalue)是比较基础的概念,虽然平常几乎用不到,但C++11之后变得十分重要,它是理解 move/forward 等新语义的基础. 左值与 ...
- es6-Set与Map
se5中的set与map 在est5中开发者使用对象属性来模拟.set多用于检查键的存在,map多用于提取数据. { let set = Object.create(null) set.foo = t ...
- ES6-11学习笔记--代理Proxy
Proxy代理 常用拦截方法 ES5拦截: let obj = {} let newVal = '' Object.defineProperty(obj, 'name', { get() { cons ...
- ubantu系统之 Ubuntu14.04安装Samba实现文件共享
1 安装 sudo apt-get install samba 2 配置 打开Samba配置文件: vim /etc/samba/smb.conf 在其最后添加: ...
- 使用Nginx做反向代理的配置
安装Nginx服务之后 修改Nginx配置文件 如下server字段中主要是配置listen监听8080 端口,然后静态文件袋里到8001 后端端口代理到8000 server { listen 8 ...
- 猿人学python爬虫第一题
打开网站.F12,开启devtools.发现有段代码阻止了我们调试 好的.接下来有几种解决方法 1- 绕过阻止调试方法 方法1(推荐) 鼠标放在debugger该行,左边数字行号那一列.右键选择不在永 ...
- 在 Docker 上快速运行 Apache Airflow 2.2.4
Docker 安装 Apache Airflow 参考资料 Running Airflow in Docker 安装依赖 Docker Engine Docker Composite 快速运行 Apa ...
- C++STL 中的数值算法(iota、accumulate、adjacent_difference、inner_product、partial_sum)
以下算法均包含在头文件 numeric 中 ##1.iota 该函数可以把一个范围内的序列从给定的初始值开始累加 先看用法. 例: 假设我需要一个长度为10,从5开始递增的序列 vector<i ...