zircon 是fuchsia的内核,其base 版本是little kernel.
zircon目前支持x86和arm64 两种架构,其arm64架构的入口地址为
zircon-master\kernel\arch\arm64\start.S
其入口函数如下:
FUNCTION(_start)
/* Save the Boot info for the primary CPU only */
mrs cpuid, mpidr_el1
ubfx cpuid, cpuid, #0, #15 /* mask Aff0 and Aff1 fields */
cbnz cpuid, .Lno_save_bootinfo
/* save x0 in zbi_paddr */
adrp tmp, zbi_paddr
str x0, [tmp, #:lo12:zbi_paddr]
/* save entry point physical address in kernel_entry_paddr */
adrp tmp, kernel_entry_paddr
adr tmp2, _start
str tmp2, [tmp, #:lo12:kernel_entry_paddr]
adrp tmp2, arch_boot_el
mrs x2, CurrentEL
str x2, [tmp2, #:lo12:arch_boot_el]
.Lno_save_bootinfo:
bl arm64_elX_to_el1
bl arch_invalidate_cache_all
#使能cache从而让atomics和spinlocks工作
/* enable caches so atomics and spinlocks work */
mrs tmp, sctlr_el1
orr tmp, tmp, #(1<<12) /* Enable icache */
orr tmp, tmp, #(1<<2) /* Enable dcache/ucache */
msr sctlr_el1, tmp
从这段代码可以知道所有cpu在zircon中的入口函数都是_start这个函数,如果是cpu o的话,需要保存BootLoader
传递过来的boot info,而其他cpu 则不用保存bootinfo,所以这里有个跳转口.Lno_save_bootinfo。如果是非0 cpu的话
则直接跳到no_save_bootinfo执行
.Lmmu_on_vaddr:
/* Disable trampoline page-table in ttbr0 */
movlit tmp, MMU_TCR_FLAGS_KERNEL
msr tcr_el1, tmp
isb
/* Invalidate TLB */
tlbi vmalle1
isb
#通过cpuid来判断释放是cpu 0,如果是cpu 0的话,则继续往下执行,如果是非cpu 0,则跳到secondary_boot 开始执行
cbnz cpuid, .Lsecondary_boot
// set up the boot stack for real
adr_global tmp, boot_cpu_kstack_end
mov sp, tmp
// Set the thread pointer early so compiler-generated references
// to the stack-guard and unsafe-sp slots work. This is not a
// real 'struct thread' yet, just a pointer to (past, actually)
// the two slots used by the ABI known to the compiler. This avoids
// having to compile-time disable safe-stack and stack-protector
// code generation features for all the C code in the bootstrap
// path, which (unlike on x86, e.g.) is enough to get annoying.
adr_global tmp, boot_cpu_fake_thread_pointer_location
msr tpidr_el1, tmp
// set the per cpu pointer for cpu 0
adr_global x18, arm64_percpu_array
// Choose a good (ideally random) stack-guard value as early as possible.
bl choose_stack_guard
mrs tmp, tpidr_el1
str x0, [tmp, #ZX_TLS_STACK_GUARD_OFFSET]
// Don't leak the value to other code.
mov x0, xzr
#开始进入c函数
bl lk_main
b .
#非bootcpu 从这里执行,最终跳到arm64_secondary_entry
.Lsecondary_boot:
bl arm64_get_secondary_sp
cbz x0, .Lunsupported_cpu_trap
mov sp, x0
msr tpidr_el1, x1
bl arm64_secondary_entry
.Lunsupported_cpu_trap:
wfe
b .Lunsupported_cpu_trap
END_FUNCTION(_start)