第一阶段 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. JAVA设计模式之简单粗暴学建造者模式

    文章由浅入深,先用简单例子说明建造者,然后分析模式的优缺点,最后结合优秀开源框架Mybatis,说明该模式的用处. 1.先定义一个机器人模型 package com.jstao.model; publ ...

  2. nginx漏洞分析与升级修复

    一 .此次漏洞分析 1 nginx HTTP/2漏洞 [nginx-announce] nginx安全公告(CVE-2018-16843,CVE-2018-16844)在nginx HTTP / 2实 ...

  3. 项目中git分支管理策略

  4. postgresql 添加uuid扩展

    去年用EF Core做数据迁移到psql数据库的时候遇到了缺失uuid的错误,当时帅气的脸蛋突然懵逼了.现记录一下 以备参考. 环境:Centos7.2  psql  Xshell Xshell连接C ...

  5. 【深度学习篇】--神经网络中的池化层和CNN架构模型

    一.前述 本文讲述池化层和经典神经网络中的架构模型. 二.池化Pooling 1.目标 降采样subsample,shrink(浓缩),减少计算负荷,减少内存使用,参数数量减少(也可防止过拟合)减少输 ...

  6. 网络协议 12 - HTTP 协议:常用而不简单

    系列文章传送门: 网络协议 1 - 概述 网络协议 2 - IP 是怎么来,又是怎么没的? 网络协议 3 - 从物理层到 MAC 层 网络协议 4 - 交换机与 VLAN:办公室太复杂,我要回学校 网 ...

  7. 【重学计算机】机组D5章:指令系统

    1. 指令系统基本概念 指令集:一台机器所有指令的集合.系列机(同一公司不同时期生产):兼容机(不同公司生产) 指令字长:指令中包含的二进制位数,有等长指令.变长指令. 指令分类 根据层次结构:高级. ...

  8. 『集群』006 Slithice 后期改进 和 Slithice可能存在的BUG

    Slithice 后期改进 和 Slithice可能存在的BUG Slithice 可能存在的 BUG: >Slithice 暂时 没有 对 循环调度 进行控制:不正确的 配置 可能导致 调度死 ...

  9. DotNetCore跨平台~在appsettings.json里自定义配置项

    回到目录 DotNetCore里一切都是依赖注入的,对于appsettings这个可扩展的配置对象也不例外,它位于项目根目录,一般在startup里去注册它,在类中通过构造方法注入来获取当前的对象,以 ...

  10. 补习系列(17)-springboot mongodb 内嵌数据库

    目录 简介 一.使用 flapdoodle.embed.mongo A. 引入依赖 B. 准备测试类 C. 完善配置 D. 启动测试 细节 二.使用Fongo A. 引入框架 B. 准备测试类 C.业 ...