This commit is contained in:
JOLIMAITRE Matthieu 2024-10-21 14:39:21 +02:00
commit bb6dd4881b
19 changed files with 441 additions and 0 deletions

10
.cargo/config.toml Normal file
View file

@ -0,0 +1,10 @@
[build]
target = ["x86_64-nulfos.json"]
[unstable]
build-std = ["core", "compiler_builtins"]
build-std-features = ["compiler-builtins-mem"]
[target.'cfg(target_os = "none")']
runner = "bootimage runner"

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

4
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,4 @@
{
"rust-analyzer.cargo.target": "x86_64-unknown-none",
"rust-analyzer.checkOnSave.allTargets": false
}

124
Cargo.lock generated Normal file
View file

@ -0,0 +1,124 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "bit_field"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
[[package]]
name = "bitflags"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "bootloader"
version = "0.9.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "365861702868e2a37b4247aaecc7bd8f4389baec8d025497ad8ba7ff37ee9440"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
dependencies = [
"spin",
]
[[package]]
name = "linked_list_allocator"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286"
dependencies = [
"spinning_top",
]
[[package]]
name = "lock_api"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "nulfos"
version = "0.1.0"
dependencies = [
"bootloader",
"lazy_static",
"linked_list_allocator",
"pic8259",
"spin",
"x86_64",
]
[[package]]
name = "pic8259"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62d9a86c292b165f757e47e7fd66855def189b2564609bc4203727b27c33db22"
dependencies = [
"x86_64",
]
[[package]]
name = "rustversion"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"lock_api",
]
[[package]]
name = "spinning_top"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b9eb1a2f4c41445a3a0ff9abc5221c5fcd28e1f13cd7c0397706f9ac938ddb0"
dependencies = [
"lock_api",
]
[[package]]
name = "volatile"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "442887c63f2c839b346c192d047a7c87e73d0689c9157b00b53dcc27dd5ea793"
[[package]]
name = "x86_64"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bc79523af8abf92fb1a970c3e086c5a343f6bcc1a0eb890f575cbb3b45743df"
dependencies = [
"bit_field",
"bitflags",
"rustversion",
"volatile",
]

21
Cargo.toml Normal file
View file

@ -0,0 +1,21 @@
[package]
name = "nulfos"
version = "0.1.0"
edition = "2021"
[dependencies]
bootloader = { version = "0.9", features = ["map_physical_memory"] }
lazy_static = { version = "1.5.0", features = ["spin_no_std"] }
linked_list_allocator = "0.10.5"
pic8259 = "0.11.0"
spin = "0.9.8"
x86_64 = "0.15.1"
# artefact configuration
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"

4
README.md Normal file
View file

@ -0,0 +1,4 @@
# Nulf OS
Toy kernel in rust.

1
rust-toolchain Normal file
View file

@ -0,0 +1 @@
nightly

2
rustfmt.toml Normal file
View file

@ -0,0 +1,2 @@
hard_tabs = true
max_width = 120

6
setup.sh Normal file
View file

@ -0,0 +1,6 @@
#!/bin/bash
set -e
rustup target add x86_64-unknown-none
rustup component add rust-src
rustup component add llvm-tools-preview

6
src/dev/alloc.rs Normal file
View file

@ -0,0 +1,6 @@
use crate::println;
pub fn init() {
println!("Initializing Allocator.");
// TODO
}

118
src/dev/console.rs Normal file
View file

@ -0,0 +1,118 @@
use core::fmt;
use lazy_static::lazy_static;
use spin::Mutex;
use crate::hard::vga::{self, Vga};
#[macro_export]
macro_rules! print {
($($arg:tt)*) => ($crate::dev::console::print_args(format_args!($($arg)*)));
}
#[macro_export]
macro_rules! println {
() => ($crate::print!("\n"));
($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*)));
}
lazy_static! {
static ref Out: Mutex<Console> = Mutex::new(Console::init());
}
pub struct Console {
cursor: Cursor,
vga: Vga,
}
impl Console {
pub fn init() -> Self {
let cursor = Cursor::new(vga::WIDTH, vga::HEIGHT);
let vga = Vga;
Self { cursor, vga }
}
pub fn print_(&mut self, text: &str) {
for c in text.chars() {
match c {
'\n' => self.cursor.ret(),
'\t' => self.print_(" "),
_ => {
self.vga.write_at(self.cursor.pos(), c);
self.cursor.progress();
}
}
}
}
}
struct Cursor {
line: usize,
column: usize,
width: usize,
height: usize,
}
impl Cursor {
pub fn new(width: usize, height: usize) -> Self {
Self {
line: 0,
column: 0,
width,
height,
}
}
pub fn pos(&self) -> (usize, usize) {
(self.column, self.line)
}
pub fn set_line(&mut self, line: usize) {
self.line = line;
}
pub fn set_col(&mut self, col: usize) {
self.column = col;
}
pub fn line(&self) -> usize {
self.line
}
pub fn col(&self) -> usize {
self.column
}
pub fn progress(&mut self) {
self.column += 1;
if self.column < self.width {
return;
}
self.column = 0;
self.line += 1;
if self.line < self.height {
return;
}
self.line = 0;
}
pub fn ret(&mut self) {
self.column = self.width;
self.progress();
}
}
impl fmt::Write for Console {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.print_(s);
Ok(())
}
}
pub fn print_args(args: fmt::Arguments) {
use core::fmt::Write;
use x86_64::instructions::interrupts;
interrupts::without_interrupts(|| {
Out.lock().write_fmt(args).unwrap();
});
}

23
src/dev/input.rs Normal file
View file

@ -0,0 +1,23 @@
use lazy_static::lazy_static;
use spin::Mutex;
use crate::hard::keyboard::Keyboard;
lazy_static! {
static ref In: Mutex<Input> = Mutex::new(Input::init());
}
pub struct Input {
keyboard: Keyboard,
}
impl Input {
pub fn init() -> Self {
let keyboard = Keyboard;
Self { keyboard }
}
pub fn read(out: &mut [char]) -> usize {
0
}
}

3
src/dev/mod.rs Normal file
View file

@ -0,0 +1,3 @@
pub mod alloc;
pub mod console;
pub mod input;

49
src/hard/int.rs Normal file
View file

@ -0,0 +1,49 @@
use lazy_static::lazy_static;
use pic8259::ChainedPics;
use spin::Mutex;
use x86_64::{
instructions::{interrupts, port::Port},
structures::idt::{InterruptDescriptorTable, InterruptStackFrame},
};
use crate::{print, println};
pub fn init() {
println!("Initializing interrupt handler.");
IDT.load();
unsafe { PICS.lock().initialize() };
interrupts::enable();
}
const INT_OFFSET: u8 = 32;
const INT_IDX_TIMER: u8 = 32;
const INT_IDX_KEYBOARD: u8 = 33;
lazy_static! {
static ref IDT: InterruptDescriptorTable = {
let mut idt = InterruptDescriptorTable::new();
let entries = idt.slice_mut(INT_OFFSET..);
entries[(INT_IDX_TIMER - INT_OFFSET) as usize].set_handler_fn(timer_handler);
entries[(INT_IDX_KEYBOARD - INT_OFFSET) as usize].set_handler_fn(keyboard_handler);
idt
};
}
static PICS: Mutex<ChainedPics> = Mutex::new(unsafe { ChainedPics::new(0x20, 0x28) });
extern "x86-interrupt" fn keyboard_handler(_stack_frame: InterruptStackFrame) {
let mut port = Port::new(0x60);
let _scancode: u8 = unsafe { port.read() };
// crate::task::keyboard::add_scancode(scancode);
println!("keyboard got scancode");
unsafe {
PICS.lock().notify_end_of_interrupt(INT_IDX_KEYBOARD);
}
}
extern "x86-interrupt" fn timer_handler(_stack_frame: InterruptStackFrame) {
print!(".");
unsafe {
PICS.lock().notify_end_of_interrupt(INT_IDX_TIMER);
}
}

7
src/hard/keyboard.rs Normal file
View file

@ -0,0 +1,7 @@
pub struct Keyboard;
impl Keyboard {
pub fn record(key_code: u8) {
// todo!()
}
}

5
src/hard/mod.rs Normal file
View file

@ -0,0 +1,5 @@
pub mod vga;
pub mod keyboard;
pub mod int;

16
src/hard/vga.rs Normal file
View file

@ -0,0 +1,16 @@
pub const WIDTH: usize = 80;
pub const HEIGHT: usize = 25;
pub struct Vga;
impl Vga {
const BUFF: *mut u8 = 0xb8000 as _;
pub fn write_at(&self, pos: (usize, usize), text: char) {
let index = (pos.0 + pos.1 * WIDTH) as isize;
let byte = text as u8;
unsafe {
*Vga::BUFF.offset(index * 2) = byte;
*Vga::BUFF.offset(index * 2 + 1) = 0xb;
}
}
}

26
src/main.rs Normal file
View file

@ -0,0 +1,26 @@
#![no_std]
#![no_main]
#![feature(abi_x86_interrupt)]
mod dev;
mod hard;
use core::panic::PanicInfo;
use dev::alloc;
use hard::int;
#[no_mangle]
pub extern "C" fn _start() -> ! {
println!("Starting.");
int::init();
alloc::init();
println!("Finished initializations.");
loop {}
}
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
println!("Paniced.");
loop {}
}

15
x86_64-nulfos.json Normal file
View file

@ -0,0 +1,15 @@
{
"llvm-target": "x86_64-unknown-none",
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
"arch": "x86_64",
"target-endian": "little",
"target-pointer-width": "64",
"target-c-int-width": "32",
"os": "none",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"panic-strategy": "abort",
"disable-redzone": true,
"features": "-mmx,-sse,+soft-float"
}