Linux内核添加系统调用和内核模块(完整步骤)【Ubuntu18.04+kernel4.14.238】

这是一个没有详解的完整步骤

一、系统调用

1

su

2

apt-get install vim

3

cd /usr/src/linux-4.14.238/kernel
vim sys.c

G进入末尾(下同),添加代码

asmlinkage long sys_helloworld(void){
        printk( "helloworld!");
        return 1;
}

asmlinkage long sys_test(int a,int b){
        /*if(a>b)
                return a;
        else
                return b;
        */
        int c=a+b;
        return c;
}

esc->:wq
保存退出(下同)

Linux内核添加系统调用和内核模块(完整步骤)【Ubuntu18.04+kernel4.14.238】_第1张图片

4

cd /usr/src/linux-4.14.238/arch/x86/include/asm/
vim syscalls.h

添加声明

asmlinkage long sys_helloworld(void);
asmlinkage long sys_test(int,int);

Linux内核添加系统调用和内核模块(完整步骤)【Ubuntu18.04+kernel4.14.238】_第2张图片

5

cd /usr/src/linux-4.14.238/arch/x86/entry/syscalls
vim syscall_64.tbl

添加系统调用号,注:64为兼容64位系统,32为兼容32位系统,common为都兼容,我在虚拟机创建的系统是64位,所以是syscall_64.tbl,系统调用号后面也是64,若是32位,则syscall_32.tbl和32?

333     64      helloworld              sys_helloworld
334     64      test                    sys_test

Linux内核添加系统调用和内核模块(完整步骤)【Ubuntu18.04+kernel4.14.238】_第3张图片

6
这一步比较关键,由于我的内核已经编译安装了(见上一篇文章),所以使用以下命令,时间比较久!

cd /usr/src/linxu-4.14.238
sudo make clean
sudo make oldconfig        #仍采用原内核配置文件
sudo make 
sudo make modules_install
sudo make install

反之正常就行,oldconfig换成menuconfig(或直接按照上篇文章来)

然后就是漫长的等待了。(可以试试sudo make -j4或-j2一类的)

7
测试一下吧(注意:一定要重启更新一下

vim test.c
#include 
#include 
#include 
#include 
int main(int argc,char **argv){
        //333,334就是我们刚才添加的系统调用的id
        long a=syscall(333);
        long c=syscall(334,111,999);
        printf("System call sys_helloworld return %ld \n",a);
        printf("System call test return %ld \n",c);
        return 0;
}
gcc -o hello hello.c
./hello

Linux内核添加系统调用和内核模块(完整步骤)【Ubuntu18.04+kernel4.14.238】_第4张图片
没毛病

二、内核模块

1
为了方便,随便创建个文件夹,进入

cd
mkdir mod
cd mod

2
创建test.c

vim test.c

这里我还没搞清楚带参数的模块如何设置,之后再研究研究,这里就先拿1-10求和测试一下吧。

#include
#include
#include

static int __init lkp_init(void)
{
        int sum=0;
        int i;
        for(i=1;i<=10;i++)
                sum+=i;
        printk("<1>Hello, World! from the kernel space...\n");
        printk("The sum of number(1-10) is : %d\n",sum);
        return 0;
}

static void __exit lkp_cleanup(void)
{
        printk("<1>Good Bye, World! leaving kernel space...\n");
}

module_init(lkp_init);  // 注册模块
module_exit(lkp_cleanup);       // 注销模块
MODULE_LICENSE("GPL");  //告诉内核该模块具有GNU公共许可证

3
编写Makefile文件(M大写),用于自动化编译

vim Makefile
# Makefile 4.0
obj-m := test.o
CONFIG_MODULE_SIG=n
CURRENT_PATH := $(shell pwd)
LINUX_KERNEL := $(shell uname -r)
LINUX_KERNEL_PATH := /usr/src/linux-$(LINUX_KERNEL)

all:
        make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
        make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean

4
直接make,这个很快。
Linux内核添加系统调用和内核模块(完整步骤)【Ubuntu18.04+kernel4.14.238】_第5张图片

ls检查一遍没毛病
在这里插入图片描述

5
插入模块

insmod test.ko

6
查看模块

lsmod | grep test

在这里插入图片描述
7
卸载模块

rmmod test.ko

8
查看一下刚刚输出的内容是否正确

dmesg > test.txt
vim test.txt

G进入末尾,看起来没问题
Linux内核添加系统调用和内核模块(完整步骤)【Ubuntu18.04+kernel4.14.238】_第6张图片

[ 1067.891416] test: loading out-of-tree module taints kernel.
[ 1067.891512] test: module verification failed: signature and/or required key missing - tainting kernel

关于这个,似乎是我还没有重新编译,查了些资料,暂时没搞明白也没解决,但不影响学习。

END

你可能感兴趣的:(How,to,Learn,Linux,Kernel,内核,linux,kernel,shell,ubuntu)