文件名称:
AM335Bootload流程分析.pdf
开发工具:
文件大小: 820kb
下载次数: 0
上传时间: 2019-10-31
详细说明:AM335Bootload流程分析,描述了uboot的启动过程和主要函数的调用过程根据am335X的芯片技术手册,获取图三,此图为芯片上电时序要求。满足该要求方法有:
可以选用特定的PMC,乜可以使用分离电源芯片,但必须严格要求上电时序。而PMC在设计上
简单,可参考T的电源芯片设计。
Figure 26-2 Public ROM Code Boot Procedure
From public startup
Dead loop in public
VDDS RTC
Set up the booting device list
RTC PWRON RSTn
Yes
PMIC POWER EN
Take next device from the list
18V/1.5V/1.35y
VDDS DDR
Device?
IC 3.3-V Supplie
1.V
VDD CORE, VDD MPU
Memory Booting
eral booti
PWRONRST
CLK M OSC
Success?
图三
图四
ge execution
从图四分析 rom code的执行流程:
芯片符合上电时序后或复位,PC指针首先跳转到0x20000地址开始执行。此时出厂固化在内部
ROM的 rom code进行芯片的简单初始化,如看门狗和NAND、NOR、SD卡、UART、SP和USB
等符合引导类型的外设。 rom code主要功能是:
1根据 SYSBOOT的配置生成引导设备列表
2査看当前的引导类型是 memory模式还是外设模式,并通过初始化相应的接冂或地址读取sPL,
可能性如下:
若SPL读取成功后,执行SPL镜像,SPL开始运行
若SPL读取失败,尝试启动列表中的下一个外设或接口
若所有外设都没有正确读取到SPL,则进入死循环( dead loop)等待看门狗复位
四.关于内存运行的位置
首先先看一下am335X内部176KB的rom和内部64 KB ram的结构如下:
Figure 26-3. ROM Memory Map
Ox2BFFF
Figure 264. Public RAM Memory Map
ROM Version
0x2BFFC
Ox4030FFFF
Static variables
Tracing data
0X4030CE00 RAM ExcVectors
sKB Public stack
0x403CB80o
Ccde
Public ram
0x20100
0x20080
Dead loops
0×2007C[ PublicROMCRC
Downloaded Image
0x20000/ ROM ExCVectors
0X402F0400
OX402FC400(GP)
ROM cOre就是运行在左上图的位置,而右上图标志的 Dowloaded Image区域:是用来保存
MLO(SPL)饶像文件的,其最大可达到109KB。
关于 bootload每个阶段的起始位置如下表所示
addr
说明
0x20000
rom code的运行起始地址
0×402f0400
SPL镜像在内部SRAM中的加载地址,也是内部ram的起始地址
0x80000000
」U-bo镜像在DDR中的加载地址,也是内部DDR的起始地址
sPL已经加载到芯片的内部SRAM中了,那么它是从哪儿开始运行的呢?这需要查看spl在
被链接的时候所需的链接文件u-boot-spl.lds,该文件决定了sp和 uboot从哪里开始运行。查看
该文件可以发现其中有一句话: CPUDIR/ start o(text*),表示了 start.s作为该起始函数。一开始
会设置CUP模式和中断,操作的奇仔器是CPSW,这个是一个很重要的奇存器,以下是对CPSW
的寄存器内容进行描述。最重要的是低四位Mo-M4,其决定CPU八种模式。
31302928
6543
zcV|保留
M4 M3M2M1MO
N Negative/ Less than
IRQ disable
Z Zero
FIQ disable
C Carry/Borrow/Extend
state bit
V Overflow
MOx4 Mode bits
处理器
M[4:0]
ARM模式可访问的寄存器
THUM模式可访问的寄存器
Ob101)
模
PC, CPSR.RONR14
PC, CPSR, RO-R7,LR, SP
0b1000/模
PC, CPSR, SPSR fig, r14 fig r8 fig, romr7
PC, CPSR, sPsr fiq, lr fiq sp tig, rory
IRQ模
b10010
PC, CPSR, SPSR_irq, R1_irquR13_irq, ROwR12 PC, CPSR, SPSR_irq, LR_irq, SP_irq, ROwR7
Ob10017/模
PC, CPSR, SPSR_sVC, R14_svCnR13_5VC, ROuR12 PC, CPSR, SPSR_SVC, LR_SVC, SP_SVC,ROwR
I模
0b10111
PC, CPSR, SPSR_abt, R14_abtrR13_abt, ROwR12 pC, CPSR, SPSR_abt, LR_abt, SP_abt, RO-R7
0b1011 *2, CPSR, SPSR_ und, 14. und-R13_ und, R0-R12 PC, cpSR, SPSR_ und, R_ und, SP- und, Ro -R7
模式
系统模
0b11111
PC CPSR RONR14
PC CPSRLR SP.RONR4
五.以下是spl和 Uboot的流程图,格式:左边是函数执行顺序,中间是分析函数内容:右边是
进一步分析。
程序流程
函数解析
进一步解析
sPL开始
CPSR:程序状态寄存器(当前程序状态寄存
Start.s
通过对CPSR操作
器),在任何处理器模式下被访问。它包
(arch\arm\cpu\armv7)
禁止 Interrupts( FIQ and IRQ)
含了条件标志位、中断禁止位、当前处
设置cpu于sVC32mode,即管
理器模式标志以及其他的一些控制和状
理模式,上图有相关描述
态位。上图已有描述
Start.s
初始化L1的/ D caches
运行cpu_ Init cp15
禁止MMU
Start.s
跳转到 lowlevel init
运行 cpu init crit
CONFIG SYS INIT SP ADDR在
设置暂时的堆栈(为了调用C函数)
Ti armv7 common. h
lowlevel init.s
SP指向 CONFIG SYS NIT SP ADDR
include\configs)定义,值为
(arch\arm\cpu \armv7)
确保sp是8字节对齐
保存当前ip指针,跳到 s init,
0×40310000-224=0×4030ff20,
224是指 global data的大小
sini实现的功能
Figure 8-18. RTC, VTP, and Debounce Clock Selection
I De/ce
s init
1.禁止看门狗
RICOSC REG SEL 32KCLK SR
768
Board. larch\arm\cpu\
2使能UAR相关引脚(可通过cene=[
-RTC cock
改其他UART1/2/3/4/5)
CLK 32KI CZ
armv7\am 33xX)
RIC IP
3.使能与UART相关时钟树和功能模块
4软件复位UART
tei L onae
RCM. CLKSEL GPO0 DBCLK
5选择rtc32kosC(设置
o GPO(1-6 MMC, etc
选择32k外部时钟源,如右图所示。
[
并允许时钟源进入RTC模块)
board init f alloc reserve主要是为
main功能
u-boot的全局变量结构体 global data
回到文件 Start.s
1.重新对SP赋值
( struct global data)分配空间,起
运行main
SP指向 CONFIG SYS N SP ADDR
始地址是0x4030千a40
crt.S(arch\arm \lib)
确保sp是8字节对齐
运行 board init f init reserve主要将
2运行 board init f alloc reserve
global data清0操作
3运行 board init f init reserve
这两函数位置都在文件 Board init c
跳到 board init f
(common(init)
board init f实现的功能:
board init f
1 board early_ init_f0;//始化时钟树PLL和使能相应引脚 timer2
Board. carch \arm\ cpu\a
∥/以下在紫色框+大蓝框进行详细解析
rmv7\am33Xx)
2.sdram init(F
∥/根据板子类型初始化相应DDR,以下有详解
3保存DDR的大小到gd-> ram sIz
4结束返回到main函数
board early init fo;
Board.c(arch\arm\cpu
\armv7\am33xx)
prcm init();//1E Clock c(arch \arm\cpularmv 7\am 33xX
1->enable basic clocks(
∥使能L3L3L4L4s和gpio1/2/3、i2c、emif、 rtc usb等时
钟域
/为tmer2选择外部24M作为时钟源
2->scale cores(: //do nothing
->setup dplls(); // Clock c(arch\armcpu\ 7\am33
设置关于 mpu core per ddr四个PLL
(mpu=300M,
100Mper=960M)
/这里关于 ddr Pll配置,主要根据板子不同而不同,板子
类型通过i2c读 eeprom来获取,若无 eeprom,用户自己定
义配置ddr的PLL频率
-> timer init();∥使能 timer2
2.set mux conf regs(;
∥/在 Board. c( board\ti\am335x)
/内部执行 enable board_pin_mux();位置在muxc
/根据 EEPRON识别板子后初始化相应引脚,客户可自行添加
sdram initO
/如开发板是EVM初始化的有mmco/1sp0 NAND rgmi1i2c1
Board. c
(board\ti\am335x)
根据板子的不同型号,初始化相对应的DDR,如SK,调用函数
config ddr(303, &ioregs evmsk, &ddr 3 data, &ddr 3 cmd ctrl data
&ddr3 emif reg data,0);/303M的时钟频率,
ddr3 emif reg data是EMF的寄存器参数等,可以在 Ddr defs h
( arch \arminclude arch-am33x)进行修改DDR的相关参数
spl relocate stack gd实现的功能:
crt.S(arch\arm lib)
/位置:Splc( common\( spl)
执行 spl relocate stack_ gd
∥/在DDR初始化堆栈,把上述的在sram里面的全局变量结
BSs清0
构体gd的内容复制到新的DDR堆栈里,成为新的gd,让接
跳到 board init r
下来的程序有更大的DDR的堆栈运行,此时gd的地址是
Ox81ffff20
1.对gd结构体里的参数进行各种赋值,保存 SDRAM大小到gd
void board init r
2gd的TLB映射( TLB table from bfffco00 to c00000)
(gd t*dummy 1,
3使能CP15的D- caches
ulong dummy
4设置大小为0x1000000的堆栈,从0x80a80000开始
//Spl. c common\spl)
5执行 void spl board init(vod)//函数解析如下方所示
6 board boot order( spl boot list://将gt的boot- device赋值给 spl boot list[oj
7 announce_ boot device(spl boot list[i]);/终端输出启动 device的名字
8执行 spl load image(spl boot list[/从相关 device载入 Image到DDR内
/函数解析如下方所示
9. cleanup before linux(;
10.jump to image no args(&spl image);
ALI: Boot-common c(arch\arm\cpu armv7\omap-common
> eImage entry(u32*) boot params;跳转到 uboot的入口地址
pl image-> entry point执行,结束了SPL的过程。
void spl board init(void)
Boot-common. c(arch\arm\cpu\armv7\omap-common)
Table 9-59 efuse sma Register Field Descriptions
1save_ omap boot params(;//保存启动的 device和mode
Bi:Field
prEset Description
2 preloader console init();//保存波特率于gd,开启串口功能
31-18 Resented
hese bits are undefined and contents can vary from device to
/此函数可以在s_init后随意调用,前提是gd有效
17-16package_type
Designates the Package type of the device(PG2x only)
3. gpmc initO
/若有 define则初始化gpmc
4i2c_int(100k,1);/若有 define则初始化c100k速率
15-13Resenved
hese bits are undefined and contents can vary from device to
device
5 arch misc init();/若有 define则初始化usb
,. hw watchdog init0/若 define则初始化看门狗
业和那即地取7.am33 x spl board init0;/在 board. c(board \ti\am35x)
IFEF-300 MHz ARM MPU Maximum (ZCZ Package only)
Ox1FAF-500 MHZ ARM MPU Maximum(ZCZ Package only)
/通过函数am335 x_ get efuse mpu max freq(cdev
Ox 1F2F-720NH2 ARM MPU Maximum(ZCZ Package only)
Ox1E2F-800 MHz ARM MPU Maximum(ZCZ Packcage only
∥/来读取 efuse sma寄存器的低13位来判别芯片MpU的最
OxiC
GHz ARM MPU Maximum (2C2 Package only
2x大频率Fmax(如左图所示),这点很重要。接着初始化PMC,使
l oher valuas are reserved
得芯片工作电压满足最高频率。最后设置core频率=1G和Mpu最
大频率Fmax
spl load image( spl boot list[)这里选择MMC加载 Image:,即执行函数
spl mmc load image( boot device)/位于在spl_mmcc( common\sp)
spl mmc_ load image里判断MMC是否支持,获取mode= MMCSD MODE FS,执行以下
spl mmc do fs boot(mmc)
if (!spl start ubootO)j
spl load image fat os(&mmc->block dev, CONFIG SYS MMCSD FS BOOT PARTITION)
>file fat read( coNFIG SPL FS LOAD ARGS NAME, (void*)CONFIG SYS SPL ARGS ADDR, O)
(在这个函数中会试图读取“args”文件到地址 CONFIG SYS SPL ARGS ADDR(=0x80F8000)中,如
果这个文件不存在,则退出这个函数,继续执行 spl mmc_ do fs boot(mmc)
->spl load image fat(&mmc->block dev, CONFIG SYS MMCSD FS BOOT PARTITION,//=1
CONFIG SPL FS LOAD PAYLOAD NAME);//=u-boot image
. file fat read(filename, header, sizeof ( struct image header));
(在这个函数中会试图读取“u- boot image” header文件到0x807fco中,大小64)
>spl load simple fit(&load, 0, header)
(会调用三次 spl fit read函数,此函数调用 fat read file( filename,buf, file offset,size,& stread)去读
“u- boot image”文件偏移量不同的地方)
Uboot开始
Start, s
通过对CPsR操作
(arch\arm\cpu\armv7
禁止 interrupts( FIQ and IRQ)
设置cpu于svC32mode
Start, s
1.重新对SP赋值
board init f alloc reserve主要是为
运行main
SP指向 CONFIG SYS| NIT SP ADDR
u-boot E] global data(struct
crt. S (arch \arm \lib)
2确保sp是8字节对齐
global data)分配空间
3运行 board init f alloc reserve
运行 board init f init reserve主要将
4运行 board init f init reserve
global data清0操作
5跳到 board init f
board init f
board init f实现功能:
Board f c(common)
1 global data清0
和spl调用的不同
2. initcall run list(init sequence f)
/一系列初始化函数以实现前半部分板级初始化的功能,比如有:
∥/使能看门狗:定时器,串口打印,打印板子信息,并保存板子信息
到gt等等
回到main
relocate code(位置: arch\arm\ lib\relocate.S)
crt.S(arch arm \ lib)
/实现 uboot代码的重定位,也即将 uboot的程序搬移到DDR内存里
运行 relocate code
合适的位置去运行。作用有一:一是为 kerne腾出低端空间,防止接
运行 relocate vectors//
下来引导进来的 kernel解压覆盖 uboot,二是对丁由静态存储器
异常向量重定位
( spiflash nandflash)启动,这个 relocation是必须的
清BSs
跳到 board init r
board init r主要实现该函数 initcall run list( init sequence_r),它又
void board init red t
会运行一系列函数,主要有
new gd, ulong dest addr)
1 initr reloc//设置gd->fag表示 relocation完成
/ Board rc(common)
2 nitr caches/使能C15 Dcaches
和spl调用的不同
3 board init,/*初始化看门狗,可选使能gpmc和PRU*,用户
常在这里修改,位置: board.c( board/ti/am335x)
4.efi_ memory_ init//memory map
5初始化接口外设,包括: nand MMC Eth usb net
6.中断使能
7. board late init,/设置etho/1的地址
8最后一项是 run main loop,进入 run main loop后便不再返回
run main loop//Board rc(common)
for (;)
main loop o
bootstage mark name/调用了show_ boot progress,利用它显示启动进程
progress),此处为空函数。
main loop(
/位置Manc( common)
ci ini0://调用u_ boot hush start);使用 hush shell|来作为执行器。 hush shell是
∥/分析如右框所示:
种轻量型的shel。 cli init用来初始化 hush shell|使用的一些变量
run_ preboot environment command该函数如果定义 CONFIG_ PREBOOT(默认不定
义)则从环境变量中获取" preboot"的内容,然后使用 run command list启动该命令
s= bootdelay_ process);从环境变量中取出" bootdelay"和" booted"的配置值,将取
出的" bootdelay"配置值转换成整数,赋值给全局变量 stored bootdelay,最后返回
" booted"的配置值,赋值给s。
bootdelay为u-boot的启动延时计数值,计数期间内若无用户按键输入干预,那么
将执行" booted"配置中的命令
由于没有定义 CONFIG_ OF CONTROL,函数ci_ process fdt返回 false,接下来执行
autoboot command(s);该函数会先等待 bootdelay这么长的时间,若无用户干预,
则函数执行run_ command list(s,-1,0);该S就是上述的" booted
run command list中调用了 hush shell的命令解释器( parse stream_ outer函数),解
释 booted中的启动命令。此处的环境变量 booted中的启动命令为:
booted=" run findfdt; run init console; run eboot; run distro bootcmd,该命令主要
选出fdt类型,保存串口打印配置,也即用来设置 linux必要的启动环境,最后
条命令是轮询的从 MMC NAND等外设去启动 kernel。u-boot启动lnux内核后,将
控制权交给nux内核,至此不再返回
若在 bootdelay期间有用户输入时,则 autoboot command(s)不执行
run command listi(s,-1,0)直接跳出函数
接着运行 cli loop(;该函数运行 int parse file outer(void);
iT: parse stream_ outer(&input, FLAG PARSE SEMICOLON);
~执行:do-whie会循环命令解析器的"命令输入解析-执行"运行模式
循环的读取用户输入的命令,执行其中的函数 run list执行如下的函数调用流程:
run list-->run list real->run pipe real
最后在函数 run pipe real中有
return cmd process(/完成u-boot命令的定位和执行,具体如下:
函数cmd_ process调用 find cmd查找到命令名对应的cmd_tblt结构体变量后,
cmd_ process接下来将调用函数 cmd cal执行 cmd tbl t中的命令,如果命令执行
的返回值为CMD_ RET USAGE,代表命令执行出错,且置标 CMD RET USAGE,那
么将调用cmd_ usage,输出简短的命令使用帮助信息
以上就是SPL和U-boot的流程分析,还是得再次强调一次,这次分析主要是以”全而简”(全
过程+简单分析)的角度进行介绍,若在细节上有任何疑问,可以根据我画的流程图方便查找和
定位,若仍然解决不了,欢迎大家可以在论坛上随时随地提出来。谢谢!
以下第六章额外附加两幅关于内存分布的图,希望能够帮助大家理解关键时刻的DDR的内存分布
六.以下框图表示不同时间段DDR内存里的内容分布
sPL加载u-boot后
Uboot加载 kernel前
DDR的内存内容分布
DDR内存内容分布
New sp(堆栈)
FIT
FDT 40K
Image
u-boot. img
文件是由这
Device Tree
三部分组成
Board info(板子的信息)
size=80B
Malc分配内存
Gd
size=218B
起始0x80a80000size=256M
代码重定位
Malloc
的效果
Size=16512k
Gd(gd是重要的结构体)
起始0x81f120sze=(224B)
boot. img
ILB
TLB
(Oxbfffc000-0XC000000)
(Oxbfff0000-Oxbfffc000)
(系统自动生成,下载前可以参看下载内容)
下载文件列表
相关说明
- 本站资源为会员上传分享交流与学习,如有侵犯您的权益,请联系我们删除.
- 本站是交换下载平台,提供交流渠道,下载内容来自于网络,除下载问题外,其它问题请自行百度。
- 本站已设置防盗链,请勿用迅雷、QQ旋风等多线程下载软件下载资源,下载后用WinRAR最新版进行解压.
- 如果您发现内容无法下载,请稍后再次尝试;或者到消费记录里找到下载记录反馈给我们.
- 下载后发现下载的内容跟说明不相乎,请到消费记录里找到下载记录反馈给我们,经确认后退回积分.
- 如下载前有疑问,可以通过点击"提供者"的名字,查看对方的联系方式,联系对方咨询.