当前位置:   article > 正文

3. ATF(ARM Trusted firmware)启动---bl2_atf mmu

atf mmu

   

BL2 image将会为后续image的加载执行相关的初始化操作。主要是内存,MMU,串口以及EL3软件运行环境的设置,并且加载bl3x的image到RAM中。通过查看bl2.ld.S文件就可以发现,bl2 image的入口函数是bl2_entrypoint。该函数定义在bl2/aarch64/bl2_entrypoint.S文件中。

1.bl2_entrypoint

该函数的内容如下,该函数最终会出发smc操作,从bl1中将CPU的控制权转交给bl31:

  1. func bl2_entrypoint
  2. /*---------------------------------------------
  3. * Save from x1 the extents of the tzram
  4. * available to BL2 for future use.
  5. * x0 is not currently used.
  6. * ---------------------------------------------
  7. */
  8. mov x20, x1
  9. /* ---------------------------------------------
  10. * Set the exception vector to something sane.
  11. * ---------------------------------------------
  12. */
  13. adr x0, early_exceptions //设定异常向量
  14. msr vbar_el1, x0
  15. isb
  16. /* ---------------------------------------------
  17. * Enable the SError interrupt now that the
  18. * exception vectors have been setup.
  19. * ---------------------------------------------
  20. */
  21. msr daifclr, #DAIF_ABT_BIT
  22. /* ---------------------------------------------
  23. * Enable the instruction cache, stack pointer
  24. * and data access alignment checks
  25. * ---------------------------------------------
  26. */
  27. mov x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
  28. mrs x0, sctlr_el1
  29. orr x0, x0, x1
  30. msr sctlr_el1, x0
  31. isb
  32. /* ---------------------------------------------
  33. * Invalidate the RW memory used by the BL2
  34. * image. This includes the data and NOBITS
  35. * sections. This is done to safeguard against
  36. * possible corruption of this memory by dirty
  37. * cache lines in a system cache as a result of
  38. * use by an earlier boot loader stage.
  39. * ---------------------------------------------
  40. */
  41. adr x0, __RW_START__
  42. adr x1, __RW_END__
  43. sub x1, x1, x0
  44. bl inv_dcache_range
  45. /* ---------------------------------------------
  46. * Zero out NOBITS sections. There are 2 of them:
  47. * - the .bss section;
  48. * - the coherent memory section.
  49. * ---------------------------------------------
  50. */
  51. ldr x0, =__BSS_START__
  52. ldr x1, =__BSS_SIZE__
  53. bl zeromem
  54. #if USE_COHERENT_MEM
  55. ldr x0, =__COHERENT_RAM_START__
  56. ldr x1, =__COHERENT_RAM_UNALIGNED_SIZE__
  57. bl zeromem
  58. #endif
  59. /* --------------------------------------------
  60. * Allocate a stack whose memory will be marked
  61. * as Normal-IS-WBWA when the MMU is enabled.
  62. * There is no risk of reading stale stack
  63. * memory after enabling the MMU as only the
  64. * primary cpu is running at the moment.
  65. * --------------------------------------------
  66. */
  67. bl plat_set_my_stack //初始化bl2运行的栈
  68. /* ---------------------------------------------
  69. * Initialize the stack protector canary before
  70. * any C code is called.
  71. * ---------------------------------------------
  72. */
  73. #if STACK_PROTECTOR_ENABLED
  74. bl update_stack_protector_canary
  75. #endif
  76. /* ---------------------------------------------
  77. * Perform early platform setup & platform
  78. * specific early arch. setup e.g. mmu setup
  79. * ---------------------------------------------
  80. */
  81. mov x0, x20
  82. bl bl2_early_platform_setup //设置平台相关
  83. bl bl2_plat_arch_setup //设置架构相关
  84. /* ---------------------------------------------
  85. * Jump to main function.
  86. * ---------------------------------------------
  87. */
  88. bl bl2_main //跳转到BL2的主要函数执行,从该函数中跳转到bl31以及bl31,
  89. /* ---------------------------------------------
  90. * Should never reach this point.
  91. * ---------------------------------------------
  92. */
  93. no_ret plat_panic_handler
  94. endfunc bl2_entrypoint

2. bl2_main

