BSP开发之ubootuboot常用命令以及代码分析

Posted 与光同程

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BSP开发之ubootuboot常用命令以及代码分析相关的知识,希望对你有一定的参考价值。

文章目录

uboot 使用

uboot命令

通用 UBOOT 命令

信息查看命令
  • bdinfo 板级信息
  • printenv 环境变量
  • version 当前版本
环境变量操作命令
  • setenv 设置环境变量
  • saveenv 保存环境变量
内存操作命令
命令作用使用
md显示内存值.b.w.l 显示内存长度 md.b addr length
nm修改内存值.b.w.l nm.b addr
mm修改内存值.b.w.l 带自增
mw数据填充.b.w.l mw.l addr xxxxx length
cp内存拷贝.b.w.l cp.l addr1 addr2 length
cmp内存比较.b.w.l cp.l addr1 addr2 length
网络操作命令

相关环境变量

环境变量描述
ipaddr本机IP地址
ethaddrmac地址
gatewayip网关地址
netmask子网掩码
serverip服务器IP地址
命令作用使用
ping测试网络ping ip uboot只能ping 外部机器 外部机器无法ping uboot!
dhcp获取ip地址
nfsnfs下载文件nfs addr netfile
tftptftp下载文件tftp addr netfile
磁盘操作命令
命令作用使用
mmc info输出mmc 设备信息
mmc read读mmc 数据
mmc write写mmc 数据
mmc rescan扫描mmc 设备
mmc part输出mmc 分区
mmc dev切换mmc 设备
mmc list列出mmc 设备
boot操作命令
  • bootz bootm
    bootz addr initrd:size fdt

    addr: zimage地址
    initrd :initrd 地址
    fdt: 设备树文件地址

  • boot
    按照bootcmd 命令启动

其他操作命令
  • reset 重启命令
  • go 跳转到指定地址执行
  • run 运行环境变量中定义的命令

RTL8197 定制UBOOT命令

  1. ?查询所有命令
----------------- COMMAND MODE HELP ------------------
HELP (?)                                    : Print this help message
DB <Address> <Len>
DW <Address> <Len>
EB <Address> <Value1> <Value2>...
EW <Address> <Value1> <Value2>...
CMP: CMP <dst><src><length>
IPCONFIG:<IPAddress>
SERVERIP:<ServerAddress>
MEMCPY:<dst><src><length>
AUTOBURN: 0/1
LOADADDR: <Load Address>
J: Jump to <TargetAddress>
FLI: Flash init
FLR: FLR <dst><src><length>
FLW <dst_ROM_offset><src_RAM_addr><length_Byte> <SPI cnt#>: Write to SPI
INITRD:<initrd_start><initrd_size>
tftp <memoryaddress> <filename>
MDIOR:  MDIOR phyid reg
MDIOW:  MDIOW phyid reg data
PHYR: PHYR <PHYID><reg>
PHYW: PHYW <PHYID><reg><data>
PHYPR: PHYPR <PHYID><page><reg>
PHYPW: PHYPW <PHYID><page><reg><data>
COUNTER: Dump Asic Counter
XMOD <addr>  [jump]
TI : timer init
T : test
ETH : startup Ethernet
CPUClk:
CP0
ERASECHIP
ERASESECTOR
SPICLB (<flash ID>) : SPI Flash Calibration
READ <Address> <Len> <Step>
WRITE <Address> <Value>
83XXREAD <Address> <Len> <Step>
83XXWRITE <Address> <Value>
D8 <Address>
E8 <Address> <Value>
updateb: updateb u-boot_rtl8197.bin
updatek: updatek digicap_rtl8197.dav
go: update sec
reset
board
mode
erase:addr len
debug
  1. db dw read d8 83XXREAD
    查看内存数据

    dx addr count
    read addr count

  2. eb ew write e8 83XXWRITE
    改写

    eb addr valuex

  3. cmp 比较命令
    用于比较两段内存的数据是否相等,命令格式如下:

    cmp addr1 addr2 count

    cmp命令同样可以以.b,.w,.l来指定操作格式,addr1为第一段内存首地址,addr2为第二段内存首地址,count为要比较的长度。

  4. board 板子信息输出
    board_type:00000011, 1000M 3KM 5.8G

  5. ipconfig 板子ip地址查看设置
    显示当前IP地址 同时设置当前IP地址

    ipconfig address 设置板子IP地址

  6. serverip 服务器ip地址查看设置

  7. memcpy 内存拷贝

    memcpy dst src length

  8. autoburn 是否自动烧写

  9. tftp 从tftp拷贝文件到一个地址

    tftp memoryaddress filename

  10. cpuclock 查看CPU时钟

    信息输出
    Now CPU Speed=999
    HW_STRAP_VAL= 0x41258ee0
    ck_cpu_freq_sel=0x0000000b
    ck_cpu_div_sel=0x00000000
    CPU=1000 MHz, DDR2 Mem=533 MHz,
    Usage: CPUCLK clk_sel div_value : 0-f, 0-3
    Usage: CPUCLK 999 999: test all freq
    00000000 : 450 MHz,   00000001 : 500 MHz,   00000002 : 550 MHz,   00000003 : 600 MHz,
    00000004 : 650 MHz,   00000005 : 700 MHz,   00000006 : 750 MHz,   00000007 : 800 MHz,
    00000008 : 850 MHz,   00000009 : 900 MHz,   0000000a : 950 MHz,   0000000b : 1000 MHz,
    0000000c : 1050 MHz,   0000000d : 1100 MHz,   0000000e : 1150 MHz,   0000000f : 1200 MHz,
    
  11. erase 数据清零

    erase:addr len

  12. 固件更新
    设置本机IP

