王鑫宇 2015.7.15

一、引

我们一般编译ecos如下:

(1)Make PROFILE=16MB oldconfig

(2)Make

OK了,产能了个ecos_lzma.trx 升级就行了。

比较奇它是如何产生的,产能的过程,组成的部分。如同Linux下,生成升级文件 ,只需要产生 vmlinuxz-lzma , target.squashfs 再用 BRCM的 trx工具一绑,过程还是很清楚的。

但eCos就摸不到头脑了,因为整个eCos就是一个大的可执行文件。

最近感觉一直脑袋痛的小问题,(其实不算问题了),就是make clean 一次好像很ok, 在make 一次,就打印好多东西,谁也说不清。(见下面的附图吧)

一直想跟一个makefile,但一直没去跟。总觉得有问题,又说不清,浑浑噩噩的,日。

二、编译过程分析

Come on, Flow me.

1. 下好代码, Make PROFILE=16MB oldconfig

居然编译了好久,不正常但又说不清

oldconfig: vclean before_oldconfig koldconfig

    chmod u+rx scripts/lxdialog/lxdialog

    bash scripts/Menuconfig config/config.in save

cp include/autoconf.h $(SRCBASE)/router/shared/bcmconfig.h

 

Vclean:清除了bcmcrypto  et router shared wl wps 这几个目录的编译文件(.o .d),随便把

src/router/shared/bcmconfig.h 这个也rm了,这几个目录都在src下面

 

before_oldconfig: 检查你给的PROFILE文件在bsp目录下是否存在,你要是写错了,就给你一句:“You should run make PROFILE=8MB_AP/8MB_AP_B0/16MB/A5V1/A5V2”

熟悉吧。

然后把config_$(PROFILE) 这个文件 cp 为 bsp目录下的.config

 

在这里多说几句,区分8M 、16M这个.config,除了wifi功能、应用程序外,它也起要的作用。CONFIG_ECC="ecc-bcm947xx-router-tiny" 这个变量,这个文件在bsp/arch/mips/下面,感觉很这里的虽然看不懂,但是很牛逼。

 

Koldconfig:最终在bsp目录下执行

oldconfig:

    bash $(BSPDIR)/scripts/Menuconfig $(BSPDIR)/arch/$(ARCH)/config.in save

    if [ -e $(SRCBASE)/wl/config/diffupdate.sh ] ; then \

        chmod u+rx $(SRCBASE)/wl/config/diffupdate.sh ; \

    fi

其中Menuconfig会根据bsp目录下的.config生成include/kautoconf.h (很贴心的命令)

 

接下来执行 oldconfig本身就以下几个命令:

    chmod u+rx scripts/lxdialog/lxdialog

    bash scripts/Menuconfig config/config.in save

    cp include/autoconf.h $(SRCBASE)/router/shared/bcmconfig.h

又是Menuconfig 产生include/autoconf.h,然后又cp为bcmconfig.h

在这里多说几句,如果我们想增加一个功能配置进 .config 和系统中,如CONFIG_IPSEC,

1.把这个模块加入在.config中

2.把关于这个的配置加入到config/config.in中,它是一个模板,为Menuconfig脚本使用

    comment 'IPSEC'

   bool '  Support IPSEC' CONFIG_IPSEC

3.编译时,会产生一个宏,__CONFIG_IPSEC__(由Menuconfig),生成在include/autoconf.h中。

此方法应该使用在能够模块的代码。

 

Oldconfig分析完成了,但它不是这样的工作的,如果你再来一次

Make PROFILE=16MB oldconfig

你会发现,这才是你要想的结果。

 

暂且搁置此问题。

 

2.第二步,make了

all: epivers version $(BSPDIR)/.config bsp $(obj-prelibs) $(obj-postlibs) ecos.trx ecos_lzma.trx cptftp

 

如上,就这几步了,我们一个一个来。

(1)epivers  为了epivers.h,此文件都是SDK版本的宏定义

(2)version  和上面那个感觉差不多。

(3)Bsp 这是一个小高潮,$(MAKE) -C $(BSPDIR) 我们跟进去 bsp/makefile

all: epivers $(MODULE)

 $(MODULE) 就是bsp.o

$(MODULE): subdirs $(SUB_OBJS)

$(XLD) -r $(ENDIAN) -o [email protected] $(SUB_OBJS)

其中:SUB_OBJS = $(join $(SUBDIRS), $(patsubst %, /obj-%.o, $(notdir $(SUBDIRS))))

为init/obj-init.o drivers/obj-drivers.o shared/obj-shared.o net/obj-net.o arch/mips/brcm-boards/bcm947xx/obj-bcm947xx.o即为此目录下的递归编译,

所以,当你改动到时BSP目录下的文件时,不用clean,它会帮你重新编译链接。

Driver下面包括了无线、有线的驱动。

 

(4)obj-prelibs = $(filter bcmcrypto nas eapd wlconf utils, $(obj-y)) 这个太直接了。在这里,obj-y是已经定制好的,所有要编译的目录

(5)obj-postlibs := $(filter-out $(obj-prelibs), $(obj-y)) 这个也太直接了

(6)余下几个就是镜像生成了,直接点,

ecos.gz: ecos.bin ecos.map

gzip -c9 ecos.bin > ecos.gz

 

ecos.lz: ecos.bin ecos.map

lzma e ecos.bin ecos.lz

这两个都依赖于ecos.bin ecos.map,其生成定义在rule.mak中

%.bin: %

    $(XOC) -O binary $(@:.bin=) [email protected]

就是

ecos: version bsp $(TRX_LIBS) $(TRX_OBJS) $(BSPDIR)/kernel/ecos_install/lib/target.ld

$(XCC) $(LDFLAGS) $(ECOS_GLOBAL_LDFLAGS) -o [email protected] $(TRX_OBJS) $(TRX_LIBS)

就这里了,TRX_OBJS += $(BSPDIR)/obj-bsp.o 这个包括了所有要编译的目录,以及bsp.o

TRX_LIBS = $(BSPDIR)/kernel/ecos_install/lib/libtarget.a 这也是个高潮了,kernel就是它了。

 

三、继续

 

$(BSPDIR)/kernel/ecos_install/lib/target.ld 这是个链接脚本,它在kernel/ecos_build/hal/mips/bcm47xx/v3_0/makefile 中定制了生成,

$(PREFIX)/lib/target.ld: $(wildcard $(REPOSITORY)/$(PACKAGE)/src/mips_bcm47xx.ld)

    $(CC) -E -P -Wp,-MD,target.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(CFLAGS) -o [email protected] $<

    @echo [email protected] ": \\" > $(notdir [email protected]).deps

    @tail -n +2 target.tmp >> $(notdir [email protected]).deps

    @echo >> $(notdir [email protected]).deps

@rm target.tmp

基本上是mips_bcm47xx.ld 了,应该是BRCM写好了的。

 

很多情况下缺少target.ld这个文件 ,就是你kernel没编译通过的原因。

 

产生ecos, 再生成压缩文件就不是问题了,有木有发现:libtarget.a 它是怎么来的啊,说了这么多费话,就是没提它呢?

 

世界那么大,就是少不了它:libtarget.a 神一样存在的kernel,你在哪里啊,我一直在寻找,直到我发现我一直在错过,是多么不懂得珍惜。

 

在编译目录下的Makefile中include $(BSPDIR)/kernel/ecos_install/include/pkgconf/ecos.mak

 

大胆放肆的存在:

Ecos kernel的路径:src/ecos/ecos-3.0/packages 与ecos官网上的一样。

BRCM把编译的文件放在:src/ecos/bsp/kernel目录下

在一开始它就不存在,而

$(BSPDIR)/kernel/ecos_install/include/pkgconf/ecos.mak: .config $(BSPDIR)/.config

    echo "RRRRRRRRRRRRRRRRRRouter ---------------"

    if [ ! -e $(BSPDIR)/kernel/ecos_install/include/pkgconf/ecos.mak ] ; then \

        make -C $(BSPDIR) kernel ; \

    fi

而无论你make神马,make都会去执着的寻找ecos.mak,它将成为编译的FB(第一个target),不离不弃。

make -C $(BSPDIR) kernel  在bsp目录下的Makefile中

 83 kernel: .config

 84     echo "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ kernelllllllllllll"

 85     @echo "Build eCos kernel library"

 86     if [ ! -d $(BSPDIR)/kernel ] ; then \

 87         mkdir -p $(BSPDIR)/kernel ; \

 88     fi

 89     if [ ! -e $(BSPDIR)/kernel/ecos.ecc ] ; then \

 90         cp -f $(BSPDIR)/arch/$(ARCH)/$(CONFIG_ECC) $(BSPDIR)/kernel/ecos.ecc ; \

 91     fi

 92     if [ ! -d $(BSPDIR)/kernel/ecos_install ] ; then \

 93         cp -f $(BSPDIR)/kernel/ecos.ecc $(BSPDIR)/kernel/ecos_work.ecc ; \

 94         mkdir -p $(BSPDIR)/kernel/ecos_build ; \

 95         cd $(BSPDIR)/kernel/ecos_build ; \

 96         $(ECOS_TOOLS)/ecosconfig --config=$(BSPDIR)/kernel/ecos_work.ecc --prefix=$(BSPDIR)/kernel/ecos_install tree ; \

 97         make -C $(BSPDIR)/kernel/ecos_build ; \

 98         rm -f $(BSPDIR)/kernel/ecos_work.ecc ; \

 99     fi \

 

又是一个高潮,ecosconfig产生了世界,make -C $(BSPDIR)/kernel/ecos_build 它产能万物。

它的目标只有一个:libtarget.a

于是乎完整了。

但是,在bsp目录下,同样有

include $(BSPDIR)/kernel/ecos_install/include/pkgconf/ecos.mak

80 $(BSPDIR)/kernel/ecos_install/include/pkgconf/ecos.mak: kernel

 81     echo "wwwwwwwwwwxxxxxecos.makxxxxxxxxxxyyyyyyyyyyyyyy:[email protected] : $^"

 

反复锤炼、拷打,这是不对的,何必这样紧紧相逼。

这就是什么在make PROFILE=16MB oldconfig ,会这么久。

这就是为什么会出现一次“make[1]: “kernel”是最新的”。

 

至于make clean,再次分析

clean: router-clean bsp-clean

就2步,第一步太直接了,

第二步如下

bsp-clean:

    $(MAKE) -C $(BSPDIR) clean

#roy+++,2010/09/28  

    $(RM) -fr $(BSPDIR)/kernel

$(RM) -fr $(BSPDIR)/include/netinet

我们残忍的rm了kernel,

 

第一次执行了,完全没有什么太大的异常,很痛快。

 

再执行一次,会发现不再痛快了,

include $(BSPDIR)/kernel/ecos_install/include/pkgconf/ecos.mak

80 $(BSPDIR)/kernel/ecos_install/include/pkgconf/ecos.mak: kernel

 81     echo "wwwwwwwwwwxxxxxecos.makxxxxxxxxxxyyyyyyyyyyyyyy:[email protected] : $^"

 

这一句会再次去编译kernel,原因很明显了。

还有一点:如果你编译下有一个目录名与你的Makefile中的target一样,target的时间戳即为同名目录的时间戳。

 

原来一切的生死劫是它:ecos.mak, 而不是花千骨。

 

eCos编译分解:

(1) make kernel -------> libtarget.ld

(2) make bsp -------> bsp.o

(3) Make all         ----------> ecos_lzma.trx

 

 

 

四、附

附ecos.mak的来源:

 

bsp/kernel/ecos_build/makefile中

 

build: headers $(PREFIX)/include/pkgconf/ecos.mak

 

$(PREFIX)/include/pkgconf/ecos.mak: makefile

@echo 'ECOS_GLOBAL_CFLAGS = -mips32...

 

这个ecos.mak原来是echo出的啊,

 

附 解决方案:

保密或自己想

附 make 两次clean的结果:

 

BRCM ecos编译好后,第一次 make clean:

BRCM eCos下的编译及问题

第二次clean(它在Build eCos kernel library)

BRCM eCos下的编译及问题

 

相关文章:

  • 2021-11-14
  • 2022-12-23
  • 2021-07-13
  • 2021-11-03
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-09-25
猜你喜欢
  • 2021-06-01
  • 2022-01-01
  • 2021-07-04
  • 2021-09-08
  • 2021-08-05
  • 2021-08-29
  • 2021-07-18
相关资源
相似解决方案