该函数主要实现将bl3x的image加载RAM中,并通过smc调用执行bl1中指定的smc handle将CPU的全向交给bl31。

  1. void bl2_main(void)
  2. {
  3. entry_point_info_t *next_bl_ep_info;
  4. NOTICE("BL2: %s\n", version_string);
  5. NOTICE("BL2: %s\n", build_message);
  6. /* Perform remaining generic architectural setup in S-EL1 */
  7. bl2_arch_setup();
  8. #if TRUSTED_BOARD_BOOT
  9. /* Initialize authentication module */
  10. auth_mod_init(); //初始化image验证模块
  11. #endif /* TRUSTED_BOARD_BOOT */
  12. /* Load the subsequent bootloader images. */
  13. next_bl_ep_info = bl2_load_images(); //加载bl3x image到RAM中并返回bl31的入口地址
  14. #ifdef AARCH32
  15. /*
  16. * For AArch32 state BL1 and BL2 share the MMU setup.
  17. * Given that BL2 does not map BL1 regions, MMU needs
  18. * to be disabled in order to go back to BL1.
  19. */
  20. disable_mmu_icache_secure();
  21. #endif /* AARCH32 */
  22. console_flush();
  23. /*
  24. * Run next BL image via an SMC to BL1. Information on how to pass
  25. * control to the BL32 (if present) and BL33 software images will
  26. * be passed to next BL image as an argument.
  27. */
  28. /* 调用smc指令,触发在bl1中设定的smc异常中断处理函数,跳转到bl31 */
  29. smc(BL1_SMC_RUN_IMAGE, (unsigned long)next_bl_ep_info, 0, 0, 0, 0, 0, 0);
  30. }

3. bl2_load_images

该函数用来加载bl3x的image到RAM中,返回一个具有image入口信息的变量。smc handle根据该变量跳转到bl31进行执行
 

  1. entry_point_info_t *bl2_load_images(void)
  2. {
  3. bl_params_t *bl2_to_next_bl_params;
  4. bl_load_info_t *bl2_load_info;
  5. const bl_load_info_node_t *bl2_node_info;
  6. int plat_setup_done = 0;
  7. int err;
  8. /*
  9. * Get information about the images to load.
  10. */
  11. /* 获取bl3x image的加载和入口信息 */
  12. bl2_load_info = plat_get_bl_image_load_info();
  13. /* 检查返回的bl2_load_info中的信息是否正确 */
  14. assert(bl2_load_info);
  15. assert(bl2_load_info->head);
  16. assert(bl2_load_info->h.type == PARAM_BL_LOAD_INFO);
  17. assert(bl2_load_info->h.version >= VERSION_2);
  18. /* 将bl2_load_info中的head变量的值赋值为bl2_node_info,即将bl31 image的入口信息传递給bl2_node_info变量 */
  19. bl2_node_info = bl2_load_info->head;
  20. /* 进入loop循环, */
  21. while (bl2_node_info) {
  22. /*
  23. * Perform platform setup before loading the image,
  24. * if indicated in the image attributes AND if NOT
  25. * already done before.
  26. */
  27. /* 在加载特定的bl3x image到RAM之前先确定是否需要做平台的初始化 */
  28. if (bl2_node_info->image_info->h.attr & IMAGE_ATTRIB_PLAT_SETUP) {
  29. if (plat_setup_done) {
  30. WARN("BL2: Platform setup already done!!\n");
  31. } else {
  32. INFO("BL2: Doing platform setup\n");
  33. bl2_platform_setup();
  34. plat_setup_done = 1;
  35. }
  36. }
  37. /* 对bl3x image进行电子验签,如果通过则执行加载操作 */
  38. if (!(bl2_node_info->image_info->h.attr & IMAGE_ATTRIB_SKIP_LOADING)) {
  39. INFO("BL2: Loading image id %d\n", bl2_node_info->image_id);
  40. err = load_auth_image(bl2_node_info->image_id,
  41. bl2_node_info->image_info);
  42. if (err) {
  43. ERROR("BL2: Failed to load image (%i)\n", err);
  44. plat_error_handler(err);
  45. }
  46. } else {
  47. INFO("BL2: Skip loading image id %d\n", bl2_node_info->image_id);
  48. }
  49. /* Allow platform to handle image information. */
  50. /* 可以根据实际需要更改,通过给定image ID来更改image的加载信息 */
  51. err = bl2_plat_handle_post_image_load(bl2_node_info->image_id);
  52. if (err) {
  53. ERROR("BL2: Failure in post image load handling (%i)\n", err);
  54. plat_error_handler(err);
  55. }
  56. /* Go to next image */
  57. bl2_node_info = bl2_node_info->next_load_info;
  58. }
  59. /*
  60. * Get information to pass to the next image.
  61. */
  62. /* 获取下一个执行的Image的入口信息,并且将以后会被执行的image的入口信息组合成链表 ,t通过判断image des中的ep_info.h.attr的值是否为(EXECUTABLE|EP_FIRST_EX)来确定接下来第一个被执行的image*/
  63. bl2_to_next_bl_params = plat_get_next_bl_params();
  64. assert(bl2_to_next_bl_params);
  65. assert(bl2_to_next_bl_params->head);
  66. assert(bl2_to_next_bl_params->h.type == PARAM_BL_PARAMS);
  67. assert(bl2_to_next_bl_params->h.version >= VERSION_2);
  68. /* Flush the parameters to be passed to next image */
  69. plat_flush_next_bl_params();
  70. /* 返回下一个进入的image的入口信息,即bl31的入口信息 */
  71. return bl2_to_next_bl_params->head->ep_info;
  72. }


