对一个uClinux中的Makefile文件的简单分析(ZT)

为了彻底搞清楚linux和uClinux的设备驱动,我觉得有必要找一份devices.txt的copy。那上面详细列出了0至255个linux主设备号的分配情况,以及各种设备的相应次设备号。对于,我自己开发非标准的linux设备非常有用。uClinux的设备和linux一样,因此这个文档同样适用于uClinux。这个文档可以从下列站点:http://www.lanana.org/docs/device-list/或者ftp://ftp.kernel.org/pub/linux/docs/device-list/获取。作为开发的常用手册,这个文档有必要打印并保存下来。

 

我自己为我的开发板上的按键写了一个驱动,我想要像其他linux标准设备那样在uClinux启动起来时,在/dev目录下有例如/dev/key这样一个设备。但是开始我一直搞不清楚为什么在menuconfig的char device和input core菜单中居然没有关于键盘的选项,但键盘驱动又是确实被编译进系统中了。后来,经过比较linux和uClinux后,我发现问题的关键不在于char/目录下的config.in文件,也不在于linux-2.4.x/arch/armnommu/Config.in文件,而在于drivers/char/Makefile文件。

 

简要说一下这个文件,它并不规定menuconfig的char device子菜单的构成,而是规定了drivers/char这个目录下的文件的编译规则。通过在此文件中,加入一些条件判断,并根据条件判断为一些变量赋值,从而达到将特定设备编译进uClinux的内核。

 

下面对Makefile中的一些定义进行解释。

 

编译目标定义:

 

obj-$(CONFIG_TC) += tc.o的语句是用来定义编译的目标,是子目录 Makefile 中最重要的部分。编译目标定义那些在本子目录(对于这个Makefile来说,就是针对/linux-2.4.x/drivers/char子目录)下,需要编译到 Linux 内核中的目标文件列表。为了只在用户选择了此功能后才编译,所有的目标定义都融合了对配置变量的判断。
前面说过,每个配置变量取值范围是:y,n,m 和空,obj-$(CONFIG_TC) 分别对应着 obj-y,obj-n,obj-m,obj-。如果 CONFIG_TC 配置为 y,那么 tc.o 就进入了 obj-y 列表。obj-y 为包含到 Linux 内核 vmlinux 中的目标文件列表;obj-m 为编译成模块的目标文件列表;obj-n 和 obj- 中的文件列表被忽略。配置系统就根据这些列表的属性进行编译和链接。export-objs 中的目标文件都使用了 EXPORT_SYMBOL() 定义了公共的符号,以便可装载模块使用。在 tc.c 文件的最后部分,有 "EXPORT_SYMBOL(search_tc_card);",表明 tc.o 有符号输出。其中的“obj-y +=”表示如果变量为真,那么就追加什么;而“obj-y :=”表示如果变量为真,那么就等于什么。

 

这里需要指出的是,对于编译目标的定义,存在着两种格式,分别是老式定义和新式定义。老式定义就是前面 Rules.make 使用的那些变量,新式定义就是 obj-y,obj-m,obj-n 和 obj-。Linux内核推荐使用新式定义,不过由于 Rules.make 不理解新式定义,需要在 Makefile 中的适配段将其转换成老式定义。

 

另外,需要指出的是linux和uClinux源码树中的Makefile分为两类,一类是由autoconf和automake根据configure.in模板自动生成,另一类是由开发者自己手工写的Makefile。所以,对于前者来说,修改文件中的任何语句或判断条件,都是徒劳无功的。因为每次创建新的配置或修改以前的配置后,Makefile就会被改写或重新生成。要想要通过这种办法达到自己满意的编译配置是不可能的。但后者就不同,由于不是由内核自动生成,因此,不论配置修改多少次,这个文件都是不会改变的。所以,我们可以通过修改Makefile中的语句或判断条件,来达到构建我们自己的编译配置。这一点对添加自己的非标准设备非常有用。

 

适配段:
适配段的作用是将新式定义转换成老式定义。在下面的例子中,适配段就是将 obj-y 和 obj-m 转换成 Rules.make 能够理解的 L_TARGET,L_OBJS,LX_OBJS,M_OBJS,MX_OBJS。

 

L_OBJS := $(sort $(filter-out $(export-objs), $(obj-y))) 定义了 L_OBJS 的生成方式:在 obj-y 的列表中过滤掉 export-objs(tc.o),然后排序并去除重复的文件名。这里使用到了GNU Make 的一些特殊功能,具体的含义可参考Make的文档(info make)。

 

显然,由于menuconfig的图形配置菜单中根本没有关于键盘的选项,因此可以看到在obj-y中并没有keyboard.o。那么键盘驱动是怎么编译进char.o的呢?

 

可以注意到:
KEYMAP   =defkeymap.o
KEYBD    =pc_keyb.o
CONSOLE =console.o
SERIAL   =serial.o
这四个变量都被赋值。它们分别表示键盘码和扫描码的映射表、键盘驱动、控制台驱动和串口驱动。上面是四个变量的默认值。

 

在下面这一段中,先判断变量ARCH是否等于sh,如果为真,那么变量为空;紧接着下一级逻辑判断中,判断变量CONFIG_SH_HP600是否为真,如果为真,那么键盘映射表还是适用默认的映射表(defkeymap.o),但键盘驱动就改为hp600_keyb.o和scan_keyb.o,控制台驱动不变。但是要注意串口在这一部分中,并没有加入判断语句中,因为串口驱动在下面用obj-$(CONFIG_68328_SERIAL) += 68328serial.o这样的形势单独列出。

 

另外,需要特别指出的是,察看linux或者uClinux各种变量配置的情况,可以看linux-2.4.x/include/linux/autoconf.huClinux-dist/config.in以及linux-2.4.x/config.in这三个文件。

 

 

还有ifeq..)表示假如等于xxx,那么xxxifneq..)便是相反意思,表示假如不等于xxx,那么xxxifdef()表示如果xxx为真,那么xxxifndef()表示如果xxx为假,那么xxx

 

ifeq ($(ARCH),sh)                                     如果ARCH=sh,那么。。。
 KEYMAP   =
 KEYBD    =
 CONSOLE =
 ifeq ($(CONFIG_SH_HP600),y)              如果CONFIG_SH_HP600=y,那么。。。
 KEYMAP   = defkeymap.o
 KEYBD    = scan_keyb.o hp600_keyb.o
 CONSOLE = console.o
 endif
endif

 

ifeq ($(ARCH),mips)
 ifneq ($(CONFIG_PC_KEYB),y)             如果CONFIG_PC_KEYB!=y,那么。。。
    KEYBD    =
 endif
endif

 

ifeq ($(ARCH),m68k)
   ifdef CONFIG_AMIGA                        如果CONFIG_AMIGA为真(即变量为y),那么。。。
      KEYBD = amikeyb.o
   else
      ifndef CONFIG_MAC                     如果CONFIG_AMIGA为假,那么。。。
        KEYBD =
      endif
   endif
   SERIAL   =
endif

 

下面这一段很重要。
ifndef CONFIG_SUN_KEYBOARD             如果变量为假,那么判断变量CONFIG_VT

 

 obj-$(CONFIG_VT) += keyboard.o $(KEYMAP) $(KEYBD) 
else
 obj-$(CONFIG_PCI) += keyboard.o $(KEYMAP)
endif
结果就是CONFIG_SUN_KEYBOARD(SUN公司PC键盘)通常为假(我们不会用到),那么CONFIG_VT是虚拟控制台,通常我们要选择,就是CONFIG_VT=y,那么追加keyboard.o、$(KEYMAP)和$(KEYBD)。这两个变量在最前面有定义:defkeymap.o和pc_keyb.o。因此,标准键盘驱动被自动编译进char.o中,进而被编译进内核中。

 

所以,我就可以根据这个道理将自己的按键驱动自动加入到内核中。下面是我加入的一段语句,完成自动将我自己的按键驱动编译进内核。

 

ifeq($(CONFIG_ARCH_S 3C44B0),y)
KEYBD = key.o
KEYMAP = mykeymap.o
       CONSOLE = console.o
endif

 

这个Makefile大致就解释到这儿。其实,不过是拿给自己看的罢了。
 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值