Compare commits

..

2 Commits

Author SHA1 Message Date
08b2d22662
This will be the end of me 2024-09-02 20:55:25 +03:00
12e9a068e9
clippy stuff 2024-09-02 17:51:10 +03:00
27 changed files with 338 additions and 171 deletions

86
Cargo.lock generated
View File

@ -20,6 +20,15 @@ version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
[[package]]
name = "approx"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6"
dependencies = [
"num-traits",
]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.3.0" version = "1.3.0"
@ -111,11 +120,13 @@ name = "kernel"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bitflags 2.5.0", "bitflags 2.5.0",
"cfg-if",
"crossbeam", "crossbeam",
"hashbrown", "hashbrown",
"lazy_static", "lazy_static",
"log", "log",
"multiboot2", "multiboot2",
"nalgebra",
"once", "once",
"pc-keyboard", "pc-keyboard",
"pic8259", "pic8259",
@ -164,6 +175,57 @@ dependencies = [
"uefi-raw", "uefi-raw",
] ]
[[package]]
name = "nalgebra"
version = "0.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c4b5f057b303842cf3262c27e465f4c303572e7f6b0648f60e16248ac3397f4"
dependencies = [
"approx",
"num-complex",
"num-rational",
"num-traits",
"simba",
"typenum",
]
[[package]]
name = "num-complex"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
dependencies = [
"num-traits",
]
[[package]]
name = "num-integer"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
dependencies = [
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "once" name = "once"
version = "0.3.4" version = "0.3.4"
@ -176,6 +238,12 @@ version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]] [[package]]
name = "pc-keyboard" name = "pc-keyboard"
version = "0.7.0" version = "0.7.0"
@ -250,6 +318,18 @@ 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 = "simba"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa"
dependencies = [
"approx",
"num-complex",
"num-traits",
"paste",
]
[[package]] [[package]]
name = "spin" name = "spin"
version = "0.5.2" version = "0.5.2"
@ -296,6 +376,12 @@ dependencies = [
"lock_api", "lock_api",
] ]
[[package]]
name = "typenum"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]] [[package]]
name = "uart_16550" name = "uart_16550"
version = "0.3.0" version = "0.3.0"

View File

@ -5,3 +5,8 @@ members = [
exclude = ["boot"] exclude = ["boot"]
resolver = "2" resolver = "2"
[profile.release]
strip = false

View File

@ -1,3 +1,10 @@
%define VIDEO_MODE 1
section .data
global __VIDEO_MODE
__VIDEO_MODE: db VIDEO_MODE
section .multiboot_header section .multiboot_header
header_start: header_start:
dd 0xe85250d6 ; magic number (multiboot 2) dd 0xe85250d6 ; magic number (multiboot 2)
@ -8,7 +15,17 @@ header_start:
; insert optional multiboot tags here ; insert optional multiboot tags here
; required end tag %if VIDEO_MODE
dw 5 ; type
dw 1 ; flags
dd 20 ; size
dd 0 ; width
dd 0 ; height
dd 24 ; depth
; grub 2 expects 8 byte alignment
dw 0 ; padding
dw 0 ; padding
%endif
dw 0 ; type dw 0 ; type
dw 0 ; flags dw 0 ; flags
dd 8 ; size dd 8 ; size

View File

@ -2,6 +2,9 @@ BUILD_DIR="./target"
BIN="$BUILD_DIR/poppin.bin" BIN="$BUILD_DIR/poppin.bin"
ISO="$BUILD_DIR/poppin.iso" ISO="$BUILD_DIR/poppin.iso"
# config
VIDEO_MODE=true;
set -e set -e
function cmd_exists() { function cmd_exists() {

View File

@ -2,7 +2,6 @@
name = "kernel" name = "kernel"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
test=false
[lib] [lib]
name="kernel" name="kernel"
@ -10,16 +9,15 @@ test=false
crate-type=["staticlib"] crate-type=["staticlib"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[profile.release]
strip = false
[dependencies] [dependencies]
bitflags = "2.5.0" bitflags = "2.5.0"
cfg-if = "1.0.0"
crossbeam = { version = "0.8.4", default-features = false, features = ["alloc"] } crossbeam = { version = "0.8.4", default-features = false, features = ["alloc"] }
hashbrown = "0.14.5" hashbrown = "0.14.5"
lazy_static = { version = "1.4.0", features = ["spin_no_std"] } lazy_static = { version = "1.4.0", features = ["spin_no_std"] }
log = "0.4.21" log = "0.4.21"
multiboot2 = "0.20.2" multiboot2 = "0.20.2"
nalgebra = { version = "0.33.0", default-features = false }
once = "0.3.4" once = "0.3.4"
pc-keyboard = "0.7.0" pc-keyboard = "0.7.0"
pic8259 = "0.11.0" pic8259 = "0.11.0"

View File

@ -37,12 +37,10 @@ impl EventManager {
} }
pub fn dispatch(&self, ev: &Event){ pub fn dispatch(&self, ev: &Event){
for listener in &self.listeners { for listener in self.listeners.iter().flatten() {
if let Some(l) = listener { if discriminant(ev) == discriminant(&listener.typ) {
if discriminant(ev) == discriminant(&l.typ) { // TODO: Do something with the result
// TODO: Do something with the result let _ = (listener.func)(ev);
let _ = (l.func)(ev);
}
} }
} }
} }

View File

@ -21,14 +21,12 @@ lazy_static! {
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
let stack_start = VirtAddr::from_ptr(unsafe { addr_of!(STACK) }); let stack_start = VirtAddr::from_ptr(unsafe { addr_of!(STACK) });
let stack_end = stack_start + STACK_SIZE as u64; stack_start + STACK_SIZE as u64
stack_end
}; };
tss.privilege_stack_table[0] = { tss.privilege_stack_table[0] = {
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
let stack_start = VirtAddr::from_ptr(unsafe { addr_of!(PRIV_TSS_STACK) }); let stack_start = VirtAddr::from_ptr(unsafe { addr_of!(PRIV_TSS_STACK) });
let stack_end = stack_start + STACK_SIZE as u64; stack_start + STACK_SIZE as u64
stack_end
}; };
tss tss
}; };

View File

@ -1,5 +1,5 @@
use x86_64::structures::idt::{InterruptStackFrame, PageFaultErrorCode}; use x86_64::structures::idt::{InterruptStackFrame, PageFaultErrorCode};
use crate::{events::EVENTMAN, interrupts::InterruptIndex}; use crate::interrupts::InterruptIndex;
mod ps2_keyboard; mod ps2_keyboard;

View File

@ -1,14 +1,10 @@
use hashbrown::HashSet;
use pc_keyboard::{DecodedKey, KeyState};
use spin::Mutex;
use x86_64::structures::idt::InterruptStackFrame; use x86_64::structures::idt::InterruptStackFrame;
use crate::{events::EVENTMAN, interrupts::PICS}; use crate::{events::EVENTMAN, interrupts::PICS};
pub struct Ps2KbPressEvent(DecodedKey);
pub extern "x86-interrupt" fn ps2_kb_int(_sf: InterruptStackFrame){ pub extern "x86-interrupt" fn ps2_kb_int(_sf: InterruptStackFrame){
use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1}; use pc_keyboard::{layouts, HandleControl, Keyboard, ScancodeSet1};
use spin::Mutex; use spin::Mutex;
use x86_64::instructions::port::Port; use x86_64::instructions::port::Port;

View File

@ -6,13 +6,12 @@
#![feature(ptr_internals)] #![feature(ptr_internals)]
#![feature(allocator_api)] #![feature(allocator_api)]
use core::ptr::addr_of; use std::vga::video::Color;
use alloc::vec::Vec; use mem::paging::ActivePageTable;
use pc_keyboard::{DecodedKey, KeyCode}; use multiboot2::{BootInformation, BootInformationHeader};
use x86_64::instructions::nop; use pc_keyboard::KeyCode;
use crate::{gdt::PRIV_TSS_STACK, scheduler::{executor::Executor, Task}, utils::jmp_to_usermode};
extern crate alloc; extern crate alloc;
@ -27,50 +26,24 @@ mod mem;
mod scheduler; mod scheduler;
mod std; mod std;
fn init(mb2p: *const BootInformationHeader) -> ActivePageTable {
#[no_mangle]
extern "C" fn kmain(mb2_info_addr: usize) -> ! {
// Init
logger::init(log::LevelFilter::Trace).unwrap(); logger::init(log::LevelFilter::Trace).unwrap();
gdt::init(); gdt::init();
interrupts::init_idt(); interrupts::init_idt();
utils::enable_nxe_bit(); utils::enable_nxe_bit();
utils::enable_write_protect_bit(); utils::enable_write_protect_bit();
std::init(); std::init();
mem::init(mb2p)
}
#[no_mangle]
extern "C" fn kmain(mb2p: *const BootInformationHeader) -> ! {
let _ = init(mb2p); // active table
let active_table = mem::init(mb2_info_addr); let vc = std::vga::video::VideoControler::new(mb2p);
// vc.set_px(0, 0, Color::new(0xFF, 0xFF, 0x0));
//unsafe { // vc.fill_screen(Color::new(0xFF, 0x0, 0x0));
// jmp_to_usermode(active_table, usermode_code as *const () as usize, addr_of!(PRIV_TSS_STACK) as *const () as usize);
//}
//let mut executor = Executor::new();
//executor.spawn(Task::new(usermode_code()));
//executor.run();
//let mut a = Vec::new();
//a.push(6);
//a.push(9);
//a.push(4);
//a.push(2);
//a.push(0);
//log::error!("{:?}", a);
// EVENTMAN.lock().add_listener(events::Event::Ps2KeyPress(None), |k| {
// let Event::Ps2KeyPress(v) = k else {panic!()};
//
// log::debug!("Keypress event received! ({:?})", v.unwrap());
// Ok(())
// });
// let (level_4_page_table, _) = Cr3::read();
// println!("Level 4 page table at: {:?}", level_4_page_table.start_address());
log::info!("end of work"); log::info!("end of work");
loop { loop {
if std::input::is_key_down(KeyCode::A) { if std::input::is_key_down(KeyCode::A) {
@ -88,6 +61,3 @@ fn panic(pi: &core::panic::PanicInfo) -> ! {
} }
async fn usermode_code() {
log::info!("Hello from usermode!");
}

View File

@ -1,12 +1,9 @@
use core::fmt::Write;
use log::{Level, LevelFilter, Metadata, Record, SetLoggerError}; use log::{Level, LevelFilter, Metadata, Record, SetLoggerError};
use crate::logger::serial::{write_com, ANSI_COLORS, COM0}; use crate::logger::serial::{write_com, ANSI_COLORS, COM0};
use crate::std::vga::text::{Color, ColorCode, WRITER};
use self::vga::{Color, ColorCode, WRITER};
#[macro_use]
pub mod vga;
pub mod serial; pub mod serial;
#[macro_use] #[macro_use]
pub mod macros; pub mod macros;
@ -16,7 +13,6 @@ pub static LOGGER: KLogger = KLogger;
pub struct KLogger; pub struct KLogger;
const C_TRACE: ColorCode = ColorCode::new(Color::Cyan, Color::Black); const C_TRACE: ColorCode = ColorCode::new(Color::Cyan, Color::Black);
const C_DEBUG: ColorCode = ColorCode::new(Color::Blue, Color::Black); const C_DEBUG: ColorCode = ColorCode::new(Color::Blue, Color::Black);
const C_INFO: ColorCode = ColorCode::new(Color::Green, Color::Black); const C_INFO: ColorCode = ColorCode::new(Color::Green, Color::Black);
@ -32,51 +28,77 @@ impl log::Log for KLogger {
fn log(&self, record: &Record) { fn log(&self, record: &Record) {
if self.enabled(record.metadata()) { if self.enabled(record.metadata()) {
{WRITER.lock().set_color(Color::Magenta, Color::Black); } if !crate::std::vga::video::is_video_mode_enabled() {
print!("["); self.log_vga(record).unwrap();
write_com(&COM0, format_args!("{}[", ANSI_COLORS::MAGENTA));
match record.level() {
Level::Trace => {
{WRITER.lock().set_color_code(C_TRACE); }
print!("TRACE");
write_com(&COM0, format_args!("{}TRACE", ANSI_COLORS::BLUE2));
}
Level::Debug => {
{WRITER.lock().set_color_code(C_DEBUG); }
print!("DEBUG");
write_com(&COM0, format_args!("{}DEBUG", ANSI_COLORS::BLUE));
}
Level::Info => {
{WRITER.lock().set_color_code(C_INFO); }
print!("INFO");
write_com(&COM0, format_args!("{}INFO", ANSI_COLORS::GREEN));
}
Level::Warn => {
{WRITER.lock().set_color_code(C_WARN); }
print!("WARN");
write_com(&COM0, format_args!("{}WARN", ANSI_COLORS::YELLOW));
}
Level::Error => {
{WRITER.lock().set_color_code(C_ERROR); }
print!("ERROR");
write_com(&COM0, format_args!("{}ERROR", ANSI_COLORS::RED));
}
} }
{WRITER.lock().set_color(Color::Magenta, Color::Black); } self.log_serial(record)
print!("]");
{WRITER.lock().set_color_code(C_NORMAL); }
write_com(&COM0, format_args!("{}]", ANSI_COLORS::MAGENTA));
println!(" {}: {}", record.module_path().unwrap_or(""), record.args());
write_com(&COM0, format_args!(" {}{}: {}\n", ANSI_COLORS::RESET, record.module_path().unwrap_or(""), record.args()));
} }
} }
fn flush(&self) {} fn flush(&self) {}
} }
impl KLogger {
fn log_vga(&self, record: &Record) -> core::fmt::Result {
let mut f = WRITER.lock();
f.set_color(Color::Magenta, Color::Black);
write!(f, "[")?;
match record.level() {
Level::Trace => {
f.set_color_code(C_TRACE);
write!(f, "TRACE")?;
}
Level::Debug => {
f.set_color_code(C_DEBUG);
write!(f, "DEBUG")?;
}
Level::Info => {
f.set_color_code(C_INFO);
write!(f, "INFO")?;
}
Level::Warn => {
f.set_color_code(C_WARN);
write!(f, "WARN")?;
}
Level::Error => {
f.set_color_code(C_ERROR);
write!(f, "ERROR")?;
}
}
f.set_color(Color::Magenta, Color::Black);
write!(f, "]")?;
f.set_color_code(C_NORMAL);
writeln!(f, " {}: {}", record.module_path().unwrap_or(""), record.args())?;
Ok(())
}
fn log_serial(&self, record: &Record) {
{WRITER.lock().set_color(Color::Magenta, Color::Black); }
write_com(&COM0, format_args!("{}[", ANSI_COLORS::MAGENTA));
match record.level() {
Level::Trace => {
write_com(&COM0, format_args!("{}TRACE", ANSI_COLORS::BLUE2));
}
Level::Debug => {
write_com(&COM0, format_args!("{}DEBUG", ANSI_COLORS::BLUE));
}
Level::Info => {
write_com(&COM0, format_args!("{}INFO", ANSI_COLORS::GREEN));
}
Level::Warn => {
write_com(&COM0, format_args!("{}WARN", ANSI_COLORS::YELLOW));
}
Level::Error => {
write_com(&COM0, format_args!("{}ERROR", ANSI_COLORS::RED));
}
}
write_com(&COM0, format_args!("{}]", ANSI_COLORS::MAGENTA));
write_com(&COM0, format_args!(" {}{}: {}\n", ANSI_COLORS::RESET, record.module_path().unwrap_or(""), record.args()));
}
}
pub fn init(lvl: LevelFilter) -> Result<(), SetLoggerError> { pub fn init(lvl: LevelFilter) -> Result<(), SetLoggerError> {
log::set_logger(&LOGGER)?; log::set_logger(&LOGGER)?;
log::set_max_level(lvl); log::set_max_level(lvl);

View File

@ -1,30 +0,0 @@
use core::fmt;
use x86_64::instructions::interrupts;
use crate::logger::vga::Writer;
impl fmt::Write for Writer {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.write_string(s);
Ok(())
}
}
#[macro_export]
macro_rules! print {
($($arg:tt)*) => ($crate::logger::vga::macros::_print(format_args!($($arg)*)));
}
#[macro_export]
macro_rules! println {
() => ($crate::print!("\n"));
($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*)));
}
#[doc(hidden)]
pub fn _print(args: fmt::Arguments) {
use core::fmt::Write;
interrupts::without_interrupts(|| {
crate::logger::vga::WRITER.lock().write_fmt(args).unwrap();
});
}

View File

@ -2,7 +2,7 @@
//use x86_64::align_up; //use x86_64::align_up;
pub const HEAP_START: usize = 0o_000_001_000_000_0000; // 0x40000000 - 0x40019000 pub const HEAP_START: usize = 0x40000000; // 0x40000000 - 0x40019000
pub const HEAP_SIZE: usize = 100 * 1024; // 100 KiB pub const HEAP_SIZE: usize = 100 * 1024; // 100 KiB
// A simple allocator that allocates memory linearly and ignores freed memory. // A simple allocator that allocates memory linearly and ignores freed memory.

View File

@ -20,7 +20,9 @@ static GLOBAL_ALLOCATOR: Talck<spin::Mutex<()>, ErrOnOom> = Talc::new(ErrOnOom).
pub struct DummyAlloc; pub struct DummyAlloc;
unsafe impl GlobalAlloc for DummyAlloc { unsafe impl GlobalAlloc for DummyAlloc {
unsafe fn alloc(&self, _: Layout) -> *mut u8 { 0 as *mut u8 } unsafe fn alloc(&self, _: Layout) -> *mut u8 {
core::ptr::null_mut::<u8>()
}
unsafe fn dealloc(&self, _ptr: *mut u8, _: Layout) {} unsafe fn dealloc(&self, _ptr: *mut u8, _: Layout) {}
} }
@ -122,12 +124,14 @@ pub struct MemInfo<'a>{
pub kernel_end: usize, pub kernel_end: usize,
pub mb_start: usize, pub mb_start: usize,
pub mb_end: usize, pub mb_end: usize,
pub vga_vide_start: usize,
pub vga_vide_size: usize,
} }
impl MemInfo<'_> { impl MemInfo<'_> {
pub fn load(mb_ptr: usize) -> Self { pub fn load(mb_ptr: *const BootInformationHeader) -> Self {
let boot_info = unsafe { let boot_info = unsafe {
multiboot2::BootInformation::load(mb_ptr as *const BootInformationHeader).unwrap() multiboot2::BootInformation::load(mb_ptr).unwrap()
}; };
let mmap_tag = boot_info.memory_map_tag().unwrap(); let mmap_tag = boot_info.memory_map_tag().unwrap();
@ -146,22 +150,27 @@ impl MemInfo<'_> {
let kernel_end = elf_secs.clone().filter(|s| s.is_allocated()).map(|s| s.end_address()).min().unwrap() as usize; let kernel_end = elf_secs.clone().filter(|s| s.is_allocated()).map(|s| s.end_address()).min().unwrap() as usize;
let mb_start = boot_info.start_address(); let mb_start = boot_info.start_address();
let mb_end = boot_info.end_address(); let mb_end = boot_info.end_address();
let vv_info = boot_info.framebuffer_tag().unwrap().unwrap();
let vv_start = vv_info.address();
let vv_size = vv_info.width() * vv_info.height();
//log::debug!("Kernel: start: 0x{:x} sz: 0x{:x}", mi.kernel_start, mi.kernel_end - mi.kernel_start); //log::debug!("Kernel: start: 0x{:x} sz: 0x{:x}", mi.kernel_start, mi.kernel_end - mi.kernel_start);
//log::debug!("Multiboot: start: 0x{:x} sz: 0x{:x}", mi.mb_start, mi.mb_end - mi.mb_start); //log::debug!("Multiboot: start: 0x{:x} sz: 0x{:x}", mi.mb_start, mi.mb_end - mi.mb_start);
Self { Self {
boot_info:unsafe { multiboot2::BootInformation::load(mb_ptr as *const BootInformationHeader).unwrap()}, boot_info: unsafe { multiboot2::BootInformation::load(mb_ptr).unwrap()},
mem_area_iter: MemoryAreaIter::new(mmap_tag), mem_area_iter: MemoryAreaIter::new(mmap_tag),
kernel_start, kernel_start,
kernel_end, kernel_end,
mb_start, mb_start,
mb_end, mb_end,
vga_vide_start: vv_start as usize,
vga_vide_size: vv_size as usize
} }
} }
} }
pub fn init(mb_ptr: usize) -> paging::ActivePageTable { pub fn init(mb_ptr: *const BootInformationHeader) -> paging::ActivePageTable {
once::assert_has_not_been_called!("mem::init must be called only once"); once::assert_has_not_been_called!("mem::init must be called only once");
let mem_info = MemInfo::load(mb_ptr); let mem_info = MemInfo::load(mb_ptr);
let mut frame_alloc = area_frame_alloc::AreaFrameAllocator::new(&mem_info); let mut frame_alloc = area_frame_alloc::AreaFrameAllocator::new(&mem_info);

View File

@ -28,13 +28,13 @@ impl EntryFlags {
if section.flags().contains(ElfSectionFlags::ALLOCATED) { if section.flags().contains(ElfSectionFlags::ALLOCATED) {
// section is loaded to memory // section is loaded to memory
flags = flags | EntryFlags::PRESENT; flags |= EntryFlags::PRESENT;
} }
if section.flags().contains(ElfSectionFlags::WRITABLE) { if section.flags().contains(ElfSectionFlags::WRITABLE) {
flags = flags | EntryFlags::WRITABLE; flags |= EntryFlags::WRITABLE;
} }
if !section.flags().contains(ElfSectionFlags::EXECUTABLE) { if !section.flags().contains(ElfSectionFlags::EXECUTABLE) {
flags = flags | EntryFlags::NO_EXECUTE; flags |= EntryFlags::NO_EXECUTE;
} }
flags flags

View File

@ -7,7 +7,7 @@ use super::{
Frame, FrameAllocator, Frame, FrameAllocator,
PAGE_SIZE, PhysicalAddress, PAGE_SIZE, PhysicalAddress,
VirtualAddress, Page, VirtualAddress, Page,
ENTRY_COUNT, InactivePageTable ENTRY_COUNT,
}; };
use core::ptr::Unique; use core::ptr::Unique;

View File

@ -1,3 +1,4 @@
#![allow(unexpected_cfgs)]
use core::ops::{Deref, DerefMut}; use core::ops::{Deref, DerefMut};
use self::{entry::*, mapper::Mapper, temporary::TemporaryPage}; use self::{entry::*, mapper::Mapper, temporary::TemporaryPage};
use super::{Frame, FrameAllocator, MemInfo, PAGE_SIZE}; use super::{Frame, FrameAllocator, MemInfo, PAGE_SIZE};
@ -119,8 +120,8 @@ impl InactivePageTable {
impl Page { impl Page {
pub fn containing_address(address: VirtualAddress) -> Page { pub fn containing_address(address: VirtualAddress) -> Page {
assert!(address < 0x0000_8000_0000_0000 || assert!(
address >= 0xffff_8000_0000_0000, !(0x0000_8000_0000_0000..0xffff_8000_0000_0000).contains(&address),
"invalid address: 0x{:x}", address); "invalid address: 0x{:x}", address);
Page { number: address / PAGE_SIZE } Page { number: address / PAGE_SIZE }
} }
@ -137,7 +138,7 @@ impl Page {
(self.number >> 9) & 0o777 (self.number >> 9) & 0o777
} }
fn p1_index(&self) -> usize { fn p1_index(&self) -> usize {
(self.number >> 0) & 0o777 self.number & 0o777
} }
pub fn range_inclusive(start: Page, end: Page) -> PageIter { pub fn range_inclusive(start: Page, end: Page) -> PageIter {
PageIter { PageIter {
@ -204,8 +205,13 @@ pub fn remap_the_kernel<A>(allocator: &mut A, mem_info: &MemInfo) -> ActivePageT
mapper.identity_map(frame, flags, allocator); mapper.identity_map(frame, flags, allocator);
} }
} }
let vga_buffer_frame = Frame::containing_address(0xb8000); let vga_text_buffer_frame = Frame::containing_address(0xb8000);
mapper.identity_map(vga_buffer_frame, EntryFlags::WRITABLE, allocator); let vga_video_buffer_frame_start = Frame::containing_address(mem_info.vga_vide_start);
let vga_video_buffer_frame_end = Frame::containing_address((mem_info.vga_vide_start + mem_info.vga_vide_size*3));
for frame in Frame::range_inclusive(vga_video_buffer_frame_start, vga_video_buffer_frame_end) {
mapper.identity_map(frame, EntryFlags::PRESENT | EntryFlags::WRITABLE, allocator);
}
mapper.identity_map(vga_text_buffer_frame, EntryFlags::WRITABLE, allocator);
let multiboot_start = Frame::containing_address(mem_info.boot_info.start_address()); let multiboot_start = Frame::containing_address(mem_info.boot_info.start_address());
let multiboot_end = Frame::containing_address(mem_info.boot_info.end_address() - 1); let multiboot_end = Frame::containing_address(mem_info.boot_info.end_address() - 1);
for frame in Frame::range_inclusive(multiboot_start, multiboot_end) { for frame in Frame::range_inclusive(multiboot_start, multiboot_end) {
@ -225,8 +231,7 @@ pub fn remap_the_kernel<A>(allocator: &mut A, mem_info: &MemInfo) -> ActivePageT
active_table active_table
} }
#[cfg(disabled)]
pub fn test_paging<A>(allocator: &mut A) pub fn test_paging<A>(allocator: &mut A)
where A: FrameAllocator where A: FrameAllocator
{ {

View File

@ -44,12 +44,12 @@ impl<L> Table<L> where L: HierarchicalLevel {
self.next_table_mut(index).unwrap() self.next_table_mut(index).unwrap()
} }
pub fn next_table<'a>(&'a self, index: usize) -> Option<&'a Table<L::NextLevel>> { pub fn next_table(&self, index: usize) -> Option<&Table<L::NextLevel>> {
self.next_table_address(index) self.next_table_address(index)
.map(|address| unsafe { &*(address as *const _) }) .map(|address| unsafe { &*(address as *const _) })
} }
pub fn next_table_mut<'a>(&'a mut self, index: usize) -> Option<&'a mut Table<L::NextLevel>> { pub fn next_table_mut(&mut self, index: usize) -> Option<&mut Table<L::NextLevel>> {
self.next_table_address(index) self.next_table_address(index)
.map(|address| unsafe { &mut *(address as *mut _) }) .map(|address| unsafe { &mut *(address as *mut _) })
} }

View File

@ -18,7 +18,7 @@ impl TemporaryPage {
where A: FrameAllocator where A: FrameAllocator
{ {
TemporaryPage { TemporaryPage {
page: page, page,
allocator: TinyAllocator::new(allocator), allocator: TinyAllocator::new(allocator),
} }
} }

View File

@ -1,3 +1,4 @@
#![allow(dead_code)]
use core::task::{Context, Poll, Waker}; use core::task::{Context, Poll, Waker};
use super::{Task, TaskId}; use super::{Task, TaskId};
@ -53,7 +54,7 @@ impl Executor {
}; };
let waker = waker_cache let waker = waker_cache
.entry(task_id) .entry(task_id)
.or_insert_with(|| TaskWaker::new(task_id, task_queue.clone())); .or_insert_with(|| TaskWaker::new_waker(task_id, task_queue.clone()));
let mut context = Context::from_waker(waker); let mut context = Context::from_waker(waker);
match task.poll(&mut context) { match task.poll(&mut context) {
Poll::Ready(()) => { Poll::Ready(()) => {
@ -77,7 +78,7 @@ impl TaskWaker {
fn wake_task(&self) { fn wake_task(&self) {
self.task_queue.push(self.task_id).expect("task_queue full"); self.task_queue.push(self.task_id).expect("task_queue full");
} }
fn new(task_id: TaskId, task_queue: Arc<ArrayQueue<TaskId>>) -> Waker { fn new_waker(task_id: TaskId, task_queue: Arc<ArrayQueue<TaskId>>) -> Waker {
Waker::from(Arc::new(TaskWaker { Waker::from(Arc::new(TaskWaker {
task_id, task_id,
task_queue, task_queue,
@ -96,3 +97,4 @@ impl Wake for TaskWaker {
} }

View File

@ -1,3 +1,4 @@
#![allow(dead_code)]
use core::{future::Future, pin::Pin, sync::atomic::{AtomicU64, Ordering}, task::{Context, Poll}}; use core::{future::Future, pin::Pin, sync::atomic::{AtomicU64, Ordering}, task::{Context, Poll}};
use alloc::boxed::Box; use alloc::boxed::Box;

View File

@ -1,9 +1,6 @@
use alloc::{boxed::Box, collections::{btree_set::BTreeSet, vec_deque::VecDeque}, sync::Arc, vec::Vec}; use alloc::collections::{btree_set::BTreeSet, vec_deque::VecDeque};
use hashbrown::HashSet; use pc_keyboard::{KeyCode, KeyEvent, KeyState};
use lazy_static::lazy_static;
use pc_keyboard::{DecodedKey, KeyCode, KeyEvent, KeyState};
use spin::Mutex; use spin::Mutex;
use x86_64::instructions::nop;
use crate::events::{Event, EVENTMAN}; use crate::events::{Event, EVENTMAN};
static mut KEYS_PRESSED: Mutex<BTreeSet<KeyCode>> = Mutex::new(BTreeSet::new()); static mut KEYS_PRESSED: Mutex<BTreeSet<KeyCode>> = Mutex::new(BTreeSet::new());

View File

@ -1,5 +1,5 @@
pub mod input; pub mod input;
pub mod vga;

View File

@ -0,0 +1,2 @@
pub mod text;
pub mod video;

View File

@ -1,9 +1,7 @@
use x86::io::{outb, inb}; use x86::io::{outb, inb};
use spin::Mutex; use spin::Mutex;
use x86_64::instructions::interrupts;
#[macro_use]
pub mod macros;
lazy_static::lazy_static!{ lazy_static::lazy_static!{
pub static ref WRITER: Mutex<Writer> = Mutex::new(Writer::new()); pub static ref WRITER: Mutex<Writer> = Mutex::new(Writer::new());
@ -93,7 +91,7 @@ impl Writer {
} }
} }
pub fn write_string(&mut self, s: &str) { fn write_string(&mut self, s: &str) {
for c in s.as_bytes() { for c in s.as_bytes() {
match c { match c {
// printable ASCII byte or newline // printable ASCII byte or newline
@ -197,3 +195,12 @@ pub fn get_cursor_position() -> (u16, u16) {
} }
(pos / (BUFFER_WIDTH as u16), pos % (BUFFER_WIDTH as u16)) (pos / (BUFFER_WIDTH as u16), pos % (BUFFER_WIDTH as u16))
} }
impl core::fmt::Write for Writer {
fn write_str(&mut self, s: &str) -> core::fmt::Result {
interrupts::without_interrupts(|| {
self.write_string(s);
});
Ok(())
}
}

View File

@ -0,0 +1,72 @@
mod util;
use core::{borrow::BorrowMut, ops::Deref};
use alloc::boxed::Box;
use lazy_static::lazy_static;
use multiboot2::{BootInformation, BootInformationHeader, FramebufferTag, FramebufferType, TagTrait};
use nalgebra::Vector2;
use spin::{Mutex, MutexGuard};
pub use util::is_video_mode_enabled;
#[derive(Clone, Copy)]
pub struct Color {
r: u8,
g: u8,
b: u8,
}
impl Color {
pub fn new(r: u8, g: u8, b: u8) -> Self {
Self {r, g, b}
}
}
pub struct VideoControler{
component_size: u8,
r_ofs: u8,
g_ofs: u8,
b_ofs: u8,
buf_addr: u64,
size: Vector2<usize>,
}
impl VideoControler {
pub fn new(mb2p: *const BootInformationHeader) -> Self {
let boot_info = unsafe { BootInformation::load(mb2p).unwrap() };
let fbt = boot_info.framebuffer_tag().unwrap().unwrap();
let FramebufferType::RGB { red, green, blue } = fbt.buffer_type().unwrap() else {
panic!();
};
assert!(red.size == green.size && green.size == blue.size);
log::info!("VGA VIDEO adddr: {:x}", fbt.address());
log::info!("VGA VIDEO FB TYPE: {:?}", fbt.buffer_type());
Self {
component_size: red.size,
r_ofs: red.position,
g_ofs: green.position,
b_ofs: blue.position,
buf_addr: fbt.address(),
size: Vector2::new(fbt.width() as usize, fbt.height() as usize)
}
}
pub fn set_px(&self, x: usize, y: usize, c: Color) {
let ptr = self.buf_addr as *mut () as *mut u8;
let px = ptr.wrapping_add(x * self.size.x + y);
unsafe {
*px.wrapping_add((self.r_ofs % 8) as usize) = c.r;
*px.wrapping_add((self.g_ofs % 8) as usize) = c.g;
*px.wrapping_add((self.b_ofs % 8) as usize) = c.b;
}
}
pub fn fill_screen(&self, c: Color) {
for x in 0..100 {
for y in 0..100 {
self.set_px(x, y, c);
}
}
}
}

View File

@ -0,0 +1,9 @@
extern "C" {
static __VIDEO_MODE: u8;
}
pub fn is_video_mode_enabled() -> bool {
unsafe {
__VIDEO_MODE == 1
}
}