u-boot中SPL源代码分析

发布时间:2022-11-11 21:21:06阅读:11次

系统大全为您提供

本文将使用sama5d3xekSPL实现做为例子  u-bootSPL(secondprogramloader),对许多人来说也说很陌生。下面对此进行一个简单介绍。  1.armSoC的启动过程:  RomBoot-->SPL-->u-boot-->Linuxkernel-->filesystem-->startapplication  (RomBoot是固化在SoC内部的。)  u-boot实现了一个新功能,能在编译u-boot的同时生成SPL二进制文件。  2.SPL运行代码gothrough  从u-boot-spl.lds链接文件可知,启动代码也是start.S.  (reset)<arch/arm

u-boot中SPL源代码分析

u/armv7/start.S>(blowlevel_init:arch/arm

u-boot中SPL源代码分析

u/armv7/lowlevel_init.S)(b_main)--><arch/arm

u-boot中SPL源代码分析

b/crt0.S>(blboard_init_f)--><arch/arm

u-boot中SPL源代码分析

b/spl.c>(board_init_r)--><common/spl/spl.c>(jump_to_image_no_args去启动u-boot)到此SPL的生命周期结束。  简单来讲:SPL所做工作,一些硬件的初始化,然后读取u-boot,最后调转至u-boot.  3.下面具体分析SPL的相关代码。  <arch/arm

u-boot中SPL源代码分析

u/armv7/start.S>  110reset:  111blsave_boot_params  112/*  113*disableinterrupts(FIQandIRQ),alsosetthecputoSVC32mode,  114*exceptifinHYPmodealready  115*/  116mrsr0,cpsr  117andr1,r0,#0x1f@maskmodebits  118teqr1,#0x1a@testforHYPmode  119bicner0,r0,#0x1f@clearallmodebits  120orrner0,r0,#0x13@setSVCmode  121orrr0,r0,#0xc0@disableFIQandIRQ  122msrcpsr,r0  123  124/*  125*Setupvector:  126*(OMAP4splTEXT_BASEisnot32bytealigned.  127*ContinuetouseROMcodevectoronlyinOMAP4spl)  128*/  129#if!(defined(CONFIG_OMAP44XX)&&defined(CONFIG_SPL_BUILD))  130/*SetV=0inCP15SCTRLregister-forVBARtopointtovector*/  131mrcp15,0,r0,c1,c0,0@ReadCP15SCTRLRegister  132bicr0,#CR_V@V=0  133mcrp15,0,r0,c1,c0,0@WriteCP15SCTRLRegister  134  135/*SetvectoraddressinCP15VBARregister*/  136ldrr0,=_start  137mcrp15,0,r0,c12,c0,0@SetVBAR  138#endif  139  140/*themaskROMcodeshouldhavePLLandothersstable*/  141#ifndefCONFIG_SKIP_LOWLEVEL_INIT  142blcpu_init_cp15  143blcpu_init_crit  144#endif  145  146bl_main  111:如果没有重新定义save_boot_params,则使用<arch/arm

u-boot中SPL源代码分析

u/armv7/start.S>中的save_boot_params.其不做任何事情,直接返回。  116~138:看注释即可明白。  141:因为SPL主要是对SoC进行初始化,所以不会定义CONFIG_SKIP_LOWLEVE_INIT,即142,143行得以执行。  142:cpu_init_cpu15,主要作用invalidateL1I/Dcache,disableMMU.检查是否需要workaround.  143:cpu_init_crit直接跳转到lowlevel_init  下面看看lowlevel_init的实现:  <arch/arm

u-boot中SPL源代码分析

u/armv7/lowlevel_init.S>  18ENTRY(lowlevel_init)  19/*  20*Setupatemporarystack  21*/  22ldrsp,=CONFIG_SYS_INIT_SP_ADDR  23bicsp,sp,#7/*8-bytealignmentforABIcompliance*/  24#ifdefCONFIG_SPL_BUILD  25ldrr9,=gdata  26#else  27subsp,#GD_SIZE  28bicsp,sp,#7  29movr9,sp  30#endif  31/*  32*Savetheoldlr(passedinip)andthecurrentlrtostack  33*/  34push{ip,lr}  35  36/*  37*gosetuppll,mux,memory  38*/  39bls_init  40pop{ip,pc}  41ENDPROC(lowlevel_init) 22:对stackpointer赋值成CONFIG_SYS_INIT_SP_ADDR  23:确保sp是8字节对齐。  25:将gdata的地址存入到r9寄存器中。  39:跳转到s_init.对Atmelsama5d3xekboard,s_init定义在:<arch/arm

u-boot中SPL源代码分析

u/at91-common/spl.c>此处暂时不分析。  然后返回到start.S处,接下来调用:bl_main到<arch/arm

u-boot中SPL源代码分析

b/crt0.S>  58ENTRY(_main)  59  60/*  61*SetupinitialCruntimeenvironmentandcallboard_init_f(0)。  62*/  63  64#ifdefined(CONFIG_SPL_BUILD)&&defined(CONFIG_SPL_STACK)  65ldrsp,=(CONFIG_SPL_STACK)  66#else  67ldrsp,=(CONFIG_SYS_INIT_SP_ADDR)

  68#endif

