Uboot优美代码赏析1:目录结构和malkefile分析

关于Uboot自己选的版本是目前最新的2011.06,官方网址为:http://www.denx.de/wiki/U-Boot/WebHome,下面的一些内容主要翻译自顶层目录的 README 。

U-Boot是一种基于PowerPC, ARM, MIPS 或者其他处理器架构的嵌入式开发板的启动引导程序(boot loader),boot loader是可以被安装在作为引导的ROM上,实现初始化和测试硬件,和下载与运行应用的代码。

U-Boot的开发与Linux紧密相连:部分代码是取自Linux的源代码,比如我们使用共同的头文件定义,同时特别提供了可以用于启动Linux内核的功能。

DENX注重于去使这个软件很容易去配置和拓展。比如,为了便于用户增加新的命令,所以的监视命令都是用同样的接口和架构实现的。另外,很少使用的命令可以动态地进行加载执行,比如硬件测试功能。

下面介绍目录结构:

/arch /存放特定架构的实现文件,系统的启动代码一般在这里的start.S中

  /arm /Arm架构

    /cpu /CPU相关文件

      /arm720t /ARM 720 CPUs

      /arm920t /ARM 920 CPUs

/at91rm9200/Atmel AT91RM9200 CPU

/imx /Freescale MC9328 i.MX CPUs

/s3c24x0 /Samsung S3C24X0 CPUs

      /arm925t /ARM 925 CPUs

      /arm926ejs /ARM 926 CPUs

      /arm1136 /ARM 1136 CPUs

      /ixp /Intel XScale IXP CPUs

      /pxa /Intel XScale PXA CPUs

      /s3c44b0 /Samsung S3C44B0 CPUs

      /sa1100 /Intel StrongARM SA1100 CPUs

    /lib /CPU library files

  /avr32 /AVR32架构

    /cpu /CPU specific files

    /lib /CPU library files

  /blackfin /Blackfin架构

  /x86 /x86 架构

  /m68k /m68k 架构

  /microblaze /microblaze 架构

  /mips /MIPS 架构

  /nios2 /NIOS2 架构

  /powerpc /PowerPC 架构

  /sh /SH 架构

  /sparc /SPARC 架构

/api /为拓展应用准备的,与硬件和架构无关的接口定义文件

/board /常用主板的文件,我们增加的主板文件也需要在这里新增目录后进行开发

/common /与架构无关的通用接口

/disk /实现磁盘分区的接口

/doc /常见功能和问题的说明文档

/drivers /常用的设备驱动程序

/examples /Demo Example code

/fs /文件系统(cramfs, ext2, jffs2, etc.)

/include /全局需要的头文件定义在这儿

/lib /所以架构通用的ib

  /libfdt Library files to support flattened device trees

  /lzma Library files to support LZMA decompression

  /lzo Library files to support LZO decompression

/net /网络相关代码

/post /Power On Self Test 开机自检

/rtc /实时时钟驱动

/tools /Tools to build S-Record or U-Boot images, etc.

README再往下就是介绍各个功能宏,便于我们进行裁剪。

下面通过smdk2410的编译来分析MAKEFILE关系。

我们知道编译smdk2410要先执行make smdk2410_config,然后执行make,生成该主板的u-boot.bin,

如果不先进行配置,直接make会报错:System not configured - see README

所以主makefile有如下大的框架:

ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))    #line 145 include/config.mk文件存在 wildcard : 扩展通配符,找到所有通配的文件并返回

else # !config.mk  #line 530 include/config.mk文件不存在

@echo "System not configured - see README" >&2

@ exit 1

    所以我们先看如何执行make smdk2410_config,要先找到目标smdk2410_config定义的地方,makefile中定义很多配置的目标,但没有这个目标,所以我们注意到

%_config:: unconfig

@$(MKCONFIG) -A $(@:_config=)

sinclude $(obj).boards.depend

$(obj).boards.depend: boards.cfg  #读取boards.cfg,生成所有XXXX_config,SMDK2410_Config就在这里产生

awk '(NF && $$1 !~ /^#/) { print $$1 ": " $$1 "_config; $$(MAKE)" }' $< > $@

