在内核中新增驱动代码目录

如果学习Linux下驱动开发,那么本文所述的“在内核中新增驱动代码目录”应该是一个最基本的知识点了。那么如何将自己写好的驱动程序新增到内核?本文将一步一步的教会你。

1.在正式开始之前,请先切换到root用户:su root。不过可能会会出现问题:不管你输入什么密码,都会提示你错误(很可能是因为之前你根本未设置过密码)。这时候我们来修改root用户的密码:

1 sudo passwd root

输入两次后,即可修改完毕,这下再su root就可以成功切换到root用户。

2.你可以现在试着在终端输入make menuconfig,终端会提示你:make: *** 没有规则可以创建目标“menuconfig”。这是因为menuconfig涉及到图形界面,所以我们得安装一些依赖包(ubuntu下):sudo apt-get install libncurses5-dev。

3.在一般的教程中,都会提到.config文件,而且这个文件就位于内核代码的根目录下。因此我会输入命令:ls -a来寻找.config。可是找来找去都没有这个文件的踪影。这是为什么?这是因为在这之前,你从来没有进行过内核配置,所以当然就不会生成.config文件了。解决的方法也很简单,有了上面两步的准备工作,那么你应该会成功进入配置用户界面,然后什么也不做,保存退出即可。那么你再ls一下,你可以发现.config已经存在了。

在开始向加入驱动代码之前,我们先了解三项基本步骤:

(1)将编好的源代码复制到Linux内核源代码的相应目录

(2)在目录的Kconfig文件中增加新源代码对应项目的编译配置选项

(3)在目录的Makefile文件中增加对新源代码的编译条目

在完成上述三项工作之前,我们先看一下我们要新增的驱动的树形结构。比如我们写的驱动程序均放在edsionteDriver目录,在此目录中包含Kconfig,Makefile和test.c三个文件,以及Key和led两个目录。我们先提前创建好这些文件,请注意本文只是为了演示说明,如果实际应用,像key,led以及test.c这样的文件都是有实际意义的。那么现在复制到内核源码目录下的driver/目录下即可。

|– edsionteDriver
|    |– Kconfig
|    |– Makefile
|    |– key
|        |– Kconfig
|        |– Makefile
|        |– mykey.c
|    |– mydriver.c
|    |– mydriver_user.c

现在我们完成了第一步工作,你应该注意到,我们现在只是创建了各个目录下的Kconfig和Makefile文件,并没添加相关内容,所以接下来我们就来进行这两个文件的编写。

对于初学者来说,直接学习Makefile以及Kconfig的编写可能会有些眩晕甚至排斥学习,不过我们可以先了解这两个文件在实际的内核分析中有什么作用。一般来说,对于内核这个庞大的网络,想要快速定位你所关心的代码就需要首先分析某个目录下的Makefile以及Kconfig文件,它们可是我们分析内核代码的goole map。

比如我们要分析ext3类型的文件系统,那么我们进入源码目录下fs/ext3/目录中,我们打开此目录的Makefile文件:

01 1 #
02  2 # Makefile for the linux ext3-filesystem routines.
03  3 #
04  4
05  5 obj-$(CONFIG_EXT3_FS) += ext3.o
06  6
07  7 ext3-y  := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
08  8            ioctl.o namei.o super.o symlink.o hash.o resize.o ext3_jbd.o
09  9
10 10 ext3-$(CONFIG_EXT3_FS_XATTR)     += xattr.o xattr_user.o xattr_trusted.o
11 11 ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o
12 12 ext3-$(CONFIG_EXT3_FS_SECURITY)  += xattr_security.o

我们应该先注意到7,8行,其定义了ext3变量(-y说明是多文件模块的定义,可以先忽略)。这里的定义变量类似于C语言中的宏定义,就是用ext3代替后面的.o文件列表。那么现在我们就可以知道与ext3模块最直接相关的就是后面这些文件对应的.c以及.h文件了,这些文件在源码相应的目录下都可以找到。那么ext3.o是否被编译取决于第的CONFIG_EXT3_FS,这个变量的值一般取y或n(甚至m)。它一般对应的是用户在配置界面时的输入。想要了解配置界面的菜单选项,就得看Kconfig文件。由于我们只关心EXT3_FS这个选项,因此我们相应的找到EXT3_FS这个选项的配置语句即可:

1 config EXT3_FS
2     tristate "Ext3 journalling file system support"
3     select JBD
4     help
5       This is the journalling version of the Second extended file system
6       (often called ext3), the de facto standard Linux file system
7       (method to organize files on a storage device) for hard disks.
8          #Other code was deleted

上述代码中,select说明只有JBD被配置,EXT3_FS这个配置项目才会在配置菜单上出现(事实上两者有更具体的依赖关系,可参考相关语法)。在配置菜单上会显示tristate后面的字符串,当用户选择配置此条目的情况下(有y,m和n三态选项),对应在Makefile文件中的CONFIG_EXT3_FS就对应为y。即obj-y的情况下,ext3.o菜会被编译。

现在将Makefile和Kconfig文件再串通起来想想,你应该会明白它们的作用。

一般来说,Makefile定义了根据该子目录下的源码文件构建目标文件的规则。像我们刚说的那个变量的定义以及根据CONFIG_EXT3_FS选项是否编译ext3.c文件。至于这些规则是否被执行,就取决于用户在配置菜单上是否选择配置这个选项,而这个配置菜单中配置选项就对应Kconfig文件。而且用户输入的配置结果会记录在.config文件当中。

