我是靠谱客的博主 落寞芝麻,这篇文章主要介绍海思芯片(hi3516dv300)uboot启动过程分析1、海思分段式uboot镜像2、海思分段式uboot镜像的优劣3、dv300芯片的地址映射4、海思uboot启动流程5、启动第一阶段6、启动第二阶段,现在分享给大家,希望可以做个参考。

1、海思分段式uboot镜像

(1)uboot镜像的生成参考博客:《海思芯片(hi3516dv300)uboot镜像生成过程详解》;
(2)海思uboot镜像类似于内核的zImage镜像,大致组成就是未压缩的头部+压缩的镜像,先运行未压缩的头部代码,头部代码会解压缩镜像并调用;

2、海思分段式uboot镜像的优劣

优点:
(1)将寄存器的设置单独用表格形式,形象直观并修改方便;
(2)压缩的镜像占的空间更小,传统的uboot.bin大小有501KB,经压缩行成的u-boot-hi3516dv300.bin大小只有21KB;
缺点:
(1)uboot镜像的生成过程变得更复杂;
(2)uboot的启动过程也变得复杂,先运行未压缩代码去解压缩,再运行压缩部分代码;
补充:海思芯片内置了硬件解压缩模块,解压缩工作是硬件完成的;

3、dv300芯片的地址映射

(1)海思hi3516dv300芯片内置BOOTROM是64KB,片内RAM是40KB,可以推测uboot启动第一阶段读进去的数据不会超过40KB;
(2)海思芯片是ARM结构,采用统一编址,32位CPU理论上可以接4G的内存,但是实际最多可以接2G内存,其余的地址空间被分配给寄存器、BOOTROM、片内RAM;

4、海思uboot启动流程

(1)海思芯片内置BOOTROM代码会从串口/网络/eMMC/Nor flash/Nand flash等方式读取uboot镜像的头部(读取的头部数据具体大小不确定,但肯定不超过40KB)到芯片内部的RAM中运行;
(2)读进去的uboot头部程序,会解析.reg文件去设置寄存器,初始化DDR;
(3)将整个uboot镜像重定位到DDR中,利用芯片硬件解压缩模块,将压缩的uboot.bin解压缩到DDR中,然后执行解压缩后的uboot代码;
(4)解压缩后的uboot代码会去初始化板级硬件,比如屏幕、触摸屏等等,最终启动内核;

5、启动第一阶段

5.1、第一阶段定义

这里说的第一阶段不是官方定义,只是个人理解,将执行压缩uboot镜像前的过程叫做第一阶段。

5.2、第一阶段涉及的源代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
u-boot-2016.11/arch/arm/cpu/armv7/hi3516dv300/hw_compressed/Makefile u-boot-2016.11/arch/arm/cpu/armv7/hi3516dv300/hw_compressed/u-boot.lds u-boot-2016.11/.reg u-boot-2016.11/u-boot.bin //.o文件,在Makefile中指定,按照链接脚本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

(1)根据链接脚本u-boot.lds可知,第一阶段的入口是u-boot-2016.11/arch/arm/cpu/armv7/hi3516dv300/hw_compressed/start.S的_start标号处;
(2)从start.S的_start标号处开始分析汇编代码,涉及的文件在Makefile中指定,注意文件的路径,因为在uboot源码中有很多同名文件;

5.3、第一阶段的代码流程

在这里插入图片描述

5.4、uboot镜像的解压缩代码

复制代码
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
//u-boot-2016.11/arch/arm/cpu/armv7/hi3516dv300/hw_compressed/image_data.S .section .image,#alloc .globl input_data /*gzip source addr must be 16 bytes aligned*/ .balign 16 input_data: .incbin "image_data.gzip" .globl input_data_end input_data_end: #define CONFIG_SYS_TEXT_BASE 0x80800000 #define GZIP_SIZE_OFFSET 0x4 const unsigned long IMAGE_ENTRY = (CONFIG_SYS_TEXT_BASE); //u-boot-2016.11/arch/arm/cpu/armv7/hi3516dv300/hw_compressed/startup.c void start_armboot(void) { unsigned char *pdst_l32; unsigned int image_data_len; int pdst_len; int ret; int i; char *p; char *q; uart_early_init(); uart_early_puts("rnUncompress "); /*use direct address mode*/ hw_dec_type=0; /*初始化硬件解压缩模块*/ hw_dec_init(); /*将压缩镜像解压后存放的内存地址*/ pdst_l32 = (unsigned char *)IMAGE_ENTRY; //整个被压缩镜像(image_data.gzip)的长度 image_data_len = input_data_end - input_data; /*获取被压缩镜像本来的大小,也就是uboot.bin的大小*/ p = (char *)&pdst_len; q = (char *)(input_data_end - GZIP_SIZE_OFFSET); for (i = 0; i < sizeof(int); i++) { p[i] = q[i]; } //解压u-boot.bin到内存地址0x80800000 ret = hw_dec_decompress(pdst_l32, &pdst_len, input_data, image_data_len, NULL); if (!ret) uart_early_puts("Ok!"); else { uart_early_puts("Fail!"); while(1); } /*反初始化硬件解压缩模块,节省性能,降低功耗*/ hw_dec_uinit(); //调用解压缩后的uboot代码,直接调用内存地址0x80800000,也就是uboot.bin镜像的入口 void (*uboot)(void); uboot = (void (*))CONFIG_SYS_TEXT_BASE; invalidate_icache_all(); uboot(); }

(1)input_data和input_data_end是压缩内核镜像(image_data.gzip)在内存中的起始/结束地址;
(2)解压缩模块是海思芯片内置的硬件模块,我们不用关心,只要按照解压函数的参数要求进行传参即可;

6、启动第二阶段

(1)在uboot启动第一阶段调用了uboot启动的第二阶段,也就是执行u-boot.bin;
(2)u-boot.bin就是一般的uboot启动流程,具体去分析顶层Makefile中是如何生成u-boot.bin的,根据链接脚本找到入口地址,这里不再赘述,可以参考我以前的uboot启动流程分析的博客;

最后

以上就是落寞芝麻最近收集整理的关于海思芯片(hi3516dv300)uboot启动过程分析1、海思分段式uboot镜像2、海思分段式uboot镜像的优劣3、dv300芯片的地址映射4、海思uboot启动流程5、启动第一阶段6、启动第二阶段的全部内容,更多相关海思芯片(hi3516dv300)uboot启动过程分析1、海思分段式uboot镜像2、海思分段式uboot镜像内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(59)

评论列表共有 0 条评论

立即
投稿
返回
顶部