注意到主目录下的.boards.depend文件和boards.cfg文件,MKCONFIG由

MKCONFIG := $(SRCTREE)/mkconfig

export MKCONFIG

定义

所以主目录下mkconfig文件来生成include下config.mk和config.h,注意里面有一个 cd ./include,来进入include文件夹的。

进行到此,例如生成了如下config.mk:

ARCH = arm

CPU = arm920t

BOARD = smdk2410

VENDOR = samsung

SOC = s3c24x0

生成了如下config.h:

/* Automatically generated - do not edit */

#define CONFIG_BOADDIR board/samsung/smdk2410 //  BOARDDIR=${vendor}/${board}

#include <config_cmd_defaults.h>

#include <config_default.h>

#include <configs/smdk2410.h>

#include <asm/config.h> // ln -s ${SRCTREE}/arch/${arch}/include/asm asm

config.h约束了全局使用到的功能。

下面分析make命令:

先创建两个实目标(非.PHONY ):

TIMESTAMP_FILE = $(obj)include/timestamp_autogenerated.h

$(TIMESTAMP_FILE):

@LC_ALL=C date +'#define U_BOOT_DATE "%b %d %C%y"' > $@

@LC_ALL=C date +'#define U_BOOT_TIME "%T"' >> $@

VERSION_FILE = $(obj)include/version_autogenerated.h

$(VERSION_FILE):

@( localvers='$(shell $(TOPDIR)/tools/setlocalversion $(TOPDIR))' ; \

  printf '#define PLAIN_VERSION "%s%s"\n' \

"$(U_BOOT_VERSION)" "$${localvers}" ; \

  printf '#define U_BOOT_VERSION "U-Boot %s%s"\n' \

"$(U_BOOT_VERSION)" "$${localvers}" ; \

) > $@.tmp

@( printf '#define CC_VERSION_STRING "%s"\n' \

'$(shell $(CC) --version | head -n 1)' )>>  $@.tmp

@( printf '#define LD_VERSION_STRING "%s"\n' \

'$(shell $(LD) -v | head -n 1)' )>>  $@.tmp

@cmp -s $@ $@.tmp && rm -f $@.tmp || mv -f $@.tmp $@

然后执行第一个目标:

all: $(ALL)

ALL目标又依赖与:

# Always append ALL so that arch config.mk's can add custom ones

ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map

ifeq ($(CONFIG_NAND_U_BOOT),y)

ALL += $(obj)u-boot-nand.bin

endif

ifeq ($(CONFIG_ONENAND_U_BOOT),y)

ALL += $(obj)u-boot-onenand.bin

ONENAND_BIN ?= $(obj)onenand_ipl/onenand-ipl-2k.bin

endif

ifeq ($(CONFIG_MMC_U_BOOT),y)

ALL += $(obj)mmc_spl/u-boot-mmc-spl.bin

endif

各目标又依赖与:

$(obj)u-boot.hex: $(obj)u-boot

