02
はじめに
Githubで公開されている,GitHub - bztsrc/raspi3-tutorial: Bare metal Raspberry Pi 3 tutorialsのコードを読んでいく.今回は02_multicorecを理解することを目的とする.
登場ファイル:start.S, main.c, link.ld, Makefile
キーワード:アセンブリ言語,c言語,無限ループ,マルチコア
アセンブリ言語ソースファイル(start.S)
.section ".text.boot" .global _start _start: // CPUの番号を取得 mrs x1, mpidr_el1 //x1レジスタにmpidr_el1レジスタの値を格納 and x1, x1, #3 //x1=x1 & 3 cbz x1, 2f //x1==0なら,直後のラベル2へジャンプ // CPU番号0番以外は, スリープ 1: wfe //スリープ b 1b //直前のラベル1へジャンプ 2: // cpu id == 0 // スタックポインタの設定 ldr x1, =_start //ラベル_startのアドレスをx1レジスタに格納 mov sp, x1 //spレジスタにx1レジスタの値を格納 // BSS領域のゼロクリア ldr x1, =__bss_start //__bss_start(アドレス)をx1レジスタに格納 ldr w2, =__bss_size //__bss_size(アドレス)をw2レジスタに格納 3: cbz w2, 4f //w2==0なら,直後のラベル4へジャンプ str xzr, [x1], #8 //x1番地に0をストア,その後x1=x1+8 sub w2, w2, #1 //w2=w2-1 cbnz w2, 3b //w2!=0なら,直前の3にジャンプ // C言語のコードに処理を移す.ここには戻ってこない 4: bl main //main関数へジャンプ // 戻ってきてしまった場合に備えて無限ループ b 1b //直前のラベル1へジャンプ
- 登場するレジスタ
・x1レジスタ ... 64 ビット汎用レジスタの一つ
・mpidr_el1レジスタ ... レジスタの全体的な機能はよくわからない.しかし,Stanford CS140e - Operating Systemsによると,下位2ビットにはコードを実行しているコアの番号が入るらしい.
・spレジスタ ... スタックポインタ
・w2レジスタ ... x2レジスタの下半分の32ビット部分
・xzrレジスタ ... 64ビットのゼロレジスタ
リンカスクリプト(link.ld)
SECTIONS { . = 0x80000; .text : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) } .rodata : { *(.rodata .rodata.* .gnu.linkonce.r*) } PROVIDE(_data = .); .data : { *(.data .data.* .gnu.linkonce.d*) } .bss (NOLOAD) : { . = ALIGN(16); __bss_start = .; *(.bss .bss.*) *(COMMON) __bss_end = .; } _end = .; /DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) } } __bss_size = (__bss_end - __bss_start)>>3;
Makefile
SRCS = $(wildcard *.c) OBJS = $(SRCS:.c=.o) CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles all: clean kernel8.img start.o: start.S aarch64-elf-gcc $(CFLAGS) -c start.S -o start.o %.o: %.c aarch64-elf-gcc $(CFLAGS) -c $< -o $@ kernel8.img: start.o $(OBJS) aarch64-elf-ld -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf aarch64-elf-objcopy -O binary kernel8.elf kernel8.img clean: rm kernel8.elf *.o >/dev/null 2>/dev/null || true run: qemu-system-aarch64 -M raspi3 -kernel kernel8.img -d in_asm