将一组与模块相关的命令加载进内核

完成功能类似2,打印proc下的相关信息。但是不用重新编译内核,节省时间,更为灵活

内核模块介绍

模块是在内核空间运行的程序,实际上是一种目标文件,不能单独运行但其代码可在运行时链接到系统中作为内核的一部分运行或卸载。Linux内核模块是一个编译好的、具有特定格式的独立目标文件,用户可通过系统提供的一组与模块相关的命令将模块加载进内核,当内核模块被加载后,它有如下特点:

  1. 与内核一起运行在相同的内核态和内核地址空间;
  2. 运行时与内核具有同样的特权级;
  3. 可方便地访问内核中的各种数据结构。

    此外,内核模块还可以很容易地被移出内核,当用户不再需要某模块功能时,可以将它从内核卸载以节省系统主存开销。

一个典型的内核模块应包含如下几个部分:

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的更多相关文章

  1. Linux内核模块编程——Hello World模块

    Linux内核模块编程 编程环境 Ubuntu 16.04 LTS 什么是模块 内核模块的全称是动态可加载内核模块(Loadable Kernel Modul,KLM),可以动态载入内核,让它成为内核 ...

  2. linux内核模块编程实例

    linux内核模块编程实例 学号:201400814125 班级:计科141 姓名:刘建伟 1.确定本机虚拟机中的Ubuntu下Linux的版本 通过使用命令uname -a/uname -r/una ...

  3. 《linux内核设计与分析》内核模块编程

    内核模块编程 一.准备工作 虚拟机:VMware Workstation 12操作系统:ubuntu当前内核版本:linux-headers-4.4.0-22-generic 二.有关于内核模块的知识 ...

  4. linux实践——内核编程 基础模块

    一.内核模块的概念 Linux模块(module)是一些可以作为独立程序来编译的函数和数据类型的集合.内核模块给我们带来的便利是模块本身并不被编译进内核文件,可在内核运行期间动态的安装或卸载.因为如果 ...

  5. Linux 动态库剖析

    进程与 API 动态链接的共享库是 GNU/Linux® 的一个重要方面.该种库允许可执行文件在运行时动态访问外部函数,从而(通过在需要时才会引入函数的方式)减少它们对内存的总体占用.本文研究了创建和 ...

  6. 【linux草鞋应用编程系列】_4_ 应用程序多线程

    一.应用程序多线程     当一个计算机上具有多个CPU核心的时候,每个CPU核心都可以执行代码,此时如果使用单线程,那么这个线程只能在一个 CPU上运行,那么其他的CPU核心就处于空闲状态,浪费了系 ...

  7. 《Linux/Unix系统编程手册》读书笔记3

    <Linux/Unix系统编程手册>读书笔记 目录 第6章 这章讲进程.虚拟内存和环境变量等. 进程是一个可执行程序的实例.一个程序可以创建很多进程. 进程是由内核定义的抽象实体,内核为此 ...

  8. linux动态库编译和使用

    linux动态库编译和使用详细剖析 引言 重点讲述linux上使用gcc编译动态库的一些操作.并且对其深入的案例分析.最后介绍一下动态库插件技术, 让代码向后兼容.关于linux上使用gcc基础编译, ...

  9. Linux下的编程实战【转】

    一篇比较不错的文章, 降到了 makefile make , gcc编译器,GDB调试器, Linux文件系统,Linux文件API,.C语言库函数(C库函数的文件操作实际上是独立于具体的操作系统平台 ...

随机推荐

  1. 经典分水岭算法的 C++ 实现

    这个程序是研一下学期的计算机视觉课程大作业,完成于 2013/06/16,是对 Soille 和 Vincent(1991)提出的模拟浸没的分水岭算法的实现,详见下面的报告. 源码托管在 Github ...

  2. poj2942 点-双联通+二分图染色

    题意:有一群骑士要坐在一个圆形的桌子上,他们之间有些人相互讨厌,所以不能挨着,要求算出一次也不能坐在桌子上的人,每次会议桌子必须奇数个人,一个人不能开会 题解:可以先建一个补图,要满足题目条件我们只要 ...

  3. Jenkins自动化部署及代码检查配置应用

    首先jenkins是基于java开发的一种持续集成工具,它的存在和实际应用使得我们在开发过程中节省了很多宝贵时间,既然基于java,所以java环境是必须的. 其次Tomcat是针对Java的一个开源 ...

  4. 奔跑吧,OpenStack现场分享:超融合架构如何抹平物理硬件差异?

    转自:https://www.ustack.com/blog/moping/ “通过引入OpenStack这一中间层,实现了云平台统一的管理调度支配向上交付,解决了业务的灵活性问题.但是在抹平下层物理 ...

  5. (转) Android Service完全解析,关于服务你所需知道的一切(上)

    相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的Android程序员如果连Service都没听说过的话,那确实也太逊了.Service作为Android四大组件之一,在每一个应用程序 ...

  6. Django 基础 web框架本质

    Web框架本质 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端. 这样我们就可以自己实现Web框架了. import socket sk ...

  7. 28 python 并发编程之多进程

    一 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程.P ...

  8. Shell编程-运算符

    1.declare命令 declare声明变量类型:declare [+/-][选项] 变量名 -:给变量设定类型属性 +:取消变量的类型属性 -a:将变量声明为数组型 -i:整数型 -x:环境变量 ...

  9. spring MVC HandlerInterceptorAdapter

    SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...

  10. 解决Opencv高低版本不兼容问题

    目前OpenCV版本已更新到2.4...由此出现了一系列问题,解决如下: 1.cxcore.h等头文件找不到: 法一.将opencv1.0中的各种.h或者.lib文件拷到opencv2.3.1对应in ...