由于用的学习材料是《linux设备驱动开发详解(第二版)》,所以linux驱动学习笔记大部分文字描述来自于这本书,学习笔记系列用于自己学习理解的一种查阅和复习方式。

#make config(基于文本的最为传统的配置界面,不推荐使用)
#make menuconfig(基于文本菜单的配置界面)
#make xconfig(要求 QT 被安装)
#make gconfig(要求 GTK+被安装)
在配置 Linux 2.6 内核所使用的 make config、 make menuconfig、 make xconfig 和 make gconfig
这 4 种方式中,最值得推荐的是 make menuconfig,它不依赖于 QT 或 GTK+,且非常直观。

make menuconfig的配置主界面:

下图是Device Drive目录下的Real Time Clock菜单,图片对应的驱动位于source/linux-2.6.32-devkit8500/drivers/rtc下,

跟上图相对应的Kconfig如下,可以发现这个界面中的所有内容都是通过Kconfig文件定义的。

Kconfig:

  1. #
  2. # RTC class/drivers configuration
  3. #
  4.  
  5. config RTC_LIB
  6. tristate
  7.  
  8. menuconfig RTC_CLASS
  9. tristate "Real Time Clock"
  10. default n
  11. depends on !S390
  12. select RTC_LIB
  13. help
  14. Generic RTC class support. If you say yes here, you will
  15. be allowed to plug one or more RTCs to your system. You will
  16. probably want to enable one or more of the interfaces below.
  17.  
  18. This driver can also be built as a module. If so, the module
  19. will be called rtc-core.
  20.  
  21. if RTC_CLASS
  22.  
  23. config RTC_HCTOSYS
  24. bool "Set system time from RTC on startup and resume"
  25. depends on RTC_CLASS = y
  26. default y
  27. help
  28. If you say yes here, the system time (wall clock) will be set using
  29. the value read from a specified RTC device. This is useful to avoid
  30. unnecessary fsck runs at boot time, and to network better.
  31.  
  32. config RTC_HCTOSYS_DEVICE
  33. string "RTC used to set the system time"
  34. depends on RTC_HCTOSYS = y
  35. default "rtc0"
  36. help
  37. The RTC device that will be used to (re)initialize the system
  38. clock, usually rtc0. Initialization is done when the system
  39. starts up, and when it resumes from a low power state. This
  40. device should record time in UTC, since the kernel won't do
  41. timezone correction.
  42.  
  43. The driver for this RTC device must be loaded before late_initcall
  44. functions run, so it must usually be statically linked.
  45.  
  46. This clock should be battery-backed, so that it reads the correct
  47. time when the system boots from a power-off state. Otherwise, your
  48. system will need an external clock source (like an NTP server).
  49.  
  50. If the clock you specify here is not battery backed, it may still
  51. be useful to reinitialize system time when resuming from system
  52. sleep states. Do not specify an RTC here unless it stays powered
  53. during all this system's supported sleep states.
  54.  
  55. config RTC_DEBUG
  56. bool "RTC debug support"
  57. depends on RTC_CLASS = y
  58. help
  59. Say yes here to enable debugging support in the RTC framework
  60. and individual RTC drivers.
  61.  
  62. comment "RTC interfaces"
  63.  
  64. config RTC_INTF_SYSFS
  65. boolean "/sys/class/rtc/rtcN (sysfs)"
  66. depends on SYSFS
  67. default RTC_CLASS
  68. help
  69. Say yes here if you want to use your RTCs using sysfs interfaces,
  70. /sys/class/rtc/rtc0 through /sys/.../rtcN.
  71.  
  72. If unsure, say Y.
  73.  
  74. config RTC_INTF_PROC
  75. boolean "/proc/driver/rtc (procfs for rtc0)"
  76. depends on PROC_FS
  77. default RTC_CLASS
  78. help
  79. Say yes here if you want to use your first RTC through the proc
  80. interface, /proc/driver/rtc. Other RTCs will not be available
  81. through that API.
  82.  
  83. If unsure, say Y.
  84.  
  85. endif # RTC_CLASS

源文件将近千行,这里只截取前面部分进行分析,

Kconfig
内核配置脚本文件的语法比较简单,主要包括如下几个方面。
( 1 )菜单入口 。
大多数的内核配置选项都对应 Kconfig 中的一个菜单入口:
config MODVERSIONS
  bool "Module versioning support"

  help
     Usually, you have to use modules compiled with your kernel.
    Saying Y here makes it ...
“ config” 关键字定义新的配置选项,之后的几行定义了该配置选项的属性。配置选项的属性包括类型、数据范围、输入提示、依赖关系、选择关系及帮助信息和默认值等。
每个配置选项都必须指定类型,类型包括 bool、 tristate、 string、 hex 和 int,其中 tristate 和string 是两种基本的类型,其他类型都基于这两种基本类型。类型定义后可以紧跟输入提示,下面的两段脚本是等价的:
bool "Networking support"

