linux 第一个内核模块Hello World

 

内核模块是Linux内核向外部提供的一个插口,其全称为动态可加载内核模块(Loadable Kernel ModuleLKM),我们简称为模块Linux内核之所以提供模块机制,是因为它本身是一个单内核(monolithic kernel)。单内核的最大优点是效率高,因为所有的内容都集成在一起,但其缺点是可扩展性和可维护性相对较差,模块机制就是为了弥补这一缺陷。

一、 什么是模块

模块是具有独立功能的程序,它可以被单独编译,但不能独立运行。它在运行时被链接到内核作为内核的一部分在内核空间运行,这与运行在用户空间的进程是不同的。模块通常由一组函数和数据结构组成,用来实现一种文件系统、一个驱动程序或其他内核上层的功能。

 

应用程序与内核模块的比较
为了加深对内核模块的了解,表一给出应用程序与内核模块程序的比较。
表一 应用程序与内核模块程序的比较

 C语言应用程序内核模块程序
使用函数Libc库内核函数
运行空间用户空间内核空间
运行权限普通用户超级用户
入口函数main()module_init()
出口函数exit()module_exit()
编译Gcc –cMakefile
连接Gccinsmod
运行直接运行insmod
调试Gdbkdbug, kdb,kgdb等

从表一我们可以看出,内核模块程序不能调用libc库中的函数,它运行在内核空间,且只有超级用户可以对其运行。另外,模块程序必须通过module_init()和module-exit()函数来告诉内核“我来了”和“我走了”。

二、 编写一个简单的模块

模块和内核都在内核空间运行,模块编程在一定意义上说就是内核编程。因为内核版本的每次变化,其中的某些函数名也会相应地发生变化,因此模块编程与内核版本密切相关。以下例子针对Ubuntu 9.10  内核2.6.31-14-generic

 

1.程序举例

 


  1. #include<linux/module.h> #include<linux/kernel.h> #include<linux/init.h> MODULE_LICENSE("GPL"); static int __init lkp_init(void) { printk(KERN_ALERT "Hello World!/n"); return 0; } static void __exit lkp_cleanup(void) { printk(KERN_ALERT "Bye World!/n"); } module_init(lkp_init); module_exit(lkp_cleanup); MODULE_AUTHOR("heyutao"); MODULE_DESCRIPTION("hello");  
 

 


说明

所有模块都要使用头文件module.h,此文件必须包含进来。
头文件kernel.h包含了常用的内核函数。
头文件init.h包含了宏_init和_exit,它们允许释放内核占用的内存。
lkp_init是模块的初始化函数,它必需包含诸如要编译的代码、初始化数据结构等内容。
使用了printk()函数,该函数是由内核定义的,功能与C库中的printf()类似,它把要打印的信息输出到终端或系统日志。
lkp_cleanup是模块的退出和清理函数。此处可以做所有终止该驱动程序时相关的清理工作。
module_init()和cleanup_exit()是模块编程中最基本也是必须的两个函数。
module_init()是驱动程序初始化的入口点。而cleanup_exit()注销由模块提供的所有功能。

2  编写Makefile 文件,与hello.c 放在同一个目录里

 

  1. obj-m := hello.o  
  2. KERNELBUILD :=/lib/modules/$(shell uname -r)/build  
  3. default:  
  4.     make -C $(KERNELBUILD) M=$(shell pwd) modules  
  5. clean:  
  6.     rm -rf *.o *.ko *.mod.c .*.cmd *.markers *.order *.symvers .tmp_versions  
 

 

(注意makefile里面要求的tab)

KERNELBUILD :=/lib/modules/$(shell uname -r)/build是编译内核模块需要的Makefile的路径,Ubuntu下是

/lib/modules/2.6.31-14-generic/build

make -C $(KERNELBUILD) M=$(shell pwd) modules 编译内核模块。-C 将工作目录转到KERNELBUILD,调用该目录下的Makefile,并向这个Makefile传递参数M的值是$(shell pwd) modules。

3. 编译模块

#sudo make    (调用第一个命令default)

这时,在hello.c 所在文件夹就会有 hello.ko ,这个就是我们需要的内核模块啦

#sudo make clean

清理编译垃圾,hello.ko 也会清理掉。

4. 插入模块,让其工作。注意必须是root权限

#sudo insmod ./hello.ko
我们用dmesg 就可以看到 产生的内核信息啦,Hello world!

如果没有输出"hello from hello world",因为如果你在字符终端而不是终端模拟器下运行的话,就会输出,因为在终端模拟器下时会把内核消息输出到日志文件/var/log/kern.log中。


#sudo rmmod ./hello
再用dmesg 可以看到 Bye world!

