linux动态内核模块编程-3
将一组与模块相关的命令加载进内核
完成功能类似2,打印proc下的相关信息。但是不用重新编译内核,节省时间,更为灵活
内核模块介绍
模块是在内核空间运行的程序,实际上是一种目标文件,不能单独运行但其代码可在运行时链接到系统中作为内核的一部分运行或卸载。Linux内核模块是一个编译好的、具有特定格式的独立目标文件,用户可通过系统提供的一组与模块相关的命令将模块加载进内核,当内核模块被加载后,它有如下特点:
- 与内核一起运行在相同的内核态和内核地址空间;
- 运行时与内核具有同样的特权级;
- 可方便地访问内核中的各种数据结构。
此外,内核模块还可以很容易地被移出内核,当用户不再需要某模块功能时,可以将它从内核卸载以节省系统主存开销。
一个典型的内核模块应包含如下几个部分:
1)头文件声明。其中module.h和init.h是必不可少的。module.h包含加载模块时需要的函数和符号定义;init.h中包含模块初始化和清理函数的定义。如果在加载时允许用户传递参数,模块中还应包含moduleparam.h头文件。
2)模块许可声明。从内核2.4.10版本开始,模块必须通过MODULE_LICENSE宏声明此模块的许可证,否则在加载此模块时会显示“kernel tainted”(内核被污染)的警告信息。从linux/module.h文件中可看到,被内核接受的许可证有GPL、GPL v2、GPL and additionalrights、Dual BSD/GPL、Dual MPL/GPL、Dual MIT/GPL和Proprietary。
3)初始化和清理函数声明。内核模块必须调用宏module_init和module_exit去注册初始化和清理函数。初始化和清理函数必须在宏module_init和module_exit使用前定义,否则会出现编译错误。这两个函数配对使用,例如当初始化函数申请了一个资源,那么清理函数就应释放这个资源,使得模块不留下任何副作用。除了模块初始化函数和清理函数,还可以根据需要设计编写其它函数。
设计内核模块程序
注意增加了模块相关的库函数和函数声明,命名为 mymodules.c(与下面的Makefile对应)
#include<linux/module.h>
#include<linux/init.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include<linux/sched.h>
static int mymodule_init(void)//模块初始化
{
struct file *fp;
mm_segment_t fs;
loff_t pos;
int i,j,k,temp,flag;
char cpuinfo[600],cpuinfo_end[]={'f','l','a','g','s'};
char meminfo[200],meminfo_end[]={'B','u','f','f','e','r','s'};
char uptime[20];int runtime;
char version[150];
printk("system info print.(by system_call)\n");
/*cpuinfo*/
fp=filp_open("/proc/cpuinfo",O_RDONLY,0);
fs=get_fs();
set_fs(KERNEL_DS);
pos=0;
vfs_read(fp,cpuinfo,sizeof(cpuinfo),&pos);
for(i=0;i<5000;i++)
{
flag=1;
for(j=0;j<5;j++)
if(cpuinfo[i+j]!=cpuinfo_end[j])
{
flag=0;
break;
}
if(flag)
break;
}
cpuinfo[i]='\0';
printk("cpuinfo:\n%s\n\n",cpuinfo);
filp_close(fp,NULL);
set_fs(fs);
/*meminfo*/
fp=filp_open("/proc/meminfo",O_RDONLY,0);
fs=get_fs();
set_fs(KERNEL_DS);
pos=0;
vfs_read(fp,meminfo,sizeof(meminfo),&pos);
for(i=0;i<1500;i++)
{
flag=1;
for(j=0;j<7;j++)
if(meminfo[i+j]!=meminfo_end[j])
{
flag=0;
break;
}
if(flag)
break;
}
meminfo[i]='\0';
printk("meminfo:\n%s\n\n",meminfo);
filp_close(fp,NULL);
set_fs(fs);
/*uptime*/
fp=filp_open("/proc/uptime",O_RDONLY,0);
fs=get_fs();
set_fs(KERNEL_DS);
pos=0;
vfs_read(fp,uptime,sizeof(uptime),&pos);
for(i=0;i<20;i++)
{
if(uptime[i]=='.')
break;
}
uptime[i]='\0';
runtime=0;
for(j=0;j<i;j++)
{
temp=uptime[j]-'0';
for(k=0;k<i-j-1;k++)
temp*=10;
runtime+=temp;
}
printk("uptime:\nsystem has already started for %d minutes.\n\n",runtime/60);
filp_close(fp,NULL);
set_fs(fs);
/*version*/
fp=filp_open("/proc/version",O_RDONLY,0);
fs=get_fs();
set_fs(KERNEL_DS);
pos=0;
vfs_read(fp,version,sizeof(version),&pos);
version[132]='\0';
printk("version:\n%s\n",version);
filp_close(fp,NULL);
set_fs(fs);
printk("info printed over.\n");
return 0;
}
static void mymodule_exit(void)//模块清理函数
{
printk("module unloading.\n");
}
module_init(mymodule_init); //注册初始化函数
module_exit(mymodule_exit); //注册清理函数
MODULE_LICENSE("GPL"); //模块许可声明
Makefile
注意modules下以tab开头
ifneq ($(KERNELRELEASE),)
obj-m := mymodules.o#obj-m 指编译成外部模块
else
KERNELDIR := /lib/modules/$(shell uname -r)/build #定义一个变量,指向内核目录
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
安装模块
切换root用户,执行以下
make
insmod ./mymodules.ko
lsmod
可以看到模块已安装

查看结果
dmesg –c

完成后可删除模块
rmmod mymodules
linux动态内核模块编程-3的更多相关文章
- Linux内核模块编程——Hello World模块
Linux内核模块编程 编程环境 Ubuntu 16.04 LTS 什么是模块 内核模块的全称是动态可加载内核模块(Loadable Kernel Modul,KLM),可以动态载入内核,让它成为内核 ...
- linux内核模块编程实例
linux内核模块编程实例 学号:201400814125 班级:计科141 姓名:刘建伟 1.确定本机虚拟机中的Ubuntu下Linux的版本 通过使用命令uname -a/uname -r/una ...
- 《linux内核设计与分析》内核模块编程
内核模块编程 一.准备工作 虚拟机:VMware Workstation 12操作系统:ubuntu当前内核版本:linux-headers-4.4.0-22-generic 二.有关于内核模块的知识 ...
- linux实践——内核编程 基础模块
一.内核模块的概念 Linux模块(module)是一些可以作为独立程序来编译的函数和数据类型的集合.内核模块给我们带来的便利是模块本身并不被编译进内核文件,可在内核运行期间动态的安装或卸载.因为如果 ...
- Linux 动态库剖析
进程与 API 动态链接的共享库是 GNU/Linux® 的一个重要方面.该种库允许可执行文件在运行时动态访问外部函数,从而(通过在需要时才会引入函数的方式)减少它们对内存的总体占用.本文研究了创建和 ...
- 【linux草鞋应用编程系列】_4_ 应用程序多线程
一.应用程序多线程 当一个计算机上具有多个CPU核心的时候,每个CPU核心都可以执行代码,此时如果使用单线程,那么这个线程只能在一个 CPU上运行,那么其他的CPU核心就处于空闲状态,浪费了系 ...
- 《Linux/Unix系统编程手册》读书笔记3
<Linux/Unix系统编程手册>读书笔记 目录 第6章 这章讲进程.虚拟内存和环境变量等. 进程是一个可执行程序的实例.一个程序可以创建很多进程. 进程是由内核定义的抽象实体,内核为此 ...
- linux动态库编译和使用
linux动态库编译和使用详细剖析 引言 重点讲述linux上使用gcc编译动态库的一些操作.并且对其深入的案例分析.最后介绍一下动态库插件技术, 让代码向后兼容.关于linux上使用gcc基础编译, ...
- Linux下的编程实战【转】
一篇比较不错的文章, 降到了 makefile make , gcc编译器,GDB调试器, Linux文件系统,Linux文件API,.C语言库函数(C库函数的文件操作实际上是独立于具体的操作系统平台 ...
随机推荐
- php特级课---2、网站大数据如何存储
php特级课---2.网站大数据如何存储 一.总结 一句话总结: mysql主从,分库分表,mysql分区,mysql集群,Nosql 1.mysql主从服务器各自的功能是什么? 增删改,主服务器 查 ...
- MVC3 学习总结一(未发布)
MVC: Model,View,Control 设置View中的数据 1. 返回model,View中强类型化 Control: public ActionResult Browse(strin ...
- Python爬虫之利用BeautifulSoup爬取豆瓣小说(一)——设置代理IP
自己写了一个爬虫爬取豆瓣小说,后来为了应对请求不到数据,增加了请求的头部信息headers,为了应对豆瓣服务器的反爬虫机制:防止请求频率过快而造成“403 forbidden”,乃至封禁本机ip的情况 ...
- IIFE 立即执行的函数表达式
介绍IIFE IIFE的性能 使用IIFE的好处 IIFE最佳实践 jQuery优化 在Bootstrap源码(具体请看<Bootstrap源码解析>)和其他jQuery插件经常看到如下的 ...
- Hive mapreduce SQL实现原理——SQL最终分解为MR任务,而group by在MR里和单词统计MR没有区别了
转自:http://blog.csdn.net/sn_zzy/article/details/43446027 SQL转化为MapReduce的过程 了解了MapReduce实现SQL基本操作之后,我 ...
- Python - Package os
for (path,dirs,files) in os.walk(path): for filename in files: #do something here os. walk(top, topd ...
- Python3.6.0安装
1.安装 具体详情请参考下图: 双击安装包: 勾选“add python 3.6 to PATH”这样可以自动生成环境变量,选择“Customize installation”自定义安装. 2. ...
- url参数的编码解码Demo
为了保证在页面传递数据的安全性,我们通常会对Url传递的参数进行编码解码操作.我们写一个Demo剖析URL编码解码过程. 完整Demo下载地址 1. Url参数如何在服务端进行编码和解码. 1.1 U ...
- CodeForces - 156D:Clues(矩阵树定理&并查集)
题意:给定N点,M边,求添加最少的边使之变为连通图的方案数. 思路:注意题目给出的M边可能带环,即最后生成的不一定是一棵树.但是影响不大.根据矩阵树定理,我们知道生成树的数量=N^(N-2),即点数^ ...
- java-07接口与继承
1.动手实验:继承条件下的构造方法调用 代码: package demo; class Grandparent{ public Grandparent(){ System.out.println(&q ...