bool
prompt "Networking support"
输入提示的一般格式为:
prompt <prompt> [if <expr>]
其中可选的 if 用来表示该提示的依赖关系。
默认值的格式为:
default <expr> [if <expr>]
一个配置选项可以存在任意多个默认值,这种情况下,只有第一个被定义的值是可用的。如果用户不设置对应的选项,配置选项的值就是默认值。
依赖关系的格式为:
depends on(或者 requires) <expr>
如果定义了多重依赖关系,它们之间用 “ &&” 间隔。依赖关系也可以应用到该菜单中所有的其他选项(同样接受 if 表达式),下面的两段脚本是等价的:
bool "foo" if BAR
default y if BAR

depends on BAR
bool "foo"
default y
选择关系(也称为反向依赖关系)的格式为:
select <symbol> [if <expr>]
A 如果选择了 B,则在 A 被选中的情况下, B 自动被选中。
kbuild Makefile 中的 expr(表达式)定义为:

<expr> ::= <symbol>
    <symbol> '=' <symbol>
   <symbol> '!=' <symbol>
   '(' <expr> ')'
   '!' <expr>
   <expr> '&&' <expr>
   <expr> '||' <expr>
也就是说 expr 是由 symbol、两个 symbol 相等、两个 symbol 不等以及 expr 的赋值、非、与
或运算构成。而 symbol 分为两类,一类是由菜单入口定义配置选项定义的非常数 symbol,另一
类是作为 expr 组成部分的常数 symbol。
数据范围的格式为:
range <symbol> <symbol> [if <expr>]
为 int 和 hex 类型的选项设置可以接受输入值范围,用户只能输入大于等于第一个 symbol,
小于等于第二个 symbol 的值。
帮助信息的格式为:
help(或---help---)
 开始

结束
帮助信息完全靠文本缩进识别结束。“---help---” 和“help” 在作用上没有区别,设计“---help---”
的初衷在于将文件中的配置逻辑与给开发人员的提示分开。
menuconfig 关键字的作用与 config 类似,但它在 config 的基础上要求所有的子选项作为独立
的行显示。
( 2)菜单结构。
菜单入口在菜单树结构中的位置可由两种方法决定。第一种方式为:
menu "Network device support"
 depends on NET
config NETDEVICES
 …
endmenu
所有处于“ menu” 和“ endmenu” 之间的菜单入口都会成为“ Network device support” 的子菜
单。而且,所有子菜单选项都会继承父菜单的依赖关系,比如,“ Network device support” 对“ NET”
的依赖会被加到了配置选项 NETDEVICES 的依赖列表中。
注意 menu 后面跟的“ Network device support”项目仅仅是 1 个菜单,没有对应真实的配置选
项,也不具备 3 种不同的状态。这是它和 config 的区别。
另一种方式是通过分析依赖关系生成菜单结构。如果菜单选项在一定程度上依赖于前面的选
项,它就能成为该选项的子菜单。如果父选项为“ N”,子选项不可见;如果父选项可见,子选项
才能可见。例如:
config MODULES
 bool "Enable loadable module support"
config MODVERSIONS
 bool "Set version information on all module symbols"
 depends on MODULES

comment "module support disabled"
depends on !MODULES
MODVERSIONS 直接依赖 MODULES,只有 MODULES 不为“ n”时,该选项才可见。
除此之外, Kconfig 中还可能使用“ choices … endchoice”、“ comment”、“ if…endif” 这样的语
法结构。其中 “ choices … endchoice” 的结构为:
choice
<choice options>
<choice block>
endchoice"
它定义一个选择群,其接受的选项(choice options)可以是前面描述的任何属性, 例如 LDD6410
的 VGA 输出分辨率可以是 1 024 !768 或者 800 !600,在 drivers/video/samsung/Kconfig 就定义了如
下的 choice:
choice
depends on FB_S3C_VGA
prompt "Select VGA Resolution for S3C Framebuffer"
default FB_S3C_VGA_1024 _768
config FB_S3C_VGA_1024 _768
bool "1 024 *768@60Hz"
---help---
TBA
config FB_S3C_VGA_640_480
bool "640*480@60Hz"
---help---
TBA
endchoic