70subsp,#GD_SIZE/*allocateoneGDaboveSP*/  71bicsp,sp,#7/*8-bytealignmentforABIcompliance*/  72movr9,sp/*GDisaboveSP*/  73movr0,#0  74blboard_init_f  65:重新对SP赋值  69:确认sp是8字对齐  70:相当于保留一个global_data的大小。  71:确认更新后的sp是8字对齐  72:r9指向global_data  73:r0赋值0  74:跳转到board_init_f中运行。  board_init_f在<arch/arm

u-boot中SPL源代码分析

b/spl.c>定义:  20/*  21*InthecontextofSPL,board_init_fmustensurethatanyclocks/etcfor  22*DDRareenabled,ensurethatthestackpointerisvalid,cleartheBSS  23*andcallboard_init_f.Weprovidethisversionbydefaultbutmarkit  24*as__weaktoallowforplatformstodothisintheirownwayifneeded.  25*/  26void__weakboard_init_f(ulongdummy)  27{  28/*CleartheBSS.*/  29memset(__bss_start,0,__bss_end-__bss_start);  30  31/*Setglobaldatapointer.*/  32gd=&gdata;  33  34board_init_r(NULL,0);  35}  26:board_init_f是一个弱函数,是可以被重新定义的。  29:对BSS段进行清零操作。  34:跳转到board_init_r  board_init_r在<common/spl/spl.c>中定义:  132voidboard_init_r(gd_t*dummy1,ulongdummy2)  133{  134u32boot_device;  135debug("》spl:board_init_r()");  136  137#ifdefCONFIG_SYS_SPL_MALLOC_START  138mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START,  139CONFIG_SYS_SPL_MALLOC_SIZE);  140#endif  141  142#ifndefCONFIG_PPC  143/*  144*timer_init()doesnotexistonPPCsystems.Thetimerisinitialized  145*andenabled(decrementer)ininterrupt_init()here.  146*/  147timer_init();  148#endif  149  150#ifdefCONFIG_SPL_BOARD_INIT  151spl_board_init();  152#endif  135:输出debug信息:》spl:board_init_r();  137~140:如果定义了:CONFIG_SYS_SPL_MALLOC_START,则进行memory的malloc池初始化。以后调用malloc就在这个池子里面分配内存。142~148:如果没有定义:CONFIG_PPC,则进行timer的初始化:timer_init()<arm/arm

u-boot中SPL源代码分析

u/armv7/at91/time.c>  150~150:CONFIG_SPL_BOARD_INIT,则调用spl_board_init()。这是board相关的定义,<board/atmel

u-boot中SPL源代码分析

ma5d3xek

u-boot中SPL源代码分析

ma5d3xek.c>  一切就绪后,就要检查从什么设备来启动了。这里就贴出RAM,MMC,NAND相关代码  154boot_device=spl_boot_device();  155debug("bootdevice-%d",boot_device);  156switch(boot_device){  157#ifdefCONFIG_SPL_RAM_DEVICE  158caseBOOT_DEVICE_RAM:  159spl_ram_load_image();  160break;  161#endif  162#ifdefCONFIG_SPL_MMC_SUPPORT  163caseBOOT_DEVICE_MMC1:  164caseBOOT_DEVICE_MMC2:  165caseBOOT_DEVICE_MMC2_2:  166spl_mmc_load_image();  167break;  168#endif  169#ifdefCONFIG_SPL_NAND_SUPPORT  170caseBOOT_DEVICE_NAND:  171spl_nand_load_image();  172break;  173#endif  154:获取spl_boot_device,即从什么设备启动。  157~161:如果定义了CONFIG_SPL_RAM_DEVICE,则执行spl_ram_load_image(),其就是将image下载到ram中。  162~168:如果定义了CONFIG_SPL_MMC_SUPPORT,则执行spl_mmc_load_image(),其就是将image从mmc/sd里面读取到ram中。  169~173:如果定义了CONFIG_SPL_NAND_SUPPORT,则执行spl_nand_load_image(),其就是将image从nandflash中读取到ram中。  当要启动的image位于RAM中后,我们就可以启动之。  213switch(spl_image.os){  214caseIH_OS_U_BOOT:  215debug("JumpingtoU-Boot");  216break;  217#ifdefCONFIG_SPL_OS_BOOT  218caseIH_OS_LINUX:  219debug("JumpingtoLinux");  220spl_board_prepare_for_linux();  221jump_to_image_linux((void*)CONFIG_SYS_SPL_ARGS_ADDR);  222#endif  223default:  224debug("UnsupportedOSimageJumpingnevertheless");  225}  226jump_to_image_no_args(&spl_image);  227}

  213:判断image的类型。

  214:如果是u-boot,则直接到227去运行u-boot.  218:如果是Linux,则到221去启动Linux.

  至此,SPL结束它的生命,控制权交于u-boot或Linux. 

  

以上就是系统大全给大家介绍的如何使的方法都有一定的了解了吧,好了,如果大家还想了解更多的资讯,那就赶紧点击系统大全官网吧。

本文来自系统大全http://www.win7cn.com/如需转载请注明!推荐:win7纯净版