linux驱动开发教程 pdf linux驱动开发教程无法解压



文章插图
linux驱动开发教程 pdf linux驱动开发教程无法解压

文章插图

最近在搞一个linux的项目,其中主要是在编写一些应用模块,对内核及其驱动模块涉及很少,遇到了一些驱动模块的问题时,临时查了些资料,大致了解了一下驱动模块开发的基本步骤和常规步骤,并从网上也收集到了一些相关的资料,于是对其进行了一下简单的总结,记录于此,便于日后查阅,并与同道中人共享 。
什么是linux内核驱动模块
Linux内核的整体结构已经非常庞大,而其包含的组件也非常多 。我们怎样把需要的部分都包含在内核中呢?
一种方法是把所有需要的功能都编译到Linux内核 。这会导致两个问题,一是生成的内核会很大,二是如果我们要在现有的内核中新增或删除功能,将不得不重新编译内核 。
有没有一种机制使得编译出的内核本身并不需要包含所有功能,而在这些功能需要被使用的时候,其对应的代码被动态地加载到内核中呢?
答案是肯定的,Linux提供了这样的一种机制,这种机制被称为模块(Module) 。模块具有这样的特点:
模块本身不被编译入内核映像,这控制了内核的大小 。
模块一旦被加载,它就和内核中的其它部分完全一样 。
那么,问题来了 。如何编写内核驱动模块呢?别急,我们一步一步来介绍 。
【文章福利】小编自己整理了一些个人觉得比较好的linux内核学习书籍、视频资料共享在群文件里面,有需要的可以私信【内核】自行添加免费领取哦!!!(含视频教程、电子书、实战项目及代码)
一、先从一个最简单的例子入手
先来看一个最简单的内核模块“Hello World” 。
#include <linux/init.h>#include <linux/module.h>MODULE_LICENSE("Dual BSD/GPL");static int hello_init(void){printk(KERN_INFO " Hello World entern");return 0;}static void hello_exit(void){printk(KERN_INFO " Hello World exitn ");}module_init(hello_init);module_exit(hello_exit);MODULE_AUTHOR("Song Baohua");MODULE_DESCRIPTION("A simple Hello World Module");MODULE_ALIAS("a simplest module");这个最简单的内核模块只包含内核模块加载函数、卸载函数和对Dual BSD/GPL许可权限的声明以及一些描述信息 。编译它会产生hello.ko目标文件,通过“insmod ./hello.ko”命令可以加载它,通过“rmmod hello”命令可以卸载它,加载时输出“Hello World enter”,卸载时输出“Hello World exit” 。
内核模块中用于输出的函数是内核空间的printk()而非用户空间的printf(),printk()作为一种最基本的内核调试手段,其用法和printf()基本相似,但可定义输出级别 。
1、查看系统中已经加载的模块列表
在Linux中,使用lsmod命令可以获得系统中加载了的所有模块以及模块间的依赖关系,例如:
【linux驱动开发教程 pdf linux驱动开发教程无法解压】[email protected]:~$lsmodModuleSizeUsed byhello15680 ohci1394327160 ide_scsi167080 ide_cd393920 cdrom369601 ide_cdlsmod命令实际上读取并分析“/proc/modules”文件,与上述lsmod命令结果对应的“/proc/modules”文件如下:
[email protected]:~$ cat /proc/modules hello15680-Live0xc8859000ohci1394327160-Live0xc88c8000ieee1394944201ohci1394,Live0xc8840000ide_scsi167080-Live0xc883a000ide_cd393920-Live0xc882f000cdrom369601ide_cd,Live0xc8876000内核中已加载模块的信息也存在于/sys/module目录下,加载hello.ko后,内核中将包含/sys/module/hello目录,该目录下又包含一个refcnt文件和一个sections目录,在/sys/module/hello目录下运行tree –a得到如下目录树:
[email protected]:~$tree -a.|-- refcnt`-- sections|-- .bss|-- .data|-- .gnu.linkonce.this_module|-- .rodata|-- .rodata.str1.1|-- .strtab|-- .symtab|-- .text`-- __versions2、查看某个具体模块的详细信息
使用“modinfo <模块名>”命令可以获得模块的信息,包括模块作者、模块的说明、模块所支持的参数等 。
[email protected]:~$ modinfo hello.kofilename:hello.kolicense:Dual BSD/GPLauthor:Song Baohuadescription:A simple Hello World Modulealias:a simplest modulevermagic:2.6.15.5 686 gcc-3.2depends:二、模块程序的基本结构
一个Linux内核模块主要由如下几个部分组成:
模块加载函数(