ipconfig 192.168.1.1

设置远程IP

serverip 192.168.1.2

更新uboot
updateb: updateb u-boot_rtl8197.bin
更新kernel
updatek: updatek digicap_rtl8197.dav

  1. reset 重启
  2. eth 启动以太网

UBOOT 代码分析(通用UBOOT 2016.01代码学习)

顶层Makefile分析

版本号
VERSION = 2016
PATCHLEVEL = 01
SUBLEVEL =
EXTRAVERSION =
NAME =
# 编译参数
MAKEFLAGS += -rR --include-dir=$(CURDIR)

#避免和环境变量冲突
unexport GREP_OPTIONS

# V是哪里来的 如果是从命令行中定义的那么将KBUILD_VERBOSE 设置为1 否则默认0
ifeq ("$(origin V)", "command line")
  KBUILD_VERBOSE = $(V)
endif
ifndef KBUILD_VERBOSE
  KBUILD_VERBOSE = 0
endif

ifeq ($(KBUILD_VERBOSE),1)
  quiet =
  Q =
else
  quiet=quiet_
  Q = @
endif


#如果用户正在运行make -s(静默模式),则禁止echo of  

ifneq ($(filter 4.%,$(MAKE_VERSION)),)	# make-4
ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)
  quiet=silent_
endif
else					# make-3.8x
ifneq ($(filter s% -s%,$(MAKEFLAGS)),)
  quiet=silent_
endif
endif

export quiet Q KBUILD_VERBOSE

# 命令中是否指定输出目录
ifeq ("$(origin O)", "command line")
  KBUILD_OUTPUT := $(O)
endif

PHONY := _all
_all:
$(CURDIR)/Makefile Makefile: ;

# 如果输出目录不空
ifneq ($(KBUILD_OUTPUT),)
saved-output := $(KBUILD_OUTPUT)
KBUILD_OUTPUT := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) \\
								&& /bin/pwd)
$(if $(KBUILD_OUTPUT),, \\
     $(error failed to create output directory "$(saved-output)"))

PHONY += $(MAKECMDGOALS) sub-make


#是否使能代码检查
ifeq ("$(origin C)", "command line")
  KBUILD_CHECKSRC = $(C)
endif
ifndef KBUILD_CHECKSRC
  KBUILD_CHECKSRC = 0
endif

#使用make M=dir指定要构建的外部模块目录  
#旧语法make… 仍然支持SUBDIRS=$PWD  
#设置环境变量KBUILD_EXTMOD优先 
ifdef SUBDIRS
  KBUILD_EXTMOD ?= $(SUBDIRS)
endif

ifeq ("$(origin M)", "command line")
  KBUILD_EXTMOD := $(M)
endif

#如果构建一个外部模块,我们不需要考虑all:规则而_all依赖于模块 
PHONY += all
ifeq ($(KBUILD_EXTMOD),)
_all: all
else
_all: modules
endif

ifeq ($(KBUILD_SRC),)
        srctree := .
else
        ifeq ($(KBUILD_SRC)/,$(dir $(CURDIR)))
                srctree := ..
        else
                srctree := $(KBUILD_SRC)
        endif
endif
objtree		:= .
src		:= $(srctree)
obj		:= $(objtree)

VPATH		:= $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD))

export srctree objtree VPATH
unexport CDPATH

# 获取主机架构以及对应操作系统
HOSTARCH := $(shell uname -m | \\
	sed -e s/i.86/x86/ \\
	    -e s/sun4u/sparc64/ \\
	    -e s/arm.*/arm/ \\
	    -e s/sa110/arm/ \\
	    -e s/ppc64/powerpc/ \\
	    -e s/ppc/powerpc/ \\
	    -e s/macppc/powerpc/\\
	    -e s/sh.*/sh/)

HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \\
	    sed -e 's/\\(cygwin\\).*/cygwin/')

export	HOSTARCH HOSTOS

# 判断主机和编译系统是否是同一架构,如果不是 许哟啊采用交叉编译器
ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE ?=arm-linux-gnueabi-
endif

KCONFIG_CONFIG	?= .config
export KCONFIG_CONFIG


scripts/Kbuild.include: ;
include scripts/Kbuild.include

# 定义编译套件
AS		= $(CROSS_COMPILE)as
ifneq ($(shell $(CROSS_COMPILE)ld.bfd -v 2> /dev/null),)
LD		= $(CROSS_COMPILE)ld.bfd
else
LD		= $(CROSS_COMPILE)ld
endif
CC		= $(CROSS_COMPILE)gcc
CPP		= $(CC) -E
AR		= $(CROSS_COMPILE)ar
NM		= $(CROSS_COMPILE)nm
LDR		= $(CROSS_COMPILE)ldr
STRIP		= $(CROSS_COMPILE)strip
OBJCOPY		= $(CROSS_COMPILE)objcopy
OBJDUMP		= $(CROSS_COMPILE)objdump
AWK		= awk
PERL		= perl
PYTHON		= python
DTC		= dtc
CHECK		= sparse


# 导出其他变量
export VERSION PATCHLEVEL SUBLEVEL UBOOTRELEASE UBOOTVERSION
export ARCH CPU BOARD VENDOR SOC CPUDIR BOARDDIR
export CONFIG_SHELL HOSTCC HOSTCFLAGS HOSTLDFLAGS CROSS_COMPILE AS LD CC
export CPP AR NM LDR STRIP OBJCOPY OBJDUMP
export MAKE AWK PERL PYTHON
export HOSTCXX HOSTCXXFLAGS DTC CHECK CHECKFLAGS
export KBUILD_CPPFLAGS NOSTDINC_FLAGS UBOOTINCLUDE OBJCOPYFLAGS LDFLAGS
export KBUILD_CFLAGS KBUILD_AFLAGS



# 定义自动生成的版本号文件
version_h := include/generated/version_autogenerated.h
timestamp_h := include/generated/timestamp_autogenerated.h

libs-y += lib/
libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/
libs-$(CONFIG_OF_EMBED) += dts/
libs-y += fs/
libs-y += net/
libs-y += disk/
libs-y += drivers/
libs-y += drivers/dma/
libs-y += drivers/gpio/
libs-y += drivers/i2c/
libs-y += drivers/mmc/
libs-y += drivers/mtd/
libs-$(CONFIG_CMD_NAND) += drivers/mtd/nand/
libs-y += drivers/mtd/onenand/
libs-$(CONFIG_CMD_UBI) += drivers/mtd/ubi/
libs-y += drivers/mtd/spi/
libs-y += drivers/net/
libs-y += drivers/net/phy/
libs-y += drivers/pci/
libs-y += drivers/power/ \\
	drivers/power/fuel_gauge/ \\
	drivers/power/mfd/ \\
	drivers/power/pmic/ \\
	drivers/power/battery/ \\
	drivers/power/regulator/
libs-y += drivers/spi/
libs-$(CONFIG_FMAN_ENET) += drivers/net/fm/
libs-$(CONFIG_SYS_FSL_DDR) += drivers/ddr/fsl/
libs-$(CONFIG_ALTERA_SDRAM) += drivers/ddr/altera/
libs-y += drivers/serial/
libs-y += drivers/usb/dwc3/
libs-y += drivers/usb/emul/
libs-y += drivers/usb/eth/
libs-y += drivers/usb/gadget/
libs-y += drivers/usb/gadget/udc/
libs-y += drivers/usb/host/
libs-y += drivers/usb/musb/
libs-y += drivers/usb/musb-new/
libs-y += drivers/usb/phy/
libs-y += drivers/usb/ulpi/
libs-y += common/
libs-$(CONFIG_API) += api/
libs-$(CONFIG_HAS_POST) += post/
libs-y += test/
libs-y += test/dm/
libs-$(CONFIG_UT_ENV) += test/env/

libs-y += $(if $(BOARDDIR),board/$(BOARDDIR)/)

libs-y := $(sort $(libs-y))

u-boot-dirs	:= $(patsubst %/,%,$(filter %/, $(libs-y))) tools examples

u-boot-alldirs	:= $(sort $(u-boot-dirs) $(patsubst %/,%,$(filter %/, $(libs-))))

libs-y		:= $(patsubst %/, %/built-in.o, $(libs-y))

u-boot-init := $(head-y)
u-boot-main := $(libs-y)

uboot生成过程分析

_all --> all --> ALL-y -->u-boot.bin --> u-boot-nodtb.bin --> uboot --> u-boot-init u-boot-main u-boot.lds

u-boot-init --> head -y --> arch/arm/cpu/start.o

u-boot-main --> lib -y --> 大量子目录中带lib -y的源码 变成build-in.o

UBOOT 启动过程代码分析

启动过程
uboot启动主要分为两个阶段。

第一阶段主要由start.s运行并实现相应的初始化,定义程序入口地址,初始化CPU,初始化内存,最后调用_main到第二阶段的板级别初始化部分。

第二阶段主要是C语言编写,对于硬件内存分配,初始化硬件设备,串口初始化,显示设备初始化,运行环境初始化等等,最后启动内核。

第一阶段

住主要需要完成如下工作
①硬件设备初始化
屏蔽所有的中断
设置CPU的速度和时钟频率
设置内存控制器
关闭 CPU 内部指令/数据 cache
②为加载 stage2 准备 RAM 空间
③拷贝 stage2 到 RAM 空间中
④设置好堆栈指针sp,为执行 C 语言代码作好准备;
⑤跳转到 stage2 阶段的C程序入口处。

这里主要会涉及到两个汇编文件,完成最底层的初始化。

start.S
路径:arch/yourplatform/cpu/start.S
yourplatform按照实际使用的平台进行选择,如arm,x86,mips

crt0_64.S
路径:arch/arm/lib/crt0_64.S

crt0是C Runtime Startup的简称,这部分程序主要完成C语言环境的初始化,最终会运行_main函数。

第二阶段

BootLoader 的 stage2 通常用C语言来实现,可以实现更复杂的功能,而且代码会具有更好的可读性和可移植性。 包括以下步骤:

①初始化本阶段要使用到的硬件设备;
串口设备:以便输出信息
……
②检测系统内存映射(memory map):准备识别在整个 4GB 物理地址空间中有哪些地址范围被分配用来寻址系统的 RAM单元;
③将 kernel 映像和根文件系统映像从 flash 上读到 RAM 空间中;
④为内核设置启动参数;
⑤调用内核:跳至内核代码入口开始执行。

由于需要适配不同的硬件平台,提高可移植性和代码的复用,这部分使用基本使用C语言
分为两部分 board/yourboard/xxx.c的 board_init_f 函数,然后就是在 common/board_r.c

void board_init_f(ulong dummy)

	/* setup AIPS and disable watchdog */
	arch_cpu_init();

	ccgr_init();
	gpr_init();

	/* iomux and setup of i2c */
	board_early_init_f();

	/* setup GP timer */
	timer_init();

	/* UART clocks enabled and gd valid - init serial console */
	preloader_console_init();

	/* DDR initialization */
	spl_dram_init();

	/* Clear the BSS. */
	memset(__bss_start, 0, __bss_end - __bss_start);

	/* load/boot image from boot device */
	board_init_r(NULL, 0);

函数中通过initcall_run_list运行initcall_run_list列表中的函数,可以看一下init_sequence_r包括了各种板级的初始化,最终运行run_main_loop。

void board_init_r(gd_t *new_gd, ulong dest_addr)

#ifdef CONFIG_NEEDS_MANUAL_RELOC
	int i;
#endif

#ifdef CONFIG_AVR32
	mmu_init_r(dest_addr);
#endif

#if !defined(CONFIG_X86) && !defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
	gd = new_gd;
#endif

#ifdef CONFIG_NEEDS_MANUAL_RELOC
	for (i = 0; i < ARRAY_SIZE(init_sequence_r); i++)
		init_sequence_r[i] += gd->reloc_off;
#endif

	if (initcall_run_list(init_sequence_r))
		hang();
	hang();

打印测试

U-Boot 2016.01 (Jul 18 2022 - 18:17:02 +0800) # common\\board_f.c 877 display_options

DRAM:  512 MiB # common\\board_f.c 983 show_dram_config(void)
WARNING: Caches not enabled
Flash: 128 MiB
MMC:   MMC: 0
*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   smc911x-0
Hit any key to stop autoboot:  0 

命令行处理

board_r(common\\board_r.c)–>run_main_loop -->main_loop(u-boot\\common\\main.c)
–>cli_loop (common\\cli.c)–>run_list(common\\cli_hush.c)–>run_list_real–>run_pipe_real
–>cmd_process–>cmd_call

添加命令行方法

在common 文件夹中新建 cmd_hello.c

#include<command.h>
#include<common.h>
static int do_hello(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])

    printf("hello world!\\n");
    return 0;

U_BOOT_CMD(
hello, //命令名称
1,      //参数个数
0,      //是否重复执行
do_hello,//对应函数
" short description. This is a string.",
" long description. This is a string."
);

对应Makefile添加
obj-y += cmd_hello.o

UBOOT 代码分析(RTL8197定制uboot代码学习)

顶层Makefile分析

# 包含 .config 文件
ifeq ($(filter-out %-config,$(MAKECMDGOALS)),)
-include .config
else
include .config
endif

# 设置将要跳转的地址
ifneq ($(CONFIG_RTL_ECOS_8M),)
  ifneq ($(CONFIG_ROM_BOOT),)
    DEFAULT_JUMP=0xa0500000
  else
    DEFAULT_JUMP=0xa0500010
  endif
else
  DEFAULT_JUMP=0xa0a00000
endif

# 设置交叉编译器
export CROSS= $(CROSS_COMPILE)

# 获取当前目录,以及子目录
ROOTDIR  = $(shell pwd)
PATH     := $(PATH):$(ROOTDIR)/tools
HOSTCC   = cc
IMAGEDIR = $(ROOTDIR)/images
RELDIR   = $(ROOTDIR)/release
ROMFSDIR = $(ROOTDIR)/romfs
ROMFSINST= romfs-inst.sh
SCRIPTSDIR = $(ROOTDIR)/config/scripts
#TFTPDIR    = /tftpboot
GDBSERVERDIR = $(ROOTDIR)/user

LINUXDIR = $(CONFIG_LINUXDIR)
ifeq ($(LINUXDIR),)
LINUXDIR := linux-2.6.x
endif

LINUX_CONFIG  = $(ROOTDIR)/.config

ifeq ($(LINUX_CONFIG),$(wildcard $(LINUX_CONFIG)))
else
all: kernel_config_error
endif

MAKE = make

ifneq ($(SUBARCH),)
MAKEARCH = $(MAKE) ARCH=$(SUBARCH) CROSS_COMPILE=$(CROSS_COMPILE)
MAKEARCH_KERNEL = $(MAKE)  ARCH=$(ARCH) SUBARCH=$(SUBARCH) CROSS_COMPILE=$(CROSS_KERNEL_COMPILE)
else
MAKEARCH = $(MAKE) V=1 ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE)
MAKEARCH_KERNEL =$(MAKE) V=1 ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_KERNEL_COMPILE)
endif

export VENDOR PRODUCT ROOTDIR LINUXDIR VENDDIR HOSTCC CONFIG_SHELL
export CONFIG_CONFIG LINUX_CONFIG ROMFSDIR SCRIPTSDIR
export VERSIONPKG VERSIONSTR ROMFSINST PATH IMAGEDIR RELDIR RELFILES TFTPDIR
export CROSS_KERNEL_COMPILE
ARCH+=RTL865X=1

ifeq (.config,$(wildcard .config))
include .config
include $(LINUX_CONFIG)

export PATH

ifeq ($(CONFIG_RTL8198),y)
endif

export CONFIG_SPI_STD_MODE

ifeq ($(CONFIG_NFBI),y)
    DEFAULT_JUMP=0x806ffff0
endif

all:         
	make -C boot boot JUMP_ADDR=$(DEFAULT_JUMP) $(ARCH)
	make -C btcode $(ARCH)
	make -C boot wboot $(ARCH)

else # else of ifeq (.config,$(wildcard .config))
all: config_error
endif # end of ifeq (.config,$(wildcard .config))

boot:
	make -C boot
16bit:	
	make -C boot boot JUMP_ADDR=$(DEFAULT_JUMP) $(ARCH)
	make -C btcode 16B=1  $(ARCH)

clean:
	make -C boot clean
	make -C btcode clean
		

			
nfbi:
	make -C boot boot JUMP_ADDR=$(DEFAULT_JUMP) $(ARCH)
	make -C btcode $(ARCH)
	
wboot16: clean
	make -C boot boot JUMP_ADDR=$(DEFAULT_JUMP) $(ARCH) 
	make -C btcode 16B=1 $(ARCH)
	make -C boot wboot $(ARCH)

	
test:
	make -C boot test	

.PHONY: $(wildcard *-config)

$(wildcard *-config):
	cp $@ .config
 
ifdef CONFIG_RTL89xxC
	$(OP) -f $(src)/voip_drivers/gpio/gpio_8954c.c				./boot/serial_sc16is7x0/gpio/gpio_8954c.c
	$(OP) -f $(src)/voip_drivers/gpio/gpio_8954c.h				./boot/serial_sc16is7x0/gpio/gpio_8954c.h
	$(OP) -f $(src)/voip_drivers/gpio/gpio_8972b.c				./boot/serial_sc16is7x0/gpio/gpio_8972b.c
	$(OP) -f $(src)/voip_drivers/gpio/gpio_8972b.h				./boot/serial_sc16is7x0/gpio/gpio_8972b.h
	$(OP) -f $(src)/voip_drivers/gpio/gpio.h					./boot/serial_sc16is7x0/gpio/gpio.h
	$(OP) -f $(src)/voip_drivers/i2c.c							./boot/serial_sc16is7x0/i2c.c
	$(OP) -f $(src)/voip_drivers/i2c.h							./boot/serial_sc16is7x0/i2c.h
	$(OP) -f $(src)/../drivers/serial/8250_sc16is7x0.c			./boot/serial_sc16is7x0/8250_sc16is7x0.c
else
	$(OP) -f $(src)/drivers/serial/gpio_8972b.c				./boot/serial_sc16is7x0/gpio/gpio_8972b.c
	$(OP) -f $(src)/drivers/serial/gpio_8972b.h				./boot/serial_sc16is7x0/gpio/gpio_8972b.h
	$(OP) -f $(src)/drivers/serial/gpio.h					./boot/serial_sc16is7x0/gpio/gpio.h
	$(OP) -f $(src)/drivers/serial/i2c.c							./boot/serial_sc16is7x0/i2c.c
	$(OP) -f $(src)/drivers/serial/i2c.h							./boot/serial_sc16is7x0/i2c.h
	$(OP) -f $(src)/drivers/serial/8250_sc16is7x0.c			./boot/serial_sc16is7x0/8250_sc16is7x0.c
endif

lnfiles:
	@make _opfiles OP="ln -s" src="$(src)" OPcmd="lnfiles"

cpfiles:
	@make _opfiles OP="cp" src="$(src)" OPcmd="cpfiles"

all --> boot btcode wboot

函数调用逻辑

第一阶段

btcode\\start.S (boot\\arch\\mips\\kernel\\head.S)reset:
–>
cache_init_end --> cache_start --> start_c

第二阶段

btcode\\start.S(boot\\arch\\mips\\kernel\\head.S) reset:
–>
boot\\arch\\mips\\kernel\\setup.c init_arch:
–>
boot\\init\\main.c start_kernel:

