Try   HackMD

Lab 0: Bare Minimum

Just test our toolchain. The resulting kernel8.img should boot on Raspberry Pi, and stop the CPU cores in an infinite loop. You can check that by running

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Assembly

When the control is passed to kernel8.img, the environment is not ready for C. Therefore we must implement a small preambule in Assembly.

CPU has 4 cores. All of them are running the same infinite loop for now.

.section ".text.boot" .global _start _start: 1: wfe b 1b

Makefile

Our Makefile is very simple. We compile start.S, as this is our only source. Then in linker phase we link it using the linker.ld script. Finaly we convert the resulting elf executable into a raw image.

ARMGNU ?= aarch64-linux-gnu COPS = -Wall -nostdlib -nostartfiles -ffreestanding -Iinclude -mgeneral-regs-only -std=gnu99 -ggdb ASMOPS = -Iinclude -ggdb BUILD_DIR = build SRC_DIR = src all : kernel8.img clean : rm -rf $(BUILD_DIR) *.img $(BUILD_DIR)/%_c.o: $(SRC_DIR)/%.c mkdir -p $(@D) $(ARMGNU)-gcc $(COPS) -MMD -c $< -o $@ $(BUILD_DIR)/%_s.o: $(SRC_DIR)/%.S mkdir -p $(@D) $(ARMGNU)-gcc $(ASMOPS) -MMD -c $< -o $@ C_FILES = $(wildcard $(SRC_DIR)/*.c) ASM_FILES = $(wildcard $(SRC_DIR)/*.S) OBJ_FILES = $(C_FILES:$(SRC_DIR)/%.c=$(BUILD_DIR)/%_c.o) OBJ_FILES += $(ASM_FILES:$(SRC_DIR)/%.S=$(BUILD_DIR)/%_s.o) DEP_FILES = $(OBJ_FILES:%.o=%.d) -include $(DEP_FILES) kernel8.img: $(SRC_DIR)/linker.ld $(OBJ_FILES) $(ARMGNU)-ld -T $(SRC_DIR)/linker.ld -o $(BUILD_DIR)/kernel8.elf $(OBJ_FILES) $(ARMGNU)-objcopy $(BUILD_DIR)/kernel8.elf -O binary kernel8.img run: qemu-system-aarch64 -M raspi3 -kernel kernel8.img -serial null -serial pty gdb: qemu-system-aarch64 -M raspi3 -kernel kernel8.img -serial null -serial pty -S -s

Linker script

Not surpisingly simple too. We just set the base address where our kernel8.img will be loaded, and we put the only section we have there.

For AArch64 the load address is 0x80000, and not 0x8000 as with AArch32.

SECTIONS { . = 0x80000; .text : { *(.text.boot) } /DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) } }

How to run

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


Next Lab : Multicore C


Project Source Code: Bare-Metal-Mini-PiOS
Author : andykuo8766