modutils是管理内核模块的一个软件包。可以在任何获得内核源代码的地方获取Modutils(modutils-x.y.z.tar.gz)源代码,然后选择最高级别的patch.x.y.z等于或小于当前的内核版本,安装后在/sbin目录下就会有insomod、rmmod、ksyms、lsmod、modprobe等实用程序。当然,通常我们在加载Linux内核时,modutils已经被载入。
1.Insmod命令
调用insmod程序把需要插入的模块以目标代码的形式插入到内核中。在插入的时候,insmod自动调用init_module()函数运行。注意,只有超级用户才能使用这个命令,其命令格式为:
# insmod  [path] modulename.ko
2. rmmod命令
调用rmmod程序将已经插入内核的模块从内核中移出,rmmod会自动运行cleanup_module()函数,其命令格式为:
#rmmod  [path] modulename.ko
3.lsmod命令
调用lsmod程序将显示当前系统中正在使用的模块信息。实际上这个程序的功能就是读取/proc文件系统中的文件/proc/modules中的信息,其命令格式为:
#lsmod
4.ksyms命令

ksyms这个程序用来显示内核符号和模块符号表的信息。与lsmod相似,它的功能是读取/proc文件系统中的另一个文件/proc/kallsyms。

这就是在2.6.xx下一个最简单的模块编写过程。

 

转载于:https://www.cnblogs.com/int32bit/archive/2011/06/12/3187798.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/362164.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JS复习笔记】00 序

作为一个前端苦手&#xff0c;说是复习&#xff0c;你就当我是重学好了。 好吧&#xff0c;我当然不可能抱着一个砖头去复习&#xff0c;所以捡了本薄的来读——《JavaScript语言精粹》。 当初带我的人说这本书挺好&#xff0c;就看这本书好了。我觉得他说的挺对。我喜欢这么…

Generator执行步骤浅析

在Generator函数出现之前JS的函数只能返回一个值&#xff0c;返回的方式就是return&#xff0c;但是Generator函数可以返回多个值&#xff0c;返回的方式是yield。并且Generator赋予了外部动态影响函数内部的执行顺序的能力。 基础语法 function* f () {const a yield 1cons…

使用 jQuery.Pin 垂直滚动时固定导航

ZKEACMS的导航默认是不能固定的&#xff0c;随着页面的滚动而滚动&#xff0c;为了有更好的用户体验&#xff0c;当页面往下滚动时&#xff0c;可以将导航固定在顶端&#xff0c;这样方便用户点击。 jQuery Pin 借助jQuery的一个插件 jQuery.Pin&#xff0c;这个插件可在用来…

MDK升级后的头文件冲突

////TITLE:// MDK升级后的头文件冲突//AUTHOR:// norains//DATE:// Friday 17-June-2011//Environment:// Keil MDK 4.2// .NET Micro Framework Porting 4.1// 因为在移植的时候&#xff0c;发现了不少MDK编译的一些问题&#xff0c;于是便想升级到最新版本&a…

阻止默认事件

在JS中经常需要阻止元素的默认事件。而阻止默认事件的方法都是使用事件对象的preventDefault()方法或者在函数中return false。在最近一次开发中使用preventDefault()方法的时候遇到一个问题&#xff0c;现在才想/猜明白原因&#xff0c;场景是这样的&#xff1a; <a href&…

MySQL之SQL优化详解(三)

目录 MySQL 之SQL优化详解&#xff08;三&#xff09; 1. 索引优化2. 剖析报告:Show ProfileMySQL 之SQL优化详解&#xff08;三&#xff09; 1. 索引优化 一旦建立索引&#xff0c;select 查询语句的where条件要尽量符合最佳左前缀的原则&#xff0c;如若能做到全值匹配最好。…

行内格式化

相对于熟知的块级格式化上下文&#xff0c;行内格式化上下文更加的复杂难明。行内元素不像块级元素那样直来直去&#xff0c;一个块级元素占据一行&#xff0c;其他块级元素在垂直方向依次向下排列即可。行内元素不同&#xff0c;多个行内元素可以在一行显示&#xff0c;那么&a…

[转载]struts+hibernate遇到的错误总结

原文地址&#xff1a;strutshibernate遇到的错误总结作者&#xff1a;畫上句號经过对strutshibernate几天的学习&#xff0c;大体上还算比较的了解机制&#xff0c;以前学习的时候都是 单个框架训练&#xff0c;没有结合2个框架做&#xff0c;所以今天就找了个网上发布租房信息…

JPA休眠替代方案。 如果JPA或Hibernate对于我的项目而言不够好,该怎么办?

你好&#xff01;你好吗&#xff1f; 今天&#xff0c;我们将讨论不建议使用JPA / Hibernate的情况。 在JPA领域之外&#xff0c;我们还有哪些选择&#xff1f; 我们将谈论的是&#xff1a; JPA /休眠问题 解决一些JPA /休眠问题的方法 选择此处描述的框架的标准 Spring J…

一个Web前端自学者的自述

想来想去还是写下这篇文章&#xff0c;先说明&#xff0c;我精通JAVA编程语言和web前端常见的技术&#xff0c;个人是做JAVA的多&#xff0c;但是更加喜欢前端。因为我从高一开始接触JAVA&#xff0c;家父是黑马的JAVA讲师&#xff0c;自己对编程很热爱&#xff0c;在大学的时候…

css实现web前端最美的loading加载动画!

这些好看的loading效果&#xff0c;你还只会用第三方库吗&#xff1f;CSS3教你实现 ​前言 loading效果在实际开发中是很常见的&#xff0c;尤其是在Ajax请求的时候&#xff0c;可以给用户一个很好的交互体验。 今天这篇文章我们一起来看看如何通过CSS3实现各种不同的loadin…

如何使用Hibernate从Play生成DDL脚本! 框架项目

好的&#xff0c;因此您一直在使用hibernate属性名称“ hibernate.hbm2ddl.auto ” value “ 更新 ”来不断更新数据库架构&#xff0c; 但是现在您需要一个完整的DDL脚本吗&#xff1f; 从您的Global Class onStart中使用此方法来导出DDL脚本。 只需为其提供实体的包名称&…

C# 设计模式,工厂方法

C#工厂方法 1 using System;2 using System.Collections.Generic;3 using System.Linq;4 using System.Text;5 using System.Threading.Tasks;6 7 namespace 工厂方法 {8 class Program {9 static void Main(string[] args) { 10 IFacotry i new Fact…

css3帮你轻松实现圆角效果,不一样的前端页面。

在Web前端页面实现圆角效果&#xff0c;CSS3帮你轻松实现&#xff0c;一个人人皆知的属性 圆角边框的绘制是Web页面和Web应用程序中经常用来美化页面效果的手法之一。今天&#xff0c;小编为大家介绍CSS3提供的可以将矩形变为圆角矩形的一个属性 技术等级&#xff1a;中级 | 适…

使用Vysper,TomEE和PrimeFaces将XMPP服务器嵌入JSF Web应用程序内部

我有一个需要在完成某些工作时通知用户的应用程序。 它使用JSF和Primefaces&#xff0c;因此可以使用大气 &#xff08;也称为Push&#xff09;来实现这种通知。 但是另一个有趣的方法是使用嵌入在Java Web应用程序中的XMPP服务器。 好的&#xff0c;好的&#xff0c;您不必嵌…

appium和selenium不同与相同之处

原文来自&#xff1a; https://www.cnblogs.com/zhengshuheng/p/6370398.html selenium是web端的自动化&#xff0c;appium是app端的自动化&#xff0c;它继承了webdriver(也就是selenium 2) 转载于:https://www.cnblogs.com/lv-lxz/p/11118862.html

使用 Visual Studio 编译 wget 为库文件

添加代码与预编译指令与上一篇使用 Visual Studio 编译 wget 为可执行文件一致&#xff0c;区别在于这回建的是静态库工程&#xff08;编译为动态库过程类似:)&#xff09; 从wget的main函数开始读下来&#xff0c;发现问题不少&#xff0c;程序可能基于效率或者编码方便的因素…

webpack中实现按需加载

当页面中一个文件过大并且还不一定用到的时候&#xff0c;我们希望在使用到的时候才开始加载这个文件俗称按需加载。这样可以减少页面的响应时间&#xff0c;提高访问速度。 使用webpack打包的出来的文件要实现以上的要求有两种方式&#xff0c;一个是webpack特有的require.en…

【总结】计算机网络常见问题

1、TCP/IP协议与OSI协议 相互通信的两个计算机系统必须高度协调工作才行&#xff0c;而这种“协调”是相当复杂的。 “分层”可将庞大而复杂的问题&#xff0c;转化为若干较小的局部问题&#xff0c;而这些较小的局部问题就比较易于研究和处理。 计算机网络采用了分层的体系结构…

webpack3的CommonsChunkPlugin插件详解

webpack打出来的包在不做处理的情况下是非常大的&#xff0c;所有依赖都被塞进一个文件中&#xff0c;文件中有业务代码&#xff0c;有业务代码依赖的第三方库代码&#xff0c;还有webpack生成的运行时代码等。这样的一个文件不方便静态资源缓存&#xff0c;并且初始化页面的时…