From b94ba7759ecb7422cccfe9415dd8b8590e045d46 Mon Sep 17 00:00:00 2001 From: equation314 Date: Mon, 4 Mar 2019 15:22:19 +0800 Subject: [PATCH] add aarch64 bootloader framework --- .gitignore | 1 + bootloader/Cargo.lock | 6 +++ bootloader/Cargo.toml | 7 +++ bootloader/Makefile | 20 +++++++++ .../src/arch/aarch64}/boot.S | 11 ++--- bootloader/src/arch/aarch64/boot.ld | 45 +++++++++++++++++++ bootloader/src/arch/aarch64/mod.rs | 1 + bootloader/src/main.rs | 15 +++++++ bootloader/targets/aarch64.json | 36 +++++++++++++++ kernel/Cargo.toml | 2 +- kernel/Makefile | 45 ++++++++++++------- kernel/src/arch/aarch64/entry.S | 21 +++++++++ kernel/src/arch/aarch64/{boot => }/linker.ld | 6 --- kernel/src/arch/aarch64/mod.rs | 2 +- kernel/targets/aarch64.json | 2 +- 15 files changed, 188 insertions(+), 32 deletions(-) create mode 100644 bootloader/Cargo.lock create mode 100644 bootloader/Cargo.toml create mode 100644 bootloader/Makefile rename {kernel/src/arch/aarch64/boot => bootloader/src/arch/aarch64}/boot.S (97%) create mode 100644 bootloader/src/arch/aarch64/boot.ld create mode 100644 bootloader/src/arch/aarch64/mod.rs create mode 100644 bootloader/src/main.rs create mode 100644 bootloader/targets/aarch64.json create mode 100644 kernel/src/arch/aarch64/entry.S rename kernel/src/arch/aarch64/{boot => }/linker.ld (86%) diff --git a/.gitignore b/.gitignore index 975d0c4a..446ff278 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ target Cargo.lock !kernel/Cargo.lock +!bootloader/Cargo.lock !user/Cargo.lock .DS_Store diff --git a/bootloader/Cargo.lock b/bootloader/Cargo.lock new file mode 100644 index 00000000..505c019e --- /dev/null +++ b/bootloader/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rcore-bootloader" +version = "0.1.0" + diff --git a/bootloader/Cargo.toml b/bootloader/Cargo.toml new file mode 100644 index 00000000..dde89766 --- /dev/null +++ b/bootloader/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "rcore-bootloader" +version = "0.1.0" +authors = ["equation314 "] +edition = "2018" + +[dependencies] diff --git a/bootloader/Makefile b/bootloader/Makefile new file mode 100644 index 00000000..0545bbdd --- /dev/null +++ b/bootloader/Makefile @@ -0,0 +1,20 @@ +arch ?= aarch64 +mode ?= debug +target := $(arch) + +bootloader := target/$(target)/$(mode)/rcore-bootloader + +build_args := --target=targets/$(arch).json +ifeq ($(mode), release) +build_args += --release +endif + +.PHONY: all clean + +all: $(bootloader) + +$(bootloader): + @cargo xbuild $(build_args) + +clean: + @cargo clean diff --git a/kernel/src/arch/aarch64/boot/boot.S b/bootloader/src/arch/aarch64/boot.S similarity index 97% rename from kernel/src/arch/aarch64/boot/boot.S rename to bootloader/src/arch/aarch64/boot.S index 7a126bd9..4f66df36 100644 --- a/kernel/src/arch/aarch64/boot/boot.S +++ b/bootloader/src/arch/aarch64/boot.S @@ -1,8 +1,9 @@ # TODO rewrite in Rust, use crate cortex-a .section .text.boot +.globl _start -boot: +_start: # read cpu affinity, start core 0, halt rest mrs x1, mpidr_el1 and x1, x1, #3 @@ -104,11 +105,7 @@ zero_bss_loop: cbnz x2, zero_bss_loop zero_bss_loop_end: - b _start - -.section .text.entry -.globl _start -_start: # jump to rust_main, which shouldn't return. halt if it does - bl rust_main + mov x9, #0x100000 + blr x9 b halt diff --git a/bootloader/src/arch/aarch64/boot.ld b/bootloader/src/arch/aarch64/boot.ld new file mode 100644 index 00000000..57e2c4b2 --- /dev/null +++ b/bootloader/src/arch/aarch64/boot.ld @@ -0,0 +1,45 @@ +ENTRY(_start) + +SECTIONS { + . = 0x80000; /* Raspbery Pi 3 AArch64 (kernel8.img) load address */ + + .text : { + stext = .; + KEEP(*(.text.boot)) /* from boot.S */ + *(.text .text.* .gnu.linkonce.t*) + . = ALIGN(4K); + etext = .; + } + + .rodata : { + srodata = .; + *(.rodata .rodata.* .gnu.linkonce.r*) + . = ALIGN(4K); + erodata = .; + } + + .data : { + sdata = .; + *(.data .data.* .gnu.linkonce.d*) + . = ALIGN(4K); + edata = .; + } + + .bss (NOLOAD) : { + . = ALIGN(32); + sbss = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4K); + ebss = .; + } + + /* end of the binary */ + _end = ALIGN(8); + + /* number of bytes in BSS section and complete binary */ + __bss_length = (ebss - sbss); + __binary_length = (_end - _start); + + /DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) } +} diff --git a/bootloader/src/arch/aarch64/mod.rs b/bootloader/src/arch/aarch64/mod.rs new file mode 100644 index 00000000..8ffaf768 --- /dev/null +++ b/bootloader/src/arch/aarch64/mod.rs @@ -0,0 +1 @@ +global_asm!(include_str!("boot.S")); diff --git a/bootloader/src/main.rs b/bootloader/src/main.rs new file mode 100644 index 00000000..46acd385 --- /dev/null +++ b/bootloader/src/main.rs @@ -0,0 +1,15 @@ +#![no_std] +#![no_main] +#![feature(global_asm)] + +use core::panic::PanicInfo; + +#[panic_handler] +#[no_mangle] +pub extern "C" fn panic(_info: &PanicInfo) -> ! { + loop {} +} + +#[cfg(target_arch = "aarch64")] +#[path = "arch/aarch64/mod.rs"] +pub mod arch; diff --git a/bootloader/targets/aarch64.json b/bootloader/targets/aarch64.json new file mode 100644 index 00000000..4a59d7fb --- /dev/null +++ b/bootloader/targets/aarch64.json @@ -0,0 +1,36 @@ +{ + "abi-blacklist": [ + "stdcall", + "fastcall", + "vectorcall", + "thiscall", + "win64", + "sysv64" + ], + "arch": "aarch64", + "data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", + "executables": true, + "linker": "rust-lld", + "linker-flavor": "ld.lld", + "linker-is-gnu": true, + "pre-link-args": { + "ld.lld": [ + "-Tsrc/arch/aarch64/boot.ld" + ] + }, + "llvm-target": "aarch64-unknown-none", + "no-compiler-rt": true, + "features": "+a53,+strict-align,-neon", + "max-atomic-width": 128, + "os": "none", + "panic": "abort", + "panic-strategy": "abort", + "relocation-model": "static", + "position-independent-executables": true, + "target-c-int-width": "32", + "target-endian": "little", + "target-pointer-width": "64", + "target-family": "unix", + "disable-redzone": true, + "eliminate-frame-pointer": false +} diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index b8b5d68b..26191302 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -27,9 +27,9 @@ board_u540 = ["sv39"] # (for aarch64 RaspberryPi3) nographic = [] board_raspi3 = ["bcm2837", "link_user"] +raspi3_use_generic_timer = ["bcm2837/use_generic_timer"] # (for riscv64) board_k210 = ["m_mode"] -raspi3_use_generic_timer = ["bcm2837/use_generic_timer"] # Hard link user program link_user = [] diff --git a/kernel/Makefile b/kernel/Makefile index 685f362b..14963de3 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -32,8 +32,12 @@ m_mode ?= target := $(arch) kernel := target/$(target)/$(mode)/rcore -bin := target/$(target)/$(mode)/kernel.bin +boot_bin := target/$(target)/$(mode)/boot.bin +kernel_bin := target/$(target)/$(mode)/kernel.bin +kernel_img := target/$(target)/$(mode)/kernel.img bootimage := target/$(target)/bootimage.bin +bootloader_dir = ../bootloader +bootloader := $(bootloader_dir)/target/$(target)/$(mode)/rcore-bootloader bbl_path := $(PWD)/../riscv-pk user_dir := ../user k210_lib := ../tools/k210/libkendryte.a @@ -53,9 +57,7 @@ endif export M_MODE = $(m_mode) ifeq ($(arch), aarch64) -graphic ?= on -else -graphic ?= off +graphic := on endif ### qemu options ### @@ -76,7 +78,7 @@ qemu_net_opts += \ else ifeq ($(arch), riscv32) qemu_opts += \ -machine virt \ - -kernel $(bin) \ + -kernel $(kernel_img) \ -drive file=$(SFSIMG),format=raw,id=sfs \ -device virtio-blk-device,drive=sfs qemu_net_opts += \ @@ -89,7 +91,7 @@ endif else ifeq ($(arch), riscv64) qemu_opts += \ -machine virt \ - -kernel $(bin) \ + -kernel $(kernel_img) \ -drive file=$(SFSIMG),format=raw,id=sfs \ -device virtio-blk-device,drive=sfs qemu_net_opts += \ @@ -103,7 +105,7 @@ else ifeq ($(arch), aarch64) qemu_opts += \ -machine $(board) \ -serial null -serial mon:stdio \ - -kernel $(bin) + -kernel $(kernel_img) endif ifdef d @@ -170,7 +172,7 @@ objdump := $(prefix)objdump objcopy := $(prefix)objcopy cc := $(prefix)gcc as := $(prefix)as -gdb := gdb +gdb := $(prefix)gdb export CC=$(cc) .PHONY: all clean run build asm doc justrun debug kernel sfsimg install runnet @@ -179,6 +181,7 @@ all: kernel clean: @cargo clean + @cd $(bootloader_dir) && make clean @cd $(user_dir) && make clean doc: @@ -199,12 +202,12 @@ justrunui: build -device virtio-gpu-device \ -device virtio-mouse-device -debug: $(kernel) $(bin) +debug: $(kernel) $(kernel_img) @qemu-system-$(arch) $(qemu_opts) -s -S & @sleep 1 @$(gdb) $(kernel) -x ../tools/gdbinit -build: $(bin) +build: $(kernel_img) asm: @$(objdump) -dS $(kernel) | less @@ -215,7 +218,13 @@ header: sym: @$(objdump) -t $(kernel) | less -$(bin): kernel +$(bootloader): +ifeq ($(arch), aarch64) + @echo Building $(arch) bootloader + cd $(bootloader_dir) && make arch=$(arch) mode=$(mode) +endif + +$(kernel_img): $(bootloader) kernel ifeq ($(arch), riscv32) @mkdir -p target/$(target)/bbl && \ cd target/$(target)/bbl && \ @@ -243,10 +252,14 @@ else cp bbl $(abspath $@) endif else ifeq ($(arch), aarch64) - @$(objcopy) $(kernel) --strip-all -O binary $@ + @$(objcopy) $(bootloader) --strip-all -O binary $(boot_bin) + @$(objcopy) $(kernel) --strip-all -O binary $(kernel_bin) + dd if=$(boot_bin) of=$@ conv=notrunc + dd if=$(kernel_bin) of=$@ seek=1024 conv=notrunc endif kernel: + @echo Building $(arch) kernel ifeq ($(arch), x86_64) @bootimage build $(build_args) else ifeq ($(arch), riscv32) @@ -287,8 +300,8 @@ endif ifdef sd_card .PHONY: -install: $(bin) - cp $(bin) $(sd_card)/kernel8.img +install: $(kernel_img) + cp $(kernel_img) $(sd_card)/kernel8.img sudo umount $(sd_card) endif @@ -296,9 +309,9 @@ endif ifeq ($(board), k210) .PHONY: -install: $(bin) +install: $(kernel_img) ## baudrate no more than 600000 - @python3 ../tools/k210/kflash.py $(bin) -b 600000 + @python3 ../tools/k210/kflash.py $(kernel_img) -b 600000 endif .PHONY: diff --git a/kernel/src/arch/aarch64/entry.S b/kernel/src/arch/aarch64/entry.S new file mode 100644 index 00000000..4f7c40b2 --- /dev/null +++ b/kernel/src/arch/aarch64/entry.S @@ -0,0 +1,21 @@ +.section .text.entry +.globl _start + +_start: + ldr x0, =bootstacktop + mov sp, x0 + +zero_bss: + # load the start address and number of bytes in BSS section + ldr x1, =sbss + ldr x2, =__bss_length + +zero_bss_loop: + # zero out the BSS section, 64-bits at a time + cbz x2, zero_bss_loop_end + str xzr, [x1], #8 + sub x2, x2, #8 + cbnz x2, zero_bss_loop + +zero_bss_loop_end: + bl rust_main diff --git a/kernel/src/arch/aarch64/boot/linker.ld b/kernel/src/arch/aarch64/linker.ld similarity index 86% rename from kernel/src/arch/aarch64/boot/linker.ld rename to kernel/src/arch/aarch64/linker.ld index 38dbba99..ef4c7dde 100644 --- a/kernel/src/arch/aarch64/boot/linker.ld +++ b/kernel/src/arch/aarch64/linker.ld @@ -1,12 +1,6 @@ ENTRY(_start) SECTIONS { - . = 0x80000; /* Raspbery Pi 3 AArch64 (kernel8.img) load address */ - - .boot : { - KEEP(*(.text.boot)) /* from boot.S */ - } - . = 0x100000; /* Load the kernel at this address. It's also kernel stack top address */ bootstacktop = .; diff --git a/kernel/src/arch/aarch64/mod.rs b/kernel/src/arch/aarch64/mod.rs index ecfc34da..4346ed39 100644 --- a/kernel/src/arch/aarch64/mod.rs +++ b/kernel/src/arch/aarch64/mod.rs @@ -12,7 +12,7 @@ pub mod driver; #[path = "board/raspi3/mod.rs"] pub mod board; -global_asm!(include_str!("boot/boot.S")); +global_asm!(include_str!("entry.S")); /// The entry point of kernel #[no_mangle] // don't mangle the name of this function diff --git a/kernel/targets/aarch64.json b/kernel/targets/aarch64.json index 149246a7..02cbe214 100644 --- a/kernel/targets/aarch64.json +++ b/kernel/targets/aarch64.json @@ -15,7 +15,7 @@ "linker-is-gnu": true, "pre-link-args": { "ld.lld": [ - "-Tsrc/arch/aarch64/boot/linker.ld" + "-Tsrc/arch/aarch64/linker.ld" ] }, "llvm-target": "aarch64-unknown-none",