最近在学习 《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)的更多相关文章

  1. [Linux学习--用户管理]centos中添加一个新用户,并授权

    前言 有时候给root用户不太方便,新建一个用于并赋予权限这个做法相对好些 创建新用户 创建一个用户名为:cmj [root@localhost ~]# adduser cmj 为这个用户初始化密码, ...

  2. 保姆级教程——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版)的亲身经历,包括遇到的问题及解决办法,也有一些 ...

  3. 自建本地服务器,自建Web服务器——保姆级教程!

    搭建本地服务器,Web服务器--保姆级教程! 本文首发于https://blog.chens.life/How-to-build-your-own-server.html. 先上图!大致思路就是如此. ...

  4. RocketMQ保姆级教程

    大家好,我是三友~~ 上周花了一点时间从头到尾.从无到有地搭建了一套RocketMQ的环境,觉得还挺easy的,所以就写篇文章分享给大家. 整篇文章可以大致分为三个部分,第一部分属于一些核心概念和工作 ...

  5. Eclipse for C/C++ 开发环境部署保姆级教程

    Eclipse for C/C++ 开发环境部署保姆级教程 工欲善其事,必先利其器. 对开发人员来说,顺手的开发工具必定事半功倍.自学编程的小白不知道该选择那个开发工具,Eclipse作为一个功能强大 ...

  6. 强大博客搭建全过程(1)-hexo博客搭建保姆级教程

    1. 前言 本人本来使用国内的开源项目solo搭建了博客,但感觉1核CPU2G内存的服务器,还是稍微有点重,包括服务器内还搭建了数据库.如果自己开发然后搭建,耗费时间又比较多,于是乎开始寻找轻量型的博 ...

  7. 保姆级教程!手把手教你使用Longhorn管理云原生分布式SQL数据库!

    作者简介 Jimmy Guerrero,在开发者关系团队和开源社区拥有20多年的经验.他目前领导YugabyteDB的社区和市场团队. 本文来自Rancher Labs Longhorn是Kubern ...

  8. ElasticSearch入门篇(保姆级教程)

    本章将介绍:ElasticSearch的作用,搭建elasticsearch的环境(Windows/Linux),ElasticSearch集群的搭建,可视化客户端插件elasticsearch-he ...

  9. 保姆级教程!使用k3d实现K3s高可用!

    你是否曾经想尝试使用K3s的高可用模式?但是苦于没有3个"备用节点",或者没有设置相同数量的虚拟机所需的时间?那么k3d这个方案也许你十分需要噢! 如果你对k3d尚不了解,它的名字 ...

随机推荐

  1. 学习Cobbler(二)

    Server端: 第一步,启动Cobbler服务 第二步,进行Cobbler错误检查,执行cobbler check命令 第三步,进行配置同步,执行cobbler sync命令 第四步,复制相关启动文 ...

  2. JDBC和桥接模式

    本文参考 网上对于JDBC与桥接模式的理解各有不同,在这片文章里提出的是我个人对于二者的理解,本文参考的其它博文如下: https://blog.csdn.net/paincupid/article/ ...

  3. CSS学习(二):背景图片如何定位?

    我们都知道background-position属性用来指定背景图片应该出现的位置,可以使用关键字.绝对值和相对值进行指定.在CSS Sprites中,这个属性使用比较频繁,使用过程中,我常混淆,经常 ...

  4. 对Flex布局的总结与思考

    阅读本文之前最好对flex布局有基本了解,可以通过"参考资料"中列举的资源来学习. flex布局规范的设计目标 一维布局模型(one-dimensional layout mode ...

  5. ES6-11学习笔记--Iterator

    迭代器 Iterator 是一种接口机制,为各种不同的数据结构提供统一访问的机制 主要供for...of消费 一句话:不支持遍历的数据结构"可遍历"   具备Symbol.iter ...

  6. JavaScript 遍历对象、数组总结

    在日常工作过程中,我们对于javaScript遍历对象.数组的操作是十分的频繁的,今天抽空把经常用到的方法小结一下,方便今后参考使用!   javaScript遍历对象总结     1.使用Objec ...

  7. ES6(Promise)等一个函数执行完后再执行另一个函数

    function text1(){ return new Promise((resolve, reject) => { setTimeout(function () { resolve(cons ...

  8. 记一次dotnet拆分包,并希望得大佬指点

    记一次dotnet拆分包,并希望得大佬指点 之前做了一个用于excel导入导出的包, 定义了一些接口, 然后基于 NPOI EPPlus MiniExcel 做了三种实现 接口大概长下面这样(现在可以 ...

  9. python---用顺序表实现双端队列

    class Dqueue(object): """双端队列""" def __init__(self): self.__list = [] ...

  10. Spring Boot配置文件加载顺序

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.通过spring.config.location改变配置文件的位置 二.外部配置加载顺序 1.使用命令行参数指定加 ...