4.REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)

该宏的执行将会初始化组成bl2加载bl3x image的列表使用到的重要全局变量,其中bl2_mem_params_descs变量的定义如下:

  1. static bl_mem_params_node_t bl2_mem_params_descs[] = {
  2. #ifdef SCP_BL2_BASE
  3. /* Fill SCP_BL2 related information if it exists */
  4. {
  5. .image_id = SCP_BL2_IMAGE_ID,
  6. SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
  7. VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
  8. SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
  9. VERSION_2, image_info_t, 0),
  10. .image_info.image_base = SCP_BL2_BASE,
  11. .image_info.image_max_size = PLAT_CSS_MAX_SCP_BL2_SIZE,
  12. .next_handoff_image_id = INVALID_IMAGE_ID,
  13. },
  14. #endif /* SCP_BL2_BASE */
  15. #ifdef EL3_PAYLOAD_BASE
  16. /* Fill EL3 payload related information (BL31 is EL3 payload)*/
  17. {
  18. .image_id = BL31_IMAGE_ID,
  19. SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
  20. VERSION_2, entry_point_info_t,
  21. SECURE | EXECUTABLE | EP_FIRST_EXE),
  22. .ep_info.pc = EL3_PAYLOAD_BASE,
  23. .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
  24. DISABLE_ALL_EXCEPTIONS),
  25. SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
  26. VERSION_2, image_info_t,
  27. IMAGE_ATTRIB_PLAT_SETUP | IMAGE_ATTRIB_SKIP_LOADING),
  28. .next_handoff_image_id = INVALID_IMAGE_ID,
  29. },
  30. #else /* EL3_PAYLOAD_BASE */
  31. /* Fill BL31 related information */
  32. {
  33. .image_id = BL31_IMAGE_ID,
  34. SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
  35. VERSION_2, entry_point_info_t,
  36. SECURE | EXECUTABLE | EP_FIRST_EXE),
  37. .ep_info.pc = BL31_BASE,
  38. .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
  39. DISABLE_ALL_EXCEPTIONS),
  40. #if DEBUG
  41. .ep_info.args.arg1 = ARM_BL31_PLAT_PARAM_VAL,
  42. #endif
  43. SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
  44. VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
  45. .image_info.image_base = BL31_BASE,
  46. .image_info.image_max_size = BL31_LIMIT - BL31_BASE,
  47. # ifdef BL32_BASE
  48. .next_handoff_image_id = BL32_IMAGE_ID,
  49. # else
  50. .next_handoff_image_id = BL33_IMAGE_ID,
  51. # endif
  52. },
  53. # ifdef BL32_BASE
  54. /* Fill BL32 related information */
  55. {
  56. .image_id = BL32_IMAGE_ID,
  57. SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
  58. VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),
  59. .ep_info.pc = BL32_BASE,
  60. SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
  61. VERSION_2, image_info_t, 0),
  62. .image_info.image_base = BL32_BASE,
  63. .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
  64. .next_handoff_image_id = BL33_IMAGE_ID,
  65. },
  66. # endif /* BL32_BASE */
  67. /* Fill BL33 related information */
  68. {
  69. .image_id = BL33_IMAGE_ID,
  70. SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
  71. VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
  72. # ifdef PRELOADED_BL33_BASE
  73. .ep_info.pc = PRELOADED_BL33_BASE,
  74. SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
  75. VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
  76. # else
  77. .ep_info.pc = PLAT_ARM_NS_IMAGE_OFFSET,
  78. SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
  79. VERSION_2, image_info_t, 0),
  80. .image_info.image_base = PLAT_ARM_NS_IMAGE_OFFSET,
  81. .image_info.image_max_size = ARM_DRAM1_SIZE,
  82. # endif /* PRELOADED_BL33_BASE */
  83. .next_handoff_image_id = INVALID_IMAGE_ID,
  84. }
  85. #endif /* EL3_PAYLOAD_BASE */
  86. };


在该变量中规定了SCP_BL2, EL3_payload, bl32, bl33 image的相关信息,例如:

image的入口地址信息:ep_info

image在RAM中的基地址:image_base

image的基本信息:image_info

image的ID值:image_id

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号