Linker Script

/* Parts of this linker script are directly taken from Andre Richters Project:
 * https://github.com/rust-embedded/rust-raspberrypi-OS-tutorials/blob/master/16_virtual_mem_part4_higher_half_kernel/src/bsp/raspberrypi/link.ld
*/
 
OUTPUT_FORMAT("elf64-littleaarch64")
OUTPUT_ARCH("aarch64")
ENTRY(_start)
phys = 0x40200000;
 
PHDRS
{
  segment_ro PT_LOAD FLAGS(4); /* 4 == RO */
  segment_rx PT_LOAD FLAGS(5); /* 5 == RX */
  segment_rw PT_LOAD FLAGS(6); /* 6 == RW */
}
 
SECTIONS
{
  . = phys;
  kernel_start = .;
  .text : {
    KEEP(*(.text._start))
    *(.text)
    *(.text.*)
  } :segment_rx
  .rodata : ALIGN(8) {
    *(.rodata)
    *(.rodata.*)
  } :segment_ro
  .got    : ALIGN(8) {
    /* Global offset table Todo */
    *(.got)
  } :segment_ro
  .data   : ALIGN(8) {
    *(.data)
    *(.data.*)
  } :segment_rw
  .bss    : ALIGN(8) {
    *(.bss)
    *(.bss.*)
  } :segment_rw
  . = ALIGN(4K); /* Align to page boundary */
  /***********************************************************************************************
   * Boot Core Stack
   ***********************************************************************************************/
  __boot_core_stack_start = .;         /*   ^             */
                                       /*   | stack       */
  . += 16K;                            /*   | growth      */
                                       /*   | direction   */
  __boot_core_stack_end_exclusive = .; /*   |             */
  kernel_end = .;
}

Initialization

.equ _core_id_mask, 0xff
 
.section .text._start
 
_start:
    // Only proceed on the boot core. Park it otherwise.
    mrs x1, mpidr_el1
    and x1, x1, _core_id_mask
    mov x2, xzr  // Assume CPU 0 is responsible for booting
    cmp x1, x2
    b.ne    1f
 
    // If execution reaches here, it is the boot core. Now, prepare the jump to Rust code.
 
    // This loads the physical address of the stack end. For details see
    // https://github.com/rust-embedded/rust-raspberrypi-OS-tutorials/blob/master/16_virtual_mem_part4_higher_half_kernel/src/bsp/raspberrypi/link.ld
    adrp    x4, __boot_core_stack_end_exclusive
    add     x4, x4, #:lo12:__boot_core_stack_end_exclusive
    mov     sp, x4
 
    // Jump to Rust code.
    b   _start_cosmos
 
    // Infinitely wait for events (aka "park the core").
1:  wfe
    b   1b
 
.size   _start, . - _start
.type   _start, function
.global _start

해석

  • mrs x1, mpidr_el1: assign mpidr_el1[^mpidr_el1] to x1
  • and x1, x1, __core_id_mask: x1 = x1 | 0xff
  • mov x2, xzr: x2 = 0
  • cmp x1, x2; b.ne 1f;: if (x1 != x2) goto 1; (1: loop)
  • adrp, add: relocation123.. 결국 x4 = __boot_core_stack_end_exclusive
  • mov sp, x4: sp = x4

Footnotes

  1. https://casionwoo.tistory.com/25

  2. https://sourceware.org/binutils/docs/as/AArch64_002dRelocations.html

  3. https://stackoverflow.com/questions/64838776/understanding-arm-relocation-example-str-x0-tmp-lo12zbi-paddr