bl31的执行
来源:互联网 发布:免费看书软件哪个好 编辑:程序博客网 时间:2024/04/30 16:47
之前没有atf的时候,一般的bootflow是rom code ->uboot->kernel
有了atf后,其bootflow 改为rom code ->uboot->atf->kernel.加入没有secure os的话,这里的atf就仅仅之bl31.bin
在arm64的时候一般从rom code ->uboot的时候cpu处于el3,32bit模式,然后uboot中设置好warm reset的地址,这样在warm reset后就到atf中,将cpu且到64 bit后执行完bl31.bin 后,切到el1后返回到kernel中执行.
从bl31 中的bl31.ld.S 中SECTIONS定义可以知道,bl31的入口函数是在bl31_entrypoint
SECTIONS
{
. = BL31_BASE;
ASSERT(. == ALIGN(4096),
"BL31_BASE address is not aligned on a page boundary.")
#if SEPARATE_CODE_AND_RODATA
.text . : {
__TEXT_START__ = .;
*bl31_entrypoint.o(.text*)
*(.text*)
*(.vectors)
. = NEXT(4096);
__TEXT_END__ = .;
} >RAM
func bl31_entrypoint
#if !RESET_TO_BL31
/* ---------------------------------------------------------------
* Preceding bootloader has populated x0 with a pointer to a
* 'bl31_params' structure & x1 with a pointer to platform
* specific structure
* ---------------------------------------------------------------
*/
mov x20, x0
mov x21, x1
/* ---------------------------------------------------------------------
* For !RESET_TO_BL31 systems, only the primary CPU ever reaches
* bl31_entrypoint() during the cold boot flow, so the cold/warm boot
* and primary/secondary CPU logic should not be executed in this case.
*
* Also, assume that the previous bootloader has already set up the CPU
* endianness and has initialised the memory.
* ---------------------------------------------------------------------
*/
el3_entrypoint_common \
_set_endian=0 \
_warm_boot_mailbox=0 \
_secondary_cold_boot=0 \
_init_memory=0 \
_init_c_runtime=1 \
_exception_vectors=runtime_exceptions
/* ---------------------------------------------------------------------
* Relay the previous bootloader's arguments to the platform layer
* ---------------------------------------------------------------------
*/
mov x0, x20
mov x1, x21
#else
/* ---------------------------------------------------------------------
* For RESET_TO_BL31 systems which have a programmable reset address,
* bl31_entrypoint() is executed only on the cold boot path so we can
* skip the warm boot mailbox mechanism.
* ---------------------------------------------------------------------
*/
el3_entrypoint_common \
_set_endian=1 \
_warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \
_secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \
_init_memory=1 \
_init_c_runtime=1 \
_exception_vectors=runtime_exceptions
/* ---------------------------------------------------------------------
* For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
* there's no argument to relay from a previous bootloader. Zero the
* arguments passed to the platform layer to reflect that.
* ---------------------------------------------------------------------
*/
mov x0, 0
mov x1, 0
#endif /* RESET_TO_BL31 */
/* ---------------------------------------------
* Perform platform specific early arch. setup
* ---------------------------------------------
*/
//分别调用bl31_early_platform_setup 和 bl31_plat_arch_setup函数,完成后返回这里继续调用bl31_main
bl bl31_early_platform_setup
bl bl31_plat_arch_setup
/* ---------------------------------------------
* Jump to main function.
* ---------------------------------------------
*/
bl bl31_main
/* -------------------------------------------------------------
* Clean the .data & .bss sections to main memory. This ensures
* that any global data which was initialised by the primary CPU
* is visible to secondary CPUs before they enable their data
* caches and participate in coherency.
* -------------------------------------------------------------
*/
adr x0, __DATA_START__
adr x1, __DATA_END__
sub x1, x1, x0
bl clean_dcache_range
adr x0, __BSS_START__
adr x1, __BSS_END__
sub x1, x1, x0
bl clean_dcache_range
//执行完bl31_main 后通过el3_exit 返回
b el3_exit
endfunc bl31_entrypoint
其中bl31_early_platform_setup和bl31_plat_arch_setup 都是对应的平台自己需要实现的函数。我们直接看公共的code
void bl31_main(void)
{
NOTICE("BL31: %s\n", version_string);
NOTICE("BL31: %s\n", build_message);
/* Perform platform setup in BL31 */
bl31_platform_setup();
/* Initialise helper libraries */
bl31_lib_init();
/* Initialize the runtime services e.g. psci. */
INFO("BL31: Initializing runtime services\n");
runtime_svc_init();
/*
* All the cold boot actions on the primary cpu are done. We now need to
* decide which is the next image (BL32 or BL33) and how to execute it.
* If the SPD runtime service is present, it would want to pass control
* to BL32 first in S-EL1. In that case, SPD would have registered a
* function to intialize bl32 where it takes responsibility of entering
* S-EL1 and returning control back to bl31_main. Once this is done we
* can prepare entry into BL33 as normal.
*/
/*
* If SPD had registerd an init hook, invoke it.
*/
//看起来bl32 是从这里跑起来的,执行完成后再回到这里继续执行bl31
if (bl32_init) {
INFO("BL31: Initializing BL32\n");
(*bl32_init)();
}
/*
* We are ready to enter the next EL. Prepare entry into the image
* corresponding to the desired security state after the next ERET.
*/
// 本例中这里就是准备kernel Image
bl31_prepare_next_image_entry();
console_flush();
/*
* Perform any platform specific runtime setup prior to cold boot exit
* from BL31
*/
//准备runtime service
bl31_plat_runtime_setup();
}
有了atf后,其bootflow 改为rom code ->uboot->atf->kernel.加入没有secure os的话,这里的atf就仅仅之bl31.bin
在arm64的时候一般从rom code ->uboot的时候cpu处于el3,32bit模式,然后uboot中设置好warm reset的地址,这样在warm reset后就到atf中,将cpu且到64 bit后执行完bl31.bin 后,切到el1后返回到kernel中执行.
从bl31 中的bl31.ld.S 中SECTIONS定义可以知道,bl31的入口函数是在bl31_entrypoint
SECTIONS
{
. = BL31_BASE;
ASSERT(. == ALIGN(4096),
"BL31_BASE address is not aligned on a page boundary.")
#if SEPARATE_CODE_AND_RODATA
.text . : {
__TEXT_START__ = .;
*bl31_entrypoint.o(.text*)
*(.text*)
*(.vectors)
. = NEXT(4096);
__TEXT_END__ = .;
} >RAM
func bl31_entrypoint
#if !RESET_TO_BL31
/* ---------------------------------------------------------------
* Preceding bootloader has populated x0 with a pointer to a
* 'bl31_params' structure & x1 with a pointer to platform
* specific structure
* ---------------------------------------------------------------
*/
mov x20, x0
mov x21, x1
/* ---------------------------------------------------------------------
* For !RESET_TO_BL31 systems, only the primary CPU ever reaches
* bl31_entrypoint() during the cold boot flow, so the cold/warm boot
* and primary/secondary CPU logic should not be executed in this case.
*
* Also, assume that the previous bootloader has already set up the CPU
* endianness and has initialised the memory.
* ---------------------------------------------------------------------
*/
el3_entrypoint_common \
_set_endian=0 \
_warm_boot_mailbox=0 \
_secondary_cold_boot=0 \
_init_memory=0 \
_init_c_runtime=1 \
_exception_vectors=runtime_exceptions
/* ---------------------------------------------------------------------
* Relay the previous bootloader's arguments to the platform layer
* ---------------------------------------------------------------------
*/
mov x0, x20
mov x1, x21
#else
/* ---------------------------------------------------------------------
* For RESET_TO_BL31 systems which have a programmable reset address,
* bl31_entrypoint() is executed only on the cold boot path so we can
* skip the warm boot mailbox mechanism.
* ---------------------------------------------------------------------
*/
el3_entrypoint_common \
_set_endian=1 \
_warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \
_secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \
_init_memory=1 \
_init_c_runtime=1 \
_exception_vectors=runtime_exceptions
/* ---------------------------------------------------------------------
* For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
* there's no argument to relay from a previous bootloader. Zero the
* arguments passed to the platform layer to reflect that.
* ---------------------------------------------------------------------
*/
mov x0, 0
mov x1, 0
#endif /* RESET_TO_BL31 */
/* ---------------------------------------------
* Perform platform specific early arch. setup
* ---------------------------------------------
*/
//分别调用bl31_early_platform_setup 和 bl31_plat_arch_setup函数,完成后返回这里继续调用bl31_main
bl bl31_early_platform_setup
bl bl31_plat_arch_setup
/* ---------------------------------------------
* Jump to main function.
* ---------------------------------------------
*/
bl bl31_main
/* -------------------------------------------------------------
* Clean the .data & .bss sections to main memory. This ensures
* that any global data which was initialised by the primary CPU
* is visible to secondary CPUs before they enable their data
* caches and participate in coherency.
* -------------------------------------------------------------
*/
adr x0, __DATA_START__
adr x1, __DATA_END__
sub x1, x1, x0
bl clean_dcache_range
adr x0, __BSS_START__
adr x1, __BSS_END__
sub x1, x1, x0
bl clean_dcache_range
//执行完bl31_main 后通过el3_exit 返回
b el3_exit
endfunc bl31_entrypoint
其中bl31_early_platform_setup和bl31_plat_arch_setup 都是对应的平台自己需要实现的函数。我们直接看公共的code
void bl31_main(void)
{
NOTICE("BL31: %s\n", version_string);
NOTICE("BL31: %s\n", build_message);
/* Perform platform setup in BL31 */
bl31_platform_setup();
/* Initialise helper libraries */
bl31_lib_init();
/* Initialize the runtime services e.g. psci. */
INFO("BL31: Initializing runtime services\n");
runtime_svc_init();
/*
* All the cold boot actions on the primary cpu are done. We now need to
* decide which is the next image (BL32 or BL33) and how to execute it.
* If the SPD runtime service is present, it would want to pass control
* to BL32 first in S-EL1. In that case, SPD would have registered a
* function to intialize bl32 where it takes responsibility of entering
* S-EL1 and returning control back to bl31_main. Once this is done we
* can prepare entry into BL33 as normal.
*/
/*
* If SPD had registerd an init hook, invoke it.
*/
//看起来bl32 是从这里跑起来的,执行完成后再回到这里继续执行bl31
if (bl32_init) {
INFO("BL31: Initializing BL32\n");
(*bl32_init)();
}
/*
* We are ready to enter the next EL. Prepare entry into the image
* corresponding to the desired security state after the next ERET.
*/
// 本例中这里就是准备kernel Image
bl31_prepare_next_image_entry();
console_flush();
/*
* Perform any platform specific runtime setup prior to cold boot exit
* from BL31
*/
//准备runtime service
bl31_plat_runtime_setup();
}
阅读全文
0 0
- bl31的执行
- bl31 进入bl32的过程
- bl31 runtime service的注册和查找
- 4. ATF(ARM Trusted firmware)启动---bl2到bl31的跳转
- 5. ATF(ARM Trusted firmware)启动---bl31
- ARM TrustZone技术简介 -- 3 (BL31 Secure Monitor简介)
- ARM TrustZone技术简介(三)(BL31 Secure Monitor简介)
- 编译执行和解释执行的区别
- 编译执行和解释执行的区别
- 编译执行和解释执行的区别
- 如何查找SQL执行的真实执行计划
- PHP的执行原理/执行流程
- 【转】PHP的执行原理/执行流程
- oracle执行计划的执行顺序
- PHP的执行原理/执行流程
- sql的执行原理和执行顺序
- 编译执行和解释执行的区别
- 编译执行和解释执行的区别
- python yield generator 详解
- MYSQL解析2017/5/24
- fedora修改hostname
- java 方法以及方法的重载
- postgres的备份(Linux)与恢复(Windows)
- bl31的执行
- 列表中播放 videoview 仿内涵段子
- 不懂提高简历命中率?难怪没有面试!
- 有点乱,想歇歇
- 28.七-27拆分的runtest
- yii2框架下在两个页面之间传递弹出消息
- Mac 下安装pip
- PHP微信接口开发
- DES加解密(Java)