Linux内核开发之将驱动程序添加到内核
驱动程序添加到内核
一.概述:
在Linux内核中增加程序需要完成以下三项工作:
1.将编写的源代码复制到Linux内核源代码的相应目录
2.在目录的Kconfig文件中增加新源代码对应项目的编译配置选项
3.在目录的Makefile文件中增加对新源代码的编译条目
二.实例
1.先把驱动代码usbtmc(文件夹)赋值到/usr/src/linux-headers-2.6.32-31-generic/drivers/char下
首先你要清楚你的模块应在内核源代码树中处于何处。
1>设备驱动程序存放在内核源码树根目录drivers/的子目录下,在其内部,设备驱动文件进一步按照类别,类型等有序地组织起来。
a.字符设备存在于drivers/char/目录下
b.块设备存放在drivers/block/目录下
c.USB设备则存放在drivers/usb/目录下。
注意:
(1)此处的文件组织规则并非绝对不变,例如:USB设备也属于字符设备,也可以存放在drivers/usb/目录下。
(2)例如我们把驱动程序usbtmc存放在drivers/char/目录下,那么你要注意,在该目录下同时会存在大量的C源代码文件和许多其他目录。所有对于仅仅只有一两个源文件的设备驱动程序,可以直接存放在该目录下,但如果驱动程序包含许多源文件和其他辅助文件,那么可以创建一个新子目录。
此处,我们是把usbtmc目录放在了drivers/char目录下面
2.修改char目录下的Kconfig和Makefile
(1)修改Kconfig
sudogedit Kconfig
添加下面一句后
source"drivers/char/usbtmc/Kconfig"
它表示将usbtmc目录下的Kconfig挂载到char目录下的Kconfig里面(为了使本层的Kconfig文件能起作用,我们需要修改父目录的Kconfig文件,加入source语句)
1>对驱动程序而言,Kconfig通常和源代码处于同一目录。
2>如果你建立了一个新字目录,而且也希望Kconfig文件存在于该目录中的话,那么就必须在一个已存在的Kconfig文件中将它引入,需要用上面的
语句将其挂接在drivers/char目录中的Kconfig中。
(2)修改Makefile
添加一句话:
obj-$(CONFIG_USBTMC)+=usbtmc/
这行编译指令告诉模块构建系统在编译模块时需要进入usbtmc/子目录中。此时的驱动程序的编译取决于一个特殊配置CONFIG_USBTMC配置选项。
3.现在在我们自己些驱动程序文件夹中添加Kconfig和Makefile
(1)修改Kconfig
新建一个Kconfig添加下面的话
menu "USBTMC"
comment"USBTMC Driver"
config USBTMC
tristate "USBTMC"
defaultn
help
Ifyou say Y here,support for the usbtmc with computer interface will becompiled into he kernel and accessible via device node. You can also say M here and the driver will be built as a module named usbtmc.ko.
Ifunsure,say N.
endmenu
endmenu
正确配置好后,我们在源码下执行sudomake menuconfig后,在出现的LinuxKernel Configuration图形界面中选择DeviceDrivers下的characterdevcie中,将会看到新加的USBTCM菜单,
(2)修改Makefile
新建一个Makefile,添加下面的话
obj-$(CONFIG_USBTMC)+=usbtmc.o
此时,构建系统运行就将会进入usbtmc/目录下,并且将usbtmc.c编译为usbtmc.ko模块
注:
如果驱动程序源文件可能不只有一个,可以把Makefile做如下修改:
obj-$(CONFIG_USBTMC)+=usbtmc.o
usbtmc-objs:=usbtmc-main.o usbtmc-usb1.o
此时,usbtmc-main.c和usbtmc-usb1.c就一起被编译和连接到了usbtmc.ko某块中。
4.现在已经Ok了,现在我们可以进入linux内核目录下通过menuconfig可以找到我们的USBTMC选项(在Device_Drivers下的characterdevices里可以找到USBTMC)对其进行选定。然后退出,编译内核,就搞定了。
5.删除:
删除也很简单,首先在drivers/char目录下删掉自己的驱动文件夹。其次再删除Makefile和Kconfig之前添加的东西,就搞定了
三.详解:
Makefile,Kconfig和配置工具组成了Linux2.6内核的配置系统。
其中Makefile定义了Linux内核的编译规则,它是大型项目开发的产物。Linux环境下的大型项目开发中,系统被分为很多模块,而这些模块一般会经历几次修改,而在修改后的编译过程中,由于某些文件中存在依赖关系,人工编译效率低(有些文件不需要重新编译)且易出错,Makefile文件便应运而生。Makefile文件定义了模块间的依赖关系,指定文件的编译顺序,以及编译所使用的命令。它和make命令使得项目的源程序文件可以自动编译,提高了软件开发效率。到此,再谈一下make,它是用来维护程序模块关系和生成可执行程序的工具,它可以根据程序模块的修改情况重新编译链接生成中间代码或最终的可执行程序,省去那些重复的不必要的编译工作,提高编译效率。
Kconfig给用户提供配置选择的功能。通常配置内核会有四种方法,makeconfig(字符界面配置),makemenuconfig(菜单界面配置),makexconfig(依赖QT),makegconfig(依赖GTK+)。makeconfig比较适合专业人员,像初学者比较适合makemenuconfig,让我们重点关注一下它。当我们运行makemenuconfig时,配置工具会首先分析与体系结构相对应的/arch/xxx/Kconfig文件(xxx为传入的arch参数),它里面包含了除一些与体系结构相关的配置项和配置菜单外,还通过source语句引入了一系列Kconfig,配置工具依据这些Kconfig包含的菜单和项目就可以描绘出一个分层结构。
例如当我们运行makezImagine、makebzImagine等生成映像的命令时,会先检索顶层的Makefie(在arch/xxx/目录下的Makefile为顶层Makefile补充体系结构相关的信息),顶层Makefile的两个主要任务是:产生内核映像文件和内核模块。接着顶层Makefile会去递归地进入内核的各个子目录,然后分别调用子目录中的Makefile(这些Makefile记录编译目标),而进入哪些子目录取决于内核的配置。
当使用makemenuconfig,makeconfig命令时,生成的.config会在源码目录下记录哪些部分被编译入内核,哪些部分被编译为内核模块。简而言之,它是保存内核配置结果的文件。当我们装上Linux系统时,第一次查看源码下的所有文件,会发现没有.config文件,那是因为从来没配置过内核。当你运行makemenuconfig保存并退出时,再次查看就有这个文件了。
配置工具,包括配置命令解释器(对配置脚本中使用的命令进行解释)和配置用户界面(提供字符界面和图形界面),配置工具都是用脚本语言编写的。
1.在进入menuconfig配置界面时,会发现每个配置项目为布尔型(要么编译入内核,要么不编译,选项为“Y”或“N”),菜单上为配置选项的名字例如:“XXXDriver”,help后面的内容为帮助信息。
1>除了布尔型的配置项目外,还存在一种三态型(tristate)配置选项,它意味着要么编译入内核,要么编译为内核模块,要么不编译,选项为“Y”,“M”或“N”。
eg: obj-$(CONFIG_USBTMC) +=usbtmc.o
上面的脚本含义是:如果USBTMC选项被选择为“Y”或“M”,即obj-$(CONFIG_USBTMC)就等同于obj-y或obj-m时,则编译usbtmc.c,选Y的情况直接会将生成的目标代码直接连接到内核,为“M”的情况则会生成模块usbtmc.ko,如果USBTMC配置选项被选择为“N”,即obj-$(CONFIG_USBTMC)等同于obj-n时,则不编译usbtmc.c
2.Makefile
对内核源代码各级子目录中的kbuildMakefile进行介绍,
(1)目标定义
目标定义用来定义哪些内容要作为模块编译,哪些要编译并连接进内核
(a)obj-y:=foo.o
表示要由foo.c或者foo.s文件编译得到foo.o并连接进内核,而obj-m则表示该文件要作为模块编译。处了y,m以外的obj-x形式的目标都不会被编译。
(b)我们最常用的的做法是根据.config文件的CONFIG_变量来决定文件的编译方式:
eg:
obj-$(CONFIG_ISDN)+=isdn.o
(c)多个文件模块的定义
如果一个模块由多个文件组成,这时候应采用模块名加-objs后缀或者-y后缀的形式来定义模块的组成文件。
如:
obj-$(CONFIG_EXT2_FS)+=ext2.o
ext2-y:=balloc.o bitmap.o
模块的名字是ext2,由balloc.o和bitmap.o两个文件最终连接生成ext2.o直至ext2.ko文件。
3.Kconfig
内核配置脚本语法:
(1)大多数的内核配置选项都对应一个Kconfig中的一个菜单入口。
menu "USBTMC"
comment "USBTMC Driver"
config USBTMC
tristate "USBTMC"
default n
endmenu
(a)“config”关键字定义新的配置选项,之后的几行定义了该配置选项的属性。配置选项的属性包括类型,数据,输入提示,依赖关系(及反向依赖关系),帮助信息和默认值等。
(b)每个配置选项都必须指定类型,其他类型都基于这两种基本类型。类型定义后可以紧跟输入提示,下面两个脚本是等价的
脚本1:
bool“Networking support”
脚本2:
bool
promt“Networking support”
输入提示的一般格式如下提示:
prompt <prompt> [if <expr>]
其中可选的if用来表示该提示的依赖关系。
默认值的格式如下所示:
default<expr> [if <expr>]
一个配置选项可以存在任意多个默认值,这种情况下,只有第一个被定义的值是可用的。如果用户不设置对应的选项,配置选项的值就是默认值。
(c)依赖关系的格式如下所示:
dependson (或者 requires)<expr>
如果定义了多个依赖关系,它们之间用”&&”间隔。依赖关系也可以应用到该菜单中所有的其他选项中。
(4)反向依赖关系的格式如下所示:
select<symbol> [if <expr>]
A.depends能限定一个symbol的上限,即如果A依赖于B,则在B被配置为“Y”的情况下,A可以为“Y”,“M”和”N”;在B被配置为“M”的情况下,A可以被配置为“M”或“N”;B在被配置为“N”的情况下,A只能为”N”。
B.select能限定一个symbol的下限,若A反向依赖于B,则A的配置值会高于或等于B(正好与depends相反)。如果symbol反向依赖于多个对象,则它的下限是这些对象的对大值。
(5)帮助信息的格式如下:
help(或---help---)
开始
。。。
结束
帮组信息完全靠文本缩进识别结束。“---help---”和”help”的初衷在于将文件中的配置逻辑与给开发人员的提示分开。
3.菜单结构
菜单入口在菜单数结构中的位置可由两种方法决定。
(1)第一中方式如下所下:
menu“Network device support”
dependson NET
config NETDEVICES
endmenu
所有处于”menu”和”endmenu”之间的菜单入口都会成为“Networkdevice support”的子菜单。而且,所有子菜单选项都会继承父菜单的依赖关系,比如:“Networkdevice support”对“NET”的依赖被加到了配置选项NETDEVICES的依赖列表中。
(2)另一种方式是通过分析依赖关系生成菜单结构。如果菜单选项在一定程度上依赖于前面的选项,它就能成为该选项的子菜单。如果父选项为“N”,则子选项不可见;如果父选项为“Y”或“M”,则子选项可见。
Eg:
config MODULES
bool “Enable loadable module support”
config MODVERSIONS
bool “Set version information on all module symbole”
dependson MODULES
comment “module support disabled”
depends on !MODULES
MODVERSIONS直接依赖MODULES,如果MODULES不为“N”,该选项才可见。
(3)除此之外,Kconfig中还可能使用“choices…...endchoice”,”comment”,”if....endif”这样的语法结构。
其中
choice
<choiceoptions>
<choiceblock>
enchoice
它定义一个选择群,其接受的选项(choiceoptions)可以是前面描述的任何属性。在一个硬件有多个驱动的情况下使用,使用选择可以实现最终只有一个驱动被编译进内核或模块。选择群还可以接受的另一个选项是“optional”,
这样菜单入口就被设置为“N”,没有被选中。
Linux内核开发之将驱动程序添加到内核的更多相关文章
- Linux驱动开发必看详解神秘内核(完全转载)
Linux驱动开发必看详解神秘内核 完全转载-链接:http://blog.chinaunix.net/uid-21356596-id-1827434.html IT168 技术文档]在开始步入L ...
- 如何参与Linux内核开发(转)
本文来源于linux内核代码的Document文件夹下的Hoto文件.Chinese translated version of Documentation/HOWTO If you have any ...
- 如何参与linux 内核开发
如果想评论或更新本文的内容,请直接联系原文档的维护者.如果你使用英文 交流有困难的话,也可以向中文版维护者求助.如果本翻译更新不及时或者翻 译存在问题,请联系中文版维护者. 英文版维护者: Gre ...
- 如何参与linux内核开发
如何参与linux 内核开发 如果想评论或更新本文的内容,请直接联系原文档的维护者.如果你使用英文 交流有困难的话,也可以向中文版维护者求助.如果本翻译更新不及时或者翻 译存在问题,请联系中文版维 ...
- Windows内核开发-2-开始内核开发-2-内核开发入门
Windows内核开发-2-开始内核开发-2- 第一个驱动程序: 直接采用vs2019中的Empty WDM Driver 模块创建: 初始的项目文件夹中有一个Driver Files里面会有一个.i ...
- Linux内核启动代码分析二之开发板相关驱动程序加载分析
Linux内核启动代码分析二之开发板相关驱动程序加载分析 1 从linux开始启动的函数start_kernel开始分析,该函数位于linux-2.6.22/init/main.c start_ke ...
- 嵌入式系统Linux内核开发工程师必须掌握的三十道题(转)
嵌入式系统Linux内核开发工程师必须掌握的三十道题 如果你能正确回答以下问题并理解相关知识点原理,那么你就可以算得上是基本合格的Linux内核开发工程师,试试看! 1) Linux中主要有哪几种内核 ...
- Linux 内核开发—内核简单介绍
内核简单介绍 Linux 构成 Linux 为什么被划分为系统空间和内核空间 隔离核心程序和应用程序,实现对核心程序和数据的保护. 什么内核空间,用户空间 内核空间和用户空间是程序执行的两种不同的状态 ...
- Linux内核(17) - 高效学习Linux驱动开发
这本<Linux内核修炼之道>已经开卖(网上的链接为: 卓越.当当.china-pub ),虽然是严肃文学,但为了保证流畅性,大部分文字我还都是斟词灼句,反复的念几遍才写上去的,尽量考虑到 ...
随机推荐
- docker基础及安装
Docker介绍: Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制 ...
- 有关mysql的for update以及 死锁问题
一.先说锁的概念 锁级别: 1.行级锁: InnoDB引擎(也支持表级锁,默认是行级锁),开销大,加锁慢:会出现死锁.锁定粒度最小,发生锁冲突的概率最低,并发度最高. 2.表级锁:MylSAM引擎和M ...
- 钉钉自定义机器人配合SVN钩子事件进行消息的推送实践
目前很多公司还是使用SVN(TortoiseSVN)进行版本控制,使用简单,适合管理一般项目.协同办公软件目前钉钉比较成熟,阿里也一直在宣传推广,这两年公司也在使用,主要用于信息的沟通,其它的绩效.考 ...
- c# 对象 & 类
类定义中可以使用的访问修饰符组合 none or internal 类只能在当前工程中访问 public 类可以在任何地方访问 abstract or internal abstract 类只能在当前 ...
- javascript中的BOM对象
1.window对象 所有的浏览器都支持window对象 概念上讲,一个html文档对应一个window对象 功能上讲,控制浏览器窗口 使用上讲,window对象不需要创建对象,直接使用 2.wind ...
- LANMP系列教程之MySQL编译安装CentOS7环境
以MySQL5.5.33版本为例 1.准备工作: 1.首先准备好源代码包 2.并且确保已安装好 "开发工具" 包组和cmake编译工具 3.确保安装好ncurses-devel ...
- 《EntrePreneur》发刊词
I do not choose to be a common person. It is my right to be uncommon - if I can. I seek opportunity ...
- linear-grident的属性和使用以及对颜色后面参数(百分比)的理解
linear-grident的属性和使用 css3新增Gradient属性,用来增加渐变的效果,渐变分为线性渐变 linear-grident 和 径向渐变 radial-grident,这篇文章 ...
- 一个.net专业户转Spring Boot V2.0开发的体会
java web的idea开发工具总体用起来还是比vs差很多,但是在使用Hibernate跟MyBatis的感触,Hibernate有着.net core ef没有的细腻,Hibernate在细节上完 ...
- 处理springMvc中responsebody返回中文乱码
法一: @RequestMapping(value="/getUsersByPage",produces = public String getUsers 法二:在sprin ...