内核源码树的目录下都有两个文档Kconfig和Makefile。分布到各目录的Kconfig构成了一个分布式的内核配置数据库,每个Kconfig分别描述了所属目录源文档相关的内核配置菜单。在内核配置make menuconfig时,从Kconfig中读出菜单,用户选择后保存到.config的内核配置文档中。在内核编译时,主Makefile调用这个.config,就知道了用户的选择。

上面的内容说明了,Kconfig就是对应着内核的配置菜单。假如要想添加新的驱动到内核的源码中,能够修改Kconfig,这样就能够选择这个驱动,假如想使这个驱动被编译,要修改Makefile。所以,添加新的驱动时需要修改的文档有两种(注意不只是两个)*Kconfig,*Makefile

.config是make menuconfig【配置后生成的一个配置文件,也就是说可以拷贝一个别人配置好的.config来使用,内核中不同开发板也自带了一些配置文件在arch/arm/config/目录下面有很多配置文件可以选择和自己单板相似。

第一种方法:

利用内核自身的Makefile特性来编译我们的驱动程序,下面由一个简单的hello.c驱动程序来说明。

在/drivers/char/目录下写hello.c  修改Makefile,Kconfig

hello.c内容:

#include /* 初始化模块所用到的头文件 */

#include /* KERN_ALERT用到的 头文件*/

static int hello_init(void)      /* 入口函数,加载驱动程序所调用的函数 */

{

printk(KERN_ALERT"Hello, world\n");

return 0;

}

static void hello_exit(void)     /* 出口函数 ,卸载驱动程序所调用的函数*/

{

printk(KERN_ALERT"Goodbye, cruel world\n");

}

module_init(hello_init);

module_exit(hello_exit);

MODULE_LICENSE("Dual BSD/GPL");   /* 通用的协议 */

MODULE_AUTHOR("wangluoren");     /* 作者 */

MODULE_DESCRIPTION("A simple hello world module");   /* 程序描述 */

MODULE_ALIAS("A simplest module");             /* 别名 */

Kconfig内容:config HELLO           /* Makefile中编译可变选项中宏的名字,作用就是定义一个可以选择的变量 */

tristate "Hello Driver added by Dong"        /* make menuconfig 菜单界面显示的信息,tristate 提供Y M N三种选项*/

default n           /* 菜单选项默认为N */

help

test for adding driver to menuconfig.     /* 一些帮助信息,写不写没有关系 */

MakeFile内容:

obj-$(CONFIG_HELLO) += hello.o     /*CONFIG_HELLO我们在Kconfig中区定义它,我们用 HELLO ,hello是文件名字*/

到此为止我们就写好了这个hello的驱动程序,然后我们可以make menuconfig 在

Device Drivers  --->

Character devices  --->

Hello Driver added by Dong /* 可以按空格选择Y M N ,来分别 编译进内核,模块,不编译*/

如果是直接编译进内核就可以执行make uImage ,如果是编译成模块就执行make modules.

上面我们采用的是静态编译方法看起来是那么的麻烦,当我们写驱动程序的时候如果采用这种方法的话那就够折腾了,我估计你调试一个驱动程序你都得折腾大半天,这种方法是我们确定我们驱动程序没有问题后在编译进内核。

第二种方法:

一般我们采用动态编译来写驱动程序,具体方法如下:

还是拿hello.c程序为例:

hello.c内容:

#include /* 初始化模块所用到的头文件 */

#include /* KERN_ALERT用到的 头文件*/

static int hello_init(void)      /* 入口函数,加载驱动程序所调用的函数 */

{

printk(KERN_ALERT"Hello, world\n");

return 0;

}

static void hello_exit(void)     /* 出口函数 ,卸载驱动程序所调用的函数 */

{

printk(KERN_ALERT"Goodbye, cruel world\n");

}

module_init(hello_init);

module_exit(hello_exit);

MODULE_LICENSE("Dual BSD/GPL");   /* 通用的协议 */

MODULE_AUTHOR("wangluoren");     /* 作者 */

MODULE_DESCRIPTION("A simple hello world module");   /* 程序描述 */

MODULE_ALIAS("A simplest module");             /* 别名 */

Makefile文件编写如下:(和hello.c放在同一层目录就OK)

KERN_DIR = /home/book/workspace/kernel/linux-3.4.2_jz2440   /* 虚拟机kernel的路径,每个人不一样 */

all:

make -C $(KERN_DIR) M=`pwd` modules   /* -C 表示进入后面KERN_DIR这个目录把当前路径的hello.c编译成模块*/

clean:

make -C $(KERN_DIR) M=`pwd` modules clean  /* 一些清除工作,清除中间生成的中间文件 */

rm -rf modules.order

obj-m   += hello.o                        /* 编译,这里要注意这个hello是你要编译的程序的文件名字 */

上面两种方法编译完成后都会生成一个hello.ko的文件,我们把这个文件复制到开发板的目录下面,执行如下命令      insmod hello.ko  就会打印:Hello, world

rmmod hello    就会打印  Goodbye, cruel world(这个是一一对应的,加载一次只能卸载一次,不能重复加载)

补充一:

动态加载补充一点:如果我要用一个Makefile同时编译多个文件该怎么办呢?(这个文件的一个函数在另外一个文件当中定义,我们可以采取如下方法)方法如下:

有来个驱动文件:hello.c  hello1.c

我们可以把上面Makefile中obj-m +=hello.o改成如下命令就可以了

obj-m :=led.o

module-objs :=hello.o hello1.o   /* 这时候生成的 驱动文件就是led.ko */

补充二:

如果同时又两个驱动程序都需要编译(两者之间没有任何联系的,就是共同用kernel来编译自己的驱动)

比如有两个文件:hello1.c  hello2.c

我们可以在同一个Makefile中这样来编写:

obj-m+=hello1.o

obj-m+= hello2.o    (注意这个:=已经变成+=,这两者的区别这里就不说明了)

补充三:

上面静态编译驱动我们采用的是在/drivers/char目录下面添加一个文件,我们也可以在/drivers目录下面添加一个文件夹,下面我们讲讲具体的怎么来实现。

我们在/drivers目录下面添加一个hello的文件夹,里面创建一个hello.c,Kconfig,Makefile,这个三个文件和静态编译添加一个文件是完全相同的,主要是更改的是/drivers目录下的Makefile和Kconfig文件。

Makefile中添加如下命令:

obj-$(CONFIG_HELLO) += hello/        /* CONFIG_HELLO这个宏定义在hello目录里面的Kconfig中,‘/’表示进入这个目录,调用子目录Makefile来编译子目录中的文件 */

Kconfig添加如下命令:

source "drivers/hello/Kconfig"     /* 把Kconfig导出到子菜单界面 */

然后执行make modules   就在drivers/hello目录下面生成了一个hello.ko的文件

现在这个驱动编译的全部用法基本讲解完毕,有了这些知识你自己都可以去分析内核的结构,从顶层Makefile开始分析,子目录下的Makefile想对简单的多,顶层Makefile是比较难的,顶层Makefile讲解在这篇文章中,请点击这里!

上面讲解了一些基础的知识,这些知识对一个驱动开发成员已经足够了,如果你是工作在内核空间,那你就应该深入分析这些结构的原理,比如怎么添加递归创建子目录,通配符,正则表达式等,你都需要去深入了解。希望我这篇文章能给驱动开发者带来帮助。

linux 驱动编译静态,Linux驱动静态编译和动态编译方法详解相关推荐

  1. linux如何打出罗马数字,vim学习高级技巧之序列的生成方法详解

    前言 本文主要给大家介绍了关于在vim中插入数字序列的方法,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 待处理文本 假设文本原来内容是 这是第一行 这是第二行 这是第四行 这是第 ...

  2. Linux单用户模式(修改密码、运行级别)方法详解

    很多新手当面对"忘记 root 账户密码导致无法登陆系统"这个问题时,直接选择重新系统.其实大可不必,我只需要进入 emergency mode(单用户模式)更新 root 账户的 ...

  3. Linux Vim多窗口编辑,Vim打开多个窗口方法详解

    在编辑文件时,有时需要参考另一个文件,如果在两个文件之间进行切换则比较麻烦.可以使用 Vim 同时打开两个文件- 在编辑文件时,有时需要参考另一个文件,如果在两个文件之间进行切换则比较麻烦.可以使用 ...

  4. win10装linux虚拟机contos,利用win10自带虚拟机hyper-v安装centos7方法详解

    一.安装win10企业版自带虚拟机 hyper-v 1.控制面板-->程序和功能-->启用或关闭Windows功能 勾上 hyper-v 确定就ok了 2.安装成功后会发现在 左下角&qu ...

  5. linux mysql 静态库_Linux静态库与动态库实例详解

    Linux静态库与动态库实例详解 1. Linux 下静态链接库编译与使用 首先编写如下代码: // main.c #include "test.h" int main(){ te ...

  6. 转载:linux驱动层到应用层的重要接口sys文件系统---/sys目录详解

    linux驱动层到应用层的重要接口sys文件系统---/sys目录详解 Linux2.6内核中引入了sysfs文件系统.sysfs文件系统整理的设备驱动的相关文件节点,被视为dev文件系统的替代者.同 ...

  7. linux find文件,并复制,通过find命令寻找文件并拷贝到一个指定目录方法详解

    有这样的一个需求,需要将一部分符合条件的文件从一个目录拷贝到另一个目录中,可以通过使用find命令从源目录查找到符合条件的文件然后使用cp命令拷贝到目标目录 将通过find命令找到的文件拷贝到一个新的 ...

  8. linux上连接ftp服务器,linux下lftp连接ftp服务器进行上传与下载的方法详解

    摘要 腾兴网为您分享:linux下lftp连接ftp服务器进行上传与下载的方法详解,中英翻译,中建在线,掌上看家,银行帮等软件知识,以及微信一键转发工具,小学英语冀教版,正是在下表情包,易问电信,万能 ...

  9. linux expect 输入密码,shell脚本无密码登录 expect的使用方法详解

    shell脚本无密码登录 expect的使用方法详解 今天需要做一个定时任务脚本将最新的数据包文件传到远程的服务器上,虽然有密钥但也是要求输入密码的那种,所以只能另想办法实现让脚本自动输入密码了. 从 ...

  10. linux动态库注册函数,Linux动态库函数的详解

    linux动态库函数的详解 加载动态库 void *dlopen(const char *filename, int flag); flag的可能值: rtld_lazy rtld_now rtld_ ...

最新文章

  1. [云炬商业计划书阅读分享]
  2. SSM项目搭建之配置文件
  3. 缓存击穿/穿透/雪崩
  4. MADDPG中环境怎么配置,multiagent包解决
  5. 自然语言处理中的预训练模型 —— 邱锡鹏老师的演讲记录
  6. Composer更新慢的终极解决方案-转
  7. CoreAnimation汇总
  8. css基础知识汇总5
  9. opencv 二值化图像 像素统计 countNonZero
  10. KAIOS软件下载-自己做的
  11. Android触摸屏驱动,电阻屏,电容屏
  12. Cisco无线路由基本操作
  13. 2020 年软件设计师考试上午真题
  14. JUCE学习笔记07-自定义正弦振荡器类
  15. 如何用Java分配一段连续的1G的内存空间?需要注意些什么?
  16. 微信邮箱格式是什么意思?为什么我们都在使用微信邮箱?
  17. Top 25款3DMAX建筑设计相关插件
  18. 正则表达式匹配任意字符串
  19. PDF417 (二维码)
  20. 一个不错的外国Flash游戏

热门文章

  1. win7服务器未能登入,Win7提示profile服务未能登录,无法在系统中创建怎么办
  2. python集合set底层原理_Python进阶11_字典dict和集合set的秘密
  3. 数据结构与算法之-----二叉树(一)
  4. ftp服务器通常提供文件上传和,基于FTPClient的文件上传至Nginx服务器
  5. java 等待时间_java工作复习——4大时间等待——显示等待
  6. 售票系统的组件图和部署图_门禁安装大样图、管线图、系统图、电锁安装图
  7. mysql+order+in索引吗_mysql – 为什么ORDER BY不使用索引?
  8. PSOLA基音同步叠加算法
  9. 机器视觉:双远心镜头在弹簧检测中的应用
  10. svn增量打包部署_实现Jenkins+svn+bat批处理构建svn版本差异增量的自动化打zip包