1.顶层 顶层的Makefile文档读取内核配置文件.config文档的内容.递归向下访问子目录的形式完成build内核和模块的工作。 .config文件的内容是在makemenuconfig的时候,通过Kconfig文档配置的结果.arch/$(ARCH)/Makefile则提供补充体 系结构相关的信息; 2.内核中的kconfig 每个Kconfig分别描述了所属目录源文件相关的内核配置菜单。 Kconfig 语法结构 每个菜单项都有一个关键字标识,最常见的就是config。 语法: config symbol options symbol就是新的菜单项,options是在这个新的菜单项下的属性和选项 其中options部分有: (1)类型定义: 每个config菜单项都要有类型定义,bool:布尔类型,tristate三态:内建、模块、移除, string:字符串,hex:十六进制, integer:整型 例如 configHELLO_MODULE bool"hello testmodule" bool类型的只能选中或不选中,tristate类型的菜单项多了编译成内核模块的选项,假如选择编译成内核模块,则会在.config中生成一个 CONFIG_HELLO_MODULE=m的配置,假如选择内建,就是直接编译成内核影响,就会在.config中生成一个CONFIG_HELLO_MODULE=y的配置. (2)依赖型定义dependson或requires 指此菜单的出现是否依赖于另一个定义 configHELLO_MODULE bool"hello testmodule" dependsonARCH_PXA 这个例子表明HELLO_MODULE这个菜单项只对XScale处理器有效,即只有在选择了ARCH_PXA,该菜单才可见(可配置)。 (3)帮助性定义 只是增加帮助用关键字help或---help-- 3.makefile的内容 (1)目标定义 目标定义就是用来定义哪些内容要做为模块编译,哪些要编译链接进内核。如: obj-y += foo.o 表示要由foo.c或者foo.s文件编译得到foo.o并链接进内核,而obj-m则表示该文件要作为模块编译。 除了y,m以外的obj-x形式的目标都不会被编译。而更常见的做法是根据.config文件的CONFIG_ 变量来决定文件的编译方式(该变量如何起作用见文末另一篇文章的链接),如: obj-$(CONFIG_EXT2) += ext2.o 除了obj-形式的目标以外,还有lib-y library库,hostprogs-y 主机程序等目标,但是基本都应用在特定的目录和场合下。 (2)多文件模块的定义 最简单的kbuild Makefile如上一节一句话的形式就够了,如果一个模块由多个文件组成,那么稍微复杂一些,采用模块名加 –objs后缀或者 –y后缀的形式来定义模块的组成文件。如以下例子: obj-$(CONFIG_EXT2) += ext2.o ext2-y := balloc.o bitmap.o 或者写成如-objs的形式: obj-$(CONFIG_EXT2) += ext2.o ext2-objs := balloc.o bitmap.o 模块的名字为ext2,如果CONFIG_EXT2的值是m,由balloc.o和bitmap.o两个目标文件最终链接生成ext2.o 直至ext2.ko文件,如果CONFIG_EXT2的值是y,生成的 ext2.o将被链接进built-in.o最终链接进内核。 (3)目录层次的迭代 如下例: obj-$(CONFIG_EXT2) += ext2/ 如果CONFIG_EXT2 的值为y或m,kbuild将会将ext2目录列入向下迭代的目标中。 4.多文件makefile和kconfig #CONFIG_ECAT_DRV为m时编译为模块,为y时编进内核 ecat.o为最终链接的目标文件 obj-$(CONFIG_ECAT_DRV) += ecat.o #-objs指定依赖的多个.o文件 这些文件都对应相应的.c文件 ecat-objs := ecateoe.o eoeappl.o mcihw.o ecatslv.o mailbox.o ecatappl.o ecat2440.o 本地Kconfig #建立一个本地子目录。“”为显示的目录名字 menu "ecat driver here" depends on NET #依赖于上层的某个开关 config ECAT_DRV #配置变量名,必须和Makefile中的变量后半段一样 bool "ecat driver" #bool量, 显示的名字 ---help--- #下面为要显示的帮助文字 This is test for ecat. endmenu #本地子目录结束 上层Makefile *#添加下面这一句 obj-$(CONFIG_ECAT_DRV) += ecat/ #打开下一级目录编译 上层Kconfig *#添加下面这一句 source "driver/xxx/ecat/Kconfig" #导入子文件夹中的Kconfig文件,可以为相对路径 |
|