zoukankan      html  css  js  c++  java
  • u-boot.bin生成过程分析

    ELF格式“u-boot”文件的生成规则如下,下面对应Makefile的执行过程分别分析各个依赖。

    $(obj)u-boot:        depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)
            UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed  -n -e 's/.*(__u_boot_cmd_.*)/-u1/p'|sort|uniq`;
            cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) 
                --start-group $(__LIBS) --end-group $(PLATFORM_LIBS) 
                -Map u-boot.map -o u-boot

    1.1 depend依赖,下面的make规则有两个目标,depend和dep 。用depend和dep一样,两个名字而已。

    depend dep:
            for dir in $(SUBDIRS) ; do $(MAKE) -C $$dir _depend ; done

    对应的makefile执行过程的打印信息如下:

    for dir in tools examples post post/cpu ; do make -C $dir _depend ; done

    1.2 $(SUBDIRS)依赖,$(SUBDIRS) = tools examples post post/cpu

    $(SUBDIRS):
            $(MAKE) -C $@ all

    对应的makefile执行过程的打印信息如下:

    make -C tools all
    make -C examples all
    make -C post all
    make -C post/cpu all

    1.2.1 tool

    在tool目录下编译出以下几个可执行文件:

    img2srec

    mkimage

    envcrc

    gen_eth_addr

    bmp_logo

    1.2.2 example

    在example目录下生成可执行文件hello_world,-Ttext 0xc10000指定链接地址,-e hello_world指定函数入口地址为int hello_world (int argc, char *argv[]),

    可仿照该示例在u-boot中写自己的应用程序。

    $(AR)用来打包静态库,可参考 静态库 DIY ar crv, 下面打印信息 a - stubs.o即是$(AR)指令执行输出的日志,表示添加了stubs.o到静态库中。

    $(CC) $(CFLAGS) -c -o hello_world.o hello_world.c
    $(CC) $(CFLAGS) -c -o stubs.o stubs.c
    $(AR) crv libstubs.a stubs.o
    a - stubs.o
    $(LD) -g  -Ttext 0xc100000 
            -o hello_world -e hello_world hello_world.o libstubs.a 
            -L$($(shell dirname `$(CC) -print-libgcc-file-name`)) -lgcc
    $(OBJCOPY) -O srec hello_world hello_world.srec 2>/dev/null
    $(OBJCOPY) -O binary hello_world hello_world.bin 2>/dev/null

    1.2.3 post

    生成静态库libpost.a。从下面的信息可以大概了解libpost.a的组成及提供的功能。

    $(CC) $(AFLAGS) -c -o cache_8xx.o cache_8xx.S
    $(CC) $(CFLAGS) -c -o cache.o cache.c
    $(CC) $(CFLAGS) -c -o codec.o codec.c
    $(CC) $(CFLAGS) -c -o cpu.o cpu.c
    $(CC) $(CFLAGS) -c -o dsp.o dsp.c
    $(CC) $(CFLAGS) -c -o ether.o ether.c
    $(CC) $(CFLAGS) -c -o i2c.o i2c.c
    $(CC) $(CFLAGS) -c -o memory.o memory.c
    $(CC) $(CFLAGS) -c -o post.o post.c
    $(CC) $(CFLAGS) -c -o rtc.o rtc.c
    $(CC) $(CFLAGS) -c -o spr.o spr.c
    $(CC) $(CFLAGS) -c -o sysmon.o sysmon.c
    $(CC) $(CFLAGS) -c -o tests.o tests.c
    $(CC) $(CFLAGS) -c -o uart.o uart.c
    $(CC) $(CFLAGS) -c -o usb.o usb.c
    $(CC) $(CFLAGS) -c -o watchdog.o watchdog.c
    $(AR) crv libpost.a stubs.o cache_8xx.o 
            cache.o codec.o cpu.o dsp.o ether.o 
            i2c.o memory.o post.o rtc.o 
            spr.o sysmon.o tests.o uart.o 
            usb.o watchdog.o

    1.2.4 post/cpu

    生成静态库libcpu.a。从下面的信息可以大概了解libcpu.a的组成及提供的功能。

    $(CC) $(AFLAGS) -c -o asm.o asm.S
    $(CC) $(CFLAGS) -c -o cmp.o cmp.c
    $(CC) $(CFLAGS) -c -o cmpi.o cmpi.c
    $(CC) $(CFLAGS) -c -o two.o two.c
    $(CC) $(CFLAGS) -c -o twox.o twox.c
    $(CC) $(CFLAGS) -c -o three.o three.c
    $(CC) $(CFLAGS) -c -o threex.o threex.c
    $(CC) $(CFLAGS) -c -o threei.o threei.c
    $(CC) $(CFLAGS) -c -o andi.o andi.c
    $(CC) $(CFLAGS) -c -o srawi.o srawi.c
    $(CC) $(CFLAGS) -c -o rlwnm.o rlwnm.c
    $(CC) $(CFLAGS) -c -o rlwinm.o rlwinm.c
    $(CC) $(CFLAGS) -c -o rlwimi.o rlwimi.c
    $(CC) $(CFLAGS) -c -o store.o store.c
    $(CC) $(CFLAGS) -c -o load.o load.c
    $(CC) $(CFLAGS) -c -o cr.o cr.c
    $(CC) $(CFLAGS) -c -o b.o b.c
    $(CC) $(CFLAGS) -c -o multi.o multi.c
    $(CC) $(CFLAGS) -c -o string.o string.c
    $(CC) $(CFLAGS) -c -o complex.o complex.c
    $(AR) crv libcpu.a      asm.o 
                cmp.o cmpi.o two.o twox.o three.o threex.o threei.o 
                andi.o srawi.o rlwnm.o rlwinm.o rlwimi.o 
                store.o load.o cr.o b.o multi.o string.o complex.o

    1.3 $(OBJS)依赖,$(OBJS) = cpu/s3c64xx/start.o

    $(OBJS):
            $(MAKE) -C cpu/$(CPU) $(if $(REMOTE_BUILD),$@,$(notdir $@))

    对应的makefile执行过程的打印信息如下:

    make -C cpu/s3c64xx start.o
    /usr/local/arm/4.3.2/bin/arm-linux-gcc  -D__ASSEMBLY__ -g  -Os   -fno-strict-aliasing  -fno-common -ffixed-r8 -msoft-float  -D__KERNEL__ -DTEXT_BASE=0xCFE00000  -I/home/yjg/arm6410/qudong/01-uboot/uboot_ok6410/include -fno-builtin -ffreestanding -nostdinc -isystem /usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/include -pipe  -DCONFIG_ARM -D__ARM__ -march=armv5t -c -o start.o start.S

    上面最后一条执行即

     arm-linux-gcc $(AFLAGS) -c -o start.o start.S

    1.4 $(LIBS)依赖 ,$(LIBS)展开如下:

    $(LIBS) = 

    lib_generic/libgeneric.a
    board/samsung/smdk6410/libsmdk6410.a
    cpu/s3c64xx/libs3c64xx.a
    cpu/s3c64xx/s3c6410/libs3c6410.a
    lib_arm/libarm.a
    fs/cramfs/libcramfs.a
    fs/fat/libfat.a
    fs/fdos/libfdos.a
    fs/jffs2/libjffs2.a
    fs/reiserfs/libreiserfs.a
    fs/ext2/libext2fs.a
    net/libnet.a
    disk/libdisk.a
    rtc/librtc.a
    dtt/libdtt.a
    drivers/libdrivers.a
    drivers/nand/libnand.a
    drivers/nand_legacy/libnand_legacy.a
    drivers/onenand/libonenand.a
    drivers/sk98lin/libsk98lin.a
    post/libpost.a
    post/cpu/libcpu.a
    common/libcommon.a

    其中与平台相关的是下面几个库

    board/samsung/smdk6410/libsmdk6410.a 
    cpu/s3c64xx/libs3c64xx.a 
    cpu/s3c64xx/s3c6410/libs3c6410.a 
    lib_arm/libarm.a 

    该目标的规则如下,LIBS表示的每个库文件,都是由进入相应的子目录执行“make”命令编译得到的。

    $(LIBS):
            $(MAKE) -C $(dir $(subst $(obj),,$@))

    例如,对于LIBS中的“common/libcommon.a”成员,程序将进入common目录执行make命令,生成libcommon.a,最终生成libcommon.a的链接命令如下:

    /usr/local/arm/4.3.2/bin/arm-linux-ar crv libcommon.a main.o ACEX1K.o altera.o bedbug.o circbuf.o cmd_ace.o cmd_autoscript.o cmd_bdinfo.o cmd_bedbug.o cmd_bmp.o cmd_boot.o cmd_bootm.o cmd_cache.o cmd_console.o cmd_date.o cmd_dcr.o cmd_diag.o cmd_display.o cmd_doc.o cmd_dtt.o cmd_eeprom.o cmd_elf.o cmd_ext2.o cmd_fat.o cmd_fdc.o cmd_fdos.o cmd_flash.o cmd_fpga.o cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o cmd_load.o cmd_log.o cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o cmd_nand.o cmd_net.o cmd_nvedit.o cmd_pci.o cmd_pcmcia.o cmd_portio.o cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o cmd_usb.o cmd_vfd.o command.o console.o cyclon2.o devices.o dlmalloc.o docecc.o environment.o env_common.o env_nand.o env_dataflash.o env_flash.o env_eeprom.o env_nvram.o env_nowhere.o env_movi.o env_onenand.o exports.o flash.o fpga.o ft_build.o hush.o kgdb.o lcd.o lists.o lynxkdi.o memsize.o miiphybb.o miiphyutil.o s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o spartan3.o usb.o usb_kbd.o usb_storage.o virtex2.o xilinx.o crc16.o xyzModem.o cmd_mac.o cmd_onenand.o cmd_usbd.o cmd_movi.o

    上面执行的即为 

    arm-linux-ar crv $@ $^

    以上各种库所包含的*.o文件整理如下:

    lib_generic/libgeneric.a :
        bzlib.o bzlib_crctable.o bzlib_decompress.o 
        bzlib_randtable.o bzlib_huffman.o 
        crc32.o ctype.o display_options.o div64.o ldiv.o 
        string.o vsprintf.o zlib.o    
          
    board/samsung/smdk6410/libsmdk6410.a :
        smdk6410.o flash.o 
        lowlevel_init.o
        
    cpu/s3c64xx/libs3c64xx.a :
        nand_cp.o i2c.o serial.o  usb_ohci.o 
        interrupts.o cpu.o nand.o onenand.o onenand_cp.o 
        usbd-otg-hs.o hs_mmc.o movi.o
        
    cpu/s3c64xx/s3c6410/libs3c6410.a :
        cpu_init.o 
        speed.o
        
    lib_arm/libarm.a :
        _ashldi3.o _ashrdi3.o _divsi3.o _modsi3.o _udivsi3.o _umodsi3.o 
        armlinux.o board.o 
        cache.o div0.o
        
    fs/cramfs/libcramfs.a :
        cramfs.o uncompress.o
        
    fs/fat/libfat.a :
         fat.o file.o
         
    fs/fdos/libfdos.a :
        fat.o vfat.o dev.o fdos.o fs.o subdir.o
        
    fs/jffs2/libjffs2.a :
        jffs2_1pass.o compr_rtime.o compr_rubin.o compr_zlib.o mini_inflate.o 
        compr_lzo.o compr_lzari.o
            
    fs/reiserfs/libreiserfs.a:
        reiserfs.o dev.o mode_string.o
         
    fs/ext2/libext2fs.a 
        ext2fs.o dev.o
        
    net/libnet.a :
        net.o tftp.o bootp.o rarp.o eth.o nfs.o sntp.o
        
    disk/libdisk.a :
        part.o part_mac.o part_dos.o part_iso.o part_amiga.o
        
    rtc/librtc.a :
        date.o   
        bf533_rtc.o ds12887.o ds1302.o ds1306.o ds1307.o 
        ds1337.o ds1374.o ds1556.o ds164x.o ds174x.o 
        m41t11.o max6900.o m48t35ax.o mc146818.o mk48t59.o 
        mpc5xxx.o mpc8xx.o pcf8563.o s3c24x0_rtc.o rs5c372.o 
        s3c24xx_rtc.o s3c64xx_rtc.o
        
    dtt/libdtt.a :
        lm75.o ds1621.o adm1021.o
        
    drivers/libdrivers.a :
          3c589.o 5701rls.o ali512x.o atmel_usart.o 
          bcm570x.o bcm570x_autoneg.o cfb_console.o cfi_flash.o 
          cs8900.o ct69000.o dataflash.o dc2114x.o dm9000x.o 
          e1000.o eepro100.o 
          i8042.o inca-ip_sw.o keyboard.o 
          lan91c96.o 
          natsemi.o ne2000.o netarm_eth.o netconsole.o 
          ns16550.o ns8382x.o ns87308.o ns7520_eth.o omap1510_i2c.o 
          omap24xx_i2c.o pci.o pci_auto.o pci_indirect.o 
          pcnet.o plb2800_eth.o 
          ps2ser.o ps2mult.o pc_keyb.o 
          rtl8019.o rtl8139.o rtl8169.o 
          s3c4510b_eth.o s3c4510b_uart.o 
          sed13806.o sed156x.o 
          serial.o serial_max3100.o 
          serial_pl010.o serial_pl011.o serial_xuartlite.o 
          sl811_usb.o sm501.o smc91111.o smiLynxEM.o 
          status_led.o sym53c8xx.o ahci.o 
          ti_pci1410a.o tigon3.o tsec.o 
          usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbtty.o 
          videomodes.o w83c553f.o 
          ks8695eth.o 
          pxa_pcmcia.o mpc8xx_pcmcia.o tqm8xx_pcmcia.o    
          rpx_pcmcia.o 
          fsl_i2c.o 
          smc911x.o
          
    drivers/nand/libnand.a :
        nand.o nand_base.o nand_ids.o nand_ecc.o nand_bbt.o nand_util.o
        
    drivers/nand_legacy/libnand_legacy.a :
        nand_legacy.o
        
    drivers/onenand/libonenand.a :
        onenand.o generic.o s3c_onenand.o
        
    drivers/sk98lin/libsk98lin.a :
        skge.o skaddr.o skgehwt.o skgeinit.o skgepnmi.o skgesirq.o 
        ski2c.o sklm80.o skqueue.o skrlmt.o sktimer.o skvpd.o 
        skxmac2.o skcsum.o
        
    post/libpost.a :
        stubs.o cache_8xx.o 
        cache.o codec.o cpu.o dsp.o ether.o 
        i2c.o memory.o post.o rtc.o 
        spr.o sysmon.o tests.o uart.o 
        usb.o watchdog.o
        
    post/cpu/libcpu.a :
        asm.o 
        cmp.o cmpi.o two.o twox.o three.o threex.o threei.o 
        andi.o srawi.o rlwnm.o rlwinm.o rlwimi.o 
        store.o load.o cr.o b.o multi.o string.o complex.o
        
    common/libcommon.a :
          main.o ACEX1K.o altera.o bedbug.o circbuf.o 
          cmd_ace.o cmd_autoscript.o 
          cmd_bdinfo.o cmd_bedbug.o cmd_bmp.o cmd_boot.o cmd_bootm.o 
          cmd_cache.o cmd_console.o 
          cmd_date.o cmd_dcr.o cmd_diag.o cmd_display.o cmd_doc.o cmd_dtt.o 
          cmd_eeprom.o cmd_elf.o cmd_ext2.o 
          cmd_fat.o cmd_fdc.o cmd_fdos.o cmd_flash.o cmd_fpga.o 
          cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o 
          cmd_load.o cmd_log.o 
          cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o 
          cmd_nand.o cmd_net.o cmd_nvedit.o 
          cmd_pci.o cmd_pcmcia.o cmd_portio.o 
          cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o 
          cmd_usb.o cmd_vfd.o 
          command.o console.o cyclon2.o devices.o dlmalloc.o docecc.o 
          environment.o env_common.o 
          env_nand.o env_dataflash.o env_flash.o env_eeprom.o 
          env_nvram.o env_nowhere.o env_movi.o env_onenand.o 
          exports.o 
          flash.o fpga.o ft_build.o 
          hush.o kgdb.o lcd.o lists.o lynxkdi.o 
          memsize.o miiphybb.o miiphyutil.o 
          s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o spartan3.o 
          usb.o usb_kbd.o usb_storage.o 
          virtex2.o xilinx.o crc16.o xyzModem.o cmd_mac.o cmd_onenand.o 
          cmd_usbd.o cmd_movi.o
    lib-components

    1.5 $(LDSCRIPT)依赖,展开为$(LDSCRIPT) =  /home/yjg/arm6410/qudong/01-uboot/uboot_ok6410/board/samsung/smdk6410/u-boot.lds

    OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
    /*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
    OUTPUT_ARCH(arm)
    ENTRY(_start)
    SECTIONS
    {
        . = 0x00000000;
    
        . = ALIGN(4);
        .text      :
        {
          cpu/s3c64xx/start.o    (.text)
          cpu/s3c64xx/s3c6410/cpu_init.o    (.text)
          cpu/s3c64xx/onenand_cp.o    (.text)
          cpu/s3c64xx/nand_cp.o    (.text)
          cpu/s3c64xx/movi.o (.text)
          *(.text)
          lib_arm/div0.o
        }
    
        . = ALIGN(4);
        .rodata : { *(.rodata) }
    
        . = ALIGN(4);
        .data : { *(.data) }
    
        . = ALIGN(4);
        .got : { *(.got) }
    
        __u_boot_cmd_start = .;
        .u_boot_cmd : { *(.u_boot_cmd) }
        __u_boot_cmd_end = .;
    
        . = ALIGN(4);
        .mmudata : { *(.mmudata) }
    
        . = ALIGN(4);
        __bss_start = .;
        .bss : { *(.bss) }
        _end = .;
    }
    u-boot.lds

    1.6 最后分析生成u-boot镜像的命令 

            UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed  -n -e 's/.*(__u_boot_cmd_.*)/-u1/p'|sort|uniq`;
            cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) 
                --start-group $(__LIBS) --end-group $(PLATFORM_LIBS) 
                -Map u-boot.map -o u-boot

    对应的makefile执行过程的打印信息如下:

    1.UNDEF_SYM=`/usr/local/arm/4.3.2/bin/arm-linux-objdump -x lib_generic/libgeneric.a board/samsung/smdk6410/libsmdk6410.a cpu/s3c64xx/libs3c64xx.a cpu/s3c64xx/s3c6410/libs3c6410.a lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a net/libnet.a disk/libdisk.a rtc/librtc.a dtt/libdtt.a drivers/libdrivers.a drivers/nand/libnand.a drivers/nand_legacy/libnand_legacy.a drivers/onenand/libonenand.a drivers/sk98lin/libsk98lin.a post/libpost.a post/cpu/libcpu.a common/libcommon.a |sed  -n -e 's/.*(__u_boot_cmd_.*)/-u1/p'|sort|uniq`; 
    2.cd /home/yjg/arm6410/qudong/01-uboot/uboot_ok6410 && /usr/local/arm/4.3.2/bin/arm-linux-ld -Bstatic -T /home/yjg/arm6410/qudong/01-uboot/uboot_ok6410/board/samsung/smdk6410/u-boot.lds -Ttext 0xCFE00000  $UNDEF_SYM cpu/s3c64xx/start.o 
            --start-group lib_generic/libgeneric.a board/samsung/smdk6410/libsmdk6410.a cpu/s3c64xx/libs3c64xx.a cpu/s3c64xx/s3c6410/libs3c6410.a lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a net/libnet.a disk/libdisk.a rtc/librtc.a dtt/libdtt.a drivers/libdrivers.a drivers/nand/libnand.a drivers/nand_legacy/libnand_legacy.a drivers/onenand/libonenand.a drivers/sk98lin/libsk98lin.a post/libpost.a post/cpu/libcpu.a common/libcommon.a --end-group -L /usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/armv4t -lgcc 
            -Map u-boot.map -o u-boot

    上述最后的链接过程等价于

    arm-linux-ld $(LDFLAGS) $$UNDEF_SYM $(__OBJS) 
                --start-group $(__LIBS) --end-group $(PLATFORM_LIBS) -Map u-boot.map -o u-boot

    其中 LDFLAGS : -Bstatic -T /home/yjg/arm6410/qudong/01-uboot/uboot_ok6410/board/samsung/smdk6410/u-boot.lds -Ttext 0xCFE00000

    -Bstatic表示使用静态方式链接库文件

    -Tu-boot.lds指定连接器脚本文件

    -Ttext 0xCFE00000指定代码段的起始地址

    --start-group...--end-group指定一组需要链接的库文件

    链接器LD去load对应的库(lib,module)的时候,可能会遇到这些情况:
    
    (1)A库,引用了B库中funcInB(),但是先ld A库,导致找不到对应的funInB而链接报错
    
    (2)A库和B库,互相都包含对应所引用到的函数,即互相引用/循环引用,ld编译器会因为找不到A库中所引用的B库的中的函数(或者反过来B库引用A库中的函数)而报错。
    
    此时,用"–start-group和 –end-group“,通知ld链接器,去在–start-group和–end-group中间的这些库函数,多花点时间,对于这些库,都从头到尾,多查几遍,去找找那些还没有找到的所引用的函数,是不是在另外的库中有这些函数,以此解决:
    1)A库引用到了后来才加载的B库中的函数
    
    (2)解决循环引用

    -Map u-boot.map表示产生符号表u-boot.map

    1.7 u-boot转换为其它格式

    生成u-boot.bin

    $(obj)u-boot.bin:    $(obj)u-boot
            $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
    
    /usr/local/arm/4.3.2/bin/arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin

    生成u-boot.srec

    $(obj)u-boot.srec:    $(obj)u-boot
            $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@
    
    /usr/local/arm/4.3.2/bin/arm-linux-objcopy --gap-fill=0xff -O srec u-boot u-boot.srec

    生成u-boot.hex

    $(obj)u-boot.hex:    $(obj)u-boot
            $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@
    
    /usr/local/arm/4.3.2/bin/arm-linux-objcopy --gap-fill=0xff -O ihex u-boot u-boot.hex
  • 相关阅读:
    Warsaw University Contest Petrozavodsk, Thursday, January 31, 2008 J题,Gym100096J
    FZU2282--错排公式
    POJ 3468 区间加减 区间求和
    HDU 1556 树状数组
    HDU 5480 树状数组
    Tomcat
    Nginx
    Centos7安装后无法联网
    限制服务器ssh登录及防御措施
    DHCP
  • 原文地址:https://www.cnblogs.com/yangjiguang/p/7822566.html
Copyright © 2011-2022 走看看