• 【BSP开发之uboot】uboot常用命令以及代码分析


    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 
    DW
    EB
    ... EW
    ... CMP: CMP IPCONFIG: SERVERIP: MEMCPY: AUTOBURN: 0/1 LOADADDR: J: Jump to FLI: Flash init FLR: FLR FLW : Write to SPI INITRD: tftp MDIOR: MDIOR phyid reg MDIOW: MDIOW phyid reg data PHYR: PHYR PHYW: PHYW PHYPR: PHYPR PHYPW: PHYPW COUNTER: Dump Asic Counter XMOD [jump] TI : timer init T : test ETH : startup Ethernet CPUClk: CP0 ERASECHIP ERASESECTOR SPICLB () : SPI Flash Calibration READ
    WRITE
    83XXREAD
    83XXWRITE
    D8
    E8
    updateb: updateb u-boot_rtl8197.bin updatek: updatek digicap_rtl8197.dav go: update sec reset board mode erase:addr len debug
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    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,
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233

    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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    函数中通过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();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    打印测试

    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 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    命令行处理

    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
    #include
    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."
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    对应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"
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139

    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();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    –>
    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;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    –>
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    命令处理流程分析

    命令处理大部分代码位于
    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(COMMAND_TABLE)) dprintf("Unknown command !\r\n");//没有找到对应函数
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    所以如果需要添加或者删除uboot 命令需要改动
    MainCmdTable 命令列表(2665 ) 并且添加相应函数

  • 相关阅读:
    【图解】连狗子都能看懂的Python基础总结!
    Java学习笔记 --- HashSet
    解决electron + react单页应用调用localhost服务失败
    程序的编译,链接,执行
    BIOMOD2模型、MaxEnt模型物种分布模拟,生物多样性生境模拟,论文写作
    黑马瑞吉外卖之购物车功能开发(添加购物车和购物车数据展示)
    9、Java 成员方法详解
    【校招Verilog手撕代码】VL3、循环仲裁器设计(Round Robin Arbiter)
    认识xml文件
    Qt操作Sqlite类封装,及命令行导入csv文件到Sqlite数据库
  • 原文地址:https://blog.csdn.net/yy197696/article/details/126186893