$(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@

$(obj)u-boot.srec: $(obj)u-boot

$(OBJCOPY) -O srec $< $@

$(obj)u-boot.bin: $(obj)u-boot

$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@

$(BOARD_SIZE_CHECK)

$(obj)u-boot.ldr: $(obj)u-boot

$(CREATE_LDR_ENV)

$(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS)

$(BOARD_SIZE_CHECK)

$(obj)u-boot.ldr.hex: $(obj)u-boot.ldr

$(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@ -I binary

$(obj)u-boot.ldr.srec: $(obj)u-boot.ldr

$(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ -I binary

$(obj)u-boot.img: $(obj)u-boot.bin

$(obj)tools/mkimage -A $(ARCH) -T firmware -C none \

-a $(CONFIG_SYS_TEXT_BASE) -e 0 \

-n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \

sed -e 's/"[]*$$/ for $(BOARD) board"/') \

-d $< $@

$(obj)u-boot.imx:       $(obj)u-boot.bin

$(obj)tools/mkimage -n  $(CONFIG_IMX_CONFIG) -T imximage \

-e $(CONFIG_SYS_TEXT_BASE) -d $< $@

$(obj)u-boot.kwb:       $(obj)u-boot.bin

$(obj)tools/mkimage -n $(CONFIG_SYS_KWD_CONFIG) -T kwbimage \

-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) -d $< $@

$(obj)u-boot.sha1: $(obj)u-boot.bin

$(obj)tools/ubsha1 $(obj)u-boot.bin

$(obj)u-boot.dis: $(obj)u-boot

$(OBJDUMP) -d $< > $@

$(obj)u-boot目标又依赖与:

$(obj)u-boot: depend \

$(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds

$(GEN_UBOOT)

SUBDIRS目标:

# The "tools" are needed early, so put this first

# Don't include stuff already done in $(LIBS)

SUBDIRS = tools \

 examples/standalone \

 examples/api

$(SUBDIRS): depend

$(MAKE) -C $@ all

OBJS目标:

OBJS  = $(CPUDIR)/start.o #这个是系统总入口

ifeq ($(CPU),x86)

OBJS += $(CPUDIR)/start16.o

OBJS += $(CPUDIR)/resetvec.o

endif

ifeq ($(CPU),ppc4xx)

OBJS += $(CPUDIR)/resetvec.o

endif

ifeq ($(CPU),mpc85xx)

OBJS += $(CPUDIR)/resetvec.o

endif

OBJS := $(addprefix $(obj),$(OBJS))

$(OBJS): depend

$(MAKE) -C $(CPUDIR) $(if $(REMOTE_BUILD),$@,$(notdir $@)) #编译notdir OBJS各项

LIBBOARD目标:

LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).o

LIBBOARD := $(addprefix $(obj),$(LIBBOARD))

$(LIBBOARD): depend $(LIBS)

$(MAKE) -C $(dir $(subst $(obj),,$@)) #将$(obj)和LIBBOARD联合后取目录编译

LIBS目标:

LIBS  = lib/libgeneric.o

LIBS += lib/lzma/liblzma.o

LIBS += lib/lzo/liblzo.o

LIBS += lib/zlib/libz.o

LIBS += $(shell if [ -f board/$(VENDOR)/common/Makefile ]; then echo \

"board/$(VENDOR)/common/lib$(VENDOR).o"; fi)

LIBS += $(CPUDIR)/lib$(CPU).o

ifdef SOC

LIBS += $(CPUDIR)/$(SOC)/lib$(SOC).o

endif

ifeq ($(CPU),ixp)

LIBS += arch/arm/cpu/ixp/npe/libnpe.o

endif

LIBS += arch/$(ARCH)/lib/lib$(ARCH).o

LIBS += fs/cramfs/libcramfs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o \

fs/reiserfs/libreiserfs.o fs/ext2/libext2fs.o fs/yaffs2/libyaffs2.o \

fs/ubifs/libubifs.o

LIBS += net/libnet.o

LIBS += disk/libdisk.o

LIBS += drivers/bios_emulator/libatibiosemu.o

LIBS += drivers/block/libblock.o

LIBS += drivers/dma/libdma.o

LIBS += drivers/fpga/libfpga.o

LIBS += drivers/gpio/libgpio.o

LIBS += drivers/hwmon/libhwmon.o

LIBS += drivers/i2c/libi2c.o

LIBS += drivers/input/libinput.o

LIBS += drivers/misc/libmisc.o

LIBS += drivers/mmc/libmmc.o

LIBS += drivers/mtd/libmtd.o

LIBS += drivers/mtd/nand/libnand.o

LIBS += drivers/mtd/onenand/libonenand.o

LIBS += drivers/mtd/ubi/libubi.o

LIBS += drivers/mtd/spi/libspi_flash.o

LIBS += drivers/net/libnet.o

LIBS += drivers/net/phy/libphy.o

LIBS += drivers/pci/libpci.o

LIBS += drivers/pcmcia/libpcmcia.o

LIBS += drivers/power/libpower.o

LIBS += drivers/spi/libspi.o

ifeq ($(CPU),mpc83xx)

LIBS += drivers/qe/libqe.o

LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o

endif

ifeq ($(CPU),mpc85xx)

LIBS += drivers/qe/libqe.o

LIBS += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o

LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o

endif

ifeq ($(CPU),mpc86xx)

LIBS += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o

LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o

endif

LIBS += drivers/rtc/librtc.o

LIBS += drivers/serial/libserial.o

LIBS += drivers/twserial/libtws.o

LIBS += drivers/usb/eth/libusb_eth.o

LIBS += drivers/usb/gadget/libusb_gadget.o

LIBS += drivers/usb/host/libusb_host.o

LIBS += drivers/usb/musb/libusb_musb.o

LIBS += drivers/usb/phy/libusb_phy.o

LIBS += drivers/video/libvideo.o

LIBS += drivers/watchdog/libwatchdog.o

LIBS += common/libcommon.o

LIBS += lib/libfdt/libfdt.o

LIBS += api/libapi.o

LIBS += post/libpost.o

ifeq ($(SOC),omap3)

LIBS += $(CPUDIR)/omap-common/libomap-common.o

endif

ifeq ($(SOC),omap4)

LIBS += $(CPUDIR)/omap-common/libomap-common.o

endif

ifeq ($(SOC),s5pc1xx)

LIBS += $(CPUDIR)/s5p-common/libs5p-common.o

endif

ifeq ($(SOC),s5pc2xx)

LIBS += $(CPUDIR)/s5p-common/libs5p-common.o

endif

LIBS := $(addprefix $(obj),$(sort $(LIBS)))

$(LIBS): depend $(SUBDIRS)

$(MAKE) -C $(dir $(subst $(obj),,$@)) #将$(obj)和LIBS联合后取目录编译

其他的目标比较好找。

依此往上,最后生成u-boot.bin

后续希望自己能完成:

Uboot硬件启动  u-boot-2011.06\arch\arm\cpu\arm920t\start.S

Uboot系统各模块初始化

各模块Command交互

Uboot优美代码赏析1.1:分散加载表u-boot.lds

1.位置:

board\samsung\smdk6410\u-boot.lds

 

2.内容分析:

OUTPUT_FORMAT("elf32-littlearm""elf32-littlearm""elf32-littlearm")
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
    }

