Bare-metal编程

针对AMR64体系结构, bare metal的启动程序。

启动

https://github.com/thisinnocence/qemu-virt-hello/blob/master/kernel/start.S

ChatGPT的解释

BEGIN_FUNC(_start)
  mrs  x1, mpidr_el1          // 获取多处理器ID寄存器的值到x1
  and  x1, x1, #3             // 检查处理器ID的最低两位, <=> x1 & 0b11
  cmp  x1, #0                 // 比较处理器ID是否为0
  bne  hang                   // 如果不是0,跳转到 hang

primary:
  bl  arm64_elX_to_el1        // 跳转到 arm64_elX_to_el1

  // set exception vector
  adr  x0, exception_vector   // 获取异常向量表的地址
  msr  vbar_el1, x0           // 设置异常向量表寄存器

  // setup stack
  ldr  x0, =stack             // 加载堆栈地址
  mov  sp, x0                 // 设置堆栈指针

  // jump to C code
  b  main                     // 跳转到main函数
  // never return

hang:
  wfi                         // 等待中断
  b  hang                     // 跳转回 hang
END_FUNC(_start)

在编译的中间文件 kernel/kernel.asm 中可以看到

0000000040000000 <_start>:
    40000000: d53800a1        mrs     x1, mpidr_el1
    40000004: 92400421        and     x1, x1, #0x3
    40000008: f100003f        cmp     x1, #0x0
    4000000c: 540000e1        b.ne    40000028 <hang>  // b.any

0000000040000010 <primary>:
    40000010: 94000615        bl      40001864 <arm64_elX_to_el1>
    40000014: 10007f60        adr     x0, 40001000 <exception_vector>
    40000018: d518c000        msr     vbar_el1, x0
    4000001c: 580000a0        ldr     x0, 40000030 <hang+0x8>
    40000020: 9100001f        mov     sp, x0
    40000024: 14000641        b       40001928 <main>

0000000040000028 <hang>:
    40000028: d503207f        wfi
    4000002c: 17ffffff        b       40000028 <hang>
    40000030: 40005008        .inst   0x40005008 ; undefined

根据 mpidr_el1 选择主核来启动,其他的核挂起。

ARM bare metal 编程

体系结构强相关的编程,bare metal 裸机编程很有帮助,聚焦体系结构。可以 fork 下面的 project 学习: