Linux 初始化 arm

* Kernel startup entry point.
 * ---------------------------
 *
 * The requirements are:
 *   MMU = off, D-cache = off, I-cache = on or off,
 *   x0 = physical address to the FDT blob.
 *
 * This code is mostly position independent so you call this at
 * __pa(PAGE_OFFSET + TEXT_OFFSET).
 *
 * Note that the callee-saved registers are used for storing variables
 * that are useful before the MMU is enabled. The allocations are described
 * in the entry routines.

__HEAD
_head:
b    stext                // branch to kernel start, magic
le64sym    _kernel_offset_le        // Image load offset from start of RAM, little-endian
le64sym    _kernel_size_le            // Effective size of kernel image, little-endian
le64sym    _kernel_flags_le        // Informative flags, little-endian
DEFINE_IMAGE_LE64(_kernel_size_le, _end - _text);    \
DEFINE_IMAGE_LE64(_kernel_offset_le, TEXT_OFFSET);    \
DEFINE_IMAGE_LE64(_kernel_flags_le, __HEAD_FLAGS);

__INIT
stext   ================= head.s
    preserve_boot_args
    el2_setup
    set_cpu_boot_mode_flag
    __create_page_tables
    __cpu_setup
    __primary_switch
        __primary_switched
            adr_l    x8, vectors            // load VBAR_EL1 with virtual
            
            msr    vbar_el1, x8            // vector table address
            
            Bits [63:11] 
            Vector Base Address. Base address of the exception vectors for exceptions taken in EL1. 
            
const struct cpu_operations acpi_parking_protocol_ops = {
    .name        = "parking-protocol",
    .cpu_init    = acpi_parking_protocol_cpu_init,
    .cpu_prepare    = acpi_parking_protocol_cpu_prepare,
    .cpu_boot    = acpi_parking_protocol_cpu_boot,
    .cpu_postboot    = acpi_parking_protocol_cpu_postboot
};
secondary_entry
    el2_setup
    set_cpu_boot_mode_flag
    secondary_startup
        __cpu_secondary_check52bitva
        __cpu_setup
        __enable_mmu
        __secondary_switched:
            adr_l    x5, vectors
            msr    vbar_el1, x5
    
            


\()\el\() 变量,  \label 变量 
        可以对应:el0_sync
/*
 * Exception vectors.
 */
    .pushsection ".entry.text", "ax"

    .align    11
        
ENTRY(vectors)
    kernel_ventry    1, sync_invalid            // Synchronous EL1t
    kernel_ventry    1, irq_invalid            // IRQ EL1t
    kernel_ventry    1, fiq_invalid            // FIQ EL1t
    kernel_ventry    1, error_invalid        // Error EL1t
    kernel_ventry    1, sync                // Synchronous EL1h
    kernel_ventry    1, irq                // IRQ EL1h
    kernel_ventry    1, fiq_invalid            // FIQ EL1h
    kernel_ventry    1, error            // Error EL1h
    kernel_ventry    0, sync                // Synchronous 64-bit EL0
    kernel_ventry    0, irq                // IRQ 64-bit EL0
    kernel_ventry    0, fiq_invalid            // FIQ 64-bit EL0
    kernel_ventry    0, error            // Error 64-bit EL0
    kernel_ventry    0, sync_invalid, 32        // Synchronous 32-bit EL0
#endif
END(vectors)


由于用户态是在el0,因此当用户态指令发生异常时会陷入到kernel中的。
会执行 ventry el0_sync // Synchronous 64-bit EL0

el0_sync()/el0_irq() ->
    el0_svc
    sys_call_table
     ret_to_user() -> work_pending() -> do_notify_resume()
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值