下面介绍drivers/rtc下的Makefile:

  1. #
  2. # Makefile for RTC class/drivers.
  3. #
  4.  
  5. ifeq ($(CONFIG_RTC_DEBUG),y)
  6. EXTRA_CFLAGS += -DDEBUG
  7. endif
  8.  
  9. obj-$(CONFIG_RTC_LIB) += rtc-lib.o
  10. obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o
  11. obj-$(CONFIG_RTC_CLASS) += rtc-core.o
  12. rtc-core-y := class.o interface.o
  13.  
  14. obj-$(CONFIG_RTC_INTF_ALARM) += alarm.o
  15. obj-$(CONFIG_RTC_INTF_ALARM_DEV) += alarm-dev.o
  16. rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o
  17. rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o
  18. rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o
  19.  
  20. # Keep the list ordered.
  21.  
  22. obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o
  23. obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o
  24. obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o
  25. obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o
  26. obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o
  27. obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o
  28. obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o
  29. obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
  30. obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o
  31. obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o
  32. obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o
  33. obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o
  34. obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o
  35. obj-$(CONFIG_RTC_DRV_DS1305) += rtc-ds1305.o
  36. obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o
  37. obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o
  38. obj-$(CONFIG_RTC_DRV_DS1390) += rtc-ds1390.o
  39. obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o
  40. obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o
  41. obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o
  42. obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o
  43. obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o
  44. obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o
  45. obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
  46. obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o
  47. obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o
  48. obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
  49. obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o
  50. obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o
  51. obj-$(CONFIG_RTC_DRV_M48T35) += rtc-m48t35.o
  52. obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o
  53. obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o
  54. obj-$(CONFIG_RTC_MXC) += rtc-mxc.o
  55. obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o
  56. obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
  57. obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o
  58. obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o
  59. obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o
  60. obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o
  61. obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
  62. obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
  63. obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o
  64. obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o
  65. obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o
  66. obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o
  67. obj-$(CONFIG_RTC_DRV_PS3) += rtc-ps3.o
  68. obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o
  69. obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o
  70. obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o
  71. obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
  72. obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o
  73. obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o
  74. obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o
  75. obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o
  76. obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o
  77. obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o
  78. obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o
  79. obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o
  80. obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
  81. obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
  82. obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o
  83. obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o
  84. obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o
  85. obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o
  86. obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o
  87. obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o
  88. obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
  89. obj-$(CONFIG_RTC_DRV_WM831X) += rtc-wm831x.o
  90. obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o
  91. obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o

这里主要对内核源代码各级子目录中的 kbuild( 内核的编译系统) Makefile 进行简单介绍,这部分是内核模块或设备驱动的开发者最常接触到的。
Makefile 的语法包括如下几个方面。
( 1 )目标定义。
目标定义就是用来定义哪些内容要作为模块编译,哪些要编译并连接进内核。
例如:
obj -y += foo.o
表示要由 foo.c 或者 foo.s 文件编译得到 foo.o 并连接进内核,而 obj-m 则表示该文件要作为模
块编译。除了 y、 m 以外的 obj-x 形式的目标都不会被编译。
而更常见的做法是根据.config 文件的 CONFIG_变量来决定文件的编译方式,如:
obj -$(CONFIG_ISDN) += isdn.o
obj -$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
除了 obj-形式的目标以外,还有 lib-y library 库, hostprogs-y 主机程序等目标,但是基本都应
用在特定的目录和场合下。
( 2)多文件模块的定义。
最简单的 Makefile 如上一节一句话的形式就够了,如果一个模块由多个文件组成,会稍微复
杂一些,这时候应采用模块名加-y 或-objs 后缀的形式来定义模块的组成文件。如以下例子:
#
# Makefile for the linux ext2-filesystem routines.
#
obj -$(CONFIG_EXT2 _FS) += ext2.o
ext2-y := balloc.o dir.o file.o fsync.o ialloc.o inode.o \
   ioctl.o namei.o super.o symlink.o
ext2-$(CONFIG_EXT2 _FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o
ext2-$(CONFIG_EXT2 _FS_POSIX_ACL) += acl.o
ext2-$(CONFIG_EXT2 _FS_SECURITY) += xattr_security.o
ext2-$(CONFIG_EXT2 _FS_XIP) += xip.o
模块的名字为 ext2,由 balloc.o、 dir.o、 file.o 等多个目标文件最终链接生成 ext2.o 直至 ext2.ko
文件,并且是否包括 xattr.o、 acl.o 等则取决于内核配置文件的配置情况,例如, 如果 CONFIG_
EXT2
_FS_POSIX_ACL 被选择,则编译 acl.c 得到 acl.o 并最终链接进 ext2。

( 3)目录层次的迭代。
如下例:
obj -$(CONFIG_EXT2 _FS) += ext2/
当 CONFIG_EXT2_FS 的值为 y 或 m 时, kbuild 将会把 ext2 目录列入向下迭代的目标中。

linux 驱动学习笔记01--Linux 内核的编译的更多相关文章

  1. 小松之LINUX 驱动学习笔记(二)

    这两天一直在看字符驱动那块,后来从网上找啦几个例子,自己编译啦下,安装啥的都挺正常,就是用测试程序测试的时候总出问题,现在找到一个能测试的代码,自己先看看和原来的那个代码有啥不同,后面会继续更新,说下 ...

  2. linux 驱动学习笔记03--Linux 内核的引导

    如图所示为 X86 PC 上从上电/复位到运行 Linux 用户空间初始进程的流程.在进入与 Linux相关代码之间,会经历如下阶段. ( 1 ) 当系统上电或复位时, CPU 会将 PC 指针赋值为 ...

  3. linux 驱动学习笔记02--应用实例:在内核中新增驱动代码目录和子目录

    下面来看一个综合实例,假设我们要在内核源代码 drivers 目录下为 ARM 体系结构新增如下用于 test driver 的树型目录:| --test  | -- cpu  | -- cpu.c ...

  4. Linux Basic学习笔记01

    介绍课程: 中级: 初级:系统基础 中级:系统管理.服务安全及服务管理.Shell脚本: 高级: MySQL数据库: cache & storage 集群: Cluster lb: 4laye ...

  5. Linux 驱动学习笔记05--字符驱动实例,实现一个共享内存设备的驱动

    断断续续学驱动,好不容易有空,做了段字符驱动的例子.主要还是跟书上学习在此记录下来,以后说不定能回过头来温故知新. 首先上驱动源码 gmem.c: /************************* ...

  6. 小松之LINUX 驱动学习笔记(一)

    本篇主要是讲解驱动开发的基础知识以及一些环境配置方面的问题. 下面是一个hello world的简单的模块代码,很简单./*********************** 模块的简单例子* author ...

  7. linux 驱动学习笔记04--简单驱动

    首先贴代码helloworld.c和Makefile /************************************************************************ ...

  8. linux驱动学习笔记---实现中断下半部以及驱动编写规范(七)【转】

    转自:https://blog.csdn.net/weixin_42471952/article/details/81609141 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协 ...

  9. 小松之LINUX驱动学习笔记之模块间函数调用通讯

    1. 符号导出函数 EXPORT_SYMBOL() EXPORT_SYMBOL标签内定义的函数对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用. EXPORT_SYMBOL_GPL( ...

随机推荐

  1. 为CDH 5.7集群添加Kerberos身份验证及Sentry权限控制

    转载请注明出处:http://www.cnblogs.com/xiaodf/ 4. 为CDH 5集群添加Kerberos身份验证 4.1 安装sentry1.点击“操作”,“添加服务”:2.选择sen ...

  2. VS 2013 打包程序教程

    简述 如果你只是想要在他人的机子上运行你的程序而不想安装,有一种简单的方法,只要使用本教程的“步骤—3.生成Release 文件夹”即可.但是有一点需要注意,如果你在程序中调用了其他的dll,那么你需 ...

  3. HTML标签小记

    <body> </body>标签,网页内容放在这里 <p> </p>标签,网页的段落 <hx> </hx>标签,网页的标题 &l ...

  4. chrome 49 版本 跨越 --args --disable-web-security --user-data-dir

    转载: 做前端的,用Ajax获取数据,是常有的事情,同域下自然没问题了,如果是不同域获取数据,浏览器就有个同源策略的限制. 如图: Origin * is not allowed by Access- ...

  5. django 过滤器 、日期格式化参数

    http://blog.csdn.net/xyp84/article/details/7945094 django1.4 html页面从数据库中读出DateTimeField字段时,显示的时间格式和数 ...

  6. SQL 数据库的使用

    <1>存到数据库 CSql Sql; Sql.SqlSave(15, &m_SALink, 0, 0, 0, 0); <2>取数据 int *pt = new int[ ...

  7. mysql的ONLY_FULL_GROUP_BY语义 --转自http://www.wtoutiao.com/p/19dh3ec.html

    执行SET GLOBAL sql_mode = ''; 把sql_mode 改成非only_full_group_by模式.验证是否生效 SELECT @@GLOBAL.sql_mode 或 SELE ...

  8. Python入门1

    简介 Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,做为ABC 语言的一种继承.Python ...

  9. 整理QQ数据库sql语句

    设置数据库的时候 qq 号如果用整型,设置成UNSIGNED,不然超过一定数值就错误 UPDATE `sao_qq` SET qq_num = REPLACE ( qq_num, '@qq.com', ...

  10. Error: Error #2014: Feature is not available at this time. at flash.filesystem::File$/initDocumentsDir()

    Error: Error #2014: Feature is not available at this time. at flash.filesystem::File$/initDocumentsD ...