文章目錄

Basic initialization

RPI 上的 GPU 會將 kernel8.img 載入到 RAM (預設位於 0x80000),之後 4 個 CPU 會同時跑 kernel code,在這邊為了簡單一點,所以只希望只有一個 core 在跑。

需求:

  1. Let only one core proceed, and let others enter a busy loop.
  2. Initialize the BSS segment.
  3. Set the stack pointer to an appropriate position.

start.s

我將 Lab 0 的 main.s 改名為 start.s,用於跑開機後的初始化流程,最後會跳到 main.c 定義的 main function。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
.section ".text.boot"

.global _start

_start:
    // get cpu id
    mrs     x1, MPIDR_EL1
    and     x1, x1, #3
    cbz     x1, 2f
    // if cpu_id > 0, stop
1:
    wfe
    b       1b
    // if cpu_id == 0
2:
    // set stack pointer
    ldr     x1, =_start
    mov     sp, x1

    // clear bss
    ldr     x1, =__bss_start
    ldr     x2, =__bss_size
3:  cbz     x2, 4f
    str     xzr, [x1], #8
    sub     x2, x2, #1
    cbnz    x2, 3b

    // jump to main function in C
4:  bl      main
    // halt this core if return
    b       1b

mrs: Move to ARM register from system coprocessor register

linker.ld

Linker Script 也做了些微的修改,將 .text.boot 固定放在 0x80000 後,確保開機跑的是對的 code。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SECTIONS
{
  . = 0x80000;
  .text :
  {
    KEEP(*(.text.boot))
    *(.text)
  }
  .data :
  {
    *(.data)
  }
  .bss ALIGN(16) (NOLOAD) :
  {
    __bss_start = .;

    *(.bss)

    __bss_end = .;
  }
}

__bss_size = (__bss_end - __bss_start) >> 3;

KEEP: Mark sections that should not be eliminated when link-time garbage collection is in use (Ref: Input Section and Garbage Collection)

NOLOAD: Mark a section to not be loaded at run time. (Ref: Optional Section Attributes)

ALIGN: 對齊到數字的倍數

comments powered by Disqus