Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mingo"
version = "0.8.0"
version = "0.6.0"
authors = ["Andre Richter <andre.o.richter@gmail.com>"]
edition = "2021"

Expand Down
11 changes: 4 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ else ifeq ($(BSP),rpi5)
JTAG_BOOT_IMAGE = ./X1_JTAG_boot/jtag_boot_rpi5.img
LD_SCRIPT_PATH = $(shell pwd)/src/bsp/raspberrypi
RUSTC_MISC_ARGS = -C target-cpu=cortex-a76
CHAINBOOT_DEMO_PAYLOAD = demo_payload_rpi5.img
endif

# Export for build.rs.
Expand Down Expand Up @@ -138,11 +139,7 @@ ifeq ($(shell uname -s),Linux)

DOCKER_MINITERM = $(DOCKER_CMD_DEV) $(DOCKER_ARG_DIR_COMMON) $(DOCKER_IMAGE)

DOCKER_CHAINBOOT = $(DOCKER_CMD_DEV) $(DOCKER_ARG_DIR_COMMON) $(DOCKER_IMAGE)
DOCKER_JTAGBOOT = $(DOCKER_CMD_DEV) $(DOCKER_ARG_DIR_COMMON) $(DOCKER_ARG_DIR_JTAG) $(DOCKER_IMAGE)
DOCKER_OPENOCD = $(DOCKER_CMD_DEV) $(DOCKER_ARG_NET) $(DOCKER_IMAGE)
else
DOCKER_OPENOCD = echo "Not yet supported on non-Linux systems."; \#
DOCKER_CHAINBOOT = $(DOCKER_CMD_DEV) $(DOCKER_ARG_DIR_COMMON) $(DOCKER_IMAGE)
endif


Expand Down Expand Up @@ -219,7 +216,7 @@ miniterm:

## Push the kernel to the real HW target
chainboot: $(KERNEL_BIN)
@$(DOCKER_CHAINBOOT) $(EXEC_MINIPUSH) $(DEV_SERIAL) $(KERNEL_BIN)
@$(DOCKER_CHAINBOOT) $(EXEC_MINIPUSH) $(DEV_SERIAL) $(CHAINBOOT_DEMO_PAYLOAD)

##------------------------------------------------------------------------------
## Run clippy
Expand Down Expand Up @@ -279,7 +276,7 @@ openocd-local:
$(call color_header, "Launching local OpenOCD with lldb")
openocd -f ./cmsis-dap.cfg -f ./rpi5-openocd.cfg -c "adapter speed 5000" &
OPENOCD_PID=$!
PROGRAM=target/aarch64-unknown-none-softfloat/release/kernel
PROGRAM=target/aarch64-unknown-none-softfloat/release/kernel
lldb $(PROGRAM)
# aarch64-elf-gdb -q -x gdb_init "$(PROGRAM)"
kill -TERM ${OPENOCD_PID}
Expand Down
1 change: 0 additions & 1 deletion common/serial/minipush.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ def wait_for_payload_request
else
# A normal character resets token counting.
count = 0

print c
end
end
Expand Down
1 change: 1 addition & 0 deletions common/serial/miniterm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
require 'rubyserial'

# SERIAL_BAUD = 921_600
# SERIAL_BAUD = 230_400 # for mac os
SERIAL_BAUD = 115_200 # for mac os

class ConnectionError < StandardError; end
Expand Down
Binary file added demo_payload_rpi5.img
Binary file not shown.
Binary file added kernel8_chainloader.img
Binary file not shown.
Binary file added kernel8_chainloader_debug_uart.img
Binary file not shown.
Binary file added kernel8_chainloader_rpi1_uart.img
Binary file not shown.
39 changes: 32 additions & 7 deletions src/_arch/aarch64/cpu/boot.s
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@
add \register, \register, #:lo12:\symbol
.endm

// Load the address of a symbol into a register, absolute.
//
// # Resources
//
// - https://sourceware.org/binutils/docs-2.36/as/AArch64_002dRelocations.html
.macro ADR_ABS register, symbol
movz \register, #:abs_g2:\symbol
movk \register, #:abs_g1_nc:\symbol
movk \register, #:abs_g0_nc:\symbol
.endm


//--------------------------------------------------------------------------------------------------
// Public Code
//--------------------------------------------------------------------------------------------------
Expand All @@ -37,23 +49,36 @@ _start:
// If execution reaches here, it is the boot core.