// const 常量数据段
    . = ALIGN(4);
    .rodata : { *(.rodata) }

// staitc/global 常量段
    . = ALIGN(4);
    .data : { *(.data) }

//这个未使用
    . = ALIGN(4);
    .got : { *(.got) }

//命令定义段
    __u_boot_cmd_start = .;
    .u_boot_cmd : { *(.u_boot_cmd) }
    __u_boot_cmd_end = .;

//mmudata段 mmu_table
    . = ALIGN(4);
    .mmudata : { *(.mmudata) }

//堆栈段/内部临时变量段
    . = ALIGN(4);
    __bss_start = .;
    .bss : { *(.bss) }
    _end = .;
}

 

下面结合 编译后根目录下生成的u-boot.mapSystem.map分析:
3  .text 段分析

只分析cpu/s3c64xx/start.o    (.text)
u-boot.map中:

Name             Origin             Length             Attributes
 cpu/s3c64xx/start.o(.text)
 .text          0xc7e00000      0x480 cpu/s3c64xx/start.o
                0xc7e00040                _end_vect
                0xc7e0017c                theLastJump
                0xc7e00460                arm1136_cache_flush
                0xc7e0004c                _bss_start
                0xc7e00050                _bss_end
                0xc7e00048                _armboot_start
                0xc7e00120                copy_from_nand
                0xc7e00000                _start
 cpu/s3c64xx/s3c6410/cpu_init.o(.text)
 .text          0xc7e00480      0x15c cpu/s3c64xx/s3c6410/cpu_init.o
                0xc7e005b0                cleanFlushCache
                0xc7e005a4                cleanFlushDCache
                0xc7e00480                mem_ctrl_asm_init
                0xc7e00598                cleanDCache
 cpu/s3c64xx/onenand_cp.o(.text)
 .text          0xc7e005dc        0x0 cpu/s3c64xx/onenand_cp.o

 

其中cpu_init.o的起始地址0xc7e00480 - start.o的起始地址0xc7e00000 = start.o的长度0x480
start.o的起始地址定义在board\samsung\smdk6410\config.mkTEXT_BASE

 

