第一阶段 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语言阶段

总结

  1. 关cache,关mmu,SVC模式
  2. 检测是不是自举模式还是pcie启动,也包括是冷启动还是热启动
  3. 串口初始化
  4. DDR初始化和DDR training
  5. 正常启动时,会检测启动方式,对代码进行相应的拷贝,重定位
  6. 设置堆栈
  7. 清bss段
  8. 跳转到第二阶段,即C语言阶段

海思uboot启动流程详细分析(一)的更多相关文章

  1. 海思uboot启动流程详细分析(转)

    海思uboot启动流程详细分析(一) 海思uboot启动流程详细分析(二) 海思uboot启动流程详细分析(三)  

  2. 海思uboot启动流程详细分析(三)【转】

    1. 前言 书接上文(u-boot启动流程分析(二)_平台相关部分),本文介绍u-boot启动流程中和具体版型(board)有关的部分,也即board_init_f/board_init_r所代表的. ...

  3. 海思uboot启动流程详细分析(二)

    1. 第二个start.S 从start_armboot开始,在startup.c中有包含#include <config.h> 在config.h中: /* Automatically ...

  4. lk启动流程详细分析

    转载请注明来源:cuixiaolei的技术博客 这篇文章是lk启动流程分析(以高通为例),将会详细介绍下面的内容: 1).正常开机引导流程 2).recovery引导流程 3).fastboot引导流 ...

  5. 【内核】linux内核启动流程详细分析

    Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件,包括内核入口ENTRY(stext)到start_kernel间的初始化代码, 主要作用 ...

  6. 【内核】linux内核启动流程详细分析【转】

    转自:http://www.cnblogs.com/lcw/p/3337937.html Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件 ...

  7. u-boot启动流程分析(2)_板级(board)部分

    转自:http://www.wowotech.net/u-boot/boot_flow_2.html 目录: 1. 前言 2. Generic Board 3. _main 4. global dat ...

  8. imx6 uboot启动流程分析

    参考http://blog.csdn.net/skyflying2012/article/details/25804209 这里以imx6平台为例,分析uboot启动流程对于任何程序,入口函数是在链接 ...

  9. Uboot启动流程分析(一)

    1.前言 Linux系统的启动需要一个bootloader程序,该bootloader程序会先初始化DDR等外设,然后将Linux内核从flash中拷贝到DDR中,最后启动Linux内核,uboot的 ...

随机推荐

  1. 零基础学Python--------第3章 流程控制语句

    第3章 流程控制语句 3.1程序的结构 计算机在解决某个具体问题时,主要有3种情况,分别是顺序执行所有的语句.选择执行部分语句和循环执行部分语句.程序设计中的3种基本结构为顺序结构.选择结构和循环结构 ...

  2. CSS 火焰?不在话下

    正文从下面开始. 今天的小技巧是使用纯 CSS 生成火焰,逼真一点的火焰. 嗯,长什么样子?在 CodePen 上输入关键字 CSS Fire,能找到这样的: 或者这样的: 我们希望,仅仅使用 CSS ...

  3. windows系统中,在当前目录下打开cmd命令行的两种方法

    1.在当前路径地址栏中直接输入‘cmd’,然后回车. 2.在当前路径下,按住‘shift’键同时点击鼠标右键,点击“在此处打开Powershell”. 其实你会发现,两个命令行有很大的区别. cmd: ...

  4. vmware P2V迁移域内windows服务器脱域问题

    windows 域服务器采用vmware converter进行物理机转换为虚拟机,需要在完成后进行退域重新加域操作. 否则,有可能会出现服务器在30天后脱域情况.出现脱域情况,可以通过退域加域的方式 ...

  5. 为什么腾讯有QQ,还要推出微信?

    在微信刚出现时候,很多人奇怪,为什么腾讯有QQ,还要推出微信? 一开始,我也认为它与QQ没有什么区别.有这种看法,是因为绝大多数时候,我都仅仅只使用即时聊天功能,微信上有的语音.视频.文字等等,这些在 ...

  6. Java相关资料分享(视频+电子书籍)

    正所谓“授人以鱼不如授人以渔”,你们想要的Java学习资料来啦!不管你是学生,还是已经步入职场的同行,希望你们都要珍惜眼前的学习机会,奋斗没有终点,知识永不过时. 关注底下的公众号,获取百度网盘提取码 ...

  7. jdk各个版本的新特性(jdk1.7,1.8,1.9)

    用了这么久的jdk,应该会有很多人和我一样,不知道各个版本的jdk的一些新特性,这里简单总结一下.. jdk1.7新特性: 1.在Switch中可以用String字符串 2.对Java集合(Colle ...

  8. Kubernetes 笔记 11 Pod 扩容与缩容 双十一前后的忙碌

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. Hi,大家好, ...

  9. oracle无法插入数据

    最近遇到一个问题,本来插入数据好好的,突然都不能插入了. 报错------------------->ora-01653:表无法通过128(在表空间)扩展 原因是表满了!!! 解决方案: 1. ...

  10. 【TensorFlow篇】--Tensorflow框架实现SoftMax模型识别手写数字集

    一.前述 本文讲述用Tensorflow框架实现SoftMax模型识别手写数字集,来实现多分类. 同时对模型的保存和恢复做下示例. 二.具体原理 代码一:实现代码 #!/usr/bin/python ...