mirror of
https://github.com/XunilGroup/XunilOS.git
synced 2026-04-25 11:49:03 +02:00
Formatted the code, made the arch code x86_64 only for now, fixed the
serial writer always centering and assuming, added a margin for correct displaying. Added the IDT and GDT tables, and the TSS so double faults cant happen. Handled all of these interrupts using functions. Serial console is now topleft and panic messages are formatted correctly from there. core PI constant is now used instead of our own.
This commit is contained in:
4
kernel/.cargo/config.toml
Normal file
4
kernel/.cargo/config.toml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[unstable]
|
||||||
|
json-target-spec = true
|
||||||
|
build-std-features = ["compiler-builtins-mem"]
|
||||||
|
build-std = ["core", "compiler_builtins"]
|
||||||
74
kernel/Cargo.lock
generated
74
kernel/Cargo.lock
generated
@@ -2,18 +2,51 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 4
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "XunilOS"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"font8x8",
|
||||||
|
"lazy_static",
|
||||||
|
"limine",
|
||||||
|
"micromath",
|
||||||
|
"spin 0.10.0",
|
||||||
|
"x86_64",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bit_field"
|
||||||
|
version = "0.10.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.9.1"
|
version = "2.9.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "const_fn"
|
||||||
|
version = "0.4.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "413d67b29ef1021b4d60f4aa1e925ca031751e213832b4b1d588fae623c05c60"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "font8x8"
|
name = "font8x8"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "875488b8711a968268c7cf5d139578713097ca4635a76044e8fe8eedf831d07e"
|
checksum = "875488b8711a968268c7cf5d139578713097ca4635a76044e8fe8eedf831d07e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
dependencies = [
|
||||||
|
"spin 0.9.8",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "limine"
|
name = "limine"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@@ -23,16 +56,6 @@ dependencies = [
|
|||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "limine-rust-template"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"font8x8",
|
|
||||||
"limine",
|
|
||||||
"micromath",
|
|
||||||
"spin",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.14"
|
version = "0.4.14"
|
||||||
@@ -48,12 +71,24 @@ version = "2.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815"
|
checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.9.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spin"
|
name = "spin"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
@@ -62,3 +97,22 @@ checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"lock_api",
|
"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.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f7841fa0098ceb15c567d93d3fae292c49e10a7662b4936d5f6a9728594555ba"
|
||||||
|
dependencies = [
|
||||||
|
"bit_field",
|
||||||
|
"bitflags",
|
||||||
|
"const_fn",
|
||||||
|
"rustversion",
|
||||||
|
"volatile",
|
||||||
|
]
|
||||||
|
|||||||
@@ -1,13 +1,20 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "limine-rust-template"
|
name = "XunilOS"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "XunilOS"
|
||||||
|
test = false
|
||||||
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
font8x8 = { version = "0.3.1", default-features = false }
|
font8x8 = { version = "0.3.1", default-features = false }
|
||||||
|
lazy_static = { version = "1.5.0", features = ["spin_no_std"] }
|
||||||
limine = "0.5"
|
limine = "0.5"
|
||||||
micromath = "2.1.0"
|
micromath = "2.1.0"
|
||||||
spin = "0.10.0"
|
spin = "0.10.0"
|
||||||
|
x86_64 = "0.15.4"
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
pub mod serial;
|
pub mod serial;
|
||||||
pub mod gdt;
|
#[cfg(target_arch = "x86_64")]
|
||||||
pub mod idt;
|
pub mod x86_64;
|
||||||
pub mod interrupts;
|
|
||||||
pub mod paging;
|
|
||||||
|
|||||||
@@ -1,42 +1,64 @@
|
|||||||
use crate::driver::graphics::framebuffer::{with_framebuffer, Framebuffer};
|
|
||||||
use crate::driver::graphics::font_render::render_text;
|
|
||||||
use crate::driver::graphics::base::rgb;
|
use crate::driver::graphics::base::rgb;
|
||||||
use spin::Mutex;
|
use crate::driver::graphics::font_render::render_text;
|
||||||
|
use crate::driver::graphics::framebuffer::Framebuffer;
|
||||||
use core::fmt::{self, Write};
|
use core::fmt::{self, Write};
|
||||||
|
use spin::Mutex;
|
||||||
const DEFAULT_FONT_SIZE: usize = 3;
|
|
||||||
|
|
||||||
pub struct ConsoleWriter<'a> {
|
pub struct ConsoleWriter<'a> {
|
||||||
pub fb: &'a mut Framebuffer,
|
pub fb: &'a mut Framebuffer,
|
||||||
pub console: &'a mut SerialConsole,
|
pub console: &'a mut SerialConsole,
|
||||||
|
pub should_center: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Write for ConsoleWriter<'_> {
|
impl Write for ConsoleWriter<'_> {
|
||||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||||
self.console.render_text(self.fb, s);
|
self.console.render_text(self.fb, s, 2, false);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SerialConsole {
|
pub struct SerialConsole {
|
||||||
start_x: usize,
|
start_x: usize,
|
||||||
current_y: usize
|
pub current_x: usize,
|
||||||
|
current_y: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SerialConsole {
|
impl SerialConsole {
|
||||||
pub fn new(start_x: usize, start_y: usize) -> SerialConsole {
|
pub fn new(start_x: usize, start_y: usize) -> SerialConsole {
|
||||||
SerialConsole {
|
SerialConsole {
|
||||||
start_x,
|
start_x,
|
||||||
current_y: start_y
|
current_x: start_x,
|
||||||
|
current_y: start_y,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_text(&mut self, fb: &mut Framebuffer, text: &str) {
|
pub fn render_text(
|
||||||
self.current_y = render_text(fb, self.start_x - ((text.len() - text.matches('\n').count()) * DEFAULT_FONT_SIZE * 4), self.current_y, text, DEFAULT_FONT_SIZE, rgb(255, 255, 255));
|
&mut self,
|
||||||
self.current_y = render_text(fb, self.start_x - ((text.len() - text.matches('\n').count()) * DEFAULT_FONT_SIZE * 4), self.current_y, "\n", DEFAULT_FONT_SIZE, rgb(255, 255, 255)); // add a newline
|
fb: &mut Framebuffer,
|
||||||
|
text: &str,
|
||||||
|
font_size: usize,
|
||||||
|
should_center: bool,
|
||||||
|
) {
|
||||||
|
let (new_x, new_y) = render_text(
|
||||||
|
fb,
|
||||||
|
if should_center {
|
||||||
|
self.current_x - (text.len() - text.matches('\n').count()) * (font_size * 4)
|
||||||
|
} else {
|
||||||
|
self.current_x
|
||||||
|
},
|
||||||
|
self.current_y,
|
||||||
|
text,
|
||||||
|
font_size,
|
||||||
|
rgb(255, 255, 255),
|
||||||
|
self.start_x,
|
||||||
|
);
|
||||||
|
self.current_x = new_x;
|
||||||
|
self.current_y = new_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&mut self, start_y: usize) {
|
pub fn clear(&mut self, start_x: usize, start_y: usize) {
|
||||||
|
self.start_x = start_x;
|
||||||
|
self.current_x = start_x;
|
||||||
self.current_y = start_y;
|
self.current_y = start_y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
60
kernel/src/arch/x86_64/gdt.rs
Normal file
60
kernel/src/arch/x86_64/gdt.rs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
use lazy_static::lazy_static;
|
||||||
|
use x86_64::VirtAddr;
|
||||||
|
use x86_64::instructions::segmentation::{CS, DS, ES, SS, Segment};
|
||||||
|
use x86_64::instructions::tables::load_tss;
|
||||||
|
use x86_64::structures::{
|
||||||
|
gdt::{Descriptor, GlobalDescriptorTable, SegmentSelector},
|
||||||
|
tss::TaskStateSegment,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const DOUBLE_FAULT_IST_INDEX: u16 = 0;
|
||||||
|
|
||||||
|
struct Selectors {
|
||||||
|
code_selector: SegmentSelector,
|
||||||
|
data_selector: SegmentSelector,
|
||||||
|
tss_selector: SegmentSelector,
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref TSS: TaskStateSegment = {
|
||||||
|
let mut tss = TaskStateSegment::new();
|
||||||
|
tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX as usize] = {
|
||||||
|
const STACK_SIZE: usize = 4096 * 5;
|
||||||
|
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
||||||
|
|
||||||
|
let stack_start = VirtAddr::from_ptr(&raw const STACK);
|
||||||
|
let stack_end = stack_start + STACK_SIZE as u64;
|
||||||
|
stack_end
|
||||||
|
};
|
||||||
|
tss
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref GDT: (GlobalDescriptorTable, Selectors) = {
|
||||||
|
let mut gdt = GlobalDescriptorTable::new();
|
||||||
|
let code_selector = gdt.append(Descriptor::kernel_code_segment());
|
||||||
|
let data_selector = gdt.append(Descriptor::kernel_data_segment());
|
||||||
|
let tss_selector = gdt.append(Descriptor::tss_segment(&TSS));
|
||||||
|
(
|
||||||
|
gdt,
|
||||||
|
Selectors {
|
||||||
|
code_selector,
|
||||||
|
data_selector,
|
||||||
|
tss_selector,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_gdt_x86_64() {
|
||||||
|
GDT.0.load();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
CS::set_reg(GDT.1.code_selector);
|
||||||
|
DS::set_reg(GDT.1.data_selector);
|
||||||
|
ES::set_reg(GDT.1.data_selector);
|
||||||
|
SS::set_reg(GDT.1.data_selector);
|
||||||
|
load_tss(GDT.1.tss_selector);
|
||||||
|
}
|
||||||
|
}
|
||||||
23
kernel/src/arch/x86_64/idt.rs
Normal file
23
kernel/src/arch/x86_64/idt.rs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
use crate::arch::x86_64::{
|
||||||
|
gdt,
|
||||||
|
interrupts::{breakpoint_handler, double_fault_handler},
|
||||||
|
};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use x86_64::structures::idt::InterruptDescriptorTable;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref IDT: InterruptDescriptorTable = {
|
||||||
|
let mut idt = InterruptDescriptorTable::new();
|
||||||
|
idt.breakpoint.set_handler_fn(breakpoint_handler);
|
||||||
|
unsafe {
|
||||||
|
idt.double_fault
|
||||||
|
.set_handler_fn(double_fault_handler)
|
||||||
|
.set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX);
|
||||||
|
}
|
||||||
|
idt
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_idt_x86_64() {
|
||||||
|
IDT.load();
|
||||||
|
}
|
||||||
13
kernel/src/arch/x86_64/interrupts.rs
Normal file
13
kernel/src/arch/x86_64/interrupts.rs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
use crate::println;
|
||||||
|
use x86_64::structures::idt::InterruptStackFrame;
|
||||||
|
|
||||||
|
pub extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) {
|
||||||
|
println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern "x86-interrupt" fn double_fault_handler(
|
||||||
|
stack_frame: InterruptStackFrame,
|
||||||
|
_error_code: u64,
|
||||||
|
) -> ! {
|
||||||
|
panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);
|
||||||
|
}
|
||||||
4
kernel/src/arch/x86_64/mod.rs
Normal file
4
kernel/src/arch/x86_64/mod.rs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
pub mod gdt;
|
||||||
|
pub mod idt;
|
||||||
|
pub mod interrupts;
|
||||||
|
pub mod paging;
|
||||||
1
kernel/src/arch/x86_64/paging.rs
Normal file
1
kernel/src/arch/x86_64/paging.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
pub const PI: f32 = 3.1415926535897;
|
|
||||||
|
|
||||||
pub fn rgb(r: u8, g: u8, b: u8) -> u32 {
|
pub fn rgb(r: u8, g: u8, b: u8) -> u32 {
|
||||||
((r as u32) << 16) | ((g as u32) << 8) | (b as u32)
|
((r as u32) << 16) | ((g as u32) << 8) | (b as u32)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,33 +4,55 @@ use crate::driver::graphics::framebuffer::Framebuffer;
|
|||||||
use crate::driver::graphics::primitives::rectangle_filled;
|
use crate::driver::graphics::primitives::rectangle_filled;
|
||||||
use font8x8::legacy::BASIC_LEGACY;
|
use font8x8::legacy::BASIC_LEGACY;
|
||||||
|
|
||||||
pub fn render_char(framebuffer: &mut Framebuffer, start_x: usize, start_y: usize, char: usize, font_size: usize, color: u32) {
|
pub fn render_char(
|
||||||
|
framebuffer: &mut Framebuffer,
|
||||||
|
start_x: usize,
|
||||||
|
start_y: usize,
|
||||||
|
char: usize,
|
||||||
|
font_size: usize,
|
||||||
|
color: u32,
|
||||||
|
) {
|
||||||
if let Some(glyph) = BASIC_LEGACY.get(char) {
|
if let Some(glyph) = BASIC_LEGACY.get(char) {
|
||||||
for (row, row_bits) in glyph.iter().enumerate() {
|
for (row, row_bits) in glyph.iter().enumerate() {
|
||||||
for bit in 0..8 {
|
for bit in 0..8 {
|
||||||
if (row_bits & (1 << bit)) != 0 {
|
if (row_bits & (1 << bit)) != 0 {
|
||||||
rectangle_filled(framebuffer, start_x + bit * font_size, start_y + row * font_size, font_size, font_size, color, false);
|
rectangle_filled(
|
||||||
|
framebuffer,
|
||||||
|
start_x + bit * font_size,
|
||||||
|
start_y + row * font_size,
|
||||||
|
font_size,
|
||||||
|
font_size,
|
||||||
|
color,
|
||||||
|
false,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_text(framebuffer: &mut Framebuffer, start_x: usize, start_y: usize, text: &str, font_size: usize, color: u32) -> usize {
|
pub fn render_text(
|
||||||
|
framebuffer: &mut Framebuffer,
|
||||||
|
start_x: usize,
|
||||||
|
start_y: usize,
|
||||||
|
text: &str,
|
||||||
|
font_size: usize,
|
||||||
|
color: u32,
|
||||||
|
margin_left: usize,
|
||||||
|
) -> (usize, usize) {
|
||||||
let mut x = start_x;
|
let mut x = start_x;
|
||||||
let mut y = start_y;
|
let mut y = start_y;
|
||||||
|
|
||||||
for b in text.bytes() {
|
for b in text.bytes() {
|
||||||
if b == b'\n' {
|
if b == b'\n' {
|
||||||
y += 12 * font_size;
|
y += 12 * font_size;
|
||||||
x = start_x;
|
x = margin_left;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
render_char(framebuffer, x, y, b as usize, font_size, color);
|
render_char(framebuffer, x, y, b as usize, font_size, color);
|
||||||
x += 8 * font_size;
|
x += 8 * font_size;
|
||||||
}
|
}
|
||||||
framebuffer.swap();
|
|
||||||
|
|
||||||
y
|
(x, y)
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
pub mod base;
|
pub mod base;
|
||||||
pub mod framebuffer;
|
|
||||||
pub mod font_render;
|
pub mod font_render;
|
||||||
|
pub mod framebuffer;
|
||||||
pub mod primitives;
|
pub mod primitives;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
use micromath::F32Ext;
|
|
||||||
use crate::driver::graphics::framebuffer::Framebuffer;
|
use crate::driver::graphics::framebuffer::Framebuffer;
|
||||||
use crate::driver::graphics::base::{rgb, PI};
|
use core::f32::consts::PI;
|
||||||
|
use micromath::F32Ext;
|
||||||
|
|
||||||
pub fn line(framebuffer: &mut Framebuffer, mut x0: i64, mut y0: i64, x1: i64, y1: i64, color: u32) {
|
pub fn line(framebuffer: &mut Framebuffer, mut x0: i64, mut y0: i64, x1: i64, y1: i64, color: u32) {
|
||||||
let mut dx = x1 - x0;
|
let mut dx = x1 - x0;
|
||||||
@@ -38,14 +38,43 @@ pub fn line(framebuffer: &mut Framebuffer, mut x0: i64, mut y0: i64, x1: i64, y1
|
|||||||
error += dx;
|
error += dx;
|
||||||
y0 += step_y;
|
y0 += step_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn triangle_outline(framebuffer: &mut Framebuffer, x1: usize, y1: usize, x2: usize, y2: usize, x3: usize, y3: usize, color: u32) {
|
pub fn triangle_outline(
|
||||||
line(framebuffer, x1 as i64, y1 as i64, x2 as i64, y2 as i64, color);
|
framebuffer: &mut Framebuffer,
|
||||||
line(framebuffer, x1 as i64, y1 as i64, x3 as i64, y3 as i64, color);
|
x1: usize,
|
||||||
line(framebuffer, x2 as i64, y2 as i64, x3 as i64, y3 as i64, color);
|
y1: usize,
|
||||||
|
x2: usize,
|
||||||
|
y2: usize,
|
||||||
|
x3: usize,
|
||||||
|
y3: usize,
|
||||||
|
color: u32,
|
||||||
|
) {
|
||||||
|
line(
|
||||||
|
framebuffer,
|
||||||
|
x1 as i64,
|
||||||
|
y1 as i64,
|
||||||
|
x2 as i64,
|
||||||
|
y2 as i64,
|
||||||
|
color,
|
||||||
|
);
|
||||||
|
line(
|
||||||
|
framebuffer,
|
||||||
|
x1 as i64,
|
||||||
|
y1 as i64,
|
||||||
|
x3 as i64,
|
||||||
|
y3 as i64,
|
||||||
|
color,
|
||||||
|
);
|
||||||
|
line(
|
||||||
|
framebuffer,
|
||||||
|
x2 as i64,
|
||||||
|
y2 as i64,
|
||||||
|
x3 as i64,
|
||||||
|
y3 as i64,
|
||||||
|
color,
|
||||||
|
);
|
||||||
framebuffer.swap();
|
framebuffer.swap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,12 +84,12 @@ pub fn circle_outline(framebuffer: &mut Framebuffer, x: usize, y: usize, radius:
|
|||||||
loop {
|
loop {
|
||||||
i += 0.1;
|
i += 0.1;
|
||||||
|
|
||||||
let x1: f32 = radius * (i * PI / 180.0).cos();
|
let x1: f32 = radius * (i * core::f32::consts::PI / 180.0).cos();
|
||||||
let y1: f32 = radius * (i * PI / 180.0).sin();
|
let y1: f32 = radius * (i * PI / 180.0).sin();
|
||||||
framebuffer.put_pixel((x as f32 + x1) as usize, (y as f32 + y1) as usize, color);
|
framebuffer.put_pixel((x as f32 + x1) as usize, (y as f32 + y1) as usize, color);
|
||||||
|
|
||||||
if i >= 360.0 {
|
if i >= 360.0 {
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
framebuffer.swap();
|
framebuffer.swap();
|
||||||
@@ -101,7 +130,15 @@ pub fn circle_filled(framebuffer: &mut Framebuffer, x0: usize, y0: usize, radius
|
|||||||
framebuffer.swap();
|
framebuffer.swap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rectangle_filled(framebuffer: &mut Framebuffer, x: usize, y: usize, width: usize, height: usize, color: u32, swap: bool) {
|
pub fn rectangle_filled(
|
||||||
|
framebuffer: &mut Framebuffer,
|
||||||
|
x: usize,
|
||||||
|
y: usize,
|
||||||
|
width: usize,
|
||||||
|
height: usize,
|
||||||
|
color: u32,
|
||||||
|
swap: bool,
|
||||||
|
) {
|
||||||
for fb_x in x..x + width {
|
for fb_x in x..x + width {
|
||||||
for fb_y in y..y + height {
|
for fb_y in y..y + height {
|
||||||
framebuffer.put_pixel(fb_x, fb_y, color);
|
framebuffer.put_pixel(fb_x, fb_y, color);
|
||||||
@@ -112,7 +149,14 @@ pub fn rectangle_filled(framebuffer: &mut Framebuffer, x: usize, y: usize, width
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rectangle_outline(framebuffer: &mut Framebuffer, x: i64, y: i64, width: i64, height: i64, color: u32) {
|
pub fn rectangle_outline(
|
||||||
|
framebuffer: &mut Framebuffer,
|
||||||
|
x: i64,
|
||||||
|
y: i64,
|
||||||
|
width: i64,
|
||||||
|
height: i64,
|
||||||
|
color: u32,
|
||||||
|
) {
|
||||||
line(framebuffer, x, y, x + width, y, color); // bottomleft -> bottomright
|
line(framebuffer, x, y, x + width, y, color); // bottomleft -> bottomright
|
||||||
line(framebuffer, x, y + height, x + width, y + height, color); // topleft -> topright
|
line(framebuffer, x, y + height, x + width, y + height, color); // topleft -> topright
|
||||||
line(framebuffer, x, y, x, y + height, color); // bottomleft -> topleft
|
line(framebuffer, x, y, x, y + height, color); // bottomleft -> topleft
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
#![feature(abi_x86_interrupt)]
|
||||||
|
|
||||||
use core::arch::asm;
|
use core::arch::asm;
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
@@ -7,15 +8,19 @@ use core::fmt::Write;
|
|||||||
use limine::BaseRevision;
|
use limine::BaseRevision;
|
||||||
use limine::request::{FramebufferRequest, RequestsEndMarker, RequestsStartMarker};
|
use limine::request::{FramebufferRequest, RequestsEndMarker, RequestsStartMarker};
|
||||||
|
|
||||||
pub mod driver;
|
|
||||||
pub mod arch;
|
pub mod arch;
|
||||||
|
pub mod driver;
|
||||||
|
|
||||||
use spin::Mutex;
|
use crate::arch::serial::{ConsoleWriter, init_serial_console, with_serial_console};
|
||||||
use crate::arch::serial::{ConsoleWriter, SerialConsole, init_serial_console, with_serial_console};
|
#[cfg(target_arch = "x86_64")]
|
||||||
use crate::driver::graphics::font_render::render_text;
|
use crate::arch::x86_64::gdt::load_gdt_x86_64;
|
||||||
use crate::driver::graphics::primitives::{circle_filled, circle_outline, rectangle_filled, rectangle_outline, triangle_outline};
|
|
||||||
use crate::driver::graphics::base::rgb;
|
use crate::driver::graphics::base::rgb;
|
||||||
use crate::driver::graphics::framebuffer::{Framebuffer, init_framebuffer, with_framebuffer};
|
use crate::driver::graphics::framebuffer::{init_framebuffer, with_framebuffer};
|
||||||
|
use crate::driver::graphics::primitives::{
|
||||||
|
circle_filled, circle_outline, rectangle_filled, rectangle_outline, triangle_outline,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::arch::x86_64::idt::init_idt_x86_64;
|
||||||
|
|
||||||
/// Sets the base revision to the latest revision supported by the crate.
|
/// Sets the base revision to the latest revision supported by the crate.
|
||||||
/// See specification for further info.
|
/// See specification for further info.
|
||||||
@@ -58,9 +63,14 @@ macro_rules! println {
|
|||||||
pub fn _print(args: core::fmt::Arguments) {
|
pub fn _print(args: core::fmt::Arguments) {
|
||||||
with_framebuffer(|fb| {
|
with_framebuffer(|fb| {
|
||||||
with_serial_console(|console| {
|
with_serial_console(|console| {
|
||||||
let mut writer = ConsoleWriter { fb, console };
|
let mut writer = ConsoleWriter {
|
||||||
|
fb,
|
||||||
|
console,
|
||||||
|
should_center: false,
|
||||||
|
};
|
||||||
let _ = writer.write_fmt(args);
|
let _ = writer.write_fmt(args);
|
||||||
});
|
});
|
||||||
|
fb.swap();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,12 +80,18 @@ unsafe extern "C" fn kmain() -> ! {
|
|||||||
// removed by the linker.
|
// removed by the linker.
|
||||||
assert!(BASE_REVISION.is_supported());
|
assert!(BASE_REVISION.is_supported());
|
||||||
|
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
{
|
||||||
|
load_gdt_x86_64();
|
||||||
|
init_idt_x86_64();
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(framebuffer_response) = FRAMEBUFFER_REQUEST.get_response() {
|
if let Some(framebuffer_response) = FRAMEBUFFER_REQUEST.get_response() {
|
||||||
if let Some(limine_framebuffer) = framebuffer_response.framebuffers().next() {
|
if let Some(limine_framebuffer) = framebuffer_response.framebuffers().next() {
|
||||||
init_framebuffer(&limine_framebuffer);
|
init_framebuffer(&limine_framebuffer);
|
||||||
with_framebuffer(|mut fb| {
|
with_framebuffer(|mut fb| {
|
||||||
let (width, height) = (fb.width.clone(), fb.height.clone());
|
let (width, height) = (fb.width.clone(), fb.height.clone());
|
||||||
init_serial_console(width / 2, height / 3);
|
init_serial_console(0, 0);
|
||||||
rectangle_filled(&mut fb, 0, 0, width, height, rgb(253, 129, 0), true);
|
rectangle_filled(&mut fb, 0, 0, width, height, rgb(253, 129, 0), true);
|
||||||
rectangle_filled(&mut fb, 700, 400, 200, 200, rgb(0, 0, 0), true);
|
rectangle_filled(&mut fb, 700, 400, 200, 200, rgb(0, 0, 0), true);
|
||||||
rectangle_outline(&mut fb, 400, 400, 100, 100, rgb(0, 0, 0));
|
rectangle_outline(&mut fb, 400, 400, 100, 100, rgb(0, 0, 0));
|
||||||
@@ -83,7 +99,6 @@ unsafe extern "C" fn kmain() -> ! {
|
|||||||
circle_outline(&mut fb, 400, 200, 100.0, rgb(0, 0, 0));
|
circle_outline(&mut fb, 400, 200, 100.0, rgb(0, 0, 0));
|
||||||
triangle_outline(&mut fb, 100, 400, 200, 400, 150, 600, rgb(0, 0, 0));
|
triangle_outline(&mut fb, 100, 400, 200, 400, 150, 600, rgb(0, 0, 0));
|
||||||
});
|
});
|
||||||
panic!("idk, test");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,16 +110,19 @@ fn rust_panic(_info: &core::panic::PanicInfo) -> ! {
|
|||||||
with_framebuffer(|mut fb| {
|
with_framebuffer(|mut fb| {
|
||||||
let (width, height) = (fb.width.clone(), fb.height.clone());
|
let (width, height) = (fb.width.clone(), fb.height.clone());
|
||||||
rectangle_filled(&mut fb, 0, 0, width, height, rgb(180, 0, 0), true);
|
rectangle_filled(&mut fb, 0, 0, width, height, rgb(180, 0, 0), true);
|
||||||
with_serial_console(|serial_console| {
|
|
||||||
serial_console.clear(height / 3);
|
with_serial_console(|console| {
|
||||||
serial_console.render_text(&mut fb, "Kernel Panic! :C\n\n\n");
|
console.clear(5, 5);
|
||||||
if let Some(message) = _info.message().as_str() {
|
|
||||||
serial_console.render_text(&mut fb, "Message:");
|
let mut writer = ConsoleWriter {
|
||||||
serial_console.render_text(&mut fb, message);
|
fb: &mut fb,
|
||||||
}
|
console,
|
||||||
crate::println!("Kernel Panic! :C");
|
should_center: true,
|
||||||
crate::print!("Message: ");
|
};
|
||||||
crate::println!("{}", _info);
|
|
||||||
|
let _ = writer.write_str("KERNEL PANIC\n\n");
|
||||||
|
let _ = writer.write_fmt(core::format_args!("{}", _info));
|
||||||
|
fb.swap();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user