uboot中SPL源代碼分析
uboot中SPL源代碼分析
;本文將使用sama5d3xek ;SPL實現做為例子。u-boot ;SPL ;(second ;program ;loader), ;對許多人來說也說很陌生。下面對此進行一個簡單介紹。1. ;arm ;SoC的啟動過程。RomBoot ;-->; ;SPL ;-->; ;u-boot ;-->; ;Linux ;kernel ;-->; ;file ;system ;-->; ;start ;application。(RomBoot是固化在SoC內部的。)。
導讀 ;本文將使用sama5d3xek ;SPL實現做為例子。u-boot ;SPL ;(second ;program ;loader), ;對許多人來說也說很陌生。下面對此進行一個簡單介紹。1. ;arm ;SoC的啟動過程。RomBoot ;-->; ;SPL ;-->; ;u-boot ;-->; ;Linux ;kernel ;-->; ;file ;system ;-->; ;start ;application。(RomBoot是固化在SoC內部的。)。
![](https://img.51dongshi.com/20250105/wz/18528824952.jpg)
系統大全為您提供?本文將使用sama5d3xek?SPL實現做為例子u-boot?SPL?(second?program?loader),?對許多人來說也說很陌生。下面對此進行一個簡單介紹。1.?arm?SoC的啟動過程:RomBoot?-->?SPL?-->?u-boot?-->?Linux?kernel?-->?file?system?-->?start?application(RomBoot是固化在SoC內部的。)u-boot實現了一個新功能,能在編譯u-boot的同時生成SPL二進制文件。2.?SPL運行代碼go?through從u-boot-spl.lds鏈接文件可知,啟動代碼也是start.S.(reset)?
?(b?lowlevel_init:?arch/armu/armv7/lowlevel_init.S)?(b?_main)?-->??(bl?board_init_f)?-->??(board_init_r)?-->??(jump_to_image_no_args去啟動u-boot)?到此SPL的生命周期結束。簡單來講:SPL所做工作,一些硬件的初始化,然后讀取u-boot,最后調轉至u-boot.3.?下面具體分析SPL的相關代碼。110?reset:111?????????bl??????save_boot_params112?????????/*113??????????*?disable?interrupts?(FIQ?and?IRQ),?also?set?the?cpu?to?SVC32?mode,114??????????*?except?if?in?HYP?mode?already115??????????*/116?????????mrs?????r0,?cpsr117?????????and?????r1,?r0,?#0x1f???????????@?mask?mode?bits118?????????teq?????r1,?#0x1a???????????????@?test?for?HYP?mode119?????????bicne???r0,?r0,?#0x1f???????????@?clear?all?mode?bits120?????????orrne???r0,?r0,?#0x13???????????@?set?SVC?mode121?????????orr?????r0,?r0,?#0xc0???????????@?disable?FIQ?and?IRQ122?????????msr?????cpsr,r0123124?/*125??*?Setup?vector:126??*?(OMAP4?spl?TEXT_BASE?is?not?32?byte?aligned.127??*?Continue?to?use?ROM?code?vector?only?in?OMAP4?spl)128??*/129?#if?!(defined(CONfig_OMAP44XX)?&&?defined(CONfig_SPL_BUILD))130?????????/*?Set?V=0?in?CP15?SCTRL?register?-?for?VBAR?to?point?to?vector?*/131?????????mrc?????p15,?0,?r0,?c1,?c0,?0???@?Read?CP15?SCTRL?Register132?????????bic?????r0,?#CR_V???????????????@?V?=?0133?????????mcr?????p15,?0,?r0,?c1,?c0,?0???@?Write?CP15?SCTRL?Register134135?????????/*?Set?vector?address?in?CP15?VBAR?register?*/136?????????ldr?????r0,?=_start137?????????mcr?????p15,?0,?r0,?c12,?c0,?0??@Set?VBAR138?#endif139140?????????/*?the?mask?ROM?code?should?have?PLL?and?others?stable?*/141?#ifndef?CONfig_SKIP_LOWLEVEL_INIT142?????????bl??????cpu_init_cp15143?????????bl??????cpu_init_crit144?#endif145146?????????bl??????_main111:如果沒有重新定義save_boot_params,則使用中的save_boot_params.其不做任何事情,直接返回。116~138:?看注釋即可明白。141:?因為SPL主要是對SoC進行初始化,所以不會定義CONfig_SKIP_LOWLEVE_INIT,?即142,143行得以執行。142:?cpu_init_cpu15,?主要作用invalidate?L1?I/D?cache,?disable?MMU.?檢查是否需要workaround.143:?cpu_init_crit直接跳轉到lowlevel_init下面看看lowlevel_init的實現:18?ENTRY(lowlevel_init)19?????????/*20??????????*?Setup?a?temporary?stack21??????????*/22?????????ldr?????sp,?=CONfig_SYS_INIT_SP_ADDR23?????????bic?????sp,?sp,?#7?/*?8-byte?alignment?for?ABI?compliance?*/24?#ifdef?CONfig_SPL_BUILD25?????????ldr?????r9,?=gdata26?#else27?????????sub?????sp,?#GD_SIZE28?????????bic?????sp,?sp,?#729?????????mov?????r9,?sp30?#endif31?????????/*32??????????*?Save?the?old?lr(passed?in?ip)?and?the?current?lr?to?stack33??????????*/34?????????push????{ip,?lr}3536?????????/*37??????????*?go?setup?pll,?mux,?memory38??????????*/39?????????bl??????s_init40?????????pop?????{ip,?pc}41?ENDPROC(lowlevel_init)22:?對stack?pointer賦值成CONfig_SYS_INIT_SP_ADDR23:?確保sp是8字節對齊。25:將gdata的地址存入到r9寄存器中。39:跳轉到s_init.對Atmel?sama5d3xek?board,?s_init定義在:?此處暫時不分析。然后返回到start.S處,接下來調用:bl?_main到58?ENTRY(_main)5960?/*61??*?Set?up?initial?C?runtime?environment?and?call?board_init_f(0)。62??*/6364?#if?defined(CONfig_SPL_BUILD)?&&?defined(CONfig_SPL_STACK)65?????????ldr?????sp,?=(CONfig_SPL_STACK)66?#else67?????????ldr?????sp,?=(CONfig_SYS_INIT_SP_ADDR)68?#endif?70?????????sub?????sp,?#GD_SIZE????/*?allocate?one?GD?above?SP?*/71?????????bic?????sp,?sp,?#7??????/*?8-byte?alignment?for?ABI?compliance?*/72?????????mov?????r9,?sp??????????/*?GD?is?above?SP?*/73?????????mov?????r0,?#074?????????bl??????board_init_f65:?重新對SP賦值69:?確認sp是8字對齊70:相當于保留一個global_data的大小。71:?確認更新后的sp是8字對齊72:r9指向global_data73:r0賦值074:跳轉到board_init_f中運行。board_init_f在定義:20?/*21??*?In?the?context?of?SPL,?board_init_f?must?ensure?that?any?clocks/etc?for22??*?DDR?are?enabled,?ensure?that?the?stack?pointer?is?valid,?clear?the?BSS23??*?and?call?board_init_f.??We?provide?this?version?by?default?but?mark?it24??*?as?__weak?to?allow?for?platforms?to?do?this?in?their?own?way?if?needed.25??*/26?void?__weak?board_init_f(ulong?dummy)27?{28?????????/*?Clear?the?BSS.?*/29?????????memset(__bss_start,?0,?__bss_end?-?__bss_start);3031?????????/*?Set?global?data?pointer.?*/32?????????gd?=?&gdata;3334?????????board_init_r(NULL,?0);35?}26:?board_init_f是一個弱函數,是可以被重新定義的。29:對BSS段進行清零操作。34:?跳轉到board_init_rboard_init_r在中定義:132?void?board_init_r(gd_t?*dummy1,?ulong?dummy2)133?{134?????????u32?boot_device;135?????????debug("》spl:board_init_r()");136137?#ifdef?CONfig_SYS_SPL_MALLOC_START138?????????mem_malloc_init(CONfig_SYS_SPL_MALLOC_START,139?????????????????????????CONfig_SYS_SPL_MALLOC_SIZE);140?#endif141142?#ifndef?CONfig_PPC143?????????/*144??????????*?timer_init()?does?not?exist?on?PPC?systems.?The?timer?is?initialized145??????????*?and?enabled?(decrementer)?in?interrupt_init()?here.146??????????*/147?????????timer_init();148?#endif149150?#ifdef?CONfig_SPL_BOARD_INIT151?????????spl_board_init();152?#endif135:?輸出debug信息:》spl:board_init_r();137~140:?如果定義了:CONfig_SYS_SPL_MALLOC_START,?則進行memory的malloc池初始化。以后調用malloc就在這個池子里面分配內存。142~148:?如果沒有定義:CONfig_PPC,?則進行timer的初始化:timer_init()?150~150:?CONfig_SPL_BOARD_INIT,?則調用spl_board_init()。?這是board相關的定義,一切就緒后,就要檢查從什么設備來啟動了。這里就貼出RAM,MMC,?NAND相關代碼154?????????boot_device?=?spl_boot_device();155?????????debug("boot?device?-?%d",?boot_device);156?????????switch?(boot_device)?{157?#ifdef?CONfig_SPL_RAM_DEVICE158?????????case?BOOT_DEVICE_RAM:159?????????????????spl_ram_load_image();160?????????????????break;161?#endif162?#ifdef?CONfig_SPL_MMC_SUPPORT163?????????case?BOOT_DEVICE_MMC1:164?????????case?BOOT_DEVICE_MMC2:165?????????case?BOOT_DEVICE_MMC2_2:166?????????????????spl_mmc_load_image();167?????????????????break;168?#endif169?#ifdef?CONfig_SPL_NAND_SUPPORT170?????????case?BOOT_DEVICE_NAND:171?????????????????spl_nand_load_image();172?????????????????break;173?#endif154:?獲取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從nand?flash中讀取到ram中。當要啟動的image位于RAM中后,我們就可以啟動之。213?????????switch?(spl_image.os)?{214?????????case?IH_OS_U_BOOT:215?????????????????debug("Jumping?to?U-Boot");216?????????????????break;217?#ifdef?CONfig_SPL_OS_BOOT218?????????case?IH_OS_LINUX:219?????????????????debug("Jumping?to?Linux");220?????????????????spl_board_prepare_for_linux();221?????????????????jump_to_image_linux((void?*)CONfig_SYS_SPL_ARGS_ADDR);222?#endif223?????????default:224?????????????????debug("Unsupported?OS?image?Jumping?nevertheless");225?????????}226?????????jump_to_image_no_args(&spl_image);227?}213:?判斷image的類型。?214:如果是u-boot,則直接到227去運行u-boot.218:如果是Linux,則到221去啟動Linux.至此,SPL結束它的生命,控制權交于u-boot或Linux.?以上就是系統大全給大家介紹的如何使的方法都有一定的了解了吧,好了,如果大家還想了解更多的資訊,那就趕緊點擊系統大全官網吧。?本文來自系統大全http:///如需轉載請注明!推薦:win7純凈版
uboot中SPL源代碼分析
;本文將使用sama5d3xek ;SPL實現做為例子。u-boot ;SPL ;(second ;program ;loader), ;對許多人來說也說很陌生。下面對此進行一個簡單介紹。1. ;arm ;SoC的啟動過程。RomBoot ;-->; ;SPL ;-->; ;u-boot ;-->; ;Linux ;kernel ;-->; ;file ;system ;-->; ;start ;application。(RomBoot是固化在SoC內部的。)。
為你推薦