arch初始化

_start_kernel:
    /* Mask all interrupts */
    csrw CSR_SIE, zero
    csrw CSR_SIP, zero
    ① 将sie,sip寄存器设置为0,关闭所有中断和清除中断的pending(不是异常)。
    /* Load the global pointer */
.option push
.option norelax
    la gp, __global_pointer$
.option pop

    /*
     * Disable FPU to detect illegal usage of
     * floating point in kernel space
     */
    li t0, SR_FS
    csrc CSR_SSTATUS, t0
②关闭掉浮点,浮点至少在内核空间才会使用

#ifdef CONFIG_SMP
    li t0, CONFIG_NR_CPUS
bgeu a0, t0, .Lsecondary_park
    ③如果使能了SMP,硬件的实际hart数量超过配置的数量部分直接进入
    第二阶段,直接进入WFI模式。
#endif

    /* Pick one hart to run the main boot sequence */
    la a3, hart_lottery //hart_lottery是一个全局变量,刚开始为0
    li a2, 1
    amoadd.w a3, a2, (a3)//将a3地址的值赋值为a3,将a2的值加到a3地址处
    bnez a3, .Lsecondary_start //判断a3的值是否为0,如果不为0,跳转
    ④彩票机制,挑选一个hart作为主hart运行,其他hart跳转到.Lsecondary_start
  彩票机制是最先运行到该代码的hart对全局变量hart_lottery+1,后续hart运行时
  检测到全局变量hart_lottery不为0时都需要跳转。

    /* Clear BSS for flat non-ELF images */
    la a3, __bss_start
    la a4, __bss_stop
    ble a4, a3, clear_bss_done
clear_bss:
    REG_S zero, (a3)
    add a3, a3, RISCV_SZPTR
    blt a3, a4, clear_bss
clear_bss_done:
⑤ 向BSS段写0

    /* Save hart ID and DTB physical address */
    mv s0, a0 //hart ID
    mv s1, a1 //DTB phy address
    la a2, boot_cpu_hartid
    REG_S a0, (a2)
    ⑥ 将hart id 保存到变量boot_cpu_hartid

    /* Initialize page tables and relocate to virtual addresses */
    la sp, init_thread_union + THREAD_SIZE //初始化一个临时栈空间,接下来会调用c函数
    mv a0, s1
    call setup_vm  //调用setup_vm,传递参数为DTB的物理地址
    la a0, early_pg_dir
    call relocate   //调用relocate,传递参数为early_pg_dir