海思uboot启动流程详细分析(一)
第一阶段 start.S
首先我们可以在u-boot.lds中看到ENTRY(_start),即指定了入口_start,_start也就是整个start.S的最开始;
1. reset
在arch\arm\cpu\armv8\hi3559av100中的start.S
注意x30在ARMV8中代表lr寄存器
reset:
/*
* Could be EL3/EL2/EL1, Initial State:
* Little Endian, MMU Disabled, i/dCache Disabled
*/
adr x0, vectors
switch_el x1, 3f, 2f, 1f
3: msr vbar_el3, x0
mrs x0, scr_el3
orr x0, x0, #0xf /* SCR_EL3.NS|IRQ|FIQ|EA */
msr scr_el3, x0
msr cptr_el3, xzr /* Enable FP/SIMD */
#ifdef COUNTER_FREQUENCY
ldr x0, =COUNTER_FREQUENCY
msr cntfrq_el0, x0 /* Initialize CNTFRQ */
#endif
b 0f
2: msr vbar_el2, x0
mov x0, #0x33ff
msr cptr_el2, x0 /* Enable FP/SIMD */
b 0f
1: msr vbar_el1, x0
mov x0, #3 << 20
msr cpacr_el1, x0 /* Enable FP/SIMD */
0:
/*
* Cache/BPB/TLB Invalidate
* i-cache is invalidated before enabled in icache_enable()
* tlb is invalidated before mmu is enabled in dcache_enable()
* d-cache is invalidated before enabled in dcache_enable()
*/
/*
* read system register REG_SC_GEN2
* check if ziju flag
*/
ldr x0, =SYS_CTRL_REG_BASE
ldr w1, [x0, #REG_SC_GEN2]
ldr w2, =0x7a696a75 /* magic for "ziju" */
cmp w1, w2
bne normal_start_flow
mov x1, sp /* save sp */
str w1, [x0, #REG_SC_GEN2] /* clear ziju flag */
adr x0, vectors,其中的vectors代表了异常向量表
主要做了如下事情:
1)reset SCTRL寄存器
具体可参考reset_sctrl函数,由CONFIG_SYS_RESET_SCTRL控制,一般不需要打开。该配置项的解释如下:
Reset the SCTRL register at the very beginning of execution to avoid interference from stale mappings set up by early firmware/loaders/etc.
http://lists.denx.de/pipermail/u-boot/2015-April/211147.html
2)根据当前的EL级别,配置中断向量、MMU、Endian、i/d Cache等。
3)配置ARM的勘误表
具体可参考apply_core_errata函数,由CONFIG_ARM_ERRATA_XXX控制,在项目的初期,可以不打开,后续根据实际情况打开)。
2. normal_start_flow流程
这里是正常启动流程
normal_start_flow:
/* set stack for C code */
ldr x0, =(CONFIG_SYS_INIT_SP_ADDR)
bic sp, x0, #0xf /* 16-byte alignment for ABI compliance */
bl uart_early_init
adr x0, Str_SystemSartup
bl uart_early_puts
ldr x0, =0x1202008c
ldr w0, [x0]
bl uart_early_put_hex
/* enable I-Cache */
bl icache_enable
1)设置代码的堆栈
2.)跳转到uart_early_init
因为uart_early_init是全局的伪汇编指令(在uart.S中定义),所以在start.S中也可以使用到
3)声明一个字符串Str_SystemSartup
4)使能icache
因为bne normal_start_flow是不跳转回来的,所以会继续向下执行
3. running_addr_check流程
判断是否进入not_ddr_init中,不需要DDR初始化,直接copy到DDR中
check_boot_mode:
ldr x0, =SYS_CTRL_REG_BASE
ldr w0, [x0, #REG_SYSSTAT]
lsr w6, w0, #4
and w6, w6, #0x3
cmp w6, #BOOT_FROM_EMMC //判断是不是EMMC启动
bne ufs_boot //如果不是,则进入ufs_boot
4. ziju_flow流程
自举模式从这里我可以推断出,芯片的启动分为两种,一种是自举模式也就是本地的spiflash或nand或emmc等启动,另一种就是pcie启动模式。不同启动模式对应不同的启动流程。但不同启动模式代码是相互交织的,需要分清楚!
1) 初始化PLL和DDRC控制器和管脚复用情况。
/* init PLL/DDRC/pin mux/... */
ldr r0, _blank_zone_start
ldr r1, _TEXT_BASE
sub r0, r0, r1
ldr r1, =RAM_START_ADRS
add r0, r0, r1
mov r1, #0x0 /* flags: 0->normal 1->pm */
bl init_registers /* init PLL/DDRC/... */
bl init_registers这个函数是初始化一些寄存器,这些寄存器分了很多,包括中断、网络、哈希功能形式的寄存器,初始化的意思就是给一个值,但这值一般没什么意义,具体的寄存器,后面会再进行配置!
2) start_ddr_training
/* DDR training:DR布线,完全按等长约束就没有ddr training的说法。
当布线去掉等长约束或放宽约束条件,就要做ddr training,以保证时序的完整性,使信号的建立&保持时间窗口一致。ddr training是调整Addr/Cmd信号对CLK,DQ信号对DQS的延时。由于没做等长约束,信号有长,有短,就会导致信号有快,慢之差(信号在1000mil走线耗时约160~180ps,相对FR-4的板材),ddr training就是找到一套参数,使信号的建立与保持时间充足。并保存且写到配置中。*/
3) pcie_slave_boot
5. jump_to_ddr
自举模式省略了一些PCIE判断的情况的解释,我也没怎么看懂
jump_to_ddr:
adr x0, _start_armboot
ldr x30,[x0]
ret
开始进入跳转到C语言阶段
总结
- 关cache,关mmu,SVC模式
- 检测是不是自举模式还是pcie启动,也包括是冷启动还是热启动
- 串口初始化
- DDR初始化和DDR training
- 正常启动时,会检测启动方式,对代码进行相应的拷贝,重定位
- 设置堆栈
- 清bss段
- 跳转到第二阶段,即C语言阶段
海思uboot启动流程详细分析(一)的更多相关文章
- 海思uboot启动流程详细分析(转)
海思uboot启动流程详细分析(一) 海思uboot启动流程详细分析(二) 海思uboot启动流程详细分析(三)
- 海思uboot启动流程详细分析(三)【转】
1. 前言 书接上文(u-boot启动流程分析(二)_平台相关部分),本文介绍u-boot启动流程中和具体版型(board)有关的部分,也即board_init_f/board_init_r所代表的. ...
- 海思uboot启动流程详细分析(二)
1. 第二个start.S 从start_armboot开始,在startup.c中有包含#include <config.h> 在config.h中: /* Automatically ...
- lk启动流程详细分析
转载请注明来源:cuixiaolei的技术博客 这篇文章是lk启动流程分析(以高通为例),将会详细介绍下面的内容: 1).正常开机引导流程 2).recovery引导流程 3).fastboot引导流 ...
- 【内核】linux内核启动流程详细分析
Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件,包括内核入口ENTRY(stext)到start_kernel间的初始化代码, 主要作用 ...
- 【内核】linux内核启动流程详细分析【转】
转自:http://www.cnblogs.com/lcw/p/3337937.html Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件 ...
- u-boot启动流程分析(2)_板级(board)部分
转自:http://www.wowotech.net/u-boot/boot_flow_2.html 目录: 1. 前言 2. Generic Board 3. _main 4. global dat ...
- imx6 uboot启动流程分析
参考http://blog.csdn.net/skyflying2012/article/details/25804209 这里以imx6平台为例,分析uboot启动流程对于任何程序,入口函数是在链接 ...
- Uboot启动流程分析(一)
1.前言 Linux系统的启动需要一个bootloader程序,该bootloader程序会先初始化DDR等外设,然后将Linux内核从flash中拷贝到DDR中,最后启动Linux内核,uboot的 ...
随机推荐
- vue学习记录⑤(组件通信-父与子)
今天我们看一下组件通信. 经过前面几篇文章,我们已经可以构建出完整的单个组件,并利用路由使其串联起来访问了. 但这明显还是不够的.一个页面不可能就是个单组件,一般是由多个组件合成的.正因为如此,组件之 ...
- css 选择器基础
有时在看别人代码时,看到一长串的选择器经常有点懵,今天来夯实一下基础 选择器有: 1.标签选择器 :就是HTML 中的标签 如<p> <h1> <body>等 2. ...
- 事务及其特性ACID
一.事务的定义 事务是一组单元化的操作,这组操作可以保证要么全部成功,要么全部失败(只要有一个失败的操作,就会把其他已经成功的操作回滚). 一般所说的数据库事务,它是访问并可能更新数据库中各种数据项的 ...
- javascript中apply、call和bind的区别及方法详解
文章目录 apply.call apply.call 区别 apply.call实例 数组之间追加 获取数组中的最大值和最小值 验证是否是数组(前提是toString()方法没有被重写过) 类(伪 ...
- CTF丨从零开始搭建WEB Docker靶场
第十二届全国大学生信息安全竞赛即将开始,小伙伴们有报名参加的吗?大家在比赛前是否开始进行模拟演练了?今天,i春秋将与大家分享靶场搭建的相关内容,帮助大家更好的进行实操演练. 学习搭建Docker靶场之 ...
- 新更新kb4493472导致无法正常开机
昨天陆续接到电话,说是系统更新后电脑不能正常使用,症状基本是开机到欢迎界面就出现各种各样的状况,比如鼠标能动,其他无反应;欢迎界面结束后黑屏,只有鼠标能动:开机后正常,但电脑使用很卡等等状况.因为昨天 ...
- markdown用法
Markdown 语法的目标是成为一种适用于网络的书写语言.不在 Markdown 涵盖范围之内的标签,都可以直接在文档里面用 HTML 撰写.不需要额外标注,只要直接加标签就可以了. 一.常用部分 ...
- 我所不知道的Makefile语法
问题一: $(CC) -c $^ -o $(ROOT_DIR)/$(OBJS_DIR)/$@ 这里的$^和$@是设么意思? 经过查找,该特殊符号的用法如下: 假如:all:library.cpp ma ...
- 网络协议 3 - 从物理层到 MAC 层
在上一篇博文中,我们见证了 IP 地址的诞生,机器一旦有了 IP,就可以在网络的环境里和其他的机器展开沟通了. 今天,我们来认识下 物理层 和 MAC 层. 日常生活中,身为 ...
- 使用sklearn时cannot import name MLPClassifier的解决办法
scikit-learn v0.17只有BernoulliRBM,没有MLPClassifier. 只需要把scikit-learn升级到v0.18即可. 在控制台输入下面任一个命令即可: conda ...