Linux驱动是驻留在内核空间的一个个模块,所以要学习内核驱动,必须对内核模块的编译与程序的框架有所了解。
以前在看内核模块编译方法的时候,曾经看到许多方法,但是基本来说可以分了两种,一是编写Makefile文件,另外是直接在gcc编译命令中加入__KERNEL__和__MODULE__宏来编译。但是使用命令来编译的时候一般都会出现很多错误,,,
这经常让人摸不着头脑,因为使用命令来编译是针对2.4内核的,而使用Makefile文件的方法一般是对于2.6内核的。
由于Linux内核从2.4到2.6改变了很多,而由固定内核版本编译的模块只能在该版本的内核中使用,并且两个版本的内核模块编译方法不一样,而网上有些文章没有说明是在哪个内核下面的模块,然后如果我们不用对应的内核版本的话就会出现很多莫名其妙的错误,,,
好,现在我们要说的是Linux2.6内核的模块~~~
内核模块可以直接编译链接到内核里面,也可以编译成独立的模块手机加载到内核空间里面,
对于集成系统的一般采用前者,在内核源码中添加相应的源码与Makefile,
但是对于我们这些大多数只是学习一下的人,一般都采用后者,编译好*.ko文件之后,使用insmod,rmmod来加载和卸载模块~
编译所需要的条件是必须安装编译工具链,就是gcc等工具,呵呵,这个要看你需要编译什么平台下面的,如果目标是PC机下面的内核,就是gcc,如果是嵌入式的内核则需要安装嵌入式的编译工具链比如:arm-eabi-gcc。
还需要的是需要有目标内核版本的源码,也就是使用2.6.x内核版本的源码编译的模块,有可能只能在2.6.x的内核中加载,,,
因为我曾经用2.6.36编译了一个模块,结果不能加载到2.6.32的内核上面。。。
我使用Ubuntu10.04在我的系统里面的源码位置在/lib/modules/2.6.32-21-generic/build里面。
有了这两个就可以编译内核模块了~~~
请看下面的源代码scull.c:
在编写内核模块源码的时候必须包含的头文件:
#include <linux/init.h>
#include <linux/module.h>
而许可证,可以用下面的宏来定义,具体的含义可以看一下module.h文件
MODULE_LICENSE("Dual BSD/GPL");
定义模块加载到内核空间的时候执行的函数,scull_init,一般在这里做初始化的数据处理
module_init(scull_init);
定义卸载模块的时候,调用的函数,,scull_exit,一般在这里释放模块在运行的时候所占用的资源
module_exit(scull_exit);
Makefile文件:
obj-m:= scull.o
这个表示需要编译的模块
PWD:= $(shell pwd)
当前源码的位置
KERN_DIR = /lib/modules/$(shell uname -r)/build
得到内核源码的位置,因为编译内核模块需要包含内核源码里面最顶层的Makefile文件,得到里面的一些设置与定义才能正确编译
$(MAKE) -C $(KERN_DIR) M=$(PWD) modules
-C 表示进入到内核源码目录里面去,
M=$(PWD) 表示需要编译的子目录
在源码目录运行:make
然后可以得到内核模块文件:scull.ko
sudo insmod scull.ko
把模块加载到内核
sudo rmmod scull
把模块从内核空间中卸载
dmesg | tail
查看dmesg最后几行,可以看到内核模块printk的输出
cat /proc/modules | grep scull
或是lsmod
可以查看模块是否已经加载到内核之中了。
分享到:
相关推荐
首先,Linux 2.6内核模块最直观的变化是文件扩展名由".o"更改为".ko",表示kernel object,表明模块是内核的目标文件,而非普通的中间编译文件。在编译过程中,会产生一个obj.mod.c文件,其中包含了当前系统的配置...
综上所述,Linux内核代码学习是一项深入且富有挑战性的任务,它涵盖了操作系统最核心的部分。通过理论学习与实践操作,我们可以更有效地驾驭这个强大的开源平台,进一步提升技术能力。对于压缩包中的"linux011内核...
这篇开放文档旨在为学习和研究Linux内核以及在ARM平台上进行开发的人们提供宝贵的资料。 首先,我们要理解Linux内核的基本概念。Linux内核是开源的,由全球开发者共同维护和改进。它包含了许多关键组件,如内存管理...
一个典型的“Hello World”级别的内核模块示例涉及编写一个最简单的内核模块,它在加载时通过模块的初始化函数打印一条消息,并在卸载时再次打印一条消息。这个过程演示了模块的加载和卸载,是学习内核模块编程的...
标题中的"内核模块-3160104875-杨樾人21"指的是一个关于操作系统内核模块开发的实验项目,由学生杨樾人完成,学号为3160104875。描述中提到了实验基于"Operating System Concepts"教材的第四章和第六章,这通常涉及...
### Linux内核模块编译方法 #### 概述 在Linux操作系统中,内核作为操作系统的核心部分,负责管理和调度硬件资源、提供系统调用接口等关键功能。为了满足不同的应用场景需求,用户通常需要对内核进行扩展或定制,...
- **最简单的内核模块**:一个基本的内核模块,用于展示如何编写和加载一个简单的模块。 - **代码示例**: ```c #include <linux/module.h> #include <linux/kernel.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR...
通过对`hello.c`示例的学习,读者可以了解到一个简单的内核模块是如何被创建、编译并加载的。此外,还深入探讨了如何使用`printk`进行信息打印以及设备驱动的基本原理。这些内容对于初学者来说是非常宝贵的入门资料...
- **简单的内核模块**:给出一个简单的内核模块示例,帮助理解模块的基本结构和工作流程。 - **PRINTK**:解释如何在内核模块中使用 printk 函数打印调试信息。 - **MODULE_PARAM 和 MODULE_PARAM_ARRAY**:介绍如何...
- **实践操作**:通过编写简单的内核模块、分析内核源代码等方式加深理解。 #### 五、Linux内核对于不同人群的意义 - **对于Linux内核爱好者**:深入学习Linux内核可以提升技术水平,有助于在开源社区中贡献自己的...
对于学习和理解如何编写和使用Linux内核模块的初学者来说,这个例子提供了宝贵的实践机会。 总的来说,Linux内核模块是Linux系统灵活性和可扩展性的体现,通过这个例子,开发者可以深入理解内核与用户空间的交互...
- **从Hello World谈起**:从最简单的“Hello World”程序出发,可以更好地理解内核启动的基本概念。在内核启动的过程中,“Hello World”可以类比为第一个被加载和执行的程序,它标志着内核初始化的完成。这个过程...
2.1. Hello, World (part 1): 最简单的内核模块 2.2. 编译内核模块 2.3. Hello World (part 2) 2.4. Hello World (part 3): 关于 __init and __exit宏 2.5. Hello World (part 4): 内核模块证书和内核模块文档说明 ...
通过对本书的学习,读者可以深入了解Linux内核的工作原理,掌握模块编程的技术细节,从而能够在实际项目中灵活应用和创新。 此外,作者提倡广泛传播本书,无论是个人还是商业用途,只要保留版权通知并遵守Open ...
- **官方文档**:Linux内核官方文档是最权威的学习资源之一,涵盖了从基础知识到高级话题的全面内容。 - **开源项目**:参与开源项目不仅可以提高自己的技术水平,还能帮助解决实际问题,积累宝贵的实践经验。 - **...