您的位置:首页 > 编程语言

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

2013-07-02 08:47 597 查看
关于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.map和System.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.mk的TEXT_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_loop的for (;;){……} 代码段内。

作者:Anpher Zhang QQ:275000205 转载请注明出处:http://www.cnblogs.com/zhangsufeng/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: