bsp开发之ubootuboot常用命令以及代码分析(代码片段)

与光同程 与光同程     2022-11-30     317

关键词:

文章目录

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) / sizeofbsp开发之kernellinux启动流程以及编译流程分析(代码片段)

文章目录linux顶层Makefile分析make过程分析子文件夹编译Makefile.build编译出子文件build-in.o过程分析vmlinux、Image,zImage、uImage的区别内核启动流程分析linux顶层Makefile分析MAKEFLAGS+=-rR#静默输出makeV=1静默输出ifeq("$(originV)&... 查看详情

bsp开发之kernellinux启动流程以及编译流程分析(代码片段)

文章目录linux顶层Makefile分析make过程分析子文件夹编译Makefile.build编译出子文件build-in.o过程分析vmlinux、Image,zImage、uImage的区别内核启动流程分析linux顶层Makefile分析MAKEFLAGS+=-rR#静默输出makeV=1静默输出ifeq("$(originV)&... 查看详情

bsp开发之kernellinux启动流程以及编译流程分析(代码片段)

文章目录linux顶层Makefile分析make过程分析子文件夹编译Makefile.build编译出子文件build-in.o过程分析vmlinux、Image,zImage、uImage的区别内核启动流程分析linux顶层Makefile分析MAKEFLAGS+=-rR#静默输出makeV=1静默输出ifeq("$(originV)&... 查看详情

git开发流程以及常用命令

git正确开发流程1.gitcloneurl从某个url克隆代码到本地2.gitcheckout-btest创建一个新的分支来进行操作,防止影响主分支3.在本地进行代码修改4.gitaddfile_name将修改后的文件添加到工作区5.gitcommit-mmessage将工作区的内容提交到版本库6.gitst... 查看详情

:常用工具命令第23节:常用命令-linux命令

...及Git常用命令。本小节中,我们主要针对面试中以及日常开发工作中常用的Linux命令进行学习。做为一名服务端开发人员,我们的开发环境大多都是Linux环境,并且服务器也是Linux环境,那么我们必须学会一些常用的Lin 查看详情

docker系列之dockerdesktop常用第三方应用安装以及命令解释

...分docker镜像安装代码,省的去找的时候不方便。Docker常用命令解释docker version //查看版本详情docker info //查看docker详情docker images //查看所有存在的镜像docker search  imagename //搜索指定名字的镜像docker pull 镜像名:tag(可为... 查看详情

测试开发之网络篇-常用命令

ipconfigWindows系统下,ipconfig加上/all参数,可查看本机的IP地址、掩码、默认网关、DHCP和DNS服务器等信息。Linux或mac系统下,请使用ifconfig命令代替。C:\Users\admin>ipconfig/allWindowsIPConfigurationEthernetadapterEthernet0:Connection-specificDNS 查看详情

linux开发常用命令(代码片段)

Linux操作1常用的命令1.1杂项history查看执行过的历史命令命令太长,需要在命令后使用回车,让·命令不执行,输入\\所有没有权限的都可以使用前置命令sudoctrl+C结束进程tab自动代码补全linux命令格式命令名称[命令... 查看详情

docker入门之常用命令

...常方便的将我们的应用程序以及运行所以来的环境部署到开发,测试及生产环境。一次编译,随处可用 &nbs 查看详情

git最常用命令

#拉取代码gitclone-b分之名称git地址#提交代码gitadd.//:注释,if是第一次提交:$gitadd-all.(请注意后面有个点)gitcommit-m"remark"gitpush#迁出分之gitcheckout-b本地分支名xorigin/远程分支名x#合并分之gitpulloriginWangjunZzzz:wangjun111#git删除分支gitb... 查看详情

es6之常用开发知识点:入门

ES6介绍ES6,全称ECMAScript6.0,2015.06发版。let和const命令let命令let命令,用来声明变量。它的用法类似于var,区别在于var声明的变量全局有效,let声明的变量只在它所在的代码块内有效。使用var声明:vara=[];for(vari=0;i<10;i++){a[i]=func... 查看详情

kubernetes集群管理常用命令一(代码片段)

...分为两个部分,第一部分介绍一些简单的,但是可能是非常常用的命令以及一些平时可能没有碰到的技巧.第二部分将综合前面介绍的工具通过示例来讲解一些更为复杂的命令.列出集群中所有pod使用kubectlgetpods获取的一般是默认名称... 查看详情

bsp开发之驱动开发

...操作系统仅仅有通过驱动程序才干訪问硬件。针对windowsce开发设备驱动。就是通过platformbuilder创建一个新的平台,然后依据硬件平台的须要插入或者移除驱动,须要改动的文件有platform.bib,platform.reg。按载入方式和接口分类,基... 查看详情

git之常用命令(代码片段)

git之常用命令1.下载远程仓库最新代码$gitpull--rebaseoriginmaster2.上传代码$gitpushoriginmaster 3.退出编辑ESC+Z+Z//z必须是大写,连按两次  报错:refusingtomergeunrelatedhistories解决:gitpulloriginmaster--allow-unrelated-histories  查看详情

ssti之细说jinja2的常用构造及利用思路(代码片段)

...板引擎的概念。模板引擎介绍模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。其不属于特定技... 查看详情

docker的简介安装以及常用命令(代码片段)

...cker是什么docker是一个开源的应用容器引擎,基于go语言,开发者可以打包他们的应用以及依赖到一个可移植的容器中,这个容器可以发布到任何装有docker软件的linux机器上。docker有4个组成部分docker客户端(client)docker守护进程(daemon... 查看详情

测试开发面试准备之linux-常用linux系统命令

1.文件管理cat-ndifflog2014.loglog2013.logchmodugo-rfilefile命令用于辨识文件类型file-iinstall.logfind命令用来在指定目录下查找文件。任何位于参数之前的字符串都将被视为欲查找的目录名。如果使用该命令时,不设置任何参数,则find命令... 查看详情

模块之软件开发目录,常用模块

软件开发目录我们学习编程开始都是将所有的代码全部都放到一个文件里面,后来我们学习函数,模块之后才会说将自己程序的功能具体分一下类,但是因为我们写的程序是需要用户来使用的,对于怎样编程,怎样分类他们都是... 查看详情