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地址 |
ethaddr | mac地址 |
gatewayip | 网关地址 |
netmask | 子网掩码 |
serverip | 服务器IP地址 |
命令 | 作用 | 使用 |
---|---|---|
ping | 测试网络 | ping ip uboot只能ping 外部机器 外部机器无法ping uboot! |
dhcp | 获取ip地址 | |
nfs | nfs下载文件 | nfs addr netfile |
tftp | tftp下载文件 | 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 fdtaddr: zimage地址
initrd :initrd 地址
fdt: 设备树文件地址 -
boot
按照bootcmd 命令启动
其他操作命令
- reset 重启命令
- go 跳转到指定地址执行
- run 运行环境变量中定义的命令
RTL8197 定制UBOOT命令
- ?查询所有命令
----------------- 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
-
db dw read d8 83XXREAD
查看内存数据dx addr count
read addr count -
eb ew write e8 83XXWRITE
改写eb addr valuex
-
cmp 比较命令
用于比较两段内存的数据是否相等,命令格式如下:cmp addr1 addr2 count
cmp命令同样可以以.b,.w,.l来指定操作格式,addr1为第一段内存首地址,addr2为第二段内存首地址,count为要比较的长度。
-
board 板子信息输出
board_type:00000011, 1000M 3KM 5.8G -
ipconfig 板子ip地址查看设置
显示当前IP地址 同时设置当前IP地址ipconfig address 设置板子IP地址
-
serverip 服务器ip地址查看设置
-
memcpy 内存拷贝
memcpy dst src length
-
autoburn 是否自动烧写
-
tftp 从tftp拷贝文件到一个地址
tftp memoryaddress filename
-
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,
-
erase 数据清零
erase:addr len
-
固件更新
设置本机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
- reset 重启
- 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常用命令以及代码分析的主要内容,如果未能解决你的问题,请参考以下文章
自学总结redis第二部分(redis常用命令高级命令特性以及与java代码的结合)