本文共 2617 字,大约阅读时间需要 8 分钟。
第一阶段主要负责 cpu的初始化
cpu 寄存器的初始化 sp寄存器 cpsr Supervisor Mode irq disabled fiq disabled little endiancp15 寄存器 的初始化 cache dcache icache write buffer mmu page table domain access
cpu 寄存器的初始化 sp寄存器 // 值来自于 cpu0的设定值 secondary_data.stack cpsr Supervisor Mode irq disabled fiq disabled little endiancp15 寄存器 的初始化 cache dcache icache write buffer mmu page table // 值来自于 cpu0的设置值 secondary_data.pgdir domain access // 值来自于 cpu0的设置值 secondary_data.pgdir
cpu0:smp_init idle_threads_init for_each_possible_cpu idle_init fork_idle copy_process bringup_nonboot_cpus cpu_up _cpu_up // cpu1跑起来的时候会设置自己cpu1,参数就是下面的值 secondary_data.stack = task_stack_page(idle) + THREAD_START_SP; secondary_data.pgdir = virt_to_phys(idmap_pgd); secondary_data.swapper_pg_dir = get_arch_pgd(swapper_pg_dir); smp_ops.smp_boot_secondary(cpu, idle); / 即 psci_boot_secondary psci_ops.cpu_on // 对应 0.1 版本的 psci为 psci_0_1_cpu_on psci_0_1_cpu_on __psci_cpu_on invoke_psci_fn // 调用什么 取决于 set_conduit 的设定值 __invoke_psci_fn_smc arm_smccc_smc __arm_smccc_smc SMCCC SMCCC_SMC __SMC 0xE1600070 | (((imm4) & 0xF) << 0), 0xF7F08000 | (((imm4) & 0xF) << 16) cpu1:secondary_startup // 设置为 svc mode // irq off // fiq off safe_svcmode_maskall r9 // 将 __secondary_switched 放到 r13 mov_l r12, __secondary_switched mov r13, r12 // 跳转到 arch/arm/mm/proc-v6.S 中的 __v6_setup ,并返回 ldr r12, [r10, #PROCINFO_INITFUNC] add r12, r12, r10 ret r12 // 跳转到 __enable_mmu __enable_mmu // 用 secondary_data.pgdir 设置 page table pointer mcr p15, 0, r4, c2, c0, 0 @ load page table pointer b __turn_mmu_on __turn_mmu_on // 跳转到 __secondary_switched mov r3, r13 ret r3 __secondary_switched // 用 secondary_data.stack 的值 设置 sp ldr_l r7, secondary_data + 12 mov sp, r7 // 跳转到 secondary_start_kernel b secondary_start_kernel
转载地址:http://icigi.baihongyu.com/