uboot源码分析1-启动第一阶段
start.S引入
/** (C) Copyright 2002* Gary Jennejohn, DENX Software Engineering, ** See file CREDITS for list of people who contributed to this* project.** This program is free software; you can redistribute it and/or* modify it under the terms of the GNU General Public License as* published by the Free Software Foundation; either version 2 of* the License, or (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 59 Temple Place, Suite 330, Boston,* MA 02111-1307 USA*/OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{. = 0x00000000;. = ALIGN(4);.text :{cpu/s5pc11x/start.o (.text)cpu/s5pc11x/s5pc110/cpu_init.o (.text)board/samsung/x210/lowlevel_init.o (.text)cpu/s5pc11x/onenand_cp.o (.text) cpu/s5pc11x/nand_cp.o (.text) cpu/s5pc11x/movi.o (.text) common/secure_boot.o (.text) common/ace_sha1.o (.text)cpu/s5pc11x/pmic.o (.text)*(.text)}. = ALIGN(4);.rodata : { *(.rodata) }. = ALIGN(4);.data : { *(.data) }. = ALIGN(4);.got : { *(.got) }__u_boot_cmd_start = .;.u_boot_cmd : { *(.u_boot_cmd) }__u_boot_cmd_end = .;. = ALIGN(4);.mmudata : { *(.mmudata) }. = ALIGN(4);__bss_start = .;.bss : { *(.bss) }_end = .;
}
(2)在uboot中因为有汇编阶段参与,因此不能直接找main.c。整个程序的入口取决于链接脚本中27行ENTRY声明的地方。ENTRY(_start)因此_start符号所在的文件就是整个程序的起始文件,_start所在处的代码就是整个程序的起始代码。
(2)利用SI工具搜索到一共7个_start,
(1)以上,找到了start.S文件,下面我们就从start.S文件开始分析uboot第一阶段。
(2)在SI中,如果我们知道我们要找的文件的名字,但是我们又不知道他在哪个目录下,我们要怎样找到并打开这个文件?方法是在SI中先打开右边的工程项目管理栏目,然后点击最左边那个(这个是以文件为单位来浏览的),然后在上面输入栏中输入要找的文件的名字。我们在输入的时候,SI在不断帮我们进行匹配,即使你不记得文件的全名只是大概记得名字,也能帮助你找到你要找的文件。
start.S解析1
#include #include #if defined(CONFIG_ENABLE_MMU)
#include #endif
(1)#include <config.h>。config.h是在include目录下的,这个文件不是源码中本身存在的文件,而是配置过程中自动生成的文件。(详见mkconfig脚本)。这个文件的内容其实是包含了一个头文件:#include <configs/x210_sd.h>".
echo "#include <configs/$1.h>" >>config.h
$(@:_config=) arm s5pc11x x210 samsung s5pc110
x210_sd_config里的_config部分用空替换,得到:x210_sd,这就是第一个参数,所以:
$1: x210_sd
$2: arm
$3: s5pc11x
$4: x210
$5: samsumg
$6: s5pc110
所以,$# = 6
.S文件和CPU架构(和硬件)有关了,可移植性就差了。
start.S解析2
#if defined(CONFIG_EVT1) && !defined(CONFIG_FUSED)
.word 0x2000
.word 0x0
.word 0x0
.word 0x0
#endif
.globl _start
_start: b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction:
.word undefined_instruction
_software_interrupt:
.word software_interrupt
_prefetch_abort:
.word prefetch_abort
_data_abort:
.word data_abort
_not_used:
.word not_used
_irq:
.word irq
_fiq:
.word fiq
_pad:
.word 0x12345678 /* now 16*4=64 */
.global _end_vect
_end_vect:
.balignl 16,0xdeadbeef
/*
*************************************************************************
*
* Startup Code (reset vector)
*
* do important init only if we don't start from memory!
* setup Memory and board specific bits prior to relocation.
* relocate armboot to ram
* setup stack
*
*************************************************************************
*/
_TEXT_BASE:
.word TEXT_BASE
(1)异常向量表是硬件决定的,软件只是参照硬件的设计来实现它。
关于ARM的异常:
1.什么是异常:
2.怎样处理:
(1) 关于异常向量表:
(2) 所有的CPU都有异常向量表,这是CPU设计时就设定好的,是硬件决定的
(3) 当异常发生时,CPU会自动动作(PC跳转到异常向量处处理异常,有时伴有一些辅助动作)
(4) 异常向量表是硬件向软件提供的处理异常的支持
2、处理机制:
3、当异常产生时,ARM core:
- 拷贝 CPSR到 SPSR_<mode>
- 设置适当的CPSR位:
、改变处理器状态进入ARM
、改变处理器模式进入相应异常模式
、设置中断禁止位禁止相应中断(如果需要)
- 保存返回地址到 LR_<mode>
- 设置PC为相应的异常变量
4、 返回时,异常处理需要:
- 从SPSR_<mode>恢复CPSR
- 从LR_<mode>恢复PC
- Note:这些操作只能在ARM态执行
(2)源代码中和配置Makefile中很多变量是可以互相运送的。简单来说有些符号的值可以从Makefile中传递到源代码中。
start.S解析3
1.
_TEXT_PHY_BASE:
.word CFG_PHY_UBOOT_BASE
.globl _armboot_start
_armboot_start:
.word _start
所以CFG_PHY_UBOOT_BASE 为0x33e00000,uboot在DDR中的物理地址;
而我们前面指定的链接地址为0xc3e00000;这是虚拟地址;
其实这两个就是一个地址,即虚拟地址映射。后面会讲~
2.设置CPU为SVC模式
reset:
/*
* set the cpu to SVC32 mode and IRQ & FIQ disable
*/
@;mrs r0,cpsr
@;bic r0,r0,#0x1f
@;orr r0,r0,#0xd3
@;msr cpsr,r0
msr cpsr_c, #0xd3 @ I & F disable, Mode: 0x13 - SVC
gnu汇编中的一些符号:
1.@用来做注释。可以在行首也可以在代码后面同一行直接跟,和C语言中//类似
2. #做注释,一般放在行首,表示这一行都是注释而不是代码
3. :以冒号结尾的是标号
4. .点号在gnu汇编中表示当前指令的地址
5. #立即数前面要加#或$,表示这是个立即数
(2)msr cpsr_c, #0xd3将CPU设置为禁止FIQ IRQ,ARM状态,SVC模式。(0xd3=0b11010011)
--------------------------------------------------------------------------------------------------------------------
补充:
mrs & msr
cpsr 和 spsr的区别和联系:
cpsr是程序状态寄存器,整个SoC中只有一个;
spsr是程序状态保存寄存器,有5个分别在5种异常模模式下,作用是当从普通模式进入异常模式时,
用来保存之前普通模式下的spsr,以在返回普通模式时恢复原来的cpsr
注:
1.mrs 用来读psr,msr用来写psr(cpsr、spsr)
2.cpsr寄存器比较特殊,需要专门的指令访问,这就是mrs和msr
--------------------------------------------------------------------------------------------------------------------
(3)其实ARM CPU在复位时默认就会进入SVC模式,但是这里还是使用软件方法将其置为SVC模式-(不依赖硬件的预先设置)。整个uboot工作时CPU一直处于SVC模式。
3.设置L2、L1cache和MMU
bl disable_l2cache
bl set_l2cache_auxctrl_cycle
bl enable_l2cache
/*
* Invalidate L1 I/D
*/
mov r0, #0 @ set up for MCR
mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
orr r0, r0, #0x00000800 @ set bit 12 (Z---) BTB
mcr p15, 0, r0, c1, c0, 0
(2)bl set_l2cache_auxctrl_cycle// l2 cache相关初始化
(3)bl enable_l2cache// 使能l2 cache
(4)刷新L1 cache的icache和dcache。
(5)关闭MMU
总结:上面这5步都是和CPU的cache和mmu有关的,不用去细看,大概知道即可。
注释:MMU是Memory Management Unit的缩写,中文名是内存管理单元,它是中央处理器(CPU)中用来管理虚拟存储器、物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及提供硬件机制的内存访问授权,多用户多进程操作系统。
/* Read booting information */
ldr r0, =PRO_ID_BASE
ldr r1, [r0,#OMR_OFFSET]
bic r2, r1, #0xffffffc1
.................................
/* NAND BOOT */
cmp r2, #0x0 @ 512B 4-cycle
moveq r3, #BOOT_NAND
cmp r2, #0x2 @ 2KB 5-cycle
moveq r3, #BOOT_NAND
cmp r2, #0x4 @ 4KB 5-cycle 8-bit ECC
moveq r3, #BOOT_NAND
cmp r2, #0x6 @ 4KB 5-cycle 16-bit ECC
moveq r3, #BOOT_NAND
cmp r2, #0x8 @ OneNAND Mux
moveq r3, #BOOT_ONENAND
/* SD/MMC BOOT */
cmp r2, #0xc
moveq r3, #BOOT_MMCSD
/* NOR BOOT */
cmp r2, #0x14
moveq r3, #BOOT_NOR
(2)实际上在210内部有一个寄存器(地址是0xE0000004),这个寄存器中的值是硬件根据OM引脚的设置而自动设置值的。这个值反映的就是OM引脚的接法(电平高低),也就是真正的启动介质是谁。
(3)我们代码中可以通过读取这个寄存器的值然后判断其值来确定当前选中的启动介质是Nand还是SD还是其他的。
/*
* Go setup Memory and board specific bits prior to relocation.
*/
ldr sp, =0xd0036000 /* end of sram dedicated to u-boot */
sub sp, sp, #12 /* set stack */
mov fp, #0
bl lowlevel_init /* go setup pll,mux,memory */
uboot源码分析1-启动第一阶段相关推荐
- ARM uboot 源码分析5 -启动第二阶段
一.start_armboot 解析6 1.console_init_f (1) console_init_f 是 console(控制台)的第一阶段初始化._f 表示是第一阶段初始化,_r 表示第二 ...
- uboot源码分析(基于S5PV210)之启动第一阶段
目录 一.start.S引入 1.u-boot.lds中找到start.S入口 2.SourceInsight中如何找到文件 3.SI中找文件技巧 二.start.S解析 1.不简单的头文件包含 2. ...
- 嵌入式之uboot源码分析-启动第二阶段学习笔记(下篇)
接上部分---->嵌入式之uboot源码分析-启动第二阶段学习笔记(上篇) 注:如下内容来自朱老师物联网大讲堂uboot课件 3.2.14 CFG_NO_FLASH (1)虽然NandFlash ...
- linux uboot 源码分析,UBoot源码分析1.pdf
UBoot源码分析1 • UBoot源码解析(一) 主要内容 • 分析UBoot是如何引导Linux内核 • UBoot源码的一阶段解析 BootLoader概念 • Boot Loader 就是在操 ...
- 【四】Spring源码分析之启动主流程---AbstractApplicationContext的refresh方法
入口: 在SpringBoot启动的时候,SpringApplication的run方法中 refreshContext(context); 里面最终调用的是AbstractApplicationCo ...
- X210之uboot源码分析
uboot源码分析 Makefile分析1 自己参考源码. Makefile分析2 ifdef O ifeq ("$(origin O)", "command line& ...
- Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3.0 ARMv7) 【转】...
原文地址:Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3.0 ARMv7) 作者:tekkamanninja 转自:http://blog.chinauni ...
- Linux内核源码分析--内核启动之(4)Image内核启动(setup_arch函数)(Linux-3.0 ARMv7)【转】...
原文地址:Linux内核源码分析--内核启动之(4)Image内核启动(setup_arch函数)(Linux-3.0 ARMv7) 作者:tekkamanninja 转自:http://blog.c ...
- Wifi模块—源码分析Wifi启动(Android P)
一.前言 Android P在wifi这块改动挺大的,Wifi到AndoidO之后不再使用jni,所以AndroidP也一样不再使用jni来实现Java代码与本地的C/C++代码交互,而是使用HIDL ...
最新文章
- python安装在哪个盘_python要安装在哪个盘
- spring storedProcedure 使用
- fruncm server sql 无法生成 线程_MSSQLSERVER启动不了,报SQL Server 无法生成 FRunCM 线程...
- [NewLife.XCode]数据模型文件
- 东方卫视收视率查询_肖战被嘲撑不起跨年收视率,看了东方卫视收视曲线,这锅不背!...
- php中的active,用ActivePHP打造版本管理系统
- android 字体像素转换工具类_android工具类,转换大小写,保留小数点处理方法
- mysql数据库诊断_RDS MySQL 数据库全量SQL诊断
- C语言和C+的区别是什么?8个点通俗易懂的告诉你
- 开发宝典:基于分布式对象的网游程序结构设计
- 游戏设计要素探秘之术语的呼唤
- 面向对象(Python):学习笔记之继承
- 星光不问赶路人,时光不负奇舞团
- 【C语言】扫雷(递归展开 + 标记功能)
- 京东自动评价助手/京东评价
- android 实现 bilili 动画播放效果
- Hie with the Pie(旅行商问题)
- 微信小程序---目录结构
- vue.runtime.esm.js?2b0e:619 [Vue warn]: Duplicate keys detected: ‘xxx‘. This may cause an update err
- 阿里云数据湖分析急招实习生