Compare commits
2 Commits
745b8efb8f
...
daca502ce0
Author | SHA1 | Date | |
---|---|---|---|
daca502ce0 | |||
b5ebe0d4ad |
@ -0,0 +1,52 @@
|
||||
const CD_SECTOR_SIZE: usize = 2048;
|
||||
|
||||
|
||||
const ATA_BUS_PRIMARY: u16= 0x1f0;
|
||||
const ATA_BUS_SECONDARY: u16 = 0x170;
|
||||
|
||||
const ATA_DRIVE_MASTER: u16 = 0xa0;
|
||||
const ATA_DRIVE_SLAVE: u16 = 0xb0;
|
||||
|
||||
macro_rules! ATA_DATA {
|
||||
($reg:expr) => (reg);
|
||||
}
|
||||
|
||||
macro_rules! ATA_ERROR {
|
||||
($reg:expr) => (reg + 1); // read
|
||||
}
|
||||
|
||||
macro_rules! ATA_FEATURES {
|
||||
($reg:expr) => (reg + 1); // write
|
||||
}
|
||||
|
||||
macro_rules! ATA_SECTOR_COUNT {
|
||||
($reg:expr) => (reg + 2);
|
||||
}
|
||||
|
||||
macro_rules! ATA_ADDRESS1 {
|
||||
($reg:expr) => (reg + 3);
|
||||
}
|
||||
|
||||
macro_rules! ATA_ADDRESS2 {
|
||||
($reg:expr) => (reg + 4);
|
||||
}
|
||||
|
||||
macro_rules! ATA_ADDRESS3 {
|
||||
($reg:expr) => (reg + 5);
|
||||
}
|
||||
|
||||
macro_rules! ATA_DRIVE_SELECT {
|
||||
($reg:expr) => (reg + 6);
|
||||
}
|
||||
|
||||
macro_rules! ATA_STATUS {
|
||||
($reg:expr) => (reg + 7); // read
|
||||
}
|
||||
|
||||
macro_rules! ATA_COMMAND {
|
||||
($reg:expr) => (reg + 7); // write
|
||||
}
|
||||
|
||||
macro_rules! ATA_DCR {
|
||||
($reg:expr) => (reg + 0x206);
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
pub mod serial;
|
||||
pub mod vga;
|
||||
pub mod atapi;
|
||||
|
@ -1,11 +1,11 @@
|
||||
use crate::memory::gdt;
|
||||
use crate::hlt_loop;
|
||||
use crate::drivers::vga::{self, Color, ColorCode};
|
||||
use crate::{println};
|
||||
use crate::hlt_loop;
|
||||
use crate::memory::gdt;
|
||||
use crate::println;
|
||||
use lazy_static::lazy_static;
|
||||
use pic::{init_pic, keyboard_interrupt_handler, timer_interrupt_handler, InterruptIndex};
|
||||
use x86_64::structures::idt::PageFaultErrorCode;
|
||||
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
||||
use pic::{InterruptIndex, init_pic, keyboard_interrupt_handler, timer_interrupt_handler};
|
||||
|
||||
pub mod pic;
|
||||
|
||||
@ -64,5 +64,3 @@ extern "x86-interrupt" fn double_fault_handler(
|
||||
) -> ! {
|
||||
panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::{PICS, InterruptIndex};
|
||||
use super::{InterruptIndex, PICS};
|
||||
|
||||
use x86_64::instructions::port::Port;
|
||||
use x86_64::structures::idt::{InterruptStackFrame};
|
||||
use x86_64::structures::idt::InterruptStackFrame;
|
||||
|
||||
pub const PS2_CONTROLLER_PORT: u16 = 0x60;
|
||||
|
||||
|
@ -1,15 +1,14 @@
|
||||
use pic8259::ChainedPics;
|
||||
use crate::{println};
|
||||
pub use pit::{timer_interrupt_handler};
|
||||
use crate::println;
|
||||
pub use keyboard::keyboard_interrupt_handler;
|
||||
use pic8259::ChainedPics;
|
||||
pub use pit::timer_interrupt_handler;
|
||||
|
||||
pub mod pit;
|
||||
pub mod keyboard;
|
||||
pub mod pit;
|
||||
|
||||
pub const PIC_1_OFFSET: u8 = 32;
|
||||
pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8;
|
||||
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
pub enum InterruptIndex {
|
||||
@ -34,5 +33,3 @@ pub fn init_pic() {
|
||||
println!("Initializing PIC");
|
||||
unsafe { PICS.lock().initialize() };
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
use super::{PICS, InterruptIndex};
|
||||
use super::{InterruptIndex, PICS};
|
||||
use x86_64::structures::idt::InterruptStackFrame;
|
||||
|
||||
static mut TICKS: u64 = 0;
|
||||
|
||||
pub fn gettick() -> u64 {
|
||||
unsafe { return TICKS }
|
||||
|
||||
}
|
||||
|
||||
pub extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: InterruptStackFrame) {
|
||||
|
@ -3,9 +3,9 @@
|
||||
#![feature(abi_x86_interrupt)]
|
||||
#![feature(alloc_error_handler)]
|
||||
|
||||
mod drivers;
|
||||
mod interrupts;
|
||||
mod memory;
|
||||
mod drivers;
|
||||
mod task;
|
||||
|
||||
//#[macro_use]
|
||||
@ -13,9 +13,9 @@ extern crate alloc;
|
||||
extern crate multiboot2;
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
use multiboot2::BootInformation;
|
||||
use drivers::vga::{self, Color, ColorCode};
|
||||
use task::{executor::Executor, Task, keyboard};
|
||||
use multiboot2::BootInformation;
|
||||
use task::{executor::Executor, keyboard, Task};
|
||||
|
||||
#[alloc_error_handler]
|
||||
fn alloc_error_handler(layout: alloc::alloc::Layout) -> ! {
|
||||
@ -35,8 +35,7 @@ pub fn hlt_loop() -> ! {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(boot_info: &BootInformation)
|
||||
{
|
||||
pub fn init(boot_info: &BootInformation) {
|
||||
vga::change_color(ColorCode::new(Color::LightCyan, Color::Black));
|
||||
println!("Starting init");
|
||||
memory::init(boot_info);
|
||||
|
@ -1,16 +1,16 @@
|
||||
pub use self::frame_allocator::AreaFrameAllocator;
|
||||
pub use paging::kernel_remap;
|
||||
use crate::println;
|
||||
use heap_alloc::{ALLOCATOR, HEAP_SIZE, HEAP_START};
|
||||
use multiboot2::BootInformation;
|
||||
use paging::{Size4KiB, RecursivePageTable, FrameAllocator, Page, Flags, Mapper};
|
||||
use heap_alloc::{HEAP_START, HEAP_SIZE, ALLOCATOR};
|
||||
use x86_64::VirtAddr;
|
||||
pub use paging::kernel_remap;
|
||||
use paging::{Flags, FrameAllocator, Mapper, Page, RecursivePageTable, Size4KiB};
|
||||
use x86_64::structures::paging::{mapper::MapToError, page::PageRangeInclusive};
|
||||
use x86_64::VirtAddr;
|
||||
|
||||
pub mod frame_allocator;
|
||||
pub mod paging;
|
||||
pub mod heap_alloc;
|
||||
pub mod gdt;
|
||||
pub mod heap_alloc;
|
||||
pub mod paging;
|
||||
|
||||
pub const PAGE_SIZE: usize = 4096;
|
||||
|
||||
@ -19,13 +19,15 @@ pub fn init(boot_info: &BootInformation) {
|
||||
enable_write_protect_bit();
|
||||
let mut frame_allocator = get_frame_allocator(boot_info.start_address());
|
||||
let mut active_table = kernel_remap(&mut frame_allocator, boot_info);
|
||||
init_heap(&mut active_table, &mut frame_allocator)
|
||||
.expect("Heap initialization failed");
|
||||
init_heap(&mut active_table, &mut frame_allocator).expect("Heap initialization failed");
|
||||
}
|
||||
|
||||
fn init_heap<A>(active_table: &mut RecursivePageTable, frame_allocator: &mut A)
|
||||
-> Result<(), MapToError<Size4KiB>>
|
||||
where A: FrameAllocator<Size4KiB>
|
||||
fn init_heap<A>(
|
||||
active_table: &mut RecursivePageTable,
|
||||
frame_allocator: &mut A,
|
||||
) -> Result<(), MapToError<Size4KiB>>
|
||||
where
|
||||
A: FrameAllocator<Size4KiB>,
|
||||
{
|
||||
let page_range: PageRangeInclusive<Size4KiB> = {
|
||||
let heap_start = VirtAddr::new(HEAP_START);
|
||||
@ -41,12 +43,16 @@ fn init_heap<A>(active_table: &mut RecursivePageTable, frame_allocator: &mut A)
|
||||
.ok_or(MapToError::FrameAllocationFailed)?;
|
||||
let flags = Flags::PRESENT | Flags::WRITABLE;
|
||||
unsafe {
|
||||
active_table.map_to(page, frame, flags, frame_allocator)?.flush();
|
||||
active_table
|
||||
.map_to(page, frame, flags, frame_allocator)?
|
||||
.flush();
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
ALLOCATOR.lock().init(HEAP_START as usize, HEAP_SIZE as usize);
|
||||
ALLOCATOR
|
||||
.lock()
|
||||
.init(HEAP_START as usize, HEAP_SIZE as usize);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -13,7 +13,6 @@ mod temporary_page;
|
||||
|
||||
pub const P4: *mut PageTable = 0o177777_777_777_777_777_0000 as *mut _;
|
||||
|
||||
|
||||
fn get_flags_from_elf_section(section: &ElfSection) -> Flags {
|
||||
use multiboot2::{ELF_SECTION_ALLOCATED, ELF_SECTION_EXECUTABLE, ELF_SECTION_WRITABLE};
|
||||
|
||||
@ -32,8 +31,9 @@ fn get_flags_from_elf_section(section: &ElfSection) -> Flags {
|
||||
flags
|
||||
}
|
||||
|
||||
pub fn kernel_remap<'a, A>(allocator: &mut A, boot_info: & BootInformation) -> RecursivePageTable<'a>
|
||||
where A: FrameAllocator<Size4KiB>,
|
||||
pub fn kernel_remap<'a, A>(allocator: &mut A, boot_info: &BootInformation) -> RecursivePageTable<'a>
|
||||
where
|
||||
A: FrameAllocator<Size4KiB>,
|
||||
{
|
||||
println!("Remapping kernel");
|
||||
let mut temporary_page = TemporaryPage::new(
|
||||
@ -107,7 +107,11 @@ pub fn kernel_remap<'a, A>(allocator: &mut A, boot_info: & BootInformation) -> R
|
||||
let old_p4_page = Page::<Size4KiB>::containing_address(VirtAddr::new(
|
||||
old_table.p4_frame.start_address().as_u64(),
|
||||
));
|
||||
active_table.unmap(old_p4_page).expect("Failed to unmap old P4").1.flush();
|
||||
active_table
|
||||
.unmap(old_p4_page)
|
||||
.expect("Failed to unmap old P4")
|
||||
.1
|
||||
.flush();
|
||||
println!("Stack guard page at {:#x}", old_p4_page.start_address());
|
||||
active_table
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use crossbeam_queue::ArrayQueue;
|
||||
pub struct Executor {
|
||||
tasks: BTreeMap<TaskId, Task>,
|
||||
task_queue: Arc<ArrayQueue<TaskId>>,
|
||||
waker_cache: BTreeMap<TaskId, Waker>
|
||||
waker_cache: BTreeMap<TaskId, Waker>,
|
||||
}
|
||||
|
||||
impl Executor {
|
||||
@ -14,7 +14,7 @@ impl Executor {
|
||||
Executor {
|
||||
tasks: BTreeMap::new(),
|
||||
task_queue: Arc::new(ArrayQueue::new(100)),
|
||||
waker_cache: BTreeMap::new()
|
||||
waker_cache: BTreeMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ impl Executor {
|
||||
let Self {
|
||||
tasks,
|
||||
task_queue,
|
||||
waker_cache
|
||||
waker_cache,
|
||||
} = self; // Executor destructuring
|
||||
|
||||
while let Ok(task_id) = task_queue.pop() {
|
||||
@ -74,14 +74,14 @@ impl Executor {
|
||||
|
||||
struct TaskWaker {
|
||||
task_id: TaskId,
|
||||
task_queue: Arc<ArrayQueue<TaskId>>
|
||||
task_queue: Arc<ArrayQueue<TaskId>>,
|
||||
}
|
||||
|
||||
impl TaskWaker {
|
||||
fn new(task_id: TaskId, task_queue: Arc<ArrayQueue<TaskId>>) -> Waker {
|
||||
Waker::from(Arc::new(TaskWaker {
|
||||
task_id,
|
||||
task_queue
|
||||
task_queue,
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,13 @@
|
||||
use crate::{println, print};
|
||||
use crate::{print, println};
|
||||
|
||||
use conquer_once::spin::OnceCell;
|
||||
use core::{pin::Pin, task::{Context, Poll}};
|
||||
use core::{
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use crossbeam_queue::ArrayQueue;
|
||||
use futures_util::task::AtomicWaker;
|
||||
use futures_util::stream::{Stream, StreamExt};
|
||||
use futures_util::task::AtomicWaker;
|
||||
use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1};
|
||||
|
||||
static SCANCODE_QUEUE: OnceCell<ArrayQueue<u8>> = OnceCell::uninit();
|
||||
@ -18,7 +21,8 @@ pub struct ScancodeStream {
|
||||
|
||||
impl ScancodeStream {
|
||||
pub fn new() -> Self {
|
||||
SCANCODE_QUEUE.try_init_once(|| ArrayQueue::new(100))
|
||||
SCANCODE_QUEUE
|
||||
.try_init_once(|| ArrayQueue::new(100))
|
||||
.expect("ScancodeStream::new should only be called once");
|
||||
ScancodeStream { _private: () }
|
||||
}
|
||||
@ -42,8 +46,8 @@ impl Stream for ScancodeStream {
|
||||
Ok(scancode) => {
|
||||
WAKER.take();
|
||||
Poll::Ready(Some(scancode))
|
||||
},
|
||||
Err(crossbeam_queue::PopError) => Poll::Pending
|
||||
}
|
||||
Err(crossbeam_queue::PopError) => Poll::Pending,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -52,12 +56,10 @@ pub(crate) fn add_scancode(scancode: u8) {
|
||||
if let Ok(queue) = SCANCODE_QUEUE.try_get() {
|
||||
if let Err(_) = queue.push(scancode) {
|
||||
println!("Keyboard scancode queue full, dropping input {}", scancode);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
WAKER.wake();
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println!("Keyboard scancode queue uninitialized");
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
use alloc::boxed::Box;
|
||||
use core::future::Future;
|
||||
use core::pin::Pin;
|
||||
use core::sync::atomic::{AtomicU64, Ordering};
|
||||
use core::task::{Context, Poll};
|
||||
use alloc::boxed::Box;
|
||||
|
||||
pub mod executor;
|
||||
pub mod keyboard;
|
||||
@ -19,14 +19,14 @@ impl TaskId {
|
||||
|
||||
pub struct Task {
|
||||
id: TaskId,
|
||||
future: Pin<Box<dyn Future<Output = ()>>>
|
||||
future: Pin<Box<dyn Future<Output = ()>>>,
|
||||
}
|
||||
|
||||
impl Task {
|
||||
pub fn new(future: impl Future<Output = ()> + 'static) -> Task {
|
||||
Task {
|
||||
id: TaskId::new(),
|
||||
future: Box::pin(future)
|
||||
future: Box::pin(future),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user