_start: # setup stacks per hart csrr t0, mhartid # read current hart id slli t0, t0, 10 # shift left the hart id by 1024 la sp, stacks + STACK_SIZE # set the initial stack pointer # to the end of the stack space add sp, sp, t0 # move the current hart stack pointer # to its place in the stack space
# park harts with id != 0 csrr a0, mhartid # read current hart id bnez a0, park # if we're not on the hart 0 # we park the hart
j os_main # hart 0 jump to c
park: wfi j park
stacks: .skip STACK_SIZE * 4 # allocate space for the harts stacks
csrr是从csr(Control and Status Register)寄存器中read值,而其中的csrr reg, mhartid则是将hart id读到对应的reg中。hart是riscv中硬件线程的最小单位,在riscv的spec中是这样描述的
A RISC-V compatible core might support multiple RISC-V-compatible hardware threads, or harts, through multithreading.
# qemu -kernel loads the kernel at 0x80000000 # and causes each hart (i.e. CPU) to jump there. # kernel.ld causes the following code to # be placed at 0x80000000. .section .text .global _entry _entry: # set up a stack for C. # stack0 is declared in start.c, # with a 4096-byte stack per CPU. # sp = stack0 + (hartid * 4096) la sp, stack0 li a0, 1024*4 csrr a1, mhartid addi a1, a1, 1 mul a0, a0, a1 add sp, sp, a0 # jump to start() in start.c call start spin: j spin