您好,欢迎光临本网站![请登录][注册会员]  
文件名称: AM335Bootload流程分析.pdf
  所属分类: 嵌入式
  开发工具:
  文件大小: 820kb
  下载次数: 0
  上传时间: 2019-10-31
  提 供 者: qq_36******
 详细说明: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最新版进行解压.
  • 如果您发现内容无法下载,请稍后再次尝试;或者到消费记录里找到下载记录反馈给我们.
  • 下载后发现下载的内容跟说明不相乎,请到消费记录里找到下载记录反馈给我们,经确认后退回积分.
  • 如下载前有疑问,可以通过点击"提供者"的名字,查看对方的联系方式,联系对方咨询.
 输入关键字,在本站1000多万海量源码库中尽情搜索: