Skip to content
Merged
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
3 changes: 3 additions & 0 deletions Cargo.lock

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

36 changes: 36 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
PROJECT_NAME := rkos
TARGET := x86_64-unknown-none
BUILD_MODE := release
KERNEL_BIN := target/$(TARGET)/$(BUILD_MODE)/$(PROJECT_NAME)

QEMU := qemu-system-x86_64
QEMU_FLAGS := -machine q35 -kernel $(KERNEL_BIN) -serial stdio

CARGO := cargo
CARGO_FLAGS := --target $(TARGET)
ifeq ($(BUILD_MODE), release)
CARGO_FLAGS += --release
endif

.PHONY: all build run clean check help

all: build

build:
@echo "Building $(PROJECT_NAME) in $(BUILD_MODE) mode..."
$(CARGO) build $(CARGO_FLAGS)
clippy:
@echo "Clippy $(PROJECT_NAME) in $(BUILD_MODE) mode..."
$(CARGO) clippy $(CARGO_FLAGS) --bins --lib -- -D warnings
run: build
@echo "Starting QEMU..."
@$(QEMU) $(QEMU_FLAGS)
clean:
@echo "Cleaning project..."
@$(CARGO) clean
@rm -f build.log

check:
@$(CARGO) check $(CARGO_FLAGS)

.DEFAULT_GOAL := check
14 changes: 13 additions & 1 deletion README.org
Original file line number Diff line number Diff line change
@@ -1,2 +1,14 @@
* Rk
* rkos
[[Github Repo Starts][https://img.shields.io/github/stars/barrensea/rkos]]
[[https://crates.io/crates/rkos][https://img.shields.io/crates/d/rkos.svg]]
[[repo-size][https://img.shields.io/github/repo-size/barrensea/algori.svg]]

** High Performance Rust Operation System Core in Rust!

** Start

Fist install the qemu, then

#+begin_src shell
make run
#+end_src
6 changes: 3 additions & 3 deletions crates/rkos-arch/src/x86/head_64.S
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Bootstrapping x86_64 kernel
see also: https://wiki.osdev.org/Entering_Long_Mode
see also: https://wiki.osdev.org/Setting_Up_Long_Mode
*/
/* prepare space for 4-level paging to entering long mode
.bss: | PML4 | PML3 | PML2 | Kernel_Stack(.bss.stack)|
Expand Down Expand Up @@ -54,7 +54,7 @@ gdt64_pointer:
/* length of gdt64 minus 1 */
.word 15
/* pointer to gdt64 */
.quad gdt64
.long gdt64

/*
multiboot header
Expand Down Expand Up @@ -151,4 +151,4 @@ long_mode_start:
/* if _main returns, loop forever */
.loop64:
hlt
jmp .loop64
jmp .loop64
2 changes: 1 addition & 1 deletion crates/rkos-arch/src/x86/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@

pub mod serial;
65 changes: 65 additions & 0 deletions crates/rkos-arch/src/x86/serial.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// see also: https://wiki.osdev.org/Serial_Ports
use core::arch::asm;
use core::fmt;

const COM1: u16 = 0x3F8;

/// Write a byte to the serial port
unsafe fn outb(port: u16, val: u8) {
unsafe {
asm!("out dx, al", in("dx") port, in("al") val, options(nomem, nostack, preserves_flags));
}
}

/// Read a byte from the serial port
unsafe fn inb(port: u16) -> u8 {
let mut val: u8;
unsafe {
asm!("in al, dx", out("al") val, in("dx") port, options(nomem, nostack, preserves_flags));
}
val
}

pub struct SerialPort;

impl SerialPort {
/// Initialize the standard COM1 serial port
pub fn init() {
unsafe {
outb(COM1 + 1, 0x00); // Disable all interrupts
outb(COM1 + 3, 0x80); // Enable DLAB (set baud rate divisor)
outb(COM1, 0x03); // Set divisor to 3 (lo byte) 38400 baud
outb(COM1 + 1, 0x00); // (hi byte)
outb(COM1 + 3, 0x03); // 8 bits, no parity, one stop bit
outb(COM1 + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
outb(COM1 + 4, 0x0B); // IRQs enabled, RTS/DSR set
}
}

/// Check if transmit buffer is empty
fn is_transmit_empty() -> bool {
unsafe { inb(COM1 + 5) & 0x20 != 0 }
}

/// Write a byte to the serial port
pub fn write_byte(b: u8) {
while !Self::is_transmit_empty() {}
unsafe {
outb(COM1, b);
}
}
}

impl fmt::Write for SerialPort {
fn write_str(&mut self, s: &str) -> fmt::Result {
for byte in s.bytes() {
SerialPort::write_byte(byte);
}
Ok(())
}
}

pub fn _print(args: fmt::Arguments) {
let mut serial = SerialPort;
let _ = fmt::Write::write_fmt(&mut serial, args);
}
2 changes: 1 addition & 1 deletion crates/rkos/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ description.workspace = true
rust-version.workspace = true

[dependencies]

rkos-arch = { path = "../rkos-arch" }

# [lints]
# workspace = true
Expand Down
18 changes: 18 additions & 0 deletions crates/rkos/src/console.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use core::fmt;

#[macro_export]
macro_rules! print {
($($arg:tt)*) => ($crate::console::_print(format_args!($($arg)*)));
}

#[macro_export]
macro_rules! println {
() => ($crate::print!("\n"));
($fmt:expr) => ($crate::print!(concat!($fmt, "\n")));
($fmt:expr, $($arg:tt)*) => ($crate::print!(concat!($fmt, "\n"), $($arg)*));
}

#[doc(hidden)]
pub fn _print(args: fmt::Arguments) {
rkos_arch::x86::serial::_print(args);
}
17 changes: 6 additions & 11 deletions crates/rkos/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,15 @@ use core::panic::PanicInfo;
#[cfg(target_arch = "x86_64")]
global_asm!(include_str!("../../rkos-arch/src/x86/head_64.S"));

#[macro_use]
pub mod console;

#[unsafe(no_mangle)]
pub extern "C" fn _main() {
// VGA_BASE: 0xb8000
let vga_buffer = 0xb8000 as *mut u8;

let text = b"[OK] Barrensea rkos has conquered 64-bit Long Mode!!!";
let color_byte = 0x0a;
rkos_arch::x86::serial::SerialPort::init();

for (i, &byte) in text.iter().enumerate() {
unsafe {
*vga_buffer.add(i * 2) = byte;
*vga_buffer.add(i * 2 + 1) = color_byte;
}
}
println!("[OK] Barrensea rkos has conquered 64-bit Long Mode!!!");
println!("Hello from rkos serial output!");

unsafe extern "C" {
fn stext();
Expand Down
Loading