From d6accd6c6918cd91c09cc2941a4ca145bd43589a Mon Sep 17 00:00:00 2001 From: Andre Richter Date: Sun, 22 Sep 2019 16:47:47 +0200 Subject: [PATCH] Add code for tutorial 02 --- .02_multicore_rust/.cargo/config | 5 - .02_multicore_rust/Makefile | 68 -------------- .02_multicore_rust/README.md | 88 ------------------ .02_multicore_rust/kernel8.img | Bin 104 -> 0 bytes .02_multicore_rust/link.ld | 55 ----------- .02_multicore_rust/raspi3_boot/Cargo.toml | 9 -- .../raspi3_boot/src/boot_cores.S | 48 ---------- .02_multicore_rust/raspi3_boot/src/lib.rs | 79 ---------------- .02_multicore_rust/src/main.rs | 32 ------- .../Cargo.lock | 18 +--- .../Cargo.toml | 13 ++- 02_runtime_init/Makefile | 76 +++++++++++++++ .../kernel8 => 02_runtime_init/kernel | Bin 66464 -> 68512 bytes 02_runtime_init/kernel8.img | Bin 0 -> 368 bytes 02_runtime_init/src/bsp.rs | 11 +++ 02_runtime_init/src/bsp/rpi3.rs | 9 ++ 02_runtime_init/src/bsp/rpi3/link.ld | 35 +++++++ 02_runtime_init/src/bsp/rpi3/panic_wait.rs | 16 ++++ 02_runtime_init/src/bsp/rpi3/start.S | 19 ++++ 02_runtime_init/src/main.rs | 23 +++++ 02_runtime_init/src/runtime_init.rs | 27 ++++++ 21 files changed, 227 insertions(+), 404 deletions(-) delete mode 100644 .02_multicore_rust/.cargo/config delete mode 100644 .02_multicore_rust/Makefile delete mode 100644 .02_multicore_rust/README.md delete mode 100755 .02_multicore_rust/kernel8.img delete mode 100644 .02_multicore_rust/link.ld delete mode 100644 .02_multicore_rust/raspi3_boot/Cargo.toml delete mode 100644 .02_multicore_rust/raspi3_boot/src/boot_cores.S delete mode 100644 .02_multicore_rust/raspi3_boot/src/lib.rs delete mode 100644 .02_multicore_rust/src/main.rs rename {.02_multicore_rust => 02_runtime_init}/Cargo.lock (50%) rename {.02_multicore_rust => 02_runtime_init}/Cargo.toml (59%) create mode 100644 02_runtime_init/Makefile rename .02_multicore_rust/kernel8 => 02_runtime_init/kernel (95%) mode change 100755 => 100644 create mode 100755 02_runtime_init/kernel8.img create mode 100644 02_runtime_init/src/bsp.rs create mode 100644 02_runtime_init/src/bsp/rpi3.rs create mode 100644 02_runtime_init/src/bsp/rpi3/link.ld create mode 100644 02_runtime_init/src/bsp/rpi3/panic_wait.rs create mode 100644 02_runtime_init/src/bsp/rpi3/start.S create mode 100644 02_runtime_init/src/main.rs create mode 100644 02_runtime_init/src/runtime_init.rs diff --git a/.02_multicore_rust/.cargo/config b/.02_multicore_rust/.cargo/config deleted file mode 100644 index de3f84c9..00000000 --- a/.02_multicore_rust/.cargo/config +++ /dev/null @@ -1,5 +0,0 @@ -[target.aarch64-unknown-none-softfloat] -rustflags = [ - "-C", "link-arg=-Tlink.ld", - "-C", "target-cpu=cortex-a53", -] diff --git a/.02_multicore_rust/Makefile b/.02_multicore_rust/Makefile deleted file mode 100644 index e98a5947..00000000 --- a/.02_multicore_rust/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -# -# MIT License -# -# Copyright (c) 2018-2019 Andre Richter -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# - -TARGET = aarch64-unknown-none-softfloat - -SOURCES = $(wildcard **/*.rs) $(wildcard **/*.S) link.ld - - -XRUSTC_CMD = cargo xrustc --target=$(TARGET) --release -CARGO_OUTPUT = target/$(TARGET)/release/kernel8 - -OBJCOPY = cargo objcopy -- -OBJCOPY_PARAMS = --strip-all -O binary - -CONTAINER_UTILS = andrerichter/raspi3-utils - -DOCKER_CMD = docker run -it --rm -DOCKER_ARG_CURDIR = -v $(shell pwd):/work -w /work - -DOCKER_EXEC_QEMU = qemu-system-aarch64 -M raspi3 -kernel kernel8.img - -.PHONY: all qemu clippy clean objdump nm - -all: clean kernel8.img - -$(CARGO_OUTPUT): $(SOURCES) - $(XRUSTC_CMD) - -kernel8.img: $(CARGO_OUTPUT) - cp $< . - $(OBJCOPY) $(OBJCOPY_PARAMS) $< kernel8.img - -qemu: all - $(DOCKER_CMD) $(DOCKER_ARG_CURDIR) $(CONTAINER_UTILS) \ - $(DOCKER_EXEC_QEMU) -d in_asm - -clippy: - cargo xclippy --target=$(TARGET) - -clean: - cargo clean - -objdump: - cargo objdump --target $(TARGET) -- -disassemble -print-imm-hex kernel8 - -nm: - cargo nm --target $(TARGET) -- kernel8 | sort diff --git a/.02_multicore_rust/README.md b/.02_multicore_rust/README.md deleted file mode 100644 index 798a004c..00000000 --- a/.02_multicore_rust/README.md +++ /dev/null @@ -1,88 +0,0 @@ -# Tutorial 02 - Multicore Rust - -Now let's try something more complex, shall we? By complex I mean stopping the -CPU cores just like in the first tutorial, but this time stop one of them from -**Rust**! - -## Boot code - -In order to conveniently incorporate Rust code, we are restructuring our crate a -bit. - -We reuse a lot of steps that are explained in great detail in [The -Embedonomicon][nom], so please take your time and read up on it. Afterwards, you -can compare to the files in this crate and see what we actually kept to get our -Raspberry Pi 3 tutorial going. Here's a short summary of the new structure of -the crate: - - - `raspi3_boot/`: The extern crate containing boot code as presented in the - Embedonomicon. - - In a small deviation to the Embedonomicon, `lib.rs` also includes - `boot_cores.S` from the previous tutorial, still with the - [global_asm!][gasm] macro. - - Therefore, `boot_cores.S` has been moved into `raspi3_boot/src/`. - - `src`: Source code of our actual Rust code, currently only containing - `main.rs` executing an endless loop. - -[nom]: https://rust-embedded.github.io/embedonomicon/ -[gasm]: https://doc.rust-lang.org/unstable-book/language-features/global-asm.html - -### Changes to `boot_cores.S` - -In contrast to the previous tutorial, we are now [distinguishing the -cores][dist]. To do so, we read the [mpidr_el1][mpdir] system register. If it is -not zero, we enter the former infinite waiting loop, aka stopping the respective -CPU core. - -If the result of the read from `mpidr_el1` is zero, which means we are executing -on core0, we set up the stack for that core, and afterwards call the Rust -`reset()` function of the boot code in `raspi3_boot/src/lib.rs`. In case the -Rust code returns (which it never should), we also jump to the same infinite -loop the other CPU cores are running. - -The Rust `reset()`, in turn, will then zero-out the `bss section` (the next -section explains what that is) and finally call our `main()` function from -`main.rs`. - -[dist]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/CFHCIDCH.html -[mpdir]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0500g/BABHBJCI.html - -## Changes to `link.ld` - -Since we are using a high-level language now in the form of Rust, we also take -precautions to have eventual space reserved in memory for the [bss -segment][bss], which is needed in case zero-initialized static variables are -allocated in the Rust code. - -[bss]: https://en.wikipedia.org/wiki/.bss - -Therefore, we added the `bss` segment to the linker script and export its -properties via `__bss_start` and `__bss_size`, which will be picked up and -zeroed out by the boot code in `raspi3_boot/src/lib.rs`. - -Additionally, there is a [data segment][data] now. - -[data]: https://en.wikipedia.org/wiki/Data_segment - -Finally, we need to take care that we still start the text segment with the -assembly code and not the newly added Rust code. This is taken care of by -placing the `.text.boot` section before all other new text sections -`KEEP(*(.text.boot)) *(.text .text.* ...`. - -This way, the assembly stays at the `0x80_000` address, which is the entry point -of the RPi3 CPU. - -## Changes to `Makefile` - -We've added one more target: -- [clippy] is Rust's linter, and can give you useful advise to improve your - code. Invoke with `make clippy`. - -[clippy]: https://github.com/rust-lang-nursery/rust-clippy - -From now on, we can use the same Makefile for every tutorial, regardless of the -number of Rust sources, and we won't discuss it any further. - -## main.rs - -Finally, our first Rust code. Just an empty loop, but still! :-) diff --git a/.02_multicore_rust/kernel8.img b/.02_multicore_rust/kernel8.img deleted file mode 100755 index 1bbbbc1816e3671ed9cc25000c9a8d6e5d1f80bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 104 zcmZ3;U~yHE#bHt+1H+bh1?H>&|Nj?X$iNU`&%iK|je%jxZy;YDD9*sZ!2kjZ3<_6( rtO=Yz%(0Mhq9zdAGjhB>#J~^&5(D#F8GeAo4*&lj^5y^k=^#A-jy@uD diff --git a/.02_multicore_rust/link.ld b/.02_multicore_rust/link.ld deleted file mode 100644 index 5c499f89..00000000 --- a/.02_multicore_rust/link.ld +++ /dev/null @@ -1,55 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2018 Andre Richter - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -ENTRY(_boot_cores); - -SECTIONS -{ - . = 0x80000; - - .text : - { - KEEP(*(.text.boot)) *(.text .text.*) - } - - .rodata : - { - *(.rodata .rodata.*) - } - - .data : - { - *(.data .data.*) - } - - .bss ALIGN(8): - { - __bss_start = .; - *(.bss .bss.*) - *(COMMON) - __bss_end = .; - } - - /DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) } -} diff --git a/.02_multicore_rust/raspi3_boot/Cargo.toml b/.02_multicore_rust/raspi3_boot/Cargo.toml deleted file mode 100644 index 1c3c1c69..00000000 --- a/.02_multicore_rust/raspi3_boot/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "raspi3_boot" -version = "0.1.0" -authors = ["Andre Richter "] -edition = "2018" - -[dependencies] -panic-abort = "0.3.1" -r0 = "0.2.2" diff --git a/.02_multicore_rust/raspi3_boot/src/boot_cores.S b/.02_multicore_rust/raspi3_boot/src/boot_cores.S deleted file mode 100644 index f6f28af6..00000000 --- a/.02_multicore_rust/raspi3_boot/src/boot_cores.S +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2018 bzt (bztsrc@github) - * Copyright (c) 2018 Andre Richter - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -.section ".text.boot" - -.global _boot_cores - -_boot_cores: - // read cpu id, stop slave cores - mrs x1, mpidr_el1 - and x1, x1, #3 - cbz x1, 2f - // cpu id > 0, stop -1: wfe - b 1b -2: // cpu id == 0 - - // set stack before our code - ldr x1, =_boot_cores - mov sp, x1 - - // jump to Rust code, should not return - bl reset - // for failsafe, halt this core too - b 1b diff --git a/.02_multicore_rust/raspi3_boot/src/lib.rs b/.02_multicore_rust/raspi3_boot/src/lib.rs deleted file mode 100644 index a185d0a9..00000000 --- a/.02_multicore_rust/raspi3_boot/src/lib.rs +++ /dev/null @@ -1,79 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2018 Jorge Aparicio - * Copyright (c) 2018-2019 Andre Richter - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#![deny(missing_docs)] -#![deny(warnings)] -#![no_std] -#![feature(global_asm)] - -//! Low-level boot of the Raspberry's processor - -extern crate panic_abort; - -/// Type check the user-supplied entry function. -#[macro_export] -macro_rules! entry { - ($path:path) => { - /// # Safety - /// - /// - User must ensure to provide a suitable main function for the - /// platform. - #[export_name = "main"] - pub unsafe fn __main() -> ! { - // type check the given path - let f: fn() -> ! = $path; - - f() - } - }; -} - -/// Reset function. -/// -/// Initializes the bss section before calling into the user's `main()`. -/// -/// # Safety -/// -/// - Only a single core must be active and running this function. -#[no_mangle] -pub unsafe extern "C" fn reset() -> ! { - extern "C" { - // Boundaries of the .bss section, provided by the linker script - static mut __bss_start: u64; - static mut __bss_end: u64; - } - - // Zeroes the .bss section - r0::zero_bss(&mut __bss_start, &mut __bss_end); - - extern "Rust" { - fn main() -> !; - } - - main(); -} - -// Disable all cores except core 0, and then jump to reset() -global_asm!(include_str!("boot_cores.S")); diff --git a/.02_multicore_rust/src/main.rs b/.02_multicore_rust/src/main.rs deleted file mode 100644 index 08a6b7e4..00000000 --- a/.02_multicore_rust/src/main.rs +++ /dev/null @@ -1,32 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2018 Andre Richter - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#![no_std] -#![no_main] - -fn kernel_entry() -> ! { - loop {} -} - -raspi3_boot::entry!(kernel_entry); diff --git a/.02_multicore_rust/Cargo.lock b/02_runtime_init/Cargo.lock similarity index 50% rename from .02_multicore_rust/Cargo.lock rename to 02_runtime_init/Cargo.lock index 69f37748..551acef0 100644 --- a/.02_multicore_rust/Cargo.lock +++ b/02_runtime_init/Cargo.lock @@ -1,30 +1,16 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] -name = "kernel8" +name = "kernel" version = "0.1.0" dependencies = [ - "raspi3_boot 0.1.0", + "r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "panic-abort" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "r0" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "raspi3_boot" -version = "0.1.0" -dependencies = [ - "panic-abort 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [metadata] -"checksum panic-abort 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c14a66511ed17b6a8b4256b868d7fd207836d891db15eea5195dbcaf87e630f" "checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f" diff --git a/.02_multicore_rust/Cargo.toml b/02_runtime_init/Cargo.toml similarity index 59% rename from .02_multicore_rust/Cargo.toml rename to 02_runtime_init/Cargo.toml index dd59a6da..ef7d6d86 100644 --- a/.02_multicore_rust/Cargo.toml +++ b/02_runtime_init/Cargo.toml @@ -1,11 +1,16 @@ [package] -name = "kernel8" +name = "kernel" version = "0.1.0" authors = ["Andre Richter "] edition = "2018" -[dependencies] -raspi3_boot = { path = "raspi3_boot" } - [package.metadata.cargo-xbuild] sysroot_path = "../xbuild_sysroot" + +# The features section is used to select the target board. +[features] +default = [] +bsp_rpi3 = [] + +[dependencies] +r0 = "0.2.2" diff --git a/02_runtime_init/Makefile b/02_runtime_init/Makefile new file mode 100644 index 00000000..8ef00caa --- /dev/null +++ b/02_runtime_init/Makefile @@ -0,0 +1,76 @@ +## SPDX-License-Identifier: MIT +## +## Copyright (c) 2018-2019 Andre Richter + +# Default to the RPi3 +ifndef BSP + BSP = bsp_rpi3 +endif + +# BSP-specific arguments +ifeq ($(BSP),bsp_rpi3) + TARGET = aarch64-unknown-none + OUTPUT = kernel8.img + QEMU_BINARY = qemu-system-aarch64 + QEMU_MACHINE_TYPE = raspi3 + QEMU_MISC_ARGS = -d in_asm + LINKER_FILE = src/bsp/rpi3/link.ld + RUSTC_MISC_ARGS = -C target-feature=-fp-armv8 -C target-cpu=cortex-a53 +endif + +SOURCES = $(wildcard **/*.rs) $(wildcard **/*.S) $(wildcard **/*.ld) + +XRUSTC_CMD = cargo xrustc \ + --target=$(TARGET) \ + --features $(BSP) \ + --release \ + -- \ + -C link-arg=-T$(LINKER_FILE) \ + $(RUSTC_MISC_ARGS) + +CARGO_OUTPUT = target/$(TARGET)/release/kernel + +OBJCOPY_CMD = cargo objcopy \ + -- \ + --strip-all \ + -O binary + +CONTAINER_UTILS = rustembedded/osdev-utils + +DOCKER_CMD = docker run -it --rm +DOCKER_ARG_CURDIR = -v $(shell pwd):/work -w /work +DOCKER_EXEC_QEMU = $(QEMU_BINARY) -M $(QEMU_MACHINE_TYPE) -kernel $(OUTPUT) + +.PHONY: all qemu clippy clean readelf objdump nm + +all: clean $(OUTPUT) + +$(CARGO_OUTPUT): $(SOURCES) + RUSTFLAGS="-D warnings -D missing_docs" $(XRUSTC_CMD) + +$(OUTPUT): $(CARGO_OUTPUT) + cp $< . + $(OBJCOPY_CMD) $< $(OUTPUT) + +doc: + cargo xdoc --target=$(TARGET) --features $(BSP) --document-private-items + xdg-open target/$(TARGET)/doc/kernel/index.html + +qemu: all + $(DOCKER_CMD) $(DOCKER_ARG_CURDIR) $(CONTAINER_UTILS) \ + $(DOCKER_EXEC_QEMU) $(QEMU_MISC_ARGS) + +clippy: + cargo xclippy --target=$(TARGET) --features $(BSP) + +clean: + cargo clean + +readelf: + readelf -a kernel + +objdump: + cargo objdump --target $(TARGET) -- -disassemble -print-imm-hex kernel + +nm: + cargo nm --target $(TARGET) -- kernel | sort diff --git a/.02_multicore_rust/kernel8 b/02_runtime_init/kernel old mode 100755 new mode 100644 similarity index 95% rename from .02_multicore_rust/kernel8 rename to 02_runtime_init/kernel index e9d90d0136f70b89cb9abbd2de5aba28235f7553..cbeeaf0f3c737ab07b2137abe43d0dfaacf02246 GIT binary patch literal 68512 zcmeI!O^6$19LMn|+1)nPQcJ1UgVdD`vi4;+;w4TpNgJBY#$>kc zir_-=Ac!;~=tZ#<(VTh_dXoBv7f%-J)s-q}+e5ovTs*{QUY^~O&eVekFW*4+nfcBC zd6`e1O!kerV^3u>8KGWTaZyBPxiBin7uI%c)s%%JvZ5@ui;1vyBCJu@qkcj}Z6}UZ zE8@|g|IPQd#beVTfB*srAb6ss@n%&fkU%a;e&E{MU6VRmrOq1nOC-Q|t7DbfFBD$^eh zGlSnh9h29`2RDw0jcmMzY1!vMuDr2R&KZpJ_UuIey7k3iZ7MTZ8x#FM4rT{eAQ7tY<)dgLvUmD|vYn9c*SDO)E1CHE&5=BgH=CetT-+LN2JykZl>BgbJuB3@R6jG$)%sLkjPvPu z-70?~Jje)rWPP7V+-!C$-yL_jEb~k@E7UmCaXu^Cr1h)u%Om3-|Cf4yr2fcQv>uhK z-MEl4PUMpj(<9@k_1w0f!#g;WGR_C#)vS1K#OJk{46*V=4K|DY>7Lzm<}ID08`k#OU|onfUWn`QD&R zzRstNb1^0VJ|+J-CI2%ezhCb2B+r?Y{CG;fEb~3`e${?>GP*6XSKjY#F(x`A`)Yqm zen95IIO=<3$K%X~_3|c0_SHLaz1nYw;(DR^^<`gZ-9^v!U7=NbJ)!kh7JRoV+mk)N z8y!WhI92bq>n+W&oWkNOjl$vDi6u=>ObwCuwD6A^99bg2oKk5f_O}vKThtc2b{OcVN~h)4>PGRT zqg%S`xCPxZO>f4o&LvG?CWTf~Xe5MsLS`g|Nz)|GlB8gVw_iw@D=C{vs4FI9C7CUB znyq@bQeA4c{ARnSdAifIPaCgA_`#y@S`pmAT?>M>+_j*z`9YS#U*l8F_K8AxBtJk) z_w0gIXw;07XIeAvTu?j{?Nh^y+Dg6ccUNSwT{P`_)zOQ(XXuTBGbh~kVq5cUr)0SW z*D&>BsqR{Oso{C1EOd(1Qqd`Crq*hmUeJt!ZP}J#7iLP9?HI+9V>+Tzk>43PgBKt5 ze7Eb1X1nQ&?o!XMRO=_?ep_n4+6+pft8$6fOeKG8K0lvdGWERM3!89nYi@f*(`MT% z`KRaeMSrDJuQWZm_L`@ga#_WyS9Iz|!w7FQ+}>L%(NU$b;L8rKWt6J*s%19{jhUid zoKs)<|I!9emf*c@a}f2*8>I3X88vrYRl#<75R}NrVE9u1ujDdO$CGic8a28)zfT?n znS7juFZI0a#Qo!Vvl&^A2!2P@+?z%6K=ogZe{h5QJ0Ra`{s-gYhh(efj-#--IT6jI Z-5$#0(fJ>hSyKP~+oH-#BNs>e{{tS*1CRg! delta 570 zcmZXR&r1S96vyAw)pYA1Va#?YSBTO>i)$u(38fBQxOT*93-pGT=O!HvYwaWOJk`3@ZT5gg)24bHiF3ZeyQR`I zKJBr-5#Ii=s5q$91at;7^jXFPPSH0RNtPkcq>4|Du+sz!|MvhCks?XclStxM==&Dw PgN!Mh_vx*mmPda9?BQIt diff --git a/02_runtime_init/kernel8.img b/02_runtime_init/kernel8.img new file mode 100755 index 0000000000000000000000000000000000000000..5784650bbc27ce5c3c40c47e60e498a28006d7f3 GIT binary patch literal 368 zcmZ3;U~yHE#bHt+1H+bh1?H>&|Nj?X$iNU`&%iK|lYwE%Zy;YDD9*sZ!2ksl7#6Th z6avaAFeqFBicSEko4|39b)qH^+cR>!KE%Kf0ulrBTN!?U#18-eAM)}4|LGt-FnbO# z$6x#3%y{wDV}^;^3=Kg%j155?Dh?}Ot!G&I=0DR)E*-~}JOU0sA1E_Se5lMg@&A9u zl`obv1Lav(zR_p+$pm$S22hU{hr>@Epq(IddK_6NzBb;w@_{nr$_LC06JKgGt$Yl% zyTN+mB?p}qpB(ld`^4b$=@ZBeAb+J+6y#(kXO<`wB<5u%7Z)Y#=O$+6=@k`2J + +//! Conditional exporting of Board Support Packages. + +#[cfg(feature = "bsp_rpi3")] +pub mod rpi3; + +#[cfg(feature = "bsp_rpi3")] +pub use rpi3::*; diff --git a/02_runtime_init/src/bsp/rpi3.rs b/02_runtime_init/src/bsp/rpi3.rs new file mode 100644 index 00000000..3dc8220d --- /dev/null +++ b/02_runtime_init/src/bsp/rpi3.rs @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +// +// Copyright (c) 2018-2019 Andre Richter + +//! Board Support Package for the Raspberry Pi 3. + +mod panic_wait; + +global_asm!(include_str!("rpi3/start.S")); diff --git a/02_runtime_init/src/bsp/rpi3/link.ld b/02_runtime_init/src/bsp/rpi3/link.ld new file mode 100644 index 00000000..13d99a65 --- /dev/null +++ b/02_runtime_init/src/bsp/rpi3/link.ld @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2018-2019 Andre Richter + */ + +SECTIONS +{ + /* Set current address to the value from which the RPi3 starts execution */ + . = 0x80000; + + .text : + { + *(.text) + } + + .rodata : + { + *(.rodata) + } + + .data : + { + *(.data) + } + + /* Align to 8 byte boundary */ + .bss ALIGN(8): + { + __bss_start = .; + *(.bss); + __bss_end = .; + } + + /DISCARD/ : { *(.comment) } +} diff --git a/02_runtime_init/src/bsp/rpi3/panic_wait.rs b/02_runtime_init/src/bsp/rpi3/panic_wait.rs new file mode 100644 index 00000000..328b50f4 --- /dev/null +++ b/02_runtime_init/src/bsp/rpi3/panic_wait.rs @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +// +// Copyright (c) 2018-2019 Andre Richter + +//! A panic handler that infinitely waits. + +use core::panic::PanicInfo; + +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + unsafe { + loop { + asm!("wfe" :::: "volatile") + } + } +} diff --git a/02_runtime_init/src/bsp/rpi3/start.S b/02_runtime_init/src/bsp/rpi3/start.S new file mode 100644 index 00000000..2bd9340d --- /dev/null +++ b/02_runtime_init/src/bsp/rpi3/start.S @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +// +// Copyright (c) 2018-2019 Andre Richter + +.global _start + +_start: + mrs x1, mpidr_el1 // Read Multiprocessor Affinity Register + and x1, x1, #3 // Clear all bits except [1:0], which hold core id + cbz x1, 2f // Jump to label 2 if we are core 0 +1: wfe // Wait for event + b 1b // In case an event happend, jump back to 1 +2: // If we are here, we are core0 + ldr x1, =_start // Load address of function "_start()" + mov sp, x1 // Set start of stack to before our code, aka first + // address before "_start()" + bl init // Jump to the "init()" kernel function + b 1b // We should never reach here. But just in case, + // park this core aswell diff --git a/02_runtime_init/src/main.rs b/02_runtime_init/src/main.rs new file mode 100644 index 00000000..50526108 --- /dev/null +++ b/02_runtime_init/src/main.rs @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +// +// Copyright (c) 2018-2019 Andre Richter + +//! The `kernel` + +#![feature(asm)] +#![feature(global_asm)] +#![no_main] +#![no_std] + +// This module conditionally includes the correct `BSP` which provides the +// `_start()` function, the first function to run. +mod bsp; + +// Afterwards, `BSP`'s early init code calls `runtime_init::init()` of this +// module, which on completion, jumps to `kernel_entry()`. +mod runtime_init; + +/// Entrypoint of the `kernel`. +fn kernel_entry() -> ! { + panic!() +} diff --git a/02_runtime_init/src/runtime_init.rs b/02_runtime_init/src/runtime_init.rs new file mode 100644 index 00000000..47dd73e3 --- /dev/null +++ b/02_runtime_init/src/runtime_init.rs @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +// +// Copyright (c) 2018-2019 Andre Richter + +//! Rust runtime initialization code. + +/// Equivalent to `crt0` or `c0` code in C/C++ world. Clears the `bss` section, +/// then calls the kernel entry. +/// +/// Called from BSP code. +/// +/// # Safety +/// +/// - Only a single core must be active and running this function. +#[no_mangle] +pub unsafe extern "C" fn init() -> ! { + extern "C" { + // Boundaries of the .bss section, provided by the linker script + static mut __bss_start: u64; + static mut __bss_end: u64; + } + + // Zero out the .bss section + r0::zero_bss(&mut __bss_start, &mut __bss_end); + + crate::kernel_entry() +}