ATF中如何用函数完成bl2的启动

描述

bl2_main函数

bl2_main函数完成了bl2阶段的主要操作,包括

  • • 对下一个阶段镜像文件的解析、
  • • 获取入口地址和镜像文件大小等信息,
  • • 然后对镜像文件进行验签和加载操作。
  • • 将bl31加载到内存中后会触发安全监控模式调用(smc)将CPU权限转交给bl31。

该函数的主要内容和相关注释如下:

**        void bl2_main(void)

        {

            entry_point_info_t *next_bl_ep_info;

            bl2_arch_setup();               //执行平台相关初始化

        #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操作

            /* 调用smc指令,触发在bl1中设定的smc异常中断处理函数,跳转到bl31 */

              smc(BL1_SMC_RUN_IMAGE, (unsigned long)next_bl_ep_info, 0, 0, 0, 0,0, 0);

          }**

bl2_load_images函数

bl2_load_images函数完成将bl32和bl33的镜像文件加载到内存中并返回bl31镜像的入口地址,最终在bl2_main函数中通过触发安全监控模式调用(smc)跳转到bl31,并将CPU控制权限交给bl31。

该函数的主要内容和注释如下:

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的加载和入口函数信息 */

            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循环 */

            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进行电子验签,如果通过则执行加载操作 */

                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);

                }

                  /* 可以根据实际需要更改,通过给定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;

              }

              /*  获取下一个执行的镜像的入口信息,并且将以后会被执行的镜像的入口信息组合成链表,通过判断

              image  des中的ep_info.h.attr的值是否为(EXECUTABLE|EP_FIRST_EX)来确定接下来第一个

              被执行的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结构体变量数组bl_mem_params_desc_ptr来保存bl3x镜像文件的信息。该结构体内容如下:

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;       //该镜像文件启动时所需参数在RAM中的信息

        } bl_mem_params_node_t;

在bl2_load_images函数中通过调用plat_get_bl_image_load_info函数来获取bl3x镜像文件的信息,ATF源代码中通过使用REGISTER_BL_IMAGE_DESCS宏将事先定义好的bl2_mem_params_descs变量中的数据保存到bl_mem_params_desc_ptr数组中,而bl2_mem_params_descs中保存的就是所有bl3x镜像文件的基本信息,开发者可根据不同平台的实际情况修改bl2_mem_params_descs变量中各镜像文件的信息。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分