// Initialize DRAM.
ADR_REL x0, __bss_start
ADR_REL x1, __bss_end_exclusive
ADR_ABS x0, __bss_start
ADR_ABS x1, __bss_end_exclusive

.L_bss_init_loop:
cmp x0, x1
b.eq .L_prepare_rust
b.eq .L_relocate_binary
stp xzr, xzr, [x0], #16
b .L_bss_init_loop

// Next, relocate the binary.
.L_relocate_binary:
ADR_REL x0, __binary_nonzero_start // The address the binary got loaded to.
ADR_ABS x1, __binary_nonzero_start // The address the binary was linked to.
ADR_ABS x2, __binary_nonzero_end_exclusive

.L_copy_loop:
ldr x3, [x0], #8
str x3, [x1], #8
cmp x1, x2
b.lo .L_copy_loop

// Prepare the jump to Rust code.
.L_prepare_rust:
// Set the stack pointer.
ADR_REL x0, __boot_core_stack_end_exclusive
; ADR_REL x0, __boot_core_stack_end_exclusive
ADR_ABS x0, __boot_core_stack_end_exclusive
mov sp, x0

// Jump to Rust code.
b _start_rust
// Jump to the relocated Rust code.
ADR_ABS x1, _start_rust
br x1

// Infinitely wait for events (aka "park the core").
.L_parking_loop:
Expand Down
13 changes: 4 additions & 9 deletions src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ impl PL011UartInner {
}

/// Retrieve a character.
fn read_char_converting(&mut self, blocking_mode: BlockingMode) -> Option<char> {
fn read_char(&mut self, blocking_mode: BlockingMode) -> Option<char> {
// If RX FIFO is empty,
if self.registers.FR.matches_all(FR::RXFE::SET) {
// immediately return in non-blocking mode.
Expand All @@ -318,12 +318,7 @@ impl PL011UartInner {
}

// Read one character.
let mut ret = self.registers.DR.get() as u8 as char;

// Convert carrige return to newline.
if ret == '\r' {
ret = '\n'
}
let ret = self.registers.DR.get() as u8 as char;

// Update statistics.
self.chars_read += 1;
Expand Down Expand Up @@ -409,14 +404,14 @@ impl console::interface::Write for PL011Uart {
impl console::interface::Read for PL011Uart {
fn read_char(&self) -> char {
self.inner
.lock(|inner| inner.read_char_converting(BlockingMode::Blocking).unwrap())
.lock(|inner| inner.read_char(BlockingMode::Blocking).unwrap())
}

fn clear_rx(&self) {
// Read from the RX FIFO until it is indicating empty.
while self
.inner
.lock(|inner| inner.read_char_converting(BlockingMode::NonBlocking))
.lock(|inner| inner.read_char(BlockingMode::NonBlocking))
.is_some()
{}
}
Expand Down
16 changes: 0 additions & 16 deletions src/bsp/raspberrypi/console.rs

This file was deleted.

8 changes: 7 additions & 1 deletion src/bsp/raspberrypi/kernel.ld
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ PHDRS

SECTIONS
{
. = __rpi_phys_dram_start_addr;
/* Set the link address to 32 MiB */
. = 0x2000000;

/***********************************************************************************************
* Boot Core Stack
Expand All @@ -46,6 +47,7 @@ SECTIONS
/***********************************************************************************************
* Code + RO Data + Global Offset Table
***********************************************************************************************/
__binary_nonzero_start = .;
.text :
{
KEEP(*(.text._start))
Expand All @@ -62,6 +64,10 @@ SECTIONS
***********************************************************************************************/
.data : { *(.data*) } :segment_data

/* Fill up to 8 byte, b/c relocating the binary is done in u64 chunks */
. = ALIGN(8);
__binary_nonzero_end_exclusive = .;

/* Section is zeroed in pairs of u64. Align start and end to 16 bytes */
.bss (NOLOAD) : ALIGN(16)
{
Expand Down
15 changes: 14 additions & 1 deletion src/bsp/raspberrypi/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
/// The board's physical memory map.
#[rustfmt::skip]
pub(super) mod map {
#[allow(dead_code)]
pub const BOARD_DEFAULT_LOAD_ADDRESS: usize = 0x8_0000;

#[allow(dead_code)]
pub const GPIO_OFFSET: usize = 0x0020_0000;
Expand Down Expand Up @@ -50,8 +52,19 @@ pub(super) mod map {
#[allow(dead_code)]
pub const START: usize = 0x107c000000;
pub const GPIO_START: usize = 0x1f000d0000;
pub const PL011_UART_START: usize = 0x1c00030000; // w/o pcie
pub const PL011_UART_START: usize = 0x1c00030000; // w/o pcie
// pub const PL011_UART_START: usize = 0x1f00030000; // w/ pcie
pub const PL011_EARLY_UART_START: usize = 0x107d001000;
}
}


//--------------------------------------------------------------------------------------------------
// Public Code
//--------------------------------------------------------------------------------------------------

/// The address on which the Raspberry firmware loads every binary by default.
#[inline(always)]
pub fn board_default_load_addr() -> *const u64 {
map::BOARD_DEFAULT_LOAD_ADDRESS as _
}
14 changes: 1 addition & 13 deletions src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@

//! Driver support.

use crate::{
println,
synchronization::{interface::Mutex, NullLock},
};
use crate::synchronization::{interface::Mutex, NullLock};

//--------------------------------------------------------------------------------------------------
// Private Definitions
Expand Down Expand Up @@ -154,13 +151,4 @@ impl DriverManager {
}
});
}

/// Enumerate all registered device drivers.
pub fn enumerate(&self) {
let mut i: usize = 1;
self.for_each_descriptor(|descriptor| {
println!(" {}. {}", i, descriptor.device_driver.compatible());
i += 1;
});
}
}
63 changes: 44 additions & 19 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,13 @@ mod driver;
mod panic_wait;
mod print;
mod synchronization;
mod time;

const MINILOAD_LOGO: &str = r#"
__ __ _ _ _ _
| \/ (_)_ _ (_) | ___ __ _ __| |
| |\/| | | ' \| | |__/ _ \/ _` / _` |
|_| |_|_|_||_|_|____\___/\__,_\__,_|
"#;

/// Early init code.
///
Expand All @@ -142,29 +148,48 @@ unsafe fn kernel_init() -> ! {
}

/// The main function running after the early init.
/// Run to build: BSP=rpi5 RPI5_EARLY_UART=1 make clean sdcard
fn kernel_main() -> ! {
use core::time::Duration;
use crate::console::console;

println!("{}", MINILOAD_LOGO);
// println!("{:^37}", bsp::board_name());
println!();
println!("[ML] Requesting binary");
console().flush();

info!(
"{} version {}",
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_VERSION")
);
info!("Booting on: {}", bsp::board_name());
// Discard any spurious received characters before starting with the loader protocol.
console().clear_rx();

info!(
"Architectural timer resolution: {} ns",
time::time_manager().resolution().as_nanos()
);
// Notify `Minipush` to send the binary.
for _ in 0..3 {
console().write_char(3 as char);
}

info!("Drivers loaded:");
driver::driver_manager().enumerate();
// Read the binary's size.
let mut size: u32 = u32::from(console().read_char() as u8);
size |= u32::from(console().read_char() as u8) << 8;
size |= u32::from(console().read_char() as u8) << 16;
size |= u32::from(console().read_char() as u8) << 24;

// Test a failing timer case.
time::time_manager().spin_for(Duration::from_nanos(1));
// Trust it's not too big.
console().write_char('O');
console().write_char('K');

loop {
info!("Spinning for 1 second");
time::time_manager().spin_for(Duration::from_secs(1));
let kernel_addr: *mut u8 = bsp::memory::board_default_load_addr() as *mut u8;
unsafe {
// Read the kernel byte by byte.
for i in 0..size {
core::ptr::write_volatile(kernel_addr.offset(i as isize), console().read_char() as u8)
}
}

println!("[ML] Loaded! Executing the payload now\n");
console().flush();

// Use black magic to create a function pointer.
let kernel: fn() -> ! = unsafe { core::mem::transmute(kernel_addr) };

// Jump to loaded kernel!
kernel()
}
5 changes: 1 addition & 4 deletions src/panic_wait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,15 @@ fn panic(info: &PanicInfo) -> ! {
// Protect against panic infinite loops if any of the following code panics itself.
panic_prevent_reenter();

let timestamp = crate::time::time_manager().uptime();
let (location, line, column) = match info.location() {
Some(loc) => (loc.file(), loc.line(), loc.column()),
_ => ("???", 0, 0),
};

println!(
"[ {:>3}.{:06}] Kernel panic!\n\n\
"Kernel panic!\n\n\
Panic location:\n File '{}', line {}, column {}\n\n\
{}",
timestamp.as_secs(),
timestamp.subsec_micros(),
location,
line,
column,
Expand Down