U-BOOT概述及源码分析(一)
嵌入式Linux系统从软件角度通常可以分为以下4个层次:
引导加载程序 | Linux内核 | 文件系统 | 用户应用程序
嵌入式Linux系统中典型分区结构:

正常启动过程中,Bootloader首先运行,然后它将内核复制到内核中,并且在内存某个固定地址设置好要传递给内核的参数,最后运行内核。内核启动之后,它会挂接根文件系统,启动文件系统中的应用程序。
一、Bootloader的作用:
CPU上电后,会从某个地址开始执行,对于ARM结构的CPU是从0x00000000开始,Bootloader就存放在这个地址的开始处。这样一上电就可以执行。Bootloader主要用于初始化最基本的硬件、准备好软件环境和加载Linux操作系统。
在Linux内核启动时,除了内核映像必须在主存的适当位置外,CPU还必须满足以下条件:
CPU寄存器的设置
1、R0 = 0
2、R1 = Machine ID
3、R2 = 内核启动参数在RAM中的起始基地址
U-boot最终是调用theKernel函数来跳转执行linux内核的,uboot调用此函数(即linux内核)时会直接传递给linux内核3个参数,而这3个参数就是通过寄存器来实现传参的。
其中第1个参数固定为0,就放在r0寄存器中,第二个参数为机器类型ID即机器码,放在r1寄存器,第3个参数就是启动参数标记列表在RAM中的首地址,就放在r2寄存器中。
CPU模式
1、必须禁止中断(IRQs 和 FIQs,中断请求和快速中断请求)
2、CPU必须是SVC模式(特权模式)
为何要禁止中断?---因为U-Boot只是完成硬件初始化、环境参数设置、代码搬运等工作,用不到中断,屏蔽中断是为了避免因为意外中断使得boot失败,毕竟很多外设还
没有初始化,对应中断代码也都没有准备好。
为何特权模式?---从uboot方面考虑,其要做的事情是初始化系统相关硬件资源,需要获取尽量多的权限,以方便操作硬件,初始化硬件。设置为svc模式,更有利于其工作。
  Cache 和MMU 的设置
    1、 MMU 必须关闭。
     2、 指令Cache 可以打开也可以关闭。
     3、数据Cache 必须关闭。
MMU在上电之初没有任何作用,即U-boot第一阶段的汇编代码与第二阶段的源代码初始化相关外设时访问的都是实际地址,为了启动之初不影响对程序启动常关MMU。
Cache是位于RAM和CPU内部寄存器之间的一个存储设施,用来加速二者之间的数据传输速度,即用来加快CPU从内存中取出指令的速度。但是在上电后CPU的初始化要比内存RAM快一拍,当CPU初始化完成后需要读取来自内存的数据,若内存还没有准备好那势必会造成异常,系统就挂掉了,因此需要关闭数据Cache,而指令Cache关与不关影响不大。
1、源代码组织
对于ARM而言,主要的目录如下:
board 平台依赖 存放电路板相关的目录文件,每一套板子对 应一个目录。如smdk2410(arm920t)
cpu 平台依赖 存放CPU相关的目录文件,每一款CPU对应一个目录,例如:arm920t、 xscale、i386等目录
lib_arm 平台依赖 存放对ARM体系结构通用的文件,主要用于实现ARM平台通用的函数,如软件浮点。
common 通用 通用的多功能函数实现,如环境,命令,控制台相关的函数实现。
include 通用 头文件和开发板配置文件,所有开发板的配置文件都在configs目录下
lib_generic 通用 通用库函数的实现
net 通用 存放网络协议的程序
drivers 通用 通用的设备驱动程序,主要有以太网接口的驱动,nand驱动。
.......
启动相关的几个重要文件:
1)cpu/arm920t 目录下
Start.S文件是一个汇编代码文件,是Bootloader运行的第一个文件,Bootloader的入口。
U-boot.lds 文件是一个连接器用的连接脚本文件,用来指定映像文件中各段的加载地址和运行地址。
......
2)Makefile简要分析
  所有这些目录的编译连接都是由顶层目录的makefile来确定的。
  在执行make之前,先要执行make $(board)_config 对工程进行配置,以确定特定于目标板的各个子目录和头文件。
  $(board)_config:是makefile 中的一个伪目标,它传入指定的CPU,ARCH,BOARD,SOC参数去执行mkconfig脚本。
  这个脚本的主要功能在于连接目标板平台相关的头文件夹,生成config.h文件包含板子的配置头文件。
  使得makefile能根据目标板的这些参数去编译正确的平台相关的子目录。
  以smdk2410板为例,执行 make smdk2410_config,
  主要完成三个功能:
    1)在include文件夹下建立相应的文件(夹)软连接,
    #如果是ARM体系将执行以下操作:
    #ln -s     asm-arm        asm   
    #ln -s  arch-s3c24x0    asm-arm/arch 
    #ln -s   proc-armv       asm-arm/proc
2)生成Makefile包含文件include/config.mk,内容很简单,定义了四个变量:
    ARCH   = arm
    CPU    = arm920t
    BOARD  = smdk2410
    SOC    = s3c24x0
3)生成include/config.h头文件,只有一行:
    /* Automatically generated - do not edit */
    #include "config/smdk2410.h"
    顶层makefile先调用各子目录的makefile,生成目标文件或者目标文件库。
    然后再连接所有目标文件(库)生成最终的u-boot.bin。
    连接的跟平台相关的主要目标(库)如下:
    cpu/$(CPU)/start.o 
    board/$(BOARDDIR)/lib$(BOARD).a 
    cpu/$(CPU)/lib$(CPU).a
    cpu/$(CPU)/$(SOC)/lib$(SOC).a 
    lib_$(ARCH)/lib$(ARCH).a
    这里面的四个变量定义在include/config.mk(见上述)。
    其余的均与平台无关。
    所以考虑移植的时候也主要考虑这几个目标文件(库)对应的目录。
U-boot启动流程:
从文件层面上看主要流程是在两个文件中:cpu/arm920t/start.s,lib_arm/board.c,下一节开始分析start.s
思考:
为什么引导代码不全用C语言写?
1、在初始化硬件时,需要设置特殊功能寄存器,比如CPU工作模式,C语言不能对这些寄存器操作
2、C程序运行需要提前设置栈空间。
U-BOOT概述及源码分析(一)的更多相关文章
- spring boot 2.0 源码分析(一)
		在学习spring boot 2.0源码之前,我们先利用spring initializr快速地创建一个基本的简单的示例: 1.先从创建示例中的main函数开始读起: package com.exam ... 
- spring boot 2.0 源码分析(四)
		在上一章的源码分析里,我们知道了spring boot 2.0中的环境是如何区分普通环境和web环境的,以及如何准备运行时环境和应用上下文的,今天我们继续分析一下run函数接下来又做了那些事情.先把r ... 
- Spring Boot 自动配置 源码分析
		Spring Boot 最大的特点(亮点)就是自动配置 AutoConfiguration 下面,先说一下 @EnableAutoConfiguration ,然后再看源代码,到底自动配置是怎么配置的 ... 
- spring boot 2.0 源码分析(二)
		在上一章学习了spring boot 2.0启动的大概流程以后,今天我们来深挖一下SpringApplication实例变量的run函数. 先把这段run函数的代码贴出来: /** * Run the ... 
- spring boot 2.0 源码分析(三)
		通过上一章的源码分析,我们知道了spring boot里面的listeners到底是什么(META-INF/spring.factories定义的资源的实例),以及它是创建和启动的,今天我们继续深入分 ... 
- spring boot 2.0 源码分析(五)
		在上一篇文章中我们详细分析了spring boot是如何准备上下文环境的,今天我们来看一下run函数剩余的内容.还是先把run函数贴出来: /** * Run the Spring applicati ... 
- spring boot中扩展spring mvc 源码分析
		首先,确认你是对spring boot的自动配置相关机制是有了解的,如果不了解请看我spring boot相关的源码分析. 通常的使用方法是继承自org.springframework.boot.au ... 
- ArrayList源码分析-jdk11 (18.9)
		目录 1.概述 2.源码分析 2.1参数 2.2 构造方法 2.2.1 无参构造方法 2.2.2 构造空的具有特定初始容量值方法 2.2.3构造一个包含指定集合元素的列表,按照集合的迭代器返回它们的顺 ... 
- 精尽Spring Boot源码分析 - 序言
		该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ... 
随机推荐
- IDEA无法启动:Failed to create JVM:error code -4
			发生该错误的原因是由于IDEA须要使用的连续内存空间没有得到满足,解决方式: 1.减小-Xmx和-XX:PermSize的值 切换到IDE_HOME\bin\文件夹下,找到<produc ... 
- SPOJ 题目705 New Distinct Substrings(后缀数组,求不同的子串个数)
			SUBST1 - New Distinct Substrings no tags Given a string, we need to find the total number of its di ... 
- 英语音乐---三、Cry on my shoulder
			英语音乐---三.Cry on my shoulder 一.总结 一句话总结:Cry on my shoulder 在我的肩膀上哭泣 1.If the hero never comes to you. ... 
- Python 序列化处理
			序列化 文件为dump 字符串为dumps dumps()方法返回一个str,内容就是标准的JSON loads()方法将其还原 在程序运行的过程中,所有的变量都是在内存 d = dict(name= ... 
- ListView的setOnItemClickListener回调不能执行的解决
			如果ListView中的单个Item的view中存在checkbox,button等view,会导致ListView.setOnItemClickListener无效,事件会被子View捕获到,Lis ... 
- javascript实现多线程 Concurrent.Thread.js
			在这次我的项目中,因为前端要检测硬件加载并识别,再向后台请求发送数据,然后再返回的相应的配置文件!在这过程,要好时好几秒钟,严重影响体验效果,所以在网上靠看的方案,运用多线程去处理,这效果明显改善! ... 
- 洛谷1019 单词接龙 字符串dfs
			问题描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合 ... 
- 洛谷—— P2934 [USACO09JAN]安全出行Safe Travel  || COGS ——279|| BZOJ——1576
			https://www.luogu.org/problem/show?pid=2934 题目描述 Gremlins have infested the farm. These nasty, ugly ... 
- [Recompose] Create Stream Behaviors to Push Props in React Components with mapPropsStream
			Rather than using Components to push streams into other Components, mapPropsStream allows you to cre ... 
- [Python] Generating random numbers using numpy lib
			import numpy as np def test_run(): data=np.random.random((3,4)) """ [[ 0.80150549 0.9 ... 
