initial
This commit is contained in:
parent
ca02b44b71
commit
0bbf694137
29 changed files with 81 additions and 267 deletions
9
.cargo/config.toml
Normal file
9
.cargo/config.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
[build]
|
||||
target = "riscv64gc-unknown-none-elf"
|
||||
|
||||
[target.riscv64gc-unknown-none-elf]
|
||||
rustflags = ["-C", "link-arg=-Tsrc/ld/kernel.ld"]
|
||||
runner = "./scripts/start.sh"
|
||||
|
||||
[term]
|
||||
verbose = true
|
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -1,2 +1,9 @@
|
|||
/target
|
||||
/build
|
||||
|
||||
|
||||
# Added by cargo
|
||||
#
|
||||
# already existing elements were commented out
|
||||
|
||||
#/target
|
||||
|
|
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -3,5 +3,5 @@
|
|||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "kernel"
|
||||
name = "eos0"
|
||||
version = "0.1.0"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
workspace.members = ["kernel"]
|
||||
workspace.resolver = "2"
|
||||
[package]
|
||||
name = "eos0"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
profile.dev.panic = "abort"
|
||||
profile.release.panic = "abort"
|
||||
[dependencies]
|
||||
|
|
8
Makefile
Normal file
8
Makefile
Normal file
|
@ -0,0 +1,8 @@
|
|||
KERNEL = target/riscv64gc-unknown-none-elf/debug/xv6-riscv-rust
|
||||
SOURCES := $(shell find -name "*.rs")
|
||||
|
||||
$(KERNEL): $(SOURCES)
|
||||
cargo build
|
||||
|
||||
fs.img: mkfs/mkfs README.md $(UPROGS)
|
||||
mkfs/mkfs fs.img README.md $(UPROGS)
|
|
@ -1,9 +0,0 @@
|
|||
# EOS0
|
||||
|
||||
This is mainly a port of MIT's xv6 operating system, for educational purposes.
|
||||
|
||||
You can consider the "e" in EOS to be either educational or experimental.
|
||||
|
||||
## References
|
||||
|
||||
- https://lowenware.com/blog/aarch64-bare-metal-program-in-rust/
|
|
@ -1,14 +0,0 @@
|
|||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x40080000;
|
||||
.text.boot : { *(.text.boot) }
|
||||
.text : { *(.text) }
|
||||
.data : { *(.data) }
|
||||
.rodata : { *(.rodata) }
|
||||
.bss : { *(.bss) }
|
||||
|
||||
. = ALIGN(8);
|
||||
. = . + 0x4000;
|
||||
LD_STACK_PTR = .;
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
{
|
||||
"arch": "aarch64",
|
||||
"crt-objects-fallback": "false",
|
||||
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
|
||||
"disable-redzone": true,
|
||||
"features": "-align,-neon",
|
||||
"linker": "rust-lld",
|
||||
"linker-flavor": "gnu-lld",
|
||||
"llvm-target": "aarch64-unknown-none",
|
||||
"max-atomic-width": 128,
|
||||
"panic-strategy": "abort",
|
||||
"pre-link-args": {
|
||||
"gnu": ["--fix-cortex-a53-843419"],
|
||||
"gnu-lld": ["--fix-cortex-a53-843419", "-Taarch64-qemu.ld"],
|
||||
"ld.lld": ["-Taarch64-qemu.ld"]
|
||||
},
|
||||
"relocation-model": "static",
|
||||
"stack-probes": {
|
||||
"kind": "inline"
|
||||
},
|
||||
"supported-sanitizers": ["kcfi", "kernel-address"],
|
||||
"target-pointer-width": "64"
|
||||
}
|
5
debug.sh
5
debug.sh
|
@ -1,5 +0,0 @@
|
|||
# Run run.sh before this!
|
||||
set -euo pipefail
|
||||
exec rust-lldb \
|
||||
-s lldb-init \
|
||||
target/aarch64-unknown-none/debug/kernel
|
|
@ -1,9 +0,0 @@
|
|||
[package]
|
||||
name = "kernel"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# [lib]
|
||||
# crate-type = ["staticlib"]
|
||||
|
||||
[dependencies]
|
|
@ -1,27 +0,0 @@
|
|||
use core::fmt::{self, Write};
|
||||
|
||||
use crate::{spinlock::SpinLock, uart::UART};
|
||||
|
||||
/// A wrapper around the console
|
||||
pub struct Console {
|
||||
lock: SpinLock,
|
||||
uart: UART,
|
||||
}
|
||||
|
||||
impl Console {
|
||||
pub fn init() -> Self {
|
||||
let lock = SpinLock::init("console");
|
||||
let uart = UART::init();
|
||||
Console { lock, uart }
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for Console {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
// TODO: Lock
|
||||
|
||||
Ok(())
|
||||
|
||||
// TODO: Release lock
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::fmt::Write;
|
||||
use core::{arch::global_asm, ptr};
|
||||
|
||||
use crate::console::Console;
|
||||
use crate::memory_layout::UART0;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
mod console;
|
||||
mod io;
|
||||
mod memory_layout;
|
||||
mod panic;
|
||||
mod spinlock;
|
||||
mod uart;
|
||||
|
||||
// global_asm!(include_str!("start.s"));
|
||||
global_asm!(include_str!("riscv64gc/start.s"));
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn main() {
|
||||
let mut console = Console::init();
|
||||
// let _ = writeln!(console, "eos0 is booting...");
|
||||
|
||||
let out_str = b"AArch64 Bare Metal";
|
||||
for byte in out_str {
|
||||
unsafe {
|
||||
ptr::write_volatile(UART0, *byte);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
pub const UART0: *mut u8 = 0x0900_0000 as *mut u8;
|
|
@ -1,7 +0,0 @@
|
|||
use core::panic::PanicInfo;
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[panic_handler]
|
||||
fn on_panic(_info: &PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
.section .text
|
||||
|
||||
.global _entry
|
||||
|
||||
_entry:
|
||||
la sp, stack0
|
||||
li a0, 1024*4
|
||||
csrr a1, mhartid
|
||||
addi a1, a1, 1
|
||||
mul a0, a0, a1
|
||||
add sp, sp, a0
|
||||
call main
|
||||
|
||||
spin:
|
||||
j spin
|
|
@ -1,18 +0,0 @@
|
|||
pub struct SpinLock {
|
||||
locked: bool,
|
||||
|
||||
/// The name of the lock, for debugging
|
||||
name: [u8; 32],
|
||||
}
|
||||
|
||||
impl SpinLock {
|
||||
pub fn init(name: &'static str) -> Self {
|
||||
let mut this_name = [0; 32];
|
||||
this_name.copy_from_slice(&name.as_bytes()[..32.min(name.len())]);
|
||||
|
||||
SpinLock {
|
||||
locked: false,
|
||||
name: this_name,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
.globl _start
|
||||
.extern LD_STACK_PTR
|
||||
|
||||
.section ".text.boot"
|
||||
|
||||
_start:
|
||||
ldr x30, =LD_STACK_PTR
|
||||
mov sp, x30
|
||||
bl main
|
||||
|
||||
.equ PSCI_SYSTEM_OFF, 0x84000008
|
||||
.globl system_off
|
||||
system_off:
|
||||
ldr x0, =PSCI_SYSTEM_OFF
|
||||
hvc #0
|
|
@ -1,40 +0,0 @@
|
|||
//! UART (Universal Asynchronous Receiver-Transmitter)
|
||||
|
||||
use crate::memory_layout::UART0;
|
||||
|
||||
/// The UART Interface
|
||||
pub struct UART {}
|
||||
|
||||
impl UART {
|
||||
/// Most of this is just a port from xv6 right now, I have no idea why any of this works
|
||||
pub fn init() -> Self {
|
||||
unsafe {
|
||||
UART::write_register(WriteRegister::IER, 0x00);
|
||||
}
|
||||
UART {}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn write_register(reg: WriteRegister, val: u8) {
|
||||
*reg.as_mut_ptr() = val;
|
||||
}
|
||||
|
||||
pub unsafe fn put_char(&self) {}
|
||||
}
|
||||
|
||||
/// <http://byterunner.com/16550.html>
|
||||
pub enum ReadRegister {}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum WriteRegister {
|
||||
IER = 1,
|
||||
}
|
||||
|
||||
impl WriteRegister {
|
||||
pub fn as_mut_ptr(&self) -> *mut u8 {
|
||||
unsafe { UART0.offset(*self as isize) }
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_register() {}
|
|
@ -1,2 +0,0 @@
|
|||
target create target/aarch64-unknown-none/debug/kernel
|
||||
gdb-remote 1234
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"arch": "riscv64",
|
||||
"code-model": "medium",
|
||||
"cpu": "generic-rv64",
|
||||
"crt-objects-fallback": "false",
|
||||
"data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
|
||||
"eh-frame-header": false,
|
||||
"emit-debug-gdb-scripts": true,
|
||||
"features": "+m,+a,+f,+d,+c",
|
||||
"linker": "rust-lld",
|
||||
"linker-flavor": "gnu-lld",
|
||||
"llvm-abiname": "lp64d",
|
||||
"llvm-target": "riscv64",
|
||||
"max-atomic-width": 64,
|
||||
"panic-strategy": "abort",
|
||||
"relocation-model": "static",
|
||||
"pre-link-args": {
|
||||
"gnu-lld": ["-Taarch64-qemu.ld"]
|
||||
},
|
||||
"supported-sanitizers": ["kernel-address"],
|
||||
"target-pointer-width": "64"
|
||||
}
|
16
run.sh
16
run.sh
|
@ -1,16 +0,0 @@
|
|||
set -euo pipefail
|
||||
cargo xbuild --target=aarch64-unknown-none.json
|
||||
|
||||
DEBUG=
|
||||
DEBUG="-s -S -d exec"
|
||||
|
||||
printf "Running with qemu...\n"
|
||||
set -x
|
||||
exec qemu-system-aarch64 \
|
||||
-machine virt \
|
||||
$DEBUG \
|
||||
-m 1024M \
|
||||
-cpu cortex-a53 \
|
||||
-no-reboot \
|
||||
-nographic \
|
||||
-kernel target/aarch64-unknown-none/debug/kernel
|
|
@ -1 +0,0 @@
|
|||
nightly
|
|
@ -1,2 +0,0 @@
|
|||
tab_spaces = 2
|
||||
max_width = 80
|
14
scripts/start.sh
Executable file
14
scripts/start.sh
Executable file
|
@ -0,0 +1,14 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
KERNEL=$1
|
||||
shift
|
||||
|
||||
qemu-system-riscv64 \
|
||||
-nographic \
|
||||
-machine virt \
|
||||
-bios none \
|
||||
-m 3G \
|
||||
-smp 3 \
|
||||
# -drive file=fs.img,if=none,format=raw,id=x0 \
|
||||
-device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 \
|
||||
-kernel "$KERNEL"
|
12
src/ld/kernel.ld
Normal file
12
src/ld/kernel.ld
Normal file
|
@ -0,0 +1,12 @@
|
|||
OUTPUT_ARCH("riscv")
|
||||
ENTRY(_entry)
|
||||
|
||||
SECTIONS {
|
||||
/*
|
||||
It seems that QEMU jumps to 0x8000000 after setting up memory, so we want
|
||||
our kernel code to begin here.
|
||||
|
||||
TODO: Is there an authoritative source that says that this is the address?
|
||||
*/
|
||||
. = 0x8000000;
|
||||
}
|
25
src/main.rs
Normal file
25
src/main.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
#[panic_handler]
|
||||
fn panic_handler(_: &PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
static HELLO: &[u8] = b"Hello World!";
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn _start() -> ! {
|
||||
let vga_buffer = 0xb8000 as *mut u8;
|
||||
|
||||
for (i, &byte) in HELLO.iter().enumerate() {
|
||||
unsafe {
|
||||
*vga_buffer.offset(i as isize * 2) = byte;
|
||||
*vga_buffer.offset(i as isize * 2 + 1) = 0xb;
|
||||
}
|
||||
}
|
||||
|
||||
loop {}
|
||||
}
|
BIN
xv6-book.pdf
Normal file
BIN
xv6-book.pdf
Normal file
Binary file not shown.
Loading…
Reference in a new issue