From b557dd62a456d71da837071e793aed68ee8676e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Neuh=C3=A4user?= Date: Sun, 18 May 2025 10:16:46 +0200 Subject: [PATCH] Hello World on simulator --- .cargo/config.toml | 5 +++++ .gitignore | 1 + .vscode/launch.json | 25 ++++++++++++++++++++++++ .vscode/tasks.json | 21 ++++++++++++++++++++ Cargo.lock | 7 +++++++ Cargo.toml | 11 +++++++++++ link.ld | 19 ++++++++++++++++++ rust-toolchain.toml | 2 ++ src/main.rs | 42 ++++++++++++++++++++++++++++++++++++++++ tools/start_simulator.sh | 3 +++ 10 files changed, 136 insertions(+) create mode 100644 .cargo/config.toml create mode 100644 .gitignore create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 link.ld create mode 100644 rust-toolchain.toml create mode 100644 src/main.rs create mode 100755 tools/start_simulator.sh diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..1c1fd15 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,5 @@ +[build] +target = "aarch64-unknown-none" + +[target.aarch64-unknown-none] +rustflags = ["-C", "link-arg=-Tlink.ld"] diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..36d3bf2 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,25 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Attach to QEMU (AArch64)", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/target/aarch64-unknown-none/debug/nova", + "miDebuggerServerAddress": "localhost:1234", + "miDebuggerPath": "gdb", + "cwd": "${workspaceFolder}", + "stopAtEntry": true, + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "preLaunchTask": "Run QEMU" + } + ] +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..0cbd7f7 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,21 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Build", + "type": "shell", + "command": "cargo build --target aarch64-unknown-none", + "args": [], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "Run QEMU", + "type": "shell", + "command": "qemu-system-aarch64 -M raspi3b -cpu cortex-a72 -display none -kernel ${workspaceFolder}/target/aarch64-unknown-none/debug/nova -s -S", + "isBackground": true + } + ] +} diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..8c89787 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "nova" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..45aea39 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "nova" +version = "0.1.0" +edition = "2021" + + +[profile.dev] +panic = "abort" + +[profile.release] +panic = "abort" diff --git a/link.ld b/link.ld new file mode 100644 index 0000000..dfbf022 --- /dev/null +++ b/link.ld @@ -0,0 +1,19 @@ +SECTIONS +{ + . = 0x80000; /* Kernel load address for AArch64 */ + .text : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) } + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r*) } + PROVIDE(_data = .); + .data : { *(.data .data.* .gnu.linkonce.d*) } + .bss (NOLOAD) : { + . = ALIGN(16); + __bss_start = .; + *(.bss .bss.*) + *(COMMON) + __bss_end = .; + } + _end = .; + + /DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) } +} +__bss_size = (__bss_end - __bss_start)>>3; diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..5d56faf --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..d1a7d4e --- /dev/null +++ b/src/main.rs @@ -0,0 +1,42 @@ +#![no_main] +#![no_std] +#![feature(asm_experimental_arch)] + +use core::{ + arch::asm, + fmt::{self, Write}, + panic::PanicInfo, +}; + +#[panic_handler] +fn panic(_panic: &PanicInfo) -> ! { + loop {} +} + +const UART0_DR: u32 = 0x3F20_1000; + +struct Uart; + +impl Write for Uart { + fn write_str(&mut self, s: &str) -> fmt::Result { + for byte in s.bytes() { + unsafe { + core::ptr::write_volatile(UART0_DR as *mut u8, byte); + } + } + Ok(()) + } +} + +#[no_mangle] +#[unsafe(naked)] +pub extern "C" fn _start() -> ! { + core::arch::naked_asm!("mov sp, #0x80000", "bl main"); +} + +#[no_mangle] +fn main() { + let mut uart = Uart {}; + writeln!(uart, "Hello World!\n"); + loop {} +} diff --git a/tools/start_simulator.sh b/tools/start_simulator.sh new file mode 100755 index 0000000..353c915 --- /dev/null +++ b/tools/start_simulator.sh @@ -0,0 +1,3 @@ +cd "$(dirname "$0")" + +qemu-system-aarch64 -M raspi3b -cpu cortex-a53 -serial stdio -display none -kernel ../target/aarch64-unknown-none/debug/nova -s