第一阶段 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. Flex很难?一文就足够了

    Flexible Box 是什么   布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中就不容易实 ...

  2. 常见文本类css属性

    学习web的第六天 p{ font-size:18px;  /*文本尺寸*/ font-family:"隶书";  /*文本字体*/ font-weight:bold;    /* ...

  3. postgreSQL 玩转josnb (长期更新)

    json和jsonb的操作符 jsonb额外操作符 json创建函数 json处理函数 函数 返回类型 描述 示例 结果 json_array_length(json) jsonb_array_len ...

  4. 第六周LINUX学习笔记

    DNS服务 DNS:Domain Name Service //协议     实现:BIND(Berkeley Internet Name Domain)     监听端口:        UDP:5 ...

  5. Windows系统桌面右击反应变慢、卡顿问题解决方法

    博主的电脑是Win10系统,在修改完系统的用户文件夹名后,桌面右击出现了反应卡顿的现象,并且点击输入法,也变得卡顿.问题解决后,于是想简单记录一下. 还是注册表的问题,使用Win+R快捷键,打开运行, ...

  6. 巧妙地使用typora编辑有道云笔记

    设置方法 找到有道云笔记本地保存路径: 找到有道云笔记的保存的路径:启动有道云 - 设置 - 有道云笔记(本地文件) - 打开文件夹 使用typora打开有道云笔记目录: typora 菜单栏 - O ...

  7. 有趣的 box-decoration-break

    这两天接触到一个很有意思的 CSS 属性 -- box-decoration-break.下面就一起去一探究竟. 因为 MDN 上关于这个属性,没有中文文档,所以一直在想一个合理贴切的中文翻译.直译一 ...

  8. python获取set-cookies

    python获取set-cookies #!/usr/bin/python3.4 # -*- coding: utf-8 -*- import requests url = "https:/ ...

  9. SQL Server常用函数使用方法(学习)

    1.转载至 https://www.cnblogs.com/Brambling/p/6779434.html Substring()函数,用于截取字符串方法,三个参数 参数1:用于指定要操作的字符串 ...

  10. ubuntu 安装 npm、nodejs 各种问题

    nodejs let notifier = require('update-notifier')({pkg}) 报错 先卸载nodejs,然后安装稳定最新版 # apt-get remove node ...