通过上面的简单举例,我们可以先大致了解Makefile、Kconfig以及.config三者之间的关系以及作用。我们刚才分析的是内核中已经写好的代码的配置规则。对于我们上面所说的新增edsionteDriver驱动,应该如何添加?




上文中,我们已经理解了Makefile与Kconfig的作用,那么我们现在要在内核中增加edsionteDriver驱动代码,并告诉内核“请您下次编译的时候捎带上我”。具体应该如何来做?首先应该在Makefile中添加相关驱动文件的编译信息,然后还得在Kconfig中添加这个新驱动对应的配置选项。

好了,开始吧!

我们首先在内核根目录下添加edsioteDriver驱动目录。如何将此驱动目录与上一级目录连接起来?那么就需要我们来做一些修改。在驱动目录的上一级目录中,我们找到Makefile文件,然后在在此文件中添加下面代码(最好在自己添加的代码前后加上注释,以便与原有代码区别):

1 #edsionteDriver 's starting
2 obj-y+=edsionteDriver/
3 #edsinteDriver's ending

这句话使得kbulid会将edsionteDriver目录列入到向下迭代的目标当中,通俗一点说就是在编译过程中会将我们写的这个驱动目录列入编译的范围之内。obj-y文件列表将会被链接到built-in.o,并最终编译到vmlinux的目标文件列表 。这个解释属于官方说法,事实上当前我也不是很清除这是神马意思,不过你只需了解obj-y开始的文件列表会被编译并连接至内核就可以了。

我们上文中所说obj-$(CONFIG_xxx):=(文件列表)这样的语句是定义变量,其中具体规则是:变量名 变量符 变量值。变量符可以是=,+=,:=,?=中的一个,其中+=是追加赋值符,实现对变量的追加赋值。其中$(CONFIG_XXX)是对CONFIG_XXX的引用,CONFIG_XXX的值会根据依赖关系以及用户输入来决定。比如如果是depend on依赖的话,那么用户可选择y或n;如果是上文中的tristate那么就是三态选项,即y、n或m。obj-m表示会将文件当作内核模块来编译,obj-n就可以忽略不进行处理。

注意:我们刚添加的语句只是对edsionteDriver目录起作用,至于这个目录下的各个子文件是要模块编译还是链入你和还要具体看我们edsionteDriver目录下的Makefile文件。

下面修改驱动目录子目录的Kconfig文件:

1 #edsionteDriver 's starting
2 source "drivers/edsionteDriver/Kconfig"
3 #edsinteDriver's ending

这条脚本是将edsionteDriver目录中的Kconfig加入到上级目录中的Kconfig中。这样上级目录的Kconfig会引用到edsionteDriver目录中的Kconfig文件。通过这条语句我们也可以体会Kconfig的另一个作用:Kconfig文件将分布在当前目录下各个子目录的Kconfig都集中在自己的Kconfig当中。

通过上述两步修改就会让父目录感知到edsionteDriver的存在了。接下来我们来编写edsionteDriver目录以及其子目录下的各个Kconfig和Makefile文件。首先是edsionteDriver目录下的两个文件配置:

Makefile文件如下:

1 # drivers/edsionteDriver/Makefile
2 # just a test
3  
4 obj-$(CONFIG_MYDRIVER) +=mydriver.o
5 obj-$(CONFIG_MYDRIVER_USER) +=mydriver_user.o
6 obj-$(CONFIG_KEY) +=key/

我们需要用户来选择是否编译mydriver.c,所以需要用CONFIG_MYDRIVER变量来保存选项值。下面两句类似我们一开始在父目录下增加edsionteDriver目录。
Kconfig文件如下:

01 # dirvers/edsionteDriver/Kconfig
02  
03 menu "Test edsionteDriver"
04  
05 config MYDRIVER
06     tristate "mydriver test!"
07 config MYDRIVER_USER
08     bool "user-space test"
09     depends on MYDRIVER
10  
11 source "drivers/edsionteDriver/key/Kconfig"
12 endmenu

首先menu和endmenu之间代码创建了一个菜单Test edsionteDriver,然后第一条config语句会建立一个名为”mydriver test”的配置菜单,用户在尽享此项目的配置时输入的配置信息(Y,N或M),会存储在config后面的MYDRIVER变量中。而这个变量会直接关系到Makefile文件中是否编译相应的文件。第二个config语句还是创建一个配置菜单的条目,只不过比较特殊的是这个菜单依赖于上面我们创建的菜单“mydriver test”(语法上是MYDRIVER_USER依赖于MYDRIVER)。具体含义是,只有当用户选择配置“mydriver test”时,才会出现下级菜单”user-sapce test”;否则这个下级菜单是不会出现的。

最后一条source语句的作用是将edsionteDriver目录下的子目录key/也加入到内核编译时扫描的对应当中。

接下来,就应该修改key目录下的相应文件了,这里不再详细说明,如果你成功修改了上述文件,修改key目录下的文件应该不困难吧?

这样的step by step并不是为了教会各位如何产生那个配置菜单,而是让各位在基本理解Kconfig,Makefile以及.config三者的基础上更深入的去学习。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值