海思芯片(hi3516dv300)uboot镜像生成过程详解

海思芯片(hi3516dv300)uboot镜像生成过程详解 thatk 2024-01-08 16:49:01 286

1、前言

(1)本文介绍的uboot编译过程是基于海思提供SDK包里的uboot源码进行编译,具体的编译参数是根据hi3516dv300芯片来设置的,编译生成的uboot烧录镜像也是用于hi3516dv300芯片的uboot镜像;
(2)对于Makefile没有特别强调则表示是uboot源码顶层的Makefile;

2、uboot的编译过程

2.1 配置编译环境

编译命令:make ARCH=arm CROSS_COMPILE=arm-himix200v002-linux- hi3516dv300_emmc_defconfig V=1

2.2 编译u-boot.bin

(1)编译命令:make ARCH=arm CROSS_COMPILE=arm-himix200-linux- -j 20
(2)-j 20:指定采用20个线程同时编译,前提是你的电脑CPU有20个核心,如果不清楚你的电脑CPU是几核的可以不加;

2.3 编译gzip工具

(1)在海思提供的SDK中会有hi_gzip目录,里面是生成gzip工具的源码和编译脚本,gzip是个压缩工具,和分段式uboot镜像的生成有关,将生成好的gzip拷贝到uboot源码的对应目录下;
(2)编译指令:cd hi_gzip;make;cp ./bin/gzip uboot/arch/arm/cpu/armv7/hi3516dv300/hw_compressed/ -rf
补充:gzip是在PC机上运行的,Makefile中指定了编译工具是gcc,所以我们在编译gzip时不同指定交叉编译工具链;

2.4 编译寄存器配置表格文件

(1)海思提供的SDK中uboot_tools/目录下打开对应单板的Excel文件,在main标签中点击”Generate reg bin file”按钮,生成reg_info.bin即为对应平台的表格文件;
(2)拷贝生成的reg_info.bin到boot源代码顶层目录,重命名为.reg;

2.5 生成分段式镜像:u-boot-z.bin

(1)编译指令:make ARCH=arm CROSS_COMPILE=arm-himix200-linux- u-boot-z.bin
(2)最终生成可烧录的uboot镜像:u-boot-hi3516dv300.bin;

3、uboot寄存器配置表格文件

3.1 功能介绍

(1)在SDK包中有uboot_tools目录,里面存放了芯片寄存器配置的xlsm格式的表格文件,比如hi3516dv300芯片对应的表格文件名字是”Hi3516DV300-DMEB_4L_FLYBY-DDR3_1800M_512MB_16bitx2-A7_900M-SYSBUS_300M.xlsm”;
(2)最下方是模块名,寄存器都是按模块存放的,比如当前是在ddrc模块,表格中的寄存器都是和配置ddrc功能相关的寄存器;
(3)Base Addrss:这是模块寄存器的基地址;芯片在分配寄存器地址时,相关寄存器的地址是连续的;
(4)Register:这一列是寄存器的名字,和数据手册相对应;
(5)Offset Address:寄存器地址相对于基地址的偏移量,对寄存器的访问是按照”基地址+偏移量”的方式;
(6)Value:将来uboot启动阶段会将这里的值写入对应寄存器;

3.2、使用方法

(1)在“main”界面点击”Generate reg bin file”按钮,在当前目录生成reg_info.bin即为对应平台的表格文件;
(2)将reg_info.bin文件拷贝到uboot源码的顶层目录,并重命名为”.reg”文件;
(3)“.reg”文件会用于生成u-boot-hi3516dv300.bin镜像文件,uboot在启动阶段会去读取”.reg”文件来设置寄存器;

4、分段式uboot镜像的生成过程

4.1 整个uboot烧录镜像的组成

(1)海思内置代码在启动时,会读取uboot镜像的前一部分到片内RAM地址空间;
(2)先执行.o文件,这些代码会读取.reg去设置寄存器,最终要初始化DDR,将uboot镜像重定位到DDR中;
(3)解压DDR中的uboot镜像,然后执行解压后的uboot镜像的代码;

4.2 主Makefile
······

