mirror of
https://github.com/XunilGroup/XunilOS.git
synced 2026-04-25 11:49:03 +02:00
Add interrupts and IDT and react to double, page, general prot faults
and breakpoints, add keyboard support through the keyboar interrupt, add paging memory management and a Frame Allocator, add a generic arch module that initializes arch-specific things, fix framebuffer and serialconsole being accessed from multiple places, move serial to driver since its not actually a serial console.
This commit is contained in:
17
kernel/Cargo.lock
generated
17
kernel/Cargo.lock
generated
@@ -10,6 +10,8 @@ dependencies = [
|
|||||||
"lazy_static",
|
"lazy_static",
|
||||||
"limine",
|
"limine",
|
||||||
"micromath",
|
"micromath",
|
||||||
|
"pc-keyboard",
|
||||||
|
"pic8259",
|
||||||
"spin 0.10.0",
|
"spin 0.10.0",
|
||||||
"x86_64",
|
"x86_64",
|
||||||
]
|
]
|
||||||
@@ -71,6 +73,21 @@ 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 = "pc-keyboard"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0ca629cbb3f0d5b699c338f0129ff78c9bfd7ea8b1258ad529bff490dc8ed5a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pic8259"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "62d9a86c292b165f757e47e7fd66855def189b2564609bc4203727b27c33db22"
|
||||||
|
dependencies = [
|
||||||
|
"x86_64",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.22"
|
version = "1.0.22"
|
||||||
|
|||||||
@@ -13,7 +13,11 @@ font8x8 = { version = "0.3.1", default-features = false }
|
|||||||
lazy_static = { version = "1.5.0", features = ["spin_no_std"] }
|
lazy_static = { version = "1.5.0", features = ["spin_no_std"] }
|
||||||
limine = "0.5"
|
limine = "0.5"
|
||||||
micromath = "2.1.0"
|
micromath = "2.1.0"
|
||||||
|
pc-keyboard = "0.8.0"
|
||||||
|
pic8259 = "0.11.0"
|
||||||
spin = "0.10.0"
|
spin = "0.10.0"
|
||||||
|
|
||||||
|
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||||
x86_64 = "0.15.4"
|
x86_64 = "0.15.4"
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
|
|||||||
54
kernel/src/arch/arch.rs
Normal file
54
kernel/src/arch/arch.rs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
use core::arch::asm;
|
||||||
|
use limine::response::{HhdmResponse, MemoryMapResponse};
|
||||||
|
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
use crate::arch::x86_64::{
|
||||||
|
init::init_x86_64,
|
||||||
|
paging::{XunilFrameAllocator, example_mapping, initialize_paging},
|
||||||
|
};
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
use x86_64::{
|
||||||
|
VirtAddr, registers::control::Cr3, structures::paging::OffsetPageTable,
|
||||||
|
structures::paging::Page,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
pub fn memory_management_init(
|
||||||
|
hhdm_response: &HhdmResponse,
|
||||||
|
memory_map_response: &MemoryMapResponse,
|
||||||
|
) -> OffsetPageTable<'static> {
|
||||||
|
let physical_offset = VirtAddr::new(hhdm_response.offset());
|
||||||
|
let (frame, _) = Cr3::read();
|
||||||
|
let mut mapper = unsafe { initialize_paging(physical_offset) };
|
||||||
|
|
||||||
|
let l4_virt = physical_offset + frame.start_address().as_u64() + 0xb8000;
|
||||||
|
let mut frame_allocator = XunilFrameAllocator::new(memory_map_response.entries());
|
||||||
|
let page = Page::containing_address(l4_virt);
|
||||||
|
unsafe {
|
||||||
|
example_mapping(page, &mut mapper, &mut frame_allocator);
|
||||||
|
}
|
||||||
|
mapper
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
pub fn init(
|
||||||
|
hhdm_response: &HhdmResponse,
|
||||||
|
memory_map_response: &MemoryMapResponse,
|
||||||
|
) -> OffsetPageTable<'static> {
|
||||||
|
init_x86_64();
|
||||||
|
|
||||||
|
return memory_management_init(hhdm_response, memory_map_response);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn idle() -> ! {
|
||||||
|
loop {
|
||||||
|
unsafe {
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
asm!("hlt");
|
||||||
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||||
|
asm!("wfi");
|
||||||
|
#[cfg(target_arch = "loongarch64")]
|
||||||
|
asm!("idle 0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
pub mod serial;
|
pub mod arch;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
pub mod x86_64;
|
pub mod x86_64;
|
||||||
|
|||||||
0
kernel/src/arch/x86_64/heap.rs
Normal file
0
kernel/src/arch/x86_64/heap.rs
Normal file
@@ -1,23 +0,0 @@
|
|||||||
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();
|
|
||||||
}
|
|
||||||
16
kernel/src/arch/x86_64/init.rs
Normal file
16
kernel/src/arch/x86_64/init.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
use crate::arch::x86_64::gdt::load_gdt_x86_64;
|
||||||
|
use crate::arch::x86_64::interrupts::{PICS, init_idt_x86_64};
|
||||||
|
use x86_64::instructions::interrupts;
|
||||||
|
|
||||||
|
pub fn init_x86_64() {
|
||||||
|
load_gdt_x86_64();
|
||||||
|
init_idt_x86_64();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let mut pics = PICS.lock();
|
||||||
|
pics.initialize();
|
||||||
|
pics.write_masks(0xFC, 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
interrupts::enable();
|
||||||
|
}
|
||||||
@@ -1,5 +1,56 @@
|
|||||||
use crate::println;
|
use crate::{arch::x86_64::gdt, driver::keyboard::keyboard_interrupt_handler, println};
|
||||||
use x86_64::structures::idt::InterruptStackFrame;
|
use lazy_static::lazy_static;
|
||||||
|
use pic8259::ChainedPics;
|
||||||
|
use spin::Mutex;
|
||||||
|
pub use x86_64::instructions::interrupts::without_interrupts;
|
||||||
|
use x86_64::{
|
||||||
|
registers::control::Cr2,
|
||||||
|
structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const PIC_1_OFFSET: u8 = 32;
|
||||||
|
pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8;
|
||||||
|
|
||||||
|
pub static PICS: Mutex<ChainedPics> =
|
||||||
|
Mutex::new(unsafe { ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET) });
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum InterruptIndex {
|
||||||
|
Timer = PIC_1_OFFSET,
|
||||||
|
Keyboard, // putting it below increments it by 1, so its offset + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InterruptIndex {
|
||||||
|
pub fn as_u8(self) -> u8 {
|
||||||
|
self as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_usize(self) -> usize {
|
||||||
|
usize::from(self.as_u8())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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[InterruptIndex::Timer.as_u8()].set_handler_fn(timer_interrupt_handler);
|
||||||
|
idt.page_fault.set_handler_fn(page_fault_handler);
|
||||||
|
idt.general_protection_fault.set_handler_fn(gpf_handler);
|
||||||
|
idt[InterruptIndex::Keyboard.as_u8()].set_handler_fn(keyboard_interrupt_handler);
|
||||||
|
idt
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_idt_x86_64() {
|
||||||
|
IDT.load();
|
||||||
|
}
|
||||||
|
|
||||||
pub extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) {
|
pub extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) {
|
||||||
println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
|
println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
|
||||||
@@ -11,3 +62,29 @@ pub extern "x86-interrupt" fn double_fault_handler(
|
|||||||
) -> ! {
|
) -> ! {
|
||||||
panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);
|
panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub extern "x86-interrupt" fn page_fault_handler(
|
||||||
|
stack_frame: InterruptStackFrame,
|
||||||
|
error_code: PageFaultErrorCode,
|
||||||
|
) {
|
||||||
|
panic!(
|
||||||
|
"EXCEPTION: PAGE FAULT\nAccessed Addresss: {:?}\nError Code: {:?}\n{:#?}",
|
||||||
|
Cr2::read(),
|
||||||
|
error_code,
|
||||||
|
stack_frame
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern "x86-interrupt" fn gpf_handler(stack_frame: InterruptStackFrame, error_code: u64) {
|
||||||
|
panic!(
|
||||||
|
"EXCEPTION: GENERAL PROTECTION FAULT\nError Code: {:?}\n{:#?}",
|
||||||
|
error_code, stack_frame
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: InterruptStackFrame) {
|
||||||
|
unsafe {
|
||||||
|
PICS.lock()
|
||||||
|
.notify_end_of_interrupt(InterruptIndex::Timer.as_u8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
pub mod gdt;
|
pub mod gdt;
|
||||||
pub mod idt;
|
pub mod init;
|
||||||
pub mod interrupts;
|
pub mod interrupts;
|
||||||
pub mod paging;
|
pub mod paging;
|
||||||
|
|||||||
@@ -1 +1,71 @@
|
|||||||
|
use x86_64::{
|
||||||
|
PhysAddr, VirtAddr,
|
||||||
|
registers::control::Cr3,
|
||||||
|
structures::paging::{
|
||||||
|
FrameAllocator, Mapper, OffsetPageTable, Page, PageTable, PageTableFlags as Flags,
|
||||||
|
PhysFrame, Size2MiB, Size4KiB,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
use limine::memory_map::{Entry, EntryType};
|
||||||
|
|
||||||
|
unsafe fn active_level_4_table(mem_offset: VirtAddr) -> &'static mut PageTable {
|
||||||
|
let (level_4_table, _) = Cr3::read();
|
||||||
|
|
||||||
|
let physical_addr = level_4_table.start_address();
|
||||||
|
let virtual_addr = mem_offset + physical_addr.as_u64();
|
||||||
|
let page_table_ptr: *mut PageTable = virtual_addr.as_mut_ptr();
|
||||||
|
|
||||||
|
unsafe { &mut *page_table_ptr }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn initialize_paging(physical_memory_offset: VirtAddr) -> OffsetPageTable<'static> {
|
||||||
|
unsafe {
|
||||||
|
let level_4_table = active_level_4_table(physical_memory_offset);
|
||||||
|
OffsetPageTable::new(level_4_table, physical_memory_offset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct XunilFrameAllocator<'a> {
|
||||||
|
next: usize,
|
||||||
|
memory_map: &'a [&'a Entry],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> XunilFrameAllocator<'a> {
|
||||||
|
pub fn new(memory_map: &'a [&'a Entry]) -> Self {
|
||||||
|
Self {
|
||||||
|
next: 0,
|
||||||
|
memory_map,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usable_frames(&self) -> impl Iterator<Item = PhysFrame> {
|
||||||
|
let regions = self.memory_map.iter();
|
||||||
|
let usable = regions.filter(|region| region.entry_type == EntryType::USABLE);
|
||||||
|
let ranges = usable
|
||||||
|
.map(|usable_region| usable_region.base..usable_region.base + usable_region.length);
|
||||||
|
let frame_addresses = ranges.flat_map(|r| r.step_by(4096));
|
||||||
|
|
||||||
|
frame_addresses
|
||||||
|
.map(|frame_address| PhysFrame::containing_address(PhysAddr::new(frame_address)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<'a> FrameAllocator<Size4KiB> for XunilFrameAllocator<'a> {
|
||||||
|
fn allocate_frame(&mut self) -> Option<PhysFrame<Size4KiB>> {
|
||||||
|
let frame = self.usable_frames().nth(self.next);
|
||||||
|
self.next += 1;
|
||||||
|
frame
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn example_mapping(
|
||||||
|
page: Page<Size2MiB>,
|
||||||
|
mapper: &mut OffsetPageTable,
|
||||||
|
frame_allocator: &mut impl FrameAllocator<Size4KiB>,
|
||||||
|
) {
|
||||||
|
let frame = PhysFrame::<Size2MiB>::containing_address(PhysAddr::new(0x0000_1234_4000_0000));
|
||||||
|
let flags = Flags::PRESENT | Flags::WRITABLE;
|
||||||
|
let map_to_result = unsafe { mapper.map_to(page, frame, flags, frame_allocator) };
|
||||||
|
map_to_result.expect("map_to failed").flush();
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
use limine::framebuffer::Framebuffer as LimineFramebuffer;
|
use limine::framebuffer::Framebuffer as LimineFramebuffer;
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
|
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
use crate::arch::x86_64::interrupts::without_interrupts;
|
||||||
|
|
||||||
const MAX_BACKBUFFER_PIXELS: usize = 1920 * 1080;
|
const MAX_BACKBUFFER_PIXELS: usize = 1920 * 1080;
|
||||||
static mut BACK_BUFFER: [u32; MAX_BACKBUFFER_PIXELS] = [0; MAX_BACKBUFFER_PIXELS];
|
static mut BACK_BUFFER: [u32; MAX_BACKBUFFER_PIXELS] = [0; MAX_BACKBUFFER_PIXELS];
|
||||||
|
|
||||||
@@ -62,8 +65,10 @@ pub fn init_framebuffer(raw: &LimineFramebuffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_framebuffer<F: FnOnce(&mut Framebuffer)>(f: F) {
|
pub fn with_framebuffer<F: FnOnce(&mut Framebuffer)>(f: F) {
|
||||||
let mut guard = FRAMEBUFFER.lock();
|
without_interrupts(|| {
|
||||||
if let Some(fb) = guard.as_mut() {
|
let mut guard = FRAMEBUFFER.lock();
|
||||||
f(fb);
|
if let Some(fb) = guard.as_mut() {
|
||||||
}
|
f(fb);
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,37 @@
|
|||||||
|
use crate::{
|
||||||
|
arch::x86_64::interrupts::{InterruptIndex, PICS},
|
||||||
|
print,
|
||||||
|
};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use pc_keyboard::{DecodedKey, HandleControl, Keyboard, ScancodeSet1, layouts};
|
||||||
|
use spin::Mutex;
|
||||||
|
use x86_64::{instructions::port::Port, structures::idt::InterruptStackFrame};
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref KEYBOARD: Mutex<Keyboard<layouts::Us104Key, ScancodeSet1>> =
|
||||||
|
Mutex::new(Keyboard::new(
|
||||||
|
ScancodeSet1::new(),
|
||||||
|
layouts::Us104Key,
|
||||||
|
HandleControl::Ignore
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) {
|
||||||
|
let mut port = Port::new(0x60);
|
||||||
|
let scancode: u8 = unsafe { port.read() };
|
||||||
|
let mut keyboard = KEYBOARD.lock();
|
||||||
|
|
||||||
|
if let Ok(Some(key_event)) = keyboard.add_byte(scancode) {
|
||||||
|
if let Some(key) = keyboard.process_keyevent(key_event) {
|
||||||
|
match key {
|
||||||
|
DecodedKey::Unicode(character) => print!("{}", character),
|
||||||
|
DecodedKey::RawKey(key) => print!("{:?}", key),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
PICS.lock()
|
||||||
|
.notify_end_of_interrupt(InterruptIndex::Keyboard.as_u8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
pub mod graphics;
|
pub mod graphics;
|
||||||
pub mod keyboard;
|
pub mod keyboard;
|
||||||
|
pub mod serial;
|
||||||
pub mod timer;
|
pub mod timer;
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ use crate::driver::graphics::framebuffer::Framebuffer;
|
|||||||
use core::fmt::{self, Write};
|
use core::fmt::{self, Write};
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
|
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
use crate::arch::x86_64::interrupts::without_interrupts;
|
||||||
|
|
||||||
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,
|
||||||
@@ -70,8 +73,10 @@ pub fn init_serial_console(start_x: usize, start_y: usize) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_serial_console<F: FnOnce(&mut SerialConsole)>(f: F) {
|
pub fn with_serial_console<F: FnOnce(&mut SerialConsole)>(f: F) {
|
||||||
let mut guard = SERIAL_CONSOLE.lock();
|
without_interrupts(|| {
|
||||||
if let Some(fb) = guard.as_mut() {
|
let mut guard = SERIAL_CONSOLE.lock();
|
||||||
f(fb);
|
if let Some(fb) = guard.as_mut() {
|
||||||
}
|
f(fb);
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
@@ -2,25 +2,22 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
#![feature(abi_x86_interrupt)]
|
#![feature(abi_x86_interrupt)]
|
||||||
|
|
||||||
use core::arch::asm;
|
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
|
|
||||||
use limine::BaseRevision;
|
use limine::BaseRevision;
|
||||||
use limine::request::{FramebufferRequest, RequestsEndMarker, RequestsStartMarker};
|
use limine::request::{
|
||||||
|
FramebufferRequest, HhdmRequest, MemoryMapRequest, RequestsEndMarker, RequestsStartMarker,
|
||||||
|
};
|
||||||
pub mod arch;
|
pub mod arch;
|
||||||
pub mod driver;
|
pub mod driver;
|
||||||
|
|
||||||
use crate::arch::serial::{ConsoleWriter, init_serial_console, with_serial_console};
|
use crate::arch::arch::{idle, init};
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
use crate::arch::x86_64::gdt::load_gdt_x86_64;
|
|
||||||
use crate::driver::graphics::base::rgb;
|
use crate::driver::graphics::base::rgb;
|
||||||
use crate::driver::graphics::framebuffer::{init_framebuffer, with_framebuffer};
|
use crate::driver::graphics::framebuffer::{init_framebuffer, with_framebuffer};
|
||||||
use crate::driver::graphics::primitives::{
|
use crate::driver::graphics::primitives::{
|
||||||
circle_filled, circle_outline, rectangle_filled, rectangle_outline, triangle_outline,
|
circle_filled, circle_outline, rectangle_filled, rectangle_outline, triangle_outline,
|
||||||
};
|
};
|
||||||
|
use crate::driver::serial::{ConsoleWriter, init_serial_console, with_serial_console};
|
||||||
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.
|
||||||
@@ -34,6 +31,14 @@ static BASE_REVISION: BaseRevision = BaseRevision::new();
|
|||||||
#[unsafe(link_section = ".requests")]
|
#[unsafe(link_section = ".requests")]
|
||||||
static FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new();
|
static FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new();
|
||||||
|
|
||||||
|
#[used]
|
||||||
|
#[unsafe(link_section = ".requests")]
|
||||||
|
static HHDM_REQUEST: HhdmRequest = HhdmRequest::new();
|
||||||
|
|
||||||
|
#[used]
|
||||||
|
#[unsafe(link_section = ".requests")]
|
||||||
|
static MEMORY_MAP_REQUEST: MemoryMapRequest = MemoryMapRequest::new();
|
||||||
|
|
||||||
/// Define the stand and end markers for Limine requests.
|
/// Define the stand and end markers for Limine requests.
|
||||||
#[used]
|
#[used]
|
||||||
#[unsafe(link_section = ".requests_start_marker")]
|
#[unsafe(link_section = ".requests_start_marker")]
|
||||||
@@ -80,28 +85,36 @@ 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| {
|
// boot_animation();
|
||||||
let (width, height) = (fb.width.clone(), fb.height.clone());
|
|
||||||
init_serial_console(0, 0);
|
|
||||||
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_outline(&mut fb, 400, 400, 100, 100, rgb(0, 0, 0));
|
|
||||||
circle_filled(&mut fb, 200, 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));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(hhdm_response) = HHDM_REQUEST.get_response() {
|
||||||
|
if let Some(memory_map_response) = MEMORY_MAP_REQUEST.get_response() {
|
||||||
|
let mapper = init(hhdm_response, memory_map_response);
|
||||||
|
} else {
|
||||||
|
init_serial_console(0, 0);
|
||||||
|
panic!("Could not get required info from Limine's memory map. ")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
init_serial_console(0, 0);
|
||||||
|
panic!("Could not get required info from the Limine's higher-half direct mapping. ")
|
||||||
|
}
|
||||||
|
|
||||||
|
with_framebuffer(|mut fb| {
|
||||||
|
let (width, height) = (fb.width.clone(), fb.height.clone());
|
||||||
|
init_serial_console(0, 0);
|
||||||
|
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_outline(&mut fb, 400, 400, 100, 100, rgb(0, 0, 0));
|
||||||
|
circle_filled(&mut fb, 200, 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));
|
||||||
|
});
|
||||||
|
|
||||||
idle();
|
idle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,16 +141,3 @@ fn rust_panic(_info: &core::panic::PanicInfo) -> ! {
|
|||||||
|
|
||||||
idle();
|
idle();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn idle() -> ! {
|
|
||||||
loop {
|
|
||||||
unsafe {
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
asm!("hlt");
|
|
||||||
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
|
||||||
asm!("wfi");
|
|
||||||
#[cfg(target_arch = "loongarch64")]
|
|
||||||
asm!("idle 0");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
|
|
||||||
Reference in New Issue
Block a user