void start_kernel(void)


	int ret;
	unsigned int reg_val = 0;

	gCHKKEY_HIT = 0;
	gCHKKEY_CNT = 0;

	IMG_HEADER_T header;
	SETTING_HEADER_T setting_header;

  //初始化串口
	setClkInitConsole();
  //初始化堆
	initHeap();
	//初始化中断
	initInterrupt();
  //初始化存储器
	initFlash();
	//初始化IIC
	#ifdef CONFIG_I2C_POLLING
	initI2C();
	#endif
  //显示板子信息
	showBoardInfo();
#if defined(CONFIG_POST_ENABLE)
	if(ret == 0)
		return;
#endif

#if defined(CONFIG_RTL8197F) && (defined (CONFIG_SW_8367R) || defined (CONFIG_SW_83XX)) && defined(CONFIG_LAN_WAN_ISOLATION)
	if (swCore_init())   	
		dprintf("\\nSwitch core initialization failed!\\n");        
		return;
	
#elif defined(CONFIG_RTL8197F) && (defined (CONFIG_SW_8367R) || defined (CONFIG_SW_83XX))
	hik_doBooting();


–>
boot\\init\\utility.c hik_doBooting:

void hik_doBooting(void)

	int ret = 0;
	IMG_HEADER_T header;
	SETTING_HEADER_T setting_header;
	switch(hik_user_interrupt(3))
	
	case LOCALSTART_MODE://正常启动
	default:		
		return_addr=0;
		ret=check_image	(&header,&setting_header);
		if(ret > 0)
		
			goToLocalStartMode(return_addr,&header);
		
		else
		
			goToDownMode();	
		
		break;
	case DOWN_MODE:
		/* 禁止屏蔽中断,否则系统时钟、网络均存在问题 */
		//REG32(BSP_GIMR)=0x0;
		goToDownMode();	
		break;
	
	return;


–>
boot\\init\\utility.c goToDownMode:
–>
boot\\monitor\\monitor.c

打印测试

# 第一阶段
# btcode\\start_c.c  start_c 
init_ram
W init ddr ok

DRAM Type: DDR2
        DRAM frequency: 533MHz
        DRAM Size: 64MB
JEDEC id EF4018, EXT id 0x0000

# 第二阶段
#boot\\flash\\m25p80.c  m25p_probe
found w25q128
flash vendor: Winbond 
#boot\\flash\\m25p80.c  2129-2132
w25q128, size=16MB, erasesize=4KB, max_speed_hz=29000000Hz
auto_mode=0 addr_width=3 erase_opcode=0x00000020

#uboot\\boot\\init\\main.c  showBoardInfo 428
=>CPU Wake-up interrupt happen! GISR=89000004
---Realtek RTL8197F boot code at 2022.07.18-10:12+0800 v3.4.11E (999MHz)

---Ethernet init Okay!
Hit ctrl+u key to stop autoboot: 2

命令处理流程分析

命令处理大部分代码位于
boot\\monitor

void monitor(void)

	char		buffer[ MAX_MONITOR_BUFFER +1 ];
	int		argc ;
	char**		argv ;
	int		i, retval ;
	while(1)
		
		dprintf( "%s", MAIN_PROMPT );
		memset( buffer, 0, MAX_MONITOR_BUFFER );
		GetLine( buffer, MAX_MONITOR_BUFFER,1);
		dprintf( "\\n" );
		argc = GetArgc( (const char *)buffer );
		argv = GetArgv( (const char *)buffer );
		if( argc < 1 ) continue ;
		StrUpr( argv[0] );
		for( i=0 ; i < (sizeof(MainCmdTable) / sizeof(COMMAND_TABLE)) ; i++ )//挨个命令比较
		
			if( ! strcmp( argv[0], MainCmdTable[i].cmd ) )//如果比较成功
			
				retval = MainCmdTable[i].func( argc - 1 , argv+1 );//调用对应的回调函数
				dprintf( "\\n" );
				break;
			
		
		if(i==sizeof(MainCmdTable) / sizeof以上是关于BSP开发之ubootuboot常用命令以及代码分析的主要内容,如果未能解决你的问题,请参考以下文章

BSP开发之kernelLinux启动流程以及编译流程分析

BSP开发之kernelLinux启动流程以及编译流程分析

BSP开发之kernelLinux启动流程以及编译流程分析

自学总结redis第二部分(redis常用命令高级命令特性以及与java代码的结合)

ubootuboot 2020.04 DM驱动模式 -- Demo体验

ubootuboot 2020.04 DM驱动模式 -- 架构分析