.PHONY: u-boot-z.bin
u-boot-z.bin: $(CURDIR)/u-boot.bin
    make -C $(CURDIR)/arch/$(ARCH)/cpu/$(CPU)/$(SOC)/$(HW_DIR)/ \
        CROSS_COMPILE=$(CROSS_COMPILE) \
        BINIMAGE=$(CURDIR)/u-boot.bin TOPDIR=$(CURDIR)

    #上面的指令具体化各个变量
    #make -C uboot/arch/arm/cpu/armv7/hi3516dv300/hw_compressed/ CROSS_COMPILE=arm-himix200-linux-  BINIMAGE=uboot/u-boot.bin TOPDIR=uboot/
······

(1)在顶层Makefile的u-boot-z.bin目标中,没有做什么实际的功能,就是依赖顶层目录的u-boot.bin文件,然后跳转到arch/arm/cpu/armv7/hi3516dv300/hw_compressed/hw_compressed目录执行make指令;
(2)补充:CURDIR是Makefile的内置变量,表示当前目录的绝对路径;

4.3 u-boot-hi3516dv300.bin的生成过程

4.4 hw_compressed/Makefile文件源码
################################################################################
#    Create By Hisilicon
################################################################################

PWD           = $(shell pwd)
HW_CROSS_COMPILE = $(CROSS_COMPILE)
TOPDIR        =

################################################################################
CC       := $(HW_CROSS_COMPILE)gcc
AR       := $(HW_CROSS_COMPILE)ar
LD       := $(HW_CROSS_COMPILE)ld
OBJCOPY  := $(HW_CROSS_COMPILE)objcopy


################################################################################
BOOT     := u-boot-$(SOC)

#镜像的链接脚本
TEXTBASE := 0x80700000

CFLAGS   :=-g -Os -fno-builtin -ffreestanding \
    -D__KERNEL__ -DTEXT_BASE=$(TEXTBASE) \
    -I$(TOPDIR)/include \
    -I$(TOPDIR)/drivers/ddr/hisilicon/default \
    -I$(TOPDIR)/drivers/ddr/hisilicon/$(SOC) \
    -I$(TOPDIR)/arch/arm/include \
    -I$(TOPDIR)/lib/hw_dec \
    -fno-pic -ffunction-sections \
    -fdata-sections -fno-common -ffixed-r9    \
    -fno-common -pipe -march=armv7-a \
    -Wall -Wstrict-prototypes -fno-stack-protector \
    -D__LINUX_ARM_ARCH__=7 -D__ARM__ \
    -DCONFIG_MMC\
    $(MKFLAGS) -fno-strict-aliasing

################################################################################

#这些.o文件会按照链接脚本u-boot.lds用于生成u-boot-hi3516dv300.elf
START := start.o
COBJS := lowlevel_init_v300.o \
    init_registers.o \
    emmc_boot.o \
    uart.o \
    ddr_training_impl.o \
    ddr_training_ctl.o \
    ddr_training_boot.o \
    ddr_training_custom.o \
    ddr_training_console.o \
    startup.o \
    image_data.o \
    div0.o \
    reset.o

# 这些.S和.c文件会被编译成.o文件,对应于COBJS
SSRC  := arch/arm/cpu/armv7/$(SOC)/start.S \
    arch/arm/cpu/armv7/$(SOC)/reset.S \
    arch/arm/cpu/armv7/$(SOC)/emmc_boot.c \
    arch/arm/cpu/armv7/$(SOC)/uart.S \
    arch/arm/cpu/armv7/$(SOC)/init_registers.c \
    arch/arm/cpu/armv7/$(SOC)/lowlevel_init_v300.c \
    drivers/ddr/hisilicon/default/ddr_training_impl.c \
    drivers/ddr/hisilicon/default/ddr_training_ctl.c \
    drivers/ddr/hisilicon/default/ddr_training_boot.c \
    drivers/ddr/hisilicon/default/ddr_training_console.c \
    drivers/ddr/hisilicon/$(SOC)/ddr_training_custom.c \
    arch/arm/lib/div0.c \
    lib/hw_dec/hw_decompress.c \
    lib/hw_dec/hw_decompress_$(SOC).c \
    lib/hw_dec/hw_decompress_v1.c \
    lib/hw_dec/hw_decompress_v1.h

