femto uboot 走读
- 格式:docx
- 大小:947.87 KB
- 文档页数:21
刷入uboot和大分区的方法一、概念解释1.1 uboot是什么U-boot是一种开源的引导加载程序,它通常用于嵌入式系统的启动过程中,负责引导操作系统的启动和初始化硬件设备。
在嵌入式系统中,uboot扮演着非常重要的角色,它的稳定性和可靠性直接影响整个系统的稳定性。
1.2 分区的作用分区是将存储设备按照一定的规则划分成多个逻辑部分的过程。
对于嵌入式系统而言,合理的分区管理可以提高存储设备的利用率,同时也方便系统的管理和维护。
二、刷入uboot的步骤2.1 确定目标设备我们需要明确要刷入uboot的目标设备是什么,是一个嵌入式开发板还是其他类型的设备。
不同的设备可能需要不同的uboot版本和刷入方法。
2.2 获取uboot源码接下来,我们需要从冠方或者其他可靠渠道获取uboot的源码。
一般来说,冠方的源码是最稳定和可靠的选择,我们可以从冠方的仓库或者全球信息站上下载源码。
2.3 编译uboot获取源码之后,我们需要根据目标设备的硬件配置,对源码进行编译。
在编译之前,我们需要配置好交叉编译工具链和相关的环境变量,确保编译过程顺利进行。
2.4 刷入uboot当uboot源码编译完成之后,我们需要将编译生成的二进制文件刷入目标设备的存储设备中。
这个过程可能涉及到串口或者其他调试工具的使用,需要特别注意刷入过程中的各项参数和配置。
2.5 测试uboot刷入完成后,我们需要对uboot进行测试,确保它能够正常启动,并且能够正确识别硬件设备。
三、创建大分区的步骤3.1 确定分区方案在创建大分区之前,我们需要确定硬盘或者TF卡的分区方案,包括分区的数量、大小和格式等。
3.2 使用分区工具常用的分区工具有fdisk、parted等,我们可以使用这些工具来创建和调整分区。
在使用分区工具时,需要特别注意当前存储设备上是否有重要的数据,避免误操作导致数据丢失。
3.3 格式化分区创建完分区之后,我们需要对分区进行格式化,以便后续的数据存储和管理。
U-Boot(Universal Boot Loader)是一个开源的、通用的引导加载程序,支持多种处理器架构和嵌入式系统。
在U-Boot中,汇编指令的使用主要涉及对硬件的低级操作和优化。
以下是一些常见的U-Boot汇编指令及其作用:
1.ldr:这是一个加载指令,用于从内存中读取数据并将其加载到寄存器中。
例如,ldr r0,=0x12345678将把地址0x12345678处的值加载到寄存
器r0中。
2.str:这是一个存储指令,用于将数据从寄存器存储到内存中。
例如,str r0,[r1]将把寄存器r0中的值存储到r1指向的内存地址中。
3.mov:这是一个移动指令,用于将数据从一个位置移动到另一个位置,而不对数据进行任何操作。
例如,mov r0,r1将把寄存器r1的值复制到寄存
器r0中。
4.add和sub:这些是算术指令,用于对数据进行加法或减法操作。
例如,add r0,r1,r2将把寄存器r1和r2的值相加,结果存储在寄存器r0中。
5.cmp:这是一个比较指令,用于比较两个值的大小。
它不保存结果,但会设置条件标志,这可以用于控制程序流。
例如,cmp r0,r1将比较寄存器
r0和r1中的值。
6.and、orr、eor等:这些是逻辑指令,用于执行逻辑与、或、异或等操作。
这些只是U-Boot汇编语言中的一部分指令,还有许多其他指令和语法结构。
建议查阅U-Boot的官方文档或参考手册以获取更详细的信息和示例。
u-boot 分析- <节选> [嵌入式Linux系统开发技术详解-基于ARM]6.1 Bootloader对于计算机系统来说,从开机上电到操作系统启动需要一个引导过程。
嵌入式Linux系统同样离不开引导程序,这个引导程序就叫作Bootloader。
6.1.1 Bootloader介绍Bootloader是在操作系统运行之前执行的一段小程序。
通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射表,从而建立适当的系统软硬件环境,为最终调用操作系统内核做好准备。
对于嵌入式系统,Bootloader是基于特定硬件平台来实现的。
因此,几乎不可能为所有的嵌入式系统建立一个通用的Bootloader,不同的处理器架构都有不同的Bootloader。
Bootloader不但依赖于CPU的体系结构,而且依赖于嵌入式系统板级设备的配置。
对于2块不同的嵌入式板而言,即使它们使用同一种处理器,要想让运行在一块板子上的Bootloader程序也能运行在另一块板子上,一般也都需要修改Bootloader的源程序。
反过来,大部分Bootloader仍然具有很多共性,某些Bootloader也能够支持多种体系结构的嵌入式系统。
例如,U-Boot就同时支持PowerPC、ARM、MIPS和X86等体系结构,支持的板子有上百种。
通常,它们都能够自动从存储介质上启动,都能够引导操作系统启动,并且大部分都可以支持串口和以太网接口。
本章将对各种Bootloader总结分类,分析它们的共同特点。
以U-Boot为例,详细讨论Bootloader的设计与实现。
6.1.2 Bootloader的启动Linux系统是通过Bootloader引导启动的。
一上电,就要执行Bootloader来初始化系统。
可以通过第4章的Linux启动过程框图回顾一下。
系统加电或复位后,所有CPU都会从某个地址开始执行,这是由处理器设计决定的。
比如,X86的复位向量在高地址端,ARM处理器在复位时从地址0x00000000取第一条指令。
凌FL2440超详细U-BOOT作业(UBoot介绍+H-jtag使用+Uboot使用)Bootloader是高端嵌入式系统开发不可或缺的部分。
它是在操作系统内核启动之前运行的一段小程序。
通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。
现在主流的bootloader有U-BOOT、vivi、Eboot等。
本次作业先做Uboot的烧写吧。
希望通过这个帖子,能让更多的初学者朋友了解一些UBoot的知识,也希望高手朋友对我的不足予以斧正。
首先说一下什么是Uboot:U-Boot,全称Universal Boot Loader,是遵循GPL条款的开放源码项目。
从FAD SROM、8xxROM、PPCBOOT逐步发展演化而来。
其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。
但是U-Boot不仅仅支持嵌入式Linu x系统的引导,当前,它还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS嵌入式操作系统。
其目前要支持的目标操作系统是OpenBSD, NetBSD, FreeBSD,4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, LynxOS, pSOS, QNX, RTEMS, ARTOS。
这是U-Boot中Universal的一层含义,另外一层含义则是U-Boot除了支持PowerPC系列的处理器外,还能支持MIPS、x86、ARM、NIOS、XScale等诸多常用系列的处理器。
这两个特点正是U-Boot项目的开发目标,即支持尽可能多的嵌入式处理器和嵌入式操作系统。
Uboot常用的命令一、概述Uboot是一款开源的引导加载程序,广泛应用于嵌入式系统。
它负责在开机时初始化硬件、加载操作系统以及其他系统组件,并提供一系列命令供用户进行系统配置和维护。
本文将介绍Uboot常用的命令,帮助读者更好地了解和使用Uboot。
二、Uboot常用命令下面是Uboot常用的命令:1. help命令格式:help [command]该命令用于显示Uboot支持的命令列表。
如果指定了具体的命令名称,则会显示该命令的详细帮助信息。
2. printenv命令格式:printenv [variable]该命令用于打印当前环境变量的值。
如果指定了具体的变量名称,则只会打印该变量的值。
3. setenv命令格式:setenv variable value该命令用于设置环境变量的值。
variable是要设置的变量名称,value是要设置的值。
4. saveenv命令格式:saveenv该命令用于保存当前环境变量到非易失性存储器中,以便下次开机时可以加载。
5. boot命令格式:boot该命令用于启动系统。
在执行该命令之前,需要设置好bootargs和bootcmd等环境变量,以确保系统能够正确启动。
6. md命令格式:md address [#of objects]该命令用于从指定的内存地址读取数据并显示。
address是内存地址,#of objects是要读取的对象数目,默认为1。
7. mw命令格式:mw address value [# of objects]该命令用于向指定的内存地址写入数据。
address是内存地址,value是要写入的值,#of objects是要写入的对象数目,默认为1。
8. ping命令格式:ping [ipaddr]该命令用于向指定的IP地址发送ICMP Echo请求,以测试网络连接的可用性。
如果未指定IP地址,则会使用默认的目标地址。
9. tftpboot命令格式:tftpboot [loadAddress] [filename]该命令用于通过TFTP协议从指定的服务器下载文件并加载到指定的内存地址。
大多数bootloader都分为stage1和stage2两部分,u-boot也不例外。
依赖于CPU体系结构的代码(如设备初始化代码等)通常都放在stage1且可以用汇编语言来实现,而stage2则通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。
1、Stage1 代码结构u-boot的stage1代码通常放在文件中,他用汇编语言写成,其主要代码部分如下:(1)定义入口。
由于一个可执行的Image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在ROM(Flash)的0x0地址,因此,必须通知编译器以使其知道这个入口,该工作可通过修改连接器脚本来完成。
(2)设置异常向量(Exception Vector)。
(3)设置CPU的速度、时钟频率及终端控制寄存器。
(4)初始化内存控制器。
(5)将ROM中的程序复制到RAM中。
(6)初始化堆栈。
(7)转到RAM中执行,该工作可使用指令ldr pc来完成。
2、Stage2 C语言代码部分lib_arm/中的start arm boot是C语言开始的函数也是整个启动代码中C语言的主函数,同时还是整个u-boot(armboot)的主函数,该函数只要完成如下操作:(1)调用一系列的初始化函数。
(2)初始化Flash设备。
(3)初始化系统内存分配函数。
(4)如果目标系统拥有NAND设备,则初始化NAND设备。
(5)如果目标系统有显示设备,则初始化该类设备。
(6)初始化相关网络设备,填写IP、MAC地址等。
(7)进去命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。
3、U-Boot的启动顺序(示例,其他u-boot版本类似)cpu/arm920t/@文件包含处理#include <>@由顶层的mkconfig生成,其中只包含了一个文件:configs/<顶层makefile中6个参数的第1个参数>.h#include <>#include <>/**************************************************************************** Jump vector table as in table in [1]***************************************************************************/注:ARM微处理器支持字节(8位)、半字(16位)、字(32位)3种数据类型@向量跳转表,每条占四个字节(一个字),地址范围为0x0000 0000~@0x0000 0020@ARM体系结构规定在上电复位后的起始位置,必须有8条连续的跳@转指令,通过硬件实现。
mdio uboot 参数摘要:1.mdio uboot参数简介2.mdio uboot参数的作用3.如何配置mdio uboot参数4.配置mdio uboot参数的实例5.总结正文:U-Boot是一款常用的嵌入式系统启动代码,负责从存储器中读取内核并启动。
在U-Boot中,有一个名为mdio的参数,它用于配置MII(Media Independent Interface,媒体独立接口)或RMII(Reduced Media Independent Interface,简化媒体独立接口)模式。
mdio参数对于网络芯片的初始化和配置非常重要。
1.mdio uboot参数简介Mdio uboot参数主要用于配置网络芯片的接口模式,包括MII和RMII。
它涉及到PHY(Physical Layer,物理层)和MDIO(Media Dependent Interface,媒体相关接口)的初始化和配置。
在嵌入式系统中,网络芯片的配置对于网络通信至关重要。
2.mdio uboot参数的作用mdio uboot参数的主要作用是配置网络芯片的接口模式,从而实现正确的网络通信。
它可以设置PHY和MDIO的地址、数据和控制信号,以及接口的工作模式。
通过配置mdio uboot参数,可以使网络芯片在MII或RMII模式下工作,满足不同的网络应用需求。
3.如何配置mdio uboot参数配置mdio uboot参数通常需要修改U-Boot的源代码,通过烧写新的U-Boot镜像到嵌入式系统来实现。
具体步骤如下:- 获取U-Boot源代码,并在源代码中找到与mdio参数相关的内容。
- 根据需求修改mdio参数的配置,例如设置PHY地址、MDIO地址、数据和控制信号等。
- 编译并烧写新的U-Boot镜像到目标系统。
- 重启动目标系统,验证mdio参数配置是否正确。
4.配置mdio uboot参数的实例以下是一个配置mdio uboot参数的实例:```# 定义PHY地址CONFIG_PHY_ADDR=0x10# 定义MDIO地址CONFIG_MDIO_ADDR=0x10# 定义PHY寄存器地址CONFIG_PHY_REG_ADDR=0x10# 定义PHY数据线引脚CONFIG_PHY_DATA_PIN=12# 定义PHY控制线引脚CONFIG_PHY_CTRL_PIN=13# 定义MDIO数据线引脚CONFIG_MDIO_DATA_PIN=14# 定义MDIO控制线引脚CONFIG_MDIO_CTRL_PIN=15```5.总结Mdio uboot参数是嵌入式系统中非常重要的一个参数,用于配置网络芯片的接口模式。
常用的U-boot命令详解帮助与环境变量U-boot发展到现在,他的命令行模式已经非常接近Linux下的shell了,在我编译的U-boot-2009.11中的命令行模式模式下支持“Tab”键的命令补全和命令的历史记录功能。
而且如果你输入的命令的前几个字符和别的命令不重复,那么你就只需要打这几个字符即可,比如我想看这个U-boot的版本号,命令就是“ version”,但是在所有的命令中没有其他任何一个的命令是由“v”开头的,所以只需要输入“v”即可。
TX-2440A> versionU-Boot 1.1.6 (Jan 18 2010 - 10:05:35)TX-2440A> vU-Boot 1.1.6 (Jan 18 2010 - 10:05:35)TX-2440A> baseBase Address: 0x00000000TX-2440A> baBase Address: 0x00000000由于U-boot支持的命令实在太多,一个一个细讲不现实,也没有必要。
所以下面我挑一些烧写和引导常用命令介绍一下,其他的命令大家就举一反三,或者“help”吧!(1)获取帮助命令:help 或?功能:查看当前U-boot版本中支持的所有命令。
T X-2440A>h e l p?-a l i a s f o r'h e l p'a u t o s c r-r u n s c r i p t f r o m m e m o r yb a s e-p r i n t o r s e t a d d r e s s o f f s e tb d i n f o-p r i n t B o a r d I n f o s t r uc t u r eb o o t-b o o t d e f a u l t,i.e.,r u n'b o o tc m d'b o o t_n o o s-b o o t U s e r P r o g r a mb o o t_z I m a g e-b o o t L i n u x's z I m a g eb o o t d-b o o t d e f a u l t,i.e.,r u n'b o o tc m d'b o o t e l f-B o o t f r o m a n E L F i m a g e i n m e m o r yb o o t m-b o o t a p p l ic a t i o n i m a g e f r o m m e m o r yb o o t p-b o o t i m a g e v i a n e t w o r k u s i n g B o o t P/T F T P p r o t oc o lb o o t v x-B o o t v x W o r k s f r o m a n E L F i m a g ec h p a r t-c h a n g e a c t i v e p a r t i t i o nc m p-m e m o r y c o m p a r ec o n i n f o-p r i n t c o n s o l ede v i c e s a n d i nf o r m a t i o nc p-m e m o r y c o p yc r c32-c h e c k s u m c a l c u l a t i o nd a t e-ge t/s e t/r e s e t d a t e&t i m ed c a c h e-e n a b l e o r d i s a b l e d a t a c a c h ee c h o-e c h o a r g s t o c o n s o l ee r a s e-e r a s e F L A S H m e m o r yf l i n f o-p r i n t F L A S H m e m o r y i n f o r m a t i o nf s i n f o-p r i n t i n f o r m a t i o n a b o u t f i l e s y s t e m sf s l o a d-l o a d b i n a r y f i l e f r o m a f i l e s y s t e m i m ag eg o-s t a r t a p p l i c a t i o n a t a d d r e s s'a d d r'h e l p-p r i n t o n l i n e h e l pi c a c h e-e n a b l e o r d i s a b l e i n s t r u c t i o n c a c h ei m i n f o-p r i n t h e a d e r i n f o r m a t i o n f o r a p p l i c a t i o n i m a g ei t e s t-r e t u r n t r u e/f a l s e o n i n t e g e r c o m p a r el o a d b-l o a d b i n a r y f i l e o v e r s e r i a l l i n e(k e r m i t m o d e) l o a d s-l o a d S-R e c o r d f i l e o v e r s e r i a l l i n el o a d x-l o a d b i n a r y f i l e o v e r s e r i a l l i n e(x m o d e m m o d e)l o a d y-l o a d b i n a r y f i l e o v e r s e r i a l l i n e(y m o d e m m o d e) l o o p-i n f i n i t e l o o p o n a d d r e s s r a n g el s-l i s t f i l e s i n a d i r e c t o r y(d e f a u l t/)m d-m e m o r y d i s p l a ym e n u-d i s p l a y a m e n u,t o s e l e c t t h e i t e m s t o d o s o m e t h i n g m m-m e m o r y m o d i f y(a u t o-i n c r e m e n t i n g)m t d p a r t s-d e f i n e f l a s h/n a n d p a r t i t i o n sm t e s t-s i m p l e R A M t e s tm w-m e m o r y w r i t e(f i l l)n a n d-N A N D s u b-s y s t e mn b o o t-b o o t f r o m N A N D d e v i c en m-m e m o r y m o d i f y(c o n s t a n t a d d r e s s)p i n g-s e n d I C M P E C H O_R E Q U E S T t o n e t w o r k h o s tp r i n t e n v-p r i n t e n v i r o n m e n t v a r i a b l e sp r o t e c t-e n a b l e o r d i s a b l e F L A S H w r i t e p r o t e c t i o nr a r p b o o t-b o o t i m a g e v i a n e t w o r k u s i n g R A R P/T F T P p r o t o c o l r e s e t-P e r f o r m R E S E T o f t h e C P Ur u n-r u n c o m m a n d s i n a n e n v i r o n m e n t v a r i a b l es a v e e n v-s a v e e n v i r o n m e n t v a r i a b l e s t o p e r s i s t e n t s t o r a g e s e t e n v-s e t e n v i r o n m e n t v a r i a b l e ss l e e p-d e l a y e x e c u t i o n f o r s o m e t i m et f t p b o o t-b o o t i m a g e v i a n e t w o r k u s i n g T F T P p r o t o c o lu s b s l a v e-g e t f i l e f r o m h o s t(P C)v e r s i o n-p r i n t m o n i t o r v e r s i o n如果你想获取某条命令的更详细的帮助,可以使用:help <你想要查的指令>或者?<你想要查的指令>,甚至h <你想要查的指令缩写>。
uboot下的指令⼀、i2c 指令i2c --help: i2c指令帮助i2c bus:获取i2c总线信息i2c dev:查看当前i2c设备i2c dev 0:将i2c0作为当前设备i2c md 0x6A 0x06.1 0x01:0x6A-->设备地址,0x06.1-->寄存器地址为0x06,寄存器宽度为1个字节,0x01-->读取⼀个字节i2c mw 0x6A 0x06.1 0x02:将0x02写⼊0x6A设备的0x06寄存器中⼆、gpio 操作gpio --help:获取gpio帮助gpio status -a:查看所有gpio信息 可以看到xilinx上有两组gpio,⼀个是ps端的gpio,地址是0xff0a0000,另外⼀组是pl端的axi gpio ,地址是0xa0070000gpio set gpio@a00700000:将axi gpio的第⼀位置⾼电平gpio clean gpio@a00700000:将axi gpio的第⼀位置低电平gpio input gpio@a00700000:将axi gpio的第⼀位置设置为输⼊三、mii命令mii命令是操作mii接⼝的命令,mii接⼝⽤来连接soc中的MAC控制器和外部的PHY芯⽚。
mii命令主要是通过mii接⼝中的MDIO来读写phy芯⽚的寄存器针对DP83867芯⽚mii info //查看mii信息mii write 0x0c 0x00 0x2100 //设置phy芯⽚为百兆,0x0c为phy芯⽚地址,0x00为phy芯⽚寄存器地址,0x2100为向0x00寄存器写⼊的值mii read 0x0c 0x00 //读取phy芯⽚0x00寄存器的值寄存器地址>0x1F的配置⽅法,因为MDIO最多能范围的寄存器范围为0~0x1F,如果寄存器地址>0x1F那么需要通过0x0d和0x0e这两个寄存器间接访问读0x31寄存器mii write 0x0c 0x0d 0x1fmii write 0x0c 0x0e 0x31mii write 0x0c 0x0d 0x401fmii read 0x0c 0x0e写0x31寄存器mii write 0x0c 0x0d 0x1fmii write 0x0c 0x0e 0x31mii write 0x0c 0x0d 0x401fmii write 0x0c 0x0e 0x1031 //向0x31寄存器写⼊0x1031四、MMC命令mmc是uboot下查看磁盘的命令mmc list:查看所有磁盘可以看到有两个磁盘,0是emmc,1是sd卡mmc dev 0:进⼊磁盘0mmc info:查看磁盘0的信息这⾥显⽰了emmc的⼀些信息五、FAT⽂件系统操作命令 5.1 fatls 查看⽂件命令 fatls命令如下所⽰: fatls mmc 0:1:查看emmc第⼀分区的内容,0表⽰哪个mmc设备,这⾥是emmc,1表⽰第⼀分区 可以看到emmc的第⼀分区中有三个⽂件 5.2 fatrm 删除⽂件命令 fatrm mmc 0:1 image.ub:删除emmc第⼀分区中的image.ub 5.3 fatwite 写⽂件 fatwrite mmc 0:1 0x10000000 image.ub 0x7d1160,从内存拷贝Image.ub到emmc第⼀分区中,0x10000000 表⽰内存拷贝的起始地址,image.ub是⽂件名,0x7d1160是拷贝的长度。
U-Boot工作过程U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下:(1)第一阶段的功能硬件设备初始化加载U-Boot第二阶段代码到RAM空间设置好栈跳转到第二阶段代码入口(2)第二阶段的功能初始化本阶段使用的硬件设备检测系统内存映射将内核从Flash读取到RAM中为内核设置启动参数调用内核1.1.1 U-Boot启动第一阶段代码分析第一阶段对应的文件是cpu/arm920t/和board/samsung/mini2440/。
U-Boot启动第一阶段流程如下:图 U-Boot启动第一阶段流程根据cpu/arm920t/中指定的连接方式:ENTRY(_start)SECTIONS{. = 0x00000000;. = ALIGN(4);.text :{cpu/arm920t/ (.text)board/samsung/mini2440/ (.text)board/samsung/mini2440/ (.text)*(.text)}… …}第一个链接的是cpu/arm920t/,因此的入口代码在cpu/arm920t/中,其源代码在cpu/arm920t/中。
下面我们来分析cpu/arm920t/的执行。
1. 硬件设备初始化(1)设置异常向量cpu/arm920t/开头有如下的代码:.globl _start_start: b start_code /* 复位*/ldr pc, _undefined_instruction /*未定义指令向量 */ldr pc, _software_interrupt /* 软件中断向量 */ldr pc, _prefetch_abort /* 预取指令异常向量 */ldr pc, _data_abort /* 数据操作异常向量 */ldr pc, _not_used /* 未使用 */ldr pc, _irq /* irq中断向量 */ldr pc, _fiq /* 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.balignl 16,0xdeadbeef以上代码设置了ARM异常向量表,各个异常向量介绍如下:表 ARM异常向量表在cpu/arm920t/中还有这些异常对应的异常处理程序。
Femtocell 项目uboot代码走读
对于计算机系统来说,从开机上电到操作系统启动需要一个引导过程,这个引导程序就叫作Bootloader。
Bootloader是在操作系统运行之前执行的一段小程序。
通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射表,从而建立适当的系统软硬件环境,为最终调用操作系统内核做好准备。
对于嵌入式系统,Bootloader是基于特定硬件平台来实现的。
因此,几乎不可能为所有的嵌入式系统建立一个通用的Bootloader,不同的处理器架构都有不同的Bootloader。
Bootloader不但依赖于CPU的体系结构,而且依赖于嵌入式系统板级设备的配置。
对于2块不同的嵌入式板而言,即使它们使用同一种处理器,要想让运行在一块板子上的Bootloader程序也能运行在另一块板子上,一般也都需要修改Bootloader的源程序。
反过来,大部分Bootloader仍然具有很多共性,某些Bootloader也能够支持多种体系结构的嵌入式系统。
例如,U-Boot就同时支持PowerPC、ARM、MIPS和X86等体系结构,支持的板子有上百种。
通常,它们都能够自动从存储介质上启动,都能够引导操作系统启动,并且大部分都可以支持串口和以太网接口。
一.汇编部分(cpu\arm926ejs\start.S),此部分为uboot能顺利运行C代码而准备其必须的环境。
1.当cpu上电后,CPU会
_start:
b reset
首先跳转到标号reset处,将CPU设置为SVC模式。
(arm926ejs通用代码)
2.cpu_init_crit: 设置I-CACHE , memory 时序等(arm926ejs
通用代码)
3.lowlevel_init:执行PC202独有的底层初始化工作
(board\picochip\Pc7802\lowlevel_init.S)
1)register_initialization : CPU需要使用仿真器的时候会定义
CONFIG_PC20X_SIMULATION(咱们设备不使用仿真器。
)
2)extinguishArmLeds:熄灭led灯;此处未执行任何操作,直接
返回。
3)ebi_init:初始化ebi总线(flash挂在ebi总线上,此处未操作直接返回)。
4)memif_init:
在初始化之前先重置一下。
4.1)DLL配置:
此处代码中的配置与手册中给出的‘nomal opration’一致,但是其中的含义手册中未给出。
(DLL: 延迟锁定回路。
DDR SDRAM对时钟的精准性有着很高的要求,而DDR内存有两个时钟,一个是外部的总线时钟,一个是内部的工作时钟,理论上来说DDR内存的这两个时钟应该是同步的,但由于种种原因,如温度,电压波动等产生的延迟使两者很难同步,所以需要根据外部时钟动态修正内部时钟的延迟来实现与外部时钟的同步,这就是DLL技术。
)
4.2)SDRAM Arbitration配置
SDRAM仲裁配置,主要将内存分为group0, gourp1的两个组,每个组有2个slot,每组分别分配1个slot给cpu,1个slot 给dsp(picoarry).
4.3)SDRAM setup
配置SDRAM的大小,位宽等等
配置完成,启用sdram和sram的配置。
4.remap_flash: flash 重映射
首先设置RapRemapModeRegOffset寄存器,此寄存器如果值为0的话,flash被映射的地址为0,当此寄存器为1(REMAP_NORMAL_MODE)的时候,flash地址被映射到0x20000000。
每当设备重启的时候,此寄存器将被自动设置为0。
remap前后norflash 在map中位置的区别:
5.ddr2_dummy_access :
此处做一个简单的内存测试(向内存中写一个数,然后再读出来,比较一下,验证内存是否能正常访问)。
??出错以后啥也不干??。
验证完了内存,下面开始很重要的代码搬移工作。
6.代码搬移:
将在flash中的整个uboot的代码全部复制到内存中去。
首先通过比较_start 与_TEXT_BASE的值判断此时是运行在内存中还是flash中。
如果此时运行在内存中,那么就不需要进行搬运了(此情况发生在内存中调试uboot时),之后直接对栈进行初始化;
(adr r0, _start :ADR伪指令将基于PC相对偏移的地址值读取到寄存器中,_TEXT_BASE为uboot 代码段的地址,其值定义在board/picochip/pc7802/config.mk,值为0x5000000)
代码:r0为代码在flash中需要复制的源地址,每操作一次,存贮在r0中的地址向后增长;r1为需要COPY到的,在内存中的源地址,每一次操作完,r1中的地址向后增长。
循环进行复制操作,直到r1中的地址与r2中存放的结束地址相等。
7.初始化STACK, BSS
至此,C代码的运行环境已经准备好,跳转到_start_armboot 开始执行C代码(从这之后才开始在内存中运行)。
二.C语言部分。
start_armboot
调用一系列的初始化函数。
global_data结构体:记录全局信息
bd_info结构体:记录开发板信息
初始化序列:
循环调用init_sequence函数指针数组中的成员,来依次调用数组列表中的函数进行初始化。
1)cpu_init: 分配IRQ,FIQ栈底地址。
请参考前边的图来看。
2)reloc_init: 设置relocation 标记位。
记录是否代码搬移完成。
3)board_init: 设置内核启动参数存放地址,板子ID,使能
ICACHE, 计时器。
4)env_init:指定环境区的地址。
default_environment是默认的
环境参数设置。
5)init_baudrate:初始化波特率(115200).
6)serial_init: 串口初始化,注意在飞烽的板子上用的是UART2,
不是UART1,CONFIG_CONS_INDEX应该设置为2。
7)console_init_f:由于标准设备还没有初始化这时控制台使用
串口作为控制台。
8)dram_init:设置内存地址范围
剩下的代码主要为:
1)初始化Flash设备。
2)初始化系统内存分配函数。
3)初始化相关网络设备,填写IP、MAC地址等。
4)进去命令循环(即整个boot的工作循环),接受用户从串口
输入的命令,然后进行相应的工作。