Add code for tutorial 02
parent
cb78e1c7cc
commit
d6accd6c69
@ -1,5 +0,0 @@
|
||||
[target.aarch64-unknown-none-softfloat]
|
||||
rustflags = [
|
||||
"-C", "link-arg=-Tlink.ld",
|
||||
"-C", "target-cpu=cortex-a53",
|
||||
]
|
@ -1,68 +0,0 @@
|
||||
#
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2018-2019 Andre Richter <andre.o.richter@gmail.com>
|
||||
#
|
||||
# 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
|
@ -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! :-)
|
Binary file not shown.
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2018 Andre Richter <andre.o.richter@gmail.com>
|
||||
*
|
||||
* 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*) }
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
[package]
|
||||
name = "raspi3_boot"
|
||||
version = "0.1.0"
|
||||
authors = ["Andre Richter <andre.o.richter@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
panic-abort = "0.3.1"
|
||||
r0 = "0.2.2"
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 bzt (bztsrc@github)
|
||||
* Copyright (c) 2018 Andre Richter <andre.o.richter@gmail.com>
|
||||
*
|
||||
* 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
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2018 Jorge Aparicio
|
||||
* Copyright (c) 2018-2019 Andre Richter <andre.o.richter@gmail.com>
|
||||
*
|
||||
* 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"));
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2018 Andre Richter <andre.o.richter@gmail.com>
|
||||
*
|
||||
* 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);
|
@ -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"
|
@ -1,11 +1,16 @@
|
||||
[package]
|
||||
name = "kernel8"
|
||||
name = "kernel"
|
||||
version = "0.1.0"
|
||||
authors = ["Andre Richter <andre.o.richter@gmail.com>"]
|
||||
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"
|
@ -0,0 +1,76 @@
|
||||
## SPDX-License-Identifier: MIT
|
||||
##
|
||||
## Copyright (c) 2018-2019 Andre Richter <andre.o.richter@gmail.com>
|
||||
|
||||
# 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
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,11 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Copyright (c) 2018-2019 Andre Richter <andre.o.richter@gmail.com>
|
||||
|
||||
//! Conditional exporting of Board Support Packages.
|
||||
|
||||
#[cfg(feature = "bsp_rpi3")]
|
||||
pub mod rpi3;
|
||||
|
||||
#[cfg(feature = "bsp_rpi3")]
|
||||
pub use rpi3::*;
|
@ -0,0 +1,9 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Copyright (c) 2018-2019 Andre Richter <andre.o.richter@gmail.com>
|
||||
|
||||
//! Board Support Package for the Raspberry Pi 3.
|
||||
|
||||
mod panic_wait;
|
||||
|
||||
global_asm!(include_str!("rpi3/start.S"));
|
@ -0,0 +1,35 @@
|
||||
/* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Copyright (c) 2018-2019 Andre Richter <andre.o.richter@gmail.com>
|
||||
*/
|
||||
|
||||
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) }
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Copyright (c) 2018-2019 Andre Richter <andre.o.richter@gmail.com>
|
||||
|
||||
//! A panic handler that infinitely waits.
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_info: &PanicInfo) -> ! {
|
||||
unsafe {
|
||||
loop {
|
||||
asm!("wfe" :::: "volatile")
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Copyright (c) 2018-2019 Andre Richter <andre.o.richter@gmail.com>
|
||||
|
||||
.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
|
@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Copyright (c) 2018-2019 Andre Richter <andre.o.richter@gmail.com>
|
||||
|
||||
//! 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!()
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Copyright (c) 2018-2019 Andre Richter <andre.o.richter@gmail.com>
|
||||
|
||||
//! 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()
|
||||
}
|
Loading…
Reference in New Issue