optee的启动

本文详细解析了Optee在ATF中的启动过程,从_kern.ld.S文件找到入口函数_start,并逐步深入到arm32和arm64的入口函数。启动过程中涉及DTB传递、内存管理、初始化、MMU启用等多个关键步骤,最终通过SMC返回到ATF。
摘要由CSDN通过智能技术生成

optee是从ATF中启动的,是作为一个svc来启动,启动玩后在optee中又通过smc返回到ATF中.
从core/arch/arm/kernel/kern.ld.S 中可以发现optee的入口,这也是个通用的规律,即从lds文件中找到入口函数

OUTPUT_FORMAT(CFG_KERN_LINKER_FORMAT)
OUTPUT_ARCH(CFG_KERN_LINKER_ARCH)

ENTRY(_start)

这里可以知道入口是_start,针对arm32的函数在entry_a32.S 中,针对arm64的入口函数在entry_a64.S中
_start 函数如下,这个函数中调用了很多其他函数,后面我们逐个分析.最后通过smc    #0 返回到ATF中
FUNC _start , :
#if defined(CFG_CORE_SEL1_SPMC)
    /*
     * With OP-TEE as SPMC at S-EL1 the SPMD (SPD_spmd) in TF-A passes
     * the DTB in x0, pagaeble part in x1 and the rest of the registers
     * are unused
     */
    mov    x19, x1        /* Save pagable part */
    mov    x20, x0        /* Save DT address */
#else
    mov    x19, x0        /* Save pagable part address */
#if defined(CFG_DT_ADDR)
    ldr     x20, =CFG_DT_ADDR
#else
    mov    x20, x2        /* Save DT address */
#endif
#endif

    adr    x0, reset_vect_table
    msr    vbar_el1, x0
    isb

    set_sctlr_el1
    isb

#ifdef CFG_WITH_PAGER
    /*
     * Move init code into correct location and move hashes to a
     * temporary safe location until the heap is initialized.
     *
     * The binary is built as:
     * [Pager code, rodata and data] : In correct location
     * [Init code and rodata] : Should be copied to __init_start
     * [struct boot_embdata + data] : Should be saved before
     * initializing pager, first uint32_t tells the length of the data
     */
    adr    x0, __init_start    /* dst */
    adr    x1, __data_end        /* src */
    adr    x2, __init_end
    sub    x2, x2, x0        /* init len */
    ldr    w4, [x1, x2]        /* length of hashes etc */
    add    x2, x2, x4        /* length of init and hashes etc */
    /* Copy backwards (as memmove) in case we're overlapping */
    add    x0, x0, x2        /* __init_start + len */
    add    x1, x1, x2        /* __data_end + len */
    adr    x3, cached_mem_end
    str    x0, [x3]
    adr    x2, __init_start
copy_init:
    ldp    x3, x4, [x1, #-16]!
    stp    x3, x4, [x0, #-16]!
    cmp    x0, x2
    b.gt    copy_init
#else
    /*
     * The binary is built as:
     * [Core, rodata and data] : In correct location
     * [struct boot_embdata + data] : Should be moved to __end, first
     * uint32_t tells the length of the struct + data
     */
    adr_l    x0, __end        /* dst */
    adr_l    x1, __data_end        /* src */
    ldr    w2, [x1]        /* struct boot_embdata::total_len */
    /* Copy backwards (as memmove) in case we're overlapping */
    add    x0, x0, x2
    add    x1, x1, x2
    adr    x3, cached_mem_end
    str    x0, [x3]
    adr_l    x2, __end

copy_init:
    ldp    x3, x4, [x1, #-16]!
    stp    x3, x4, [x0, #-16]!
    cmp    x0, x2
    b.gt    copy_init
#endif

    /*
     * Clear .bss, this code obviously depends on the linker keeping
     * start/end of .bss at least 8 byte aligned.
     */
    adr_l    x0, __bss_start
    adr_l    x1, __bss_end
clear_bss:
    str    xzr, [x0], #8
    cmp    x0, x1
    b.lt    clear_bss

#设置SP
    /* Setup SP_EL0 and SP_EL1, SP will be set to SP_EL0 */
    set_sp
#线程的初始化
    bl    thread_init_thread_core_local

    /* Enable aborts now that we can receive exceptions */
    msr    daifclr, #DAIFBIT_ABT

    /*
     * Invalidate dcache for all memory used during initialization to
     * avoid nasty surprices when the cache is turned on. We must not
     * invalidate memory not used by OP-TEE since we may invalidate
     * entries used by for instance ARM Trusted Firmware.
     */
    adr_l    x0, __text_start
    ldr    x1, cached_mem_end
    sub    x1, x1, x0
    bl    dcache_cleaninv_range
#使能串口
    /* Enable Console */
    bl    console_init

#ifdef CFG_CORE_ASLR
    mov    x0, x20
    bl    get_aslr_seed
#else
    mov    x0, #0
#endif

    adr    x1, boot_mmu_config
    bl    core_init_mmu_map

#使能mmu
    bl    __get_core_pos
    bl    enable_mmu

    mov    x0, x19        /* pagable part address */
    mov    x1, #-1
    bl    boot_init_primary_early

    mov    x0, x20        /* DT address */
    bl    boot_init_primary_late

    /*
     * In case we've touched memory that secondary CPUs will use before
     * they have turned on their D-cache, clean and invalidate the
     * D-cache before exiting to normal world.
     */
    adr_l    x0, __text_start
    ldr    x1, cached_mem_end
    sub    x1, x1, x0
    bl    dcache_cleaninv_range


    /*
     * Clear current thread id now to allow the thread to be reused on
     * next entry. Matches the thread_init_boot_thread in
     * boot.c.
     */

#ifdef CFG_CORE_FFA
    adr    x0, cpu_on_handler
    /*
     * Compensate for the load offset since cpu_on_handler() is
     * called with MMU off.
     */
    ldr    x1, boot_mmu_config + CORE_MMU_CONFIG_LOAD_OFFSET
    sub    x0, x0, x1
    bl    ffa_secondary_cpu_ep_register
    b    thread_ffa_msg_wait
#else
    /*
     * Pass the vector address returned from main_init
     * Compensate for the load offset since cpu_on_handler() is
     * called with MMU off.
     */
    ldr    x0, boot_mmu_config + CORE_MMU_CONFIG_LOAD_OFFSET
    adr    x1, thread_vector_table
    sub    x1, x1, x0
    mov    x0, #TEESMC_OPTEED_RETURN_ENTRY_DONE
    smc    #0
    b    .    /* SMC should not return */
#endif
END_FUNC _start
DECLARE_KEEP_INIT _start

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值