bl2_main函數(shù)
bl2_main函數(shù)完成了bl2階段的主要操作,包括
- ? 對下一個階段鏡像文件的解析、
- ? 獲取入口地址和鏡像文件大小等信息,
- ? 然后對鏡像文件進行驗簽和加載操作。
- ? 將bl31加載到內(nèi)存中后會觸發(fā)安全監(jiān)控模式調(diào)用(smc)將CPU權(quán)限轉(zhuǎn)交給bl31。
該函數(shù)的主要內(nèi)容和相關(guān)注釋如下:
** void bl2_main(void)
{
entry_point_info_t *next_bl_ep_info;
bl2_arch_setup(); //執(zhí)行平臺相關(guān)初始化
#if TRUSTED_BOARD_BOOT
/* Initialize authentication module */
auth_mod_init(); //初始化image驗證模塊
#endif /* TRUSTED_BOARD_BOOT */
//加載bl3x image到RAM中并返回bl31的入口地址
next_bl_ep_info = bl2_load_images();
#ifdef AARCH32
disable_mmu_icache_secure(); //禁止MMU的指令cache
#endif /* AArch32 */
console_flush(); //刷新console操作
/* 調(diào)用smc指令,觸發(fā)在bl1中設(shè)定的smc異常中斷處理函數(shù),跳轉(zhuǎn)到bl31 */
smc(BL1_SMC_RUN_IMAGE, (unsigned long)next_bl_ep_info, 0, 0, 0, 0,0, 0);
}**
bl2_load_images函數(shù)
bl2_load_images函數(shù)完成將bl32和bl33的鏡像文件加載到內(nèi)存中并返回bl31鏡像的入口地址,最終在bl2_main函數(shù)中通過觸發(fā)安全監(jiān)控模式調(diào)用(smc)跳轉(zhuǎn)到bl31,并將CPU控制權(quán)限交給bl31。
該函數(shù)的主要內(nèi)容和注釋如下:
entry_point_info_t *bl2_load_images(void)
{
bl_params_t *bl2_to_next_bl_params;
bl_load_info_t *bl2_load_info;
const bl_load_info_node_t *bl2_node_info;
int plat_setup_done = 0;
int err;
/* 獲取bl3x image的加載和入口函數(shù)信息 */
bl2_load_info = plat_get_bl_image_load_info();
/* 檢查返回的bl2_load_info中的信息是否正確 */
assert(bl2_load_info);
assert(bl2_load_info- >head);
assert(bl2_load_info- >h.type == PARAM_BL_LOAD_INFO);
assert(bl2_load_info- >h.version >= VERSION_2);
/* 將bl2_load_info中的head變量的值賦值為bl2_node_info,即將bl31 image的入口信息
傳遞給bl2_node_info變量 */
bl2_node_info = bl2_load_info- >head;
/* 進入loop循環(huán) */
while (bl2_node_info) {
/* 在加載特定的bl3x image到RAM之前先確定是否需要進行平臺的初始化 */
if (bl2_node_info- >image_info- >h.attr & IMAGE_ATTRIB_PLAT_SETUP) {
if (plat_setup_done) {
WARN("BL2: Platform setup already done! ! n");
} else {
INFO("BL2: Doing platform setupn");
bl2_platform_setup();
plat_setup_done = 1;
}
}
/* 對bl3x image進行電子驗簽,如果通過則執(zhí)行加載操作 */
if (! (bl2_node_info- >image_info- >h.attr & IMAGE_ATTRIB_SKIP_LOADING)) {
INFO("BL2: Loading image id %dn", bl2_node_info- >image_id);
err = load_auth_image(bl2_node_info- >image_id,
bl2_node_info- >image_info);
if (err) {
ERROR("BL2: Failed to load image (%i)n", err);
plat_error_handler(err);
}
} else {
INFO("BL2: Skip loading image id %dn", bl2_node_info- >image_id);
}
/* 可以根據(jù)實際需要更改,通過給定image ID來更改image的加載信息 */
err = bl2_plat_handle_post_image_load(bl2_node_info- >image_id);
if (err) {
ERROR("BL2: Failure in post image load handling (%i)n", err);
plat_error_handler(err);
}
bl2_node_info = bl2_node_info- >next_load_info;
}
/* 獲取下一個執(zhí)行的鏡像的入口信息,并且將以后會被執(zhí)行的鏡像的入口信息組合成鏈表,通過判斷
image des中的ep_info.h.attr的值是否為(EXECUTABLE|EP_FIRST_EX)來確定接下來第一個
被執(zhí)行的image*/
bl2_to_next_bl_params = plat_get_next_bl_params();
assert(bl2_to_next_bl_params);
assert(bl2_to_next_bl_params- >head);
assert(bl2_to_next_bl_params- >h.type == PARAM_BL_PARAMS);
assert(bl2_to_next_bl_params- >h.version >= VERSION_2);
plat_flush_next_bl_params();
/* 返回下一個進入的鏡像的入口信息,即bl31的入口信息 */
return bl2_to_next_bl_params- >head- >ep_info;
}
bl3x鏡像文件信息
ATF使用bl_mem_params_node_t結(jié)構(gòu)體變量數(shù)組bl_mem_params_desc_ptr來保存bl3x鏡像文件的信息。該結(jié)構(gòu)體內(nèi)容如下:
typedef struct bl_mem_params_node {
unsigned int image_id; //鏡像文件的id值
image_info_t image_info; //鏡像文件的信息
entry_point_info_t ep_info; //bl3x的入口地址信息
unsigned int next_handoff_image_id; //寫一個階段bl3x的id值
bl_load_info_node_t load_node_mem; //該鏡像文件需要被保存在RAM中的信息
bl_params_node_t params_node_mem; //該鏡像文件啟動時所需參數(shù)在RAM中的信息
} bl_mem_params_node_t;
在bl2_load_images函數(shù)中通過調(diào)用plat_get_bl_image_load_info函數(shù)來獲取bl3x鏡像文件的信息,ATF源代碼中通過使用REGISTER_BL_IMAGE_DESCS宏將事先定義好的bl2_mem_params_descs變量中的數(shù)據(jù)保存到bl_mem_params_desc_ptr數(shù)組中,而bl2_mem_params_descs中保存的就是所有bl3x鏡像文件的基本信息,開發(fā)者可根據(jù)不同平臺的實際情況修改bl2_mem_params_descs變量中各鏡像文件的信息。
-
內(nèi)存
+關(guān)注
關(guān)注
8文章
2967瀏覽量
73815 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4283瀏覽量
62325 -
變量
+關(guān)注
關(guān)注
0文章
613瀏覽量
28306
發(fā)布評論請先 登錄
相關(guān)推薦
評論