base
This commit is contained in:
commit
bb6dd4881b
19 changed files with 441 additions and 0 deletions
10
.cargo/config.toml
Normal file
10
.cargo/config.toml
Normal 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
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
4
.vscode/settings.json
vendored
Normal file
4
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"rust-analyzer.cargo.target": "x86_64-unknown-none",
|
||||||
|
"rust-analyzer.checkOnSave.allTargets": false
|
||||||
|
}
|
124
Cargo.lock
generated
Normal file
124
Cargo.lock
generated
Normal 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
21
Cargo.toml
Normal 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
4
README.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# Nulf OS
|
||||||
|
|
||||||
|
Toy kernel in rust.
|
||||||
|
|
1
rust-toolchain
Normal file
1
rust-toolchain
Normal file
|
@ -0,0 +1 @@
|
||||||
|
nightly
|
2
rustfmt.toml
Normal file
2
rustfmt.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
hard_tabs = true
|
||||||
|
max_width = 120
|
6
setup.sh
Normal file
6
setup.sh
Normal 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
6
src/dev/alloc.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
use crate::println;
|
||||||
|
|
||||||
|
pub fn init() {
|
||||||
|
println!("Initializing Allocator.");
|
||||||
|
// TODO
|
||||||
|
}
|
118
src/dev/console.rs
Normal file
118
src/dev/console.rs
Normal 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
23
src/dev/input.rs
Normal 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
3
src/dev/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
pub mod alloc;
|
||||||
|
pub mod console;
|
||||||
|
pub mod input;
|
49
src/hard/int.rs
Normal file
49
src/hard/int.rs
Normal 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
7
src/hard/keyboard.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
pub struct Keyboard;
|
||||||
|
|
||||||
|
impl Keyboard {
|
||||||
|
pub fn record(key_code: u8) {
|
||||||
|
// todo!()
|
||||||
|
}
|
||||||
|
}
|
5
src/hard/mod.rs
Normal file
5
src/hard/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
pub mod vga;
|
||||||
|
|
||||||
|
pub mod keyboard;
|
||||||
|
|
||||||
|
pub mod int;
|
16
src/hard/vga.rs
Normal file
16
src/hard/vga.rs
Normal 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
26
src/main.rs
Normal 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
15
x86_64-nulfos.json
Normal 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"
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue