[保姆级教程] 如何在 Linux Kernel (V5.17.7) 中添加一个系统调用(System call)

在Linux5.17.7中添加系统调用指南,

        最近在学习 《linux Kernel Development》,本书用的linux kernel 是v2.6 版本的。看完”系统调用“一节后,想尝试添加一个系统调用,然后重编一个kernel。经过几个小时的尝试,实现了这个小功能,其中也遇到了不少坑,本文主要是记录分享下如何在Linux Kernel (V5.17.7) 中添加一个系统调用(System call)。

        编kernel之前需要注意:

  • 修改的kernel是目前最新的release 版本(V5.17.7), 书中v2.6版本的kernel太老了,gcc需要降到4.8版本,否则无法编过。 kernel 发布地址:https://www.kernel.org/
  • 需要选用大内存,多核的机器编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 $? 
sudo 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, xxx! Your system call is functional. Run the command dmesg in the terminal and find out!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值