REG := $(wildcard $(TOPDIR)/*.reg $(TOPDIR)/.reg)
SRC := $(notdir $(SSRC))

################################################################################
.PHONY: $(BOOT).bin
$(BOOT).bin: $(BOOT).tmp regfile
    #把./$(BOOT).tmp前64字节保存到tmp1
    @dd if=./$(BOOT).tmp of=./tmp1 bs=1 count=64 2>/dev/null 

    #把顶层.reg文件保存到tmp2中,文件大小扩充到8192字节
    @dd if=$(REG) of=./tmp2 bs=8192 conv=sync 2>/dev/null

    #把./u-boot-hi3516dv300.tmp保存到tmp3文件中,tmp3文件要跳过前8256个字节
    @dd if=./$(BOOT).tmp of=./tmp3 bs=1 skip=8256 2>/dev/null

    #将tmp1、tmp2、tmp3依次构成u-boot-hi3516dv300.bin文件
    @cat tmp1 tmp2 tmp3 > $(BOOT).bin
    @rm -f tmp1 tmp2 tmp3
    @chmod 754 $(BOOT).bin
    @cp -fv $@ $(TOPDIR)
    @echo $(BOOT).bin is Ready.

#用objcopy工具将可执行程序制作成二进制格式文件
$(BOOT).tmp: $(BOOT).elf
    $(OBJCOPY) -O srec $< $(BOOT).srec
    $(OBJCOPY) -j .text -O binary $< $(BOOT).text
    $(OBJCOPY) --gap-fill=0xff -O binary $< $@

#将image_data.gzip和.o文件链接成可执行程序$(BOOT).elf
#生成map文件$(BOOT).map
$(BOOT).elf: image_data.gzip $(SRC) $(START) $(COBJS)
    $(LD) -Bstatic -T u-boot.lds -Ttext $(TEXTBASE) $(START) \
        $(COBJS) -Map $(BOOT).map -o $@

    #生成反汇编文件
    $(OBJDUMP) -d  $@ > $@.asm

#检查顶层目录下是否有.reg文件
.PHONY: regfile
regfile:
    @if [ "$(words $(REG))" = "0" ]; then ( \
        echo '***' Need '.reg' or '*.reg' file in directory $(TOPDIR); \
        exit 1; \
    ) fi
    @if [ "$(words $(REG))" != "1" ]; then ( \
        echo '***' Found multi '.reg' or '*.reg' file in directory $(TOPDIR); \
        echo '***' Files: $(notdir $(REG)); \
        exit 1; \
    ) fi

################################################################################
start.o: start.S
    $(CC) -D__ASSEMBLY__ $(CFLAGS) -o $@ $< -c

#将u-boot.bin压缩成image_data.gzip
# -1 : --fast      -9 : --best
image_data.gzip: $(BINIMAGE)
    ./gzip -fNqc -7 $< > $@

%.o: %.c
    $(CC) $(CFLAGS) -Wall -Wstrict-prototypes \
        -fno-stack-protector -o $@ $< -c

%.o: %.S
    $(CC) -D__ASSEMBLY__ $(CFLAGS) -o $@ $< -c

image_data.o: image_data.S image_data.gzip
    $(CC) -D__ASSEMBLY__ $(CFLAGS) -o $@ $< -c

#############################################################################

$(SRC):
    ln -sf ../../../../../../$(filter %/$@,$(SSRC)) $@
################################################################################
TMPS := $(COBJS) start.o $(SRC) \
    $(BOOT).map $(BOOT).elf $(BOOT).srec $(BOOT).bin $(BOOT).text $(BOOT).tmp \
    image_data.gzip

distclean: clean

clean:
    -rm -f $(TMPS)

################################################################################
.PHONY: clean
################################################################################

(1)image_data.gzip:由u-boot.bin被gzip工具压缩形成;
(2)u-boot-hi3516dv300.elf:由image_data.gzip和.o文件,在当前目录的u-boot.lds链接脚本文件指导下被连接成可执行文件,链接地址是0x80700000;还会生成u-boot-hi3516dv300.map地址映射文件和u-boot-hi3516dv300.asm反汇编文件;
(3)u-boot-hi3516dv300.tmp:用objcopy工具将elf格式生成二进制格式;
(4)u-boot-hi3516dv300.bin:由u-boot-hi3516dv300.tmp和.reg文件生成,具体为什么分成tmp1、tmp2、tmp3再组合成最终的烧录镜像,对应我们使用芯片的工程师来说并不清楚,应该是和海思芯片内置的IROM里的代码有关,不过我们也不用关心;

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
thatk
红包 点赞 收藏 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
thatk
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区