System.map中:

c7e00000 T _start
c7e00020 t _undefined_instruction
c7e00024 t _software_interrupt
c7e00028 t _prefetch_abort
c7e0002c t _data_abort
c7e00030 t _not_used
c7e00034 t _irq
c7e00038 t _fiq
c7e0003c t _pad
c7e00040 T _end_vect
c7e00040 t _TEXT_BASE
c7e00044 t _TEXT_PHY_BASE
c7e00048 T _armboot_start
c7e0004c T _bss_start
c7e00050 T _bss_end
c7e00054 t reset
c7e00064 t cpu_init_crit
c7e000b8 t after_copy
c7e000b8 t enable_mmu
c7e000d8 t mmu_on
c7e000f4 t skip_hw_init
c7e000f4 t stack_setup
c7e000f8 t clear_bss
c7e00104 t clbss_l
c7e00118 t _start_armboot
c7e0011c t _mmu_table_base
c7e00120 T copy_from_nand
c7e0016c t copy_failed
c7e00174 t compare_failed
c7e0017c T theLastJump
c7e00198 t phy_last_jump
c7e001c0 t undefined_instruction
c7e00220 t software_interrupt
c7e00280 t prefetch_abort
c7e002e0 t data_abort
c7e00340 t not_used
c7e003a0 t irq
c7e00400 t fiq
c7e00460 T arm1136_cache_flush
c7e00480 T mem_ctrl_asm_init

 

T代表是public的,t代表是local/static

 

 

4.其他段的定义和生成逻辑同理通过u-boot.map去查

.text 段存放代码.o (.text)的起始地址,长度,与未声明为static的函数符号地址(同上)
.rodata 段存放声明为const的变量及其他预先声明在等号右边的字串数据(.rodata.str1.1 

 

 .rodata        0xc7e238a4       0x33 lib_arm/libarm.a(board.o)
                0xc7e238a4                version_string
 .rodata.str1.1
                0xc7e245c8       0x78 lib_arm/libarm.a(board.o)
                                 0x7a (size before relaxing)

 

 

.data 数据存放那些全局定义的变量

 

 

 .data          0xc7e2a5a4       0x34 lib_arm/libarm.a(board.o)
                0xc7e2a5a4                init_sequence

 

 

 

.bss 需要进堆或进栈去申请的数据

 

 

 

 .bss           0xc7e3400c       0x10 lib_arm/libarm.a(board.o)
                0xc7e34018                monitor_flash_len
 .bss           0xc7e3401c     0x25cc net/libnet.a(net.o)
                0xc7e34078                NetArpWaitTry
                0xc7e34054                NetArpWaitPacketMAC
                0xc7e3402c                NetOurEther
                0xc7e34028                NetOurIP
                0xc7e34034                NetPingIP
                0xc7e34060                NetServerIP
                0xc7e3405c                NetArpWaitTxPacketSize
                0xc7e34048                NetArpWaitReplyIP
                0xc7e34058                NetArpWaitTxPacket
                0xc7e35eac                NetRxPackets
                0xc7e364e4                NetOurNISDomain
                0xc7e3403c                NetArpWaitPacketIP
                0xc7e3401c                NetState
                0xc7e36566                BootFile
                0xc7e34064                NetServerEther
                0xc7e34040                NetOurSubnetMask
                0xc7e36564                NetBootFileSize
                0xc7e34024                NetIPID
                0xc7e36504                NetOurHostName
                0xc7e3404c                NetRxPkt
                0xc7e34044                NetOurGatewayIP
                0xc7e34070                NetEtherNullAddr
                0xc7e35ebc                NetArpWaitPacketBuf
                0xc7e34050                NetRxPktLen
                0xc7e34038                NetTxPacket
                0xc7e364dc                NetBootFileXferSize
                0xc7e364e0                NetOurDNSIP
                0xc7e3408c                PktBuf
                0xc7e36524                NetOurRootPath
                0xc7e3407c                NetArpWaitTimerStart

 

 

 

 

 

 

 

5。下面重点说说.u_boot_cmd段:

 先看u-boot.map中生成:

               0xc7e2c980                __u_boot_cmd_start = .

.u_boot_cmd     0xc7e2c980      0x480
 *(.u_boot_cmd)
 .u_boot_cmd    0xc7e2c980       0x18 common/libcommon.a(cmd_bdinfo.o)
                0xc7e2c980                __u_boot_cmd_bdinfo
 .u_boot_cmd    0xc7e2c998       0x30 common/libcommon.a(cmd_boot.o)
                0xc7e2c9b0                __u_boot_cmd_reset
                0xc7e2c998                __u_boot_cmd_go
 .u_boot_cmd    0xc7e2c9c8       0x30 common/libcommon.a(cmd_bootm.o)
                0xc7e2c9c8                __u_boot_cmd_bootm
                0xc7e2c9e0                __u_boot_cmd_imls
 .u_boot_cmd    0xc7e2c9f8       0x48 common/libcommon.a(cmd_cache.o)
                0xc7e2ca10                __u_boot_cmd_dcache
                0xc7e2ca28                __u_boot_cmd_branch
                0xc7e2c9f8                __u_boot_cmd_icache
 .u_boot_cmd    0xc7e2ca40       0x18 common/libcommon.a(cmd_date.o)
                0xc7e2ca40                __u_boot_cmd_date
 .u_boot_cmd    0xc7e2ca58       0x30 common/libcommon.a(cmd_elf.o)
                0xc7e2ca70                __u_boot_cmd_bootvx
                0xc7e2ca58                __u_boot_cmd_bootelf
 .u_boot_cmd    0xc7e2ca88       0x48 common/libcommon.a(cmd_flash.o)
                0xc7e2ca88                __u_boot_cmd_flinfo
                0xc7e2caa0                __u_boot_cmd_erase
                0xc7e2cab8                __u_boot_cmd_protect
 .u_boot_cmd    0xc7e2cad0       0x18 common/libcommon.a(cmd_itest.o)
                0xc7e2cad0                __u_boot_cmd_itest
 .u_boot_cmd    0xc7e2cae8       0x48 common/libcommon.a(cmd_load.o)
                0xc7e2cb18                __u_boot_cmd_loady
                0xc7e2cb00                __u_boot_cmd_loadb
                0xc7e2cae8                __u_boot_cmd_loads
 .u_boot_cmd    0xc7e2cb30       0xf0 common/libcommon.a(cmd_mem.o)
                0xc7e2cb30                __u_boot_cmd_md
                0xc7e2cba8                __u_boot_cmd_cmp
                0xc7e2cb78                __u_boot_cmd_mw
                0xc7e2cbf0                __u_boot_cmd_loop
                0xc7e2cbd8                __u_boot_cmd_base
                0xc7e2cb48                __u_boot_cmd_mm
                0xc7e2cbc0                __u_boot_cmd_crc32
                0xc7e2cb60                __u_boot_cmd_nm
                0xc7e2cc08                __u_boot_cmd_mtest
                0xc7e2cb90                __u_boot_cmd_cp
 .u_boot_cmd    0xc7e2cc20       0x18 common/libcommon.a(cmd_misc.o)
                0xc7e2cc20                __u_boot_cmd_sleep
 .u_boot_cmd    0xc7e2cc38       0x30 common/libcommon.a(cmd_nand.o)
                0xc7e2cc38                __u_boot_cmd_nand
                0xc7e2cc50                __u_boot_cmd_nboot
 .u_boot_cmd    0xc7e2cc68       0x78 common/libcommon.a(cmd_net.o)
                0xc7e2ccb0                __u_boot_cmd_nfs
                0xc7e2ccc8                __u_boot_cmd_ping
                0xc7e2cc98                __u_boot_cmd_rarpboot
                0xc7e2cc80                __u_boot_cmd_tftpboot
                0xc7e2cc68                __u_boot_cmd_bootp
 .u_boot_cmd    0xc7e2cce0       0x48 common/libcommon.a(cmd_nvedit.o)
                0xc7e2cd10                __u_boot_cmd_saveenv
                0xc7e2cce0                __u_boot_cmd_printenv
                0xc7e2ccf8                __u_boot_cmd_setenv
 .u_boot_cmd    0xc7e2cd28       0x30 common/libcommon.a(cmd_usb.o)
                0xc7e2cd28                __u_boot_cmd_usb
                0xc7e2cd40                __u_boot_cmd_usbboot
 .u_boot_cmd    0xc7e2cd58       0x90 common/libcommon.a(command.o)
                0xc7e2cda0                __u_boot_cmd_exit
                0xc7e2cd70                __u_boot_cmd_echo
                0xc7e2cdd0                __u_boot_cmd_question_mark
                0xc7e2cd58                __u_boot_cmd_version
                0xc7e2cdb8                __u_boot_cmd_help
                0xc7e2cd88                __u_boot_cmd_test
 .u_boot_cmd    0xc7e2cde8       0x18 common/libcommon.a(cmd_usbd.o)
                0xc7e2cde8                __u_boot_cmd_dnw
                0xc7e2ce00                __u_boot_cmd_end = .
                0xc7e2ce00                . = ALIGN (0x4)

 

include/command.h中,

 

#define Struct_Section  __attribute__ ((unused,section (".u_boot_cmd")))

#ifdef  CFG_LONGHELP

#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}

#else    /* no long help info */

#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage}

#endif    /* CFG_LONGHELP */

 

所以我们新增指令后直接用U_BOOT_CMD声明,即可将数据放入.u_boot_cmd段,搜索段开始标志符__u_boot_cmd_start和段结束标志符__u_boot_cmd_end,得到此段数据的检测位于:command.c中的find_cmd,执行的入口位于:common/main.c中的run_command函数,此函数的调用位于uboot主循环main_loopfor (;;){……代码段内。

作者:Anpher Zhang QQ:275000205 转载请注明出处:http://www.cnblogs.com/zhangsufeng/

 

所有资料来源网上,与朋友分享 u-boot-1.1.6之cpu/arm920t/start.s分析 2 u-boot中.lds连接脚本文件的分析 12 分享一篇我总结的uboot学习笔记(转) 15 U-BOOT内存布局及启动过程浅析 22 u-boot中的命令实现 25 U-BOOT环境变量实现 28 1.相关文件 28 2.数据结构 28 3.ENV 的初始化 30 3.1env_init 30 3.2 env_relocate 30 3.3*env_relocate_spec 31 4. ENV 的保存 31 U-Boot环境变量 32 u-boot代码链接的问题 35 ldr和adr在使用标号表达式作为操作数的区别 40 start_armboot浅析 42 1.全局数据结构的初始化 42 2.调用通用初始化函数 43 3.初始化具体设备 44 4.初始化环境变量 44 5.进入主循环 44 u-boot编译过程 44 mkconfig文件的分析 47 从NAND闪存中启动U-BOOT的设计 50 引言 50 NAND闪存工作原理 51 从NAND闪存启动U-BOOT的设计思路 51 具体设计 51 支持NAND闪存的启动程序设计 51 支持U-BOOT命令设计 52 结语 53 参考文献 53 U-boot给kernel传参数和kernel读取参数—struct tag (以及补充) 53 1 、u-boot 给kernel 传RAM 参数 54 2 、Kernel 读取U-boot 传递的相关参数 56 3 、关于U-boot 中的bd 和gd 59 U-BOOT源码分析及移植 60 一、u-boot工程的总体结构: 61 1、源代码组织 61 2.makefile简要分析 61 3、u-boot的通用目录是怎么做到与平台无关的? 63 4、smkd2410其余重要的文件 : 63 二、u-boot的流程、主要的数据结构、内存分配 64 1、u-boot的启动流程: 64 2、u-boot主要的数据结构 66 3、u-boot重定位后的内存分布: 68 三、u-boot的重要细节 。 68 关于U-boot中命令相关的编程 : 73 四、U-boot在ST2410的移植,基于NOR FLASH和NAND FLASH启动。 76 1、从smdk2410到ST2410: 76 2、移植过程: 76 3、移植要考虑的问题: 77 4、SST39VF1601: 77 5、我实现的flash.c主要部分: 78 6、增加从Nand 启动的代码 : 82 7、添加网络命令。 87
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值