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
|
/target
|
||||||
/build
|
/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
|
version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kernel"
|
name = "eos0"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
workspace.members = ["kernel"]
|
[package]
|
||||||
workspace.resolver = "2"
|
name = "eos0"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
profile.dev.panic = "abort"
|
[dependencies]
|
||||||
profile.release.panic = "abort"
|
|
||||||
|
|
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