内核的加载与装卸(C/C++版)
内核编译简介
Linux内核模块时一个编译好的,具有特定格式的独立目标文件,用户可通过系统提供的一组与模块相关的命令将内核模块加载进内核,内核模块加载后,它具有以下特点:
-
与内核一起运行在相同的内核态和内核地址
-
运行时具有与内核同样的特权级
-
可方便地访问内核中地各种数据结构。
C语言内核编译需要内核中预定的宏,即使用MODULE——LICENSE宏声明此模块的许可证和module_init和module_exit初始化和请理函数声明,以及头文件说明,这里采用<linux/init.h>和<linux/module.h>。
利用C语言编译程序
知道了内核的运行方式,我们可以利用C语言,编译一个内核程序(这里的程序为打印内核进程列表),然后通过加载进内核的方式实现对内核的编译加载。
引入C语言库
定义接受用户的参数(静态)
Static int num=-1
宏声明
Module_param(num,int,S_IRUGO)
其作用是用来传递参数。
定义结构体
使用内部含有指针来访问以链表形式储存的进程块
程序主体
使用for_each_process核定义宏来遍历进程,当遍历到最后指针指向NULL的时候跳出。
执行输出函数peintk();
C语言代码部分:
编写makefile文件
根据C语言文件,我们写出相应的makefile文件并执行make
makefile文件内容如下:
然后使用make命令编译.c文件
make
使用ls命令查看,应该是多出了一些文件(包括ko文件)。
安装ko文件
sudo insmod listprocess.ko
利用管道输出和cat查看输出的内容
为了查看我们的编译结果和内容,我们使用管道加cat输出的方式打印结果,然后用grep过滤。
cat /var/log/syslog |grep -a aei-pid
#/var/log/syslog目录是用来存储内核加载过程的日志的,我们可以通过它查看
#其中aei-pid是我在程序输出中标注的我的用户-pid,在程序设计中,可以改成自己的用户+pid
管道,cat,grep相关知识内容,可以查看Linux命令行学习的8,21章部分。
输出结果:
结果表明,编写的程序已经加载进了内核。
装卸ko文件
利用以下操作,我们可以很容易的装卸内核:
sudo insmod listprocess.ko