ata drive writes + code cleanup here and there
This commit is contained in:
@@ -5,6 +5,6 @@ TIMEOUT=3
|
|||||||
PROTOCOL=limine
|
PROTOCOL=limine
|
||||||
|
|
||||||
KERNEL_PATH=boot:///boot/CappuccinOS.elf
|
KERNEL_PATH=boot:///boot/CappuccinOS.elf
|
||||||
KERNEL_CMDLINE=fat_in_mem=false
|
KERNEL_CMDLINE=fat_in_mem=true big_fat_phony
|
||||||
|
|
||||||
MODULE_PATH=boot:///boot/initramfs.img
|
MODULE_PATH=boot:///boot/initramfs.img
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#[cfg(any(target_arch = "x86_64"))]
|
#[cfg(target_arch = "x86_64")]
|
||||||
pub use self::x86_64::*;
|
pub use self::x86_64::*;
|
||||||
|
|
||||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||||
|
|||||||
@@ -116,12 +116,12 @@ exception_function!(0xFF, generic_handler, true);
|
|||||||
|
|
||||||
pub fn set_exceptions() {
|
pub fn set_exceptions() {
|
||||||
for i in 0..32 {
|
for i in 0..32 {
|
||||||
idt_set_gate(i, generic_handler as u64);
|
idt_set_gate(i, generic_handler as usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
idt_set_gate(0x00, div_error as u64);
|
idt_set_gate(0x00, div_error as usize);
|
||||||
idt_set_gate(0x06, invalid_opcode as u64);
|
idt_set_gate(0x06, invalid_opcode as usize);
|
||||||
idt_set_gate(0x08, double_fault as u64);
|
idt_set_gate(0x08, double_fault as usize);
|
||||||
idt_set_gate(0x0D, general_protection_fault as u64);
|
idt_set_gate(0x0D, general_protection_fault as usize);
|
||||||
idt_set_gate(0x0E, page_fault as u64);
|
idt_set_gate(0x0E, page_fault as usize);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ struct IdtPtr {
|
|||||||
|
|
||||||
static IDT: Mutex<[IdtEntry; 256]> = Mutex::new([IdtEntry::new(); 256]);
|
static IDT: Mutex<[IdtEntry; 256]> = Mutex::new([IdtEntry::new(); 256]);
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum InterruptIndex {
|
pub enum InterruptIndex {
|
||||||
Timer = PIC_1_OFFSET,
|
Timer = PIC_1_OFFSET,
|
||||||
@@ -43,8 +44,8 @@ pub enum InterruptIndex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl InterruptIndex {
|
impl InterruptIndex {
|
||||||
pub fn as_u8(self) -> u8 {
|
pub fn as_u8(&self) -> u8 {
|
||||||
self as u8
|
*self as u8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +59,7 @@ static mut IDT_PTR: IdtPtr = IdtPtr {
|
|||||||
base: 0,
|
base: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn idt_set_gate(num: u8, function_ptr: u64) {
|
pub fn idt_set_gate(num: u8, function_ptr: usize) {
|
||||||
let base = function_ptr;
|
let base = function_ptr;
|
||||||
IDT.lock().write()[num as usize] = IdtEntry {
|
IDT.lock().write()[num as usize] = IdtEntry {
|
||||||
base_lo: (base & 0xFFFF) as u16,
|
base_lo: (base & 0xFFFF) as u16,
|
||||||
@@ -98,13 +99,13 @@ fn idt_init() {
|
|||||||
|
|
||||||
// Set every interrupt to the "null" interrupt handler (it does nothing)
|
// Set every interrupt to the "null" interrupt handler (it does nothing)
|
||||||
for num in 0..=255 {
|
for num in 0..=255 {
|
||||||
idt_set_gate(num, null_interrupt_handler as u64);
|
idt_set_gate(num, null_interrupt_handler as usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
exceptions::set_exceptions();
|
exceptions::set_exceptions();
|
||||||
|
|
||||||
idt_set_gate(InterruptIndex::Timer.as_u8(), timer_handler as u64);
|
idt_set_gate(InterruptIndex::Timer.as_u8(), timer_handler as usize);
|
||||||
idt_set_gate(0x80, syscall as u64);
|
idt_set_gate(0x80, syscall as usize);
|
||||||
|
|
||||||
core::arch::asm!(
|
core::arch::asm!(
|
||||||
"lidt [{}]",
|
"lidt [{}]",
|
||||||
|
|||||||
@@ -71,6 +71,23 @@ pub unsafe fn insw(port: u16, buffer: *mut u16, count: usize) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Outputs `count` 16-bit values from the specified `port` into the `buffer`.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// This function panics if the supplied buffer's size is smaller than `count`.
|
||||||
|
#[inline(always)]
|
||||||
|
pub unsafe fn outsw(port: u16, buffer: *mut u16, count: usize) {
|
||||||
|
unsafe {
|
||||||
|
asm!("cld",
|
||||||
|
"rep outsw",
|
||||||
|
in("dx") port,
|
||||||
|
inout("rdi") buffer => _,
|
||||||
|
inout("rcx") count => _
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn outl(port: u16, value: u32) {
|
pub fn outl(port: u16, value: u32) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Originally from pic8259 (https://docs.rs/pic8259/0.10.1/pic8259/)
|
// Originally from pic8259 (https://docs.rs/pic8259/0.10.1/pic8259/)
|
||||||
// But this one feeds my addiction of not adding unnecessary crates
|
// But this one feeds my addiction of not adding unnecessary crates
|
||||||
// And I can read and learn about the PIC too ig
|
// And I can read and learn about the PIC too ig
|
||||||
// Driver for the 8086 PIC, we might switch to the APIC later on.
|
// Driver for the 8086 PIC, we will switch to the APIC later on.
|
||||||
|
|
||||||
use super::io::{io_wait, outb};
|
use super::io::{io_wait, outb};
|
||||||
|
|
||||||
@@ -114,11 +114,10 @@ impl ChainedPics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn notify_end_of_interrupt(&mut self, interrupt_id: u8) {
|
pub fn notify_end_of_interrupt(&mut self, interrupt_id: u8) {
|
||||||
if self.handles_interrupt(interrupt_id) {
|
if self.handles_interrupt(interrupt_id) && self.pics[1].handles_interrupt(interrupt_id) {
|
||||||
if self.pics[1].handles_interrupt(interrupt_id) {
|
self.pics[1].end_of_interrupt();
|
||||||
self.pics[1].end_of_interrupt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.pics[0].end_of_interrupt();
|
self.pics[0].end_of_interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,11 @@ pub fn print_stack_trace(max_frames: usize, rbp: u64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_function_name(function_address: u64) -> Result<(String, u64), ()> {
|
fn get_function_name(function_address: u64) -> Result<(String, u64), ()> {
|
||||||
if crate::drivers::fs::vfs::VFS_INSTANCES.lock().read().len() == 0 {
|
if crate::drivers::fs::vfs::VFS_INSTANCES
|
||||||
|
.lock()
|
||||||
|
.read()
|
||||||
|
.is_empty()
|
||||||
|
{
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +62,7 @@ fn get_function_name(function_address: u64) -> Result<(String, u64), ()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let (address, function_name) = (
|
let (address, function_name) = (
|
||||||
u64::from_str_radix(&line_parts[0], 16).ok().ok_or(())?,
|
u64::from_str_radix(line_parts[0], 16).ok().ok_or(())?,
|
||||||
line_parts[1],
|
line_parts[1],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use limine::RsdpRequest;
|
|||||||
static RSDP_REQUEST: RsdpRequest = RsdpRequest::new(0);
|
static RSDP_REQUEST: RsdpRequest = RsdpRequest::new(0);
|
||||||
|
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
struct RSDP {
|
struct Rsdp {
|
||||||
signature: [u8; 8],
|
signature: [u8; 8],
|
||||||
checksum: u8,
|
checksum: u8,
|
||||||
oem_id: [u8; 6],
|
oem_id: [u8; 6],
|
||||||
@@ -19,10 +19,10 @@ struct RSDP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const RSDP_V1_LENGTH: usize = 20;
|
const RSDP_V1_LENGTH: usize = 20;
|
||||||
const RSDP_V2_EXT_LENGTH: usize = core::mem::size_of::<RSDP>() - RSDP_V1_LENGTH;
|
const RSDP_V2_EXT_LENGTH: usize = core::mem::size_of::<Rsdp>() - RSDP_V1_LENGTH;
|
||||||
const RSDP_SIG: [u8; 8] = *b"RSD PTR ";
|
const RSDP_SIG: [u8; 8] = *b"RSD PTR ";
|
||||||
|
|
||||||
impl RSDP {
|
impl Rsdp {
|
||||||
pub fn is_valid(&self) -> bool {
|
pub fn is_valid(&self) -> bool {
|
||||||
if self.signature != RSDP_SIG {
|
if self.signature != RSDP_SIG {
|
||||||
return false;
|
return false;
|
||||||
@@ -39,7 +39,7 @@ impl RSDP {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let bytes =
|
let bytes =
|
||||||
unsafe { core::slice::from_raw_parts(self as *const RSDP as *const u8, length) };
|
unsafe { core::slice::from_raw_parts(self as *const Rsdp as *const u8, length) };
|
||||||
let sum = bytes.iter().fold(0u8, |sum, &byte| sum.wrapping_add(byte));
|
let sum = bytes.iter().fold(0u8, |sum, &byte| sum.wrapping_add(byte));
|
||||||
|
|
||||||
if sum != 0 {
|
if sum != 0 {
|
||||||
@@ -60,7 +60,7 @@ pub fn init_acpi() {
|
|||||||
|
|
||||||
let rsdp_address = &rsdp_response.unwrap().address;
|
let rsdp_address = &rsdp_response.unwrap().address;
|
||||||
|
|
||||||
let rsdp_table: &RSDP = unsafe { &*(rsdp_address.as_ptr().unwrap() as *const RSDP) };
|
let rsdp_table: &Rsdp = unsafe { &*(rsdp_address.as_ptr().unwrap() as *const Rsdp) };
|
||||||
|
|
||||||
if !rsdp_table.is_valid() {
|
if !rsdp_table.is_valid() {
|
||||||
log_error!("Failed to initialize ACPI: RSDP was not valid!");
|
log_error!("Failed to initialize ACPI: RSDP was not valid!");
|
||||||
@@ -68,7 +68,7 @@ pub fn init_acpi() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log_info!("{}", rsdp_table.revision);
|
log_info!("{}", rsdp_table.revision);
|
||||||
let mut facp: Option<&ACPISDTHeader> = None;
|
let mut facp: Option<&AcpiSdtHeader> = None;
|
||||||
|
|
||||||
let rsdt_address = rsdp_table.rsdt_address;
|
let rsdt_address = rsdp_table.rsdt_address;
|
||||||
facp = find_facp(rsdt_address as *const u32, rsdp_table.revision);
|
facp = find_facp(rsdt_address as *const u32, rsdp_table.revision);
|
||||||
@@ -80,7 +80,7 @@ pub fn init_acpi() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct ACPISDTHeader {
|
struct AcpiSdtHeader {
|
||||||
signature: [u8; 4],
|
signature: [u8; 4],
|
||||||
length: u32,
|
length: u32,
|
||||||
revision: u8,
|
revision: u8,
|
||||||
@@ -92,7 +92,7 @@ struct ACPISDTHeader {
|
|||||||
creator_revision: u32,
|
creator_revision: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_rsdt_checksum(table_header: *const ACPISDTHeader) -> bool {
|
fn check_rsdt_checksum(table_header: *const AcpiSdtHeader) -> bool {
|
||||||
let mut sum: u8 = 0;
|
let mut sum: u8 = 0;
|
||||||
|
|
||||||
for i in 0..unsafe { (*table_header).length } {
|
for i in 0..unsafe { (*table_header).length } {
|
||||||
@@ -103,23 +103,23 @@ fn check_rsdt_checksum(table_header: *const ACPISDTHeader) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct RSDT {
|
struct Rsdt {
|
||||||
h: ACPISDTHeader,
|
h: AcpiSdtHeader,
|
||||||
pointer_to_other_sdt: *const u32,
|
pointer_to_other_sdt: *const u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_facp(root_sdt: *const u32, revision: u8) -> Option<&'static ACPISDTHeader> {
|
fn find_facp(root_sdt: *const u32, revision: u8) -> Option<&'static AcpiSdtHeader> {
|
||||||
let rsdt: &mut RSDT = unsafe { &mut *(root_sdt as *mut RSDT) };
|
let rsdt: &mut Rsdt = unsafe { &mut *(root_sdt as *mut Rsdt) };
|
||||||
rsdt.pointer_to_other_sdt =
|
rsdt.pointer_to_other_sdt =
|
||||||
[(rsdt.h.length - core::mem::size_of::<ACPISDTHeader>() as u32) / 4].as_ptr();
|
[(rsdt.h.length - core::mem::size_of::<AcpiSdtHeader>() as u32) / 4].as_ptr();
|
||||||
|
|
||||||
let entry_bytes = if revision > 0 { 8 } else { 4 };
|
let entry_bytes = if revision > 0 { 8 } else { 4 };
|
||||||
|
|
||||||
let entries = (rsdt.h.length - core::mem::size_of::<ACPISDTHeader>() as u32) / entry_bytes;
|
let entries = (rsdt.h.length - core::mem::size_of::<AcpiSdtHeader>() as u32) / entry_bytes;
|
||||||
|
|
||||||
for i in 0..entries {
|
for i in 0..entries {
|
||||||
crate::println!("{i}");
|
crate::println!("{i}");
|
||||||
let h = unsafe { rsdt.pointer_to_other_sdt.add(i as usize) as *const ACPISDTHeader };
|
let h = unsafe { rsdt.pointer_to_other_sdt.add(i as usize) as *const AcpiSdtHeader };
|
||||||
let signature_bytes = unsafe { (*h).signature };
|
let signature_bytes = unsafe { (*h).signature };
|
||||||
let signature_str = core::str::from_utf8(&signature_bytes).unwrap_or("");
|
let signature_str = core::str::from_utf8(&signature_bytes).unwrap_or("");
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use alloc::{
|
|||||||
|
|
||||||
use crate::drivers::storage::drive::{BlockDevice, GPTPartitionEntry};
|
use crate::drivers::storage::drive::{BlockDevice, GPTPartitionEntry};
|
||||||
|
|
||||||
use super::vfs::{VFSDirectory, VFSFile, VFSFileSystem};
|
use super::vfs::{VfsDirectory, VfsFile, VfsFileSystem};
|
||||||
|
|
||||||
// The first Cluster (perhaps 0xF0FFFF0F) is the FAT ID
|
// The first Cluster (perhaps 0xF0FFFF0F) is the FAT ID
|
||||||
// The second cluster stores the end-of-cluster-chain marker
|
// The second cluster stores the end-of-cluster-chain marker
|
||||||
@@ -144,9 +144,9 @@ pub struct FileEntry {
|
|||||||
file_size: u32,
|
file_size: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FATFS<'a> {
|
pub struct FatFs<'a> {
|
||||||
// Block device Info
|
// Block device Info
|
||||||
drive: Box<&'a dyn BlockDevice>,
|
drive: &'a dyn BlockDevice,
|
||||||
partition: GPTPartitionEntry,
|
partition: GPTPartitionEntry,
|
||||||
// FAT info
|
// FAT info
|
||||||
fs_info: FSInfo,
|
fs_info: FSInfo,
|
||||||
@@ -158,7 +158,7 @@ pub struct FATFS<'a> {
|
|||||||
sectors_per_fat: usize,
|
sectors_per_fat: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FATFS<'a> {
|
impl<'a> FatFs<'a> {
|
||||||
pub fn new(drive: &'a dyn BlockDevice, partition: GPTPartitionEntry) -> Result<Self, ()> {
|
pub fn new(drive: &'a dyn BlockDevice, partition: GPTPartitionEntry) -> Result<Self, ()> {
|
||||||
let bpb_bytes = drive
|
let bpb_bytes = drive
|
||||||
.read(partition.start_sector, 1)
|
.read(partition.start_sector, 1)
|
||||||
@@ -173,7 +173,7 @@ impl<'a> FATFS<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We're trusting it
|
// We're trusting it
|
||||||
if let Some(system_identifier_string) = system_identifier.ok() {
|
if let Ok(system_identifier_string) = system_identifier {
|
||||||
if !system_identifier_string.contains("FAT32") {
|
if !system_identifier_string.contains("FAT32") {
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
@@ -249,7 +249,7 @@ impl<'a> FATFS<'a> {
|
|||||||
let cluster_size = bpb.sectors_per_cluster as usize * 512;
|
let cluster_size = bpb.sectors_per_cluster as usize * 512;
|
||||||
|
|
||||||
return Ok(Self {
|
return Ok(Self {
|
||||||
drive: Box::new(drive),
|
drive,
|
||||||
partition,
|
partition,
|
||||||
fs_info,
|
fs_info,
|
||||||
fat,
|
fat,
|
||||||
@@ -336,19 +336,17 @@ impl<'a> FATFS<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if name.replacen(".", "", 1).len() <= 11 {
|
if name.replacen('.', "", 1).len() <= 11 {
|
||||||
let search_parts: Vec<&str> = name.split(".").collect();
|
let search_parts: Vec<&str> = name.split('.').collect();
|
||||||
|
|
||||||
let filename = core::str::from_utf8(&file_entry.file_name).unwrap();
|
let filename = core::str::from_utf8(&file_entry.file_name).unwrap();
|
||||||
let extension = core::str::from_utf8(&file_entry.extension).unwrap();
|
let extension = core::str::from_utf8(&file_entry.extension).unwrap();
|
||||||
|
|
||||||
if search_parts.len() == 1
|
if (search_parts.len() == 1
|
||||||
&& !filename.contains(&search_parts[0].to_ascii_uppercase())
|
&& !filename.contains(&search_parts[0].to_ascii_uppercase()))
|
||||||
{
|
|| (search_parts.len() > 1
|
||||||
continue;
|
&& (!filename.contains(&search_parts[0].to_ascii_uppercase())
|
||||||
} else if search_parts.len() > 1
|
|| !extension.contains(&search_parts[1].to_ascii_uppercase())))
|
||||||
&& (!filename.contains(&search_parts[0].to_ascii_uppercase())
|
|
||||||
|| !extension.contains(&search_parts[1].to_ascii_uppercase()))
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -432,8 +430,8 @@ impl<'a> FATFS<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VFSFileSystem for FATFS<'a> {
|
impl<'a> VfsFileSystem for FatFs<'a> {
|
||||||
fn open(&self, path: &str) -> Result<Box<dyn VFSFile + '_>, ()> {
|
fn open(&self, path: &str) -> Result<Box<dyn VfsFile + '_>, ()> {
|
||||||
let path_componenets: Vec<&str> = path.trim_start_matches('/').split('/').collect();
|
let path_componenets: Vec<&str> = path.trim_start_matches('/').split('/').collect();
|
||||||
let mut current_cluster = self.bpb.root_dir_cluster as usize;
|
let mut current_cluster = self.bpb.root_dir_cluster as usize;
|
||||||
|
|
||||||
@@ -446,7 +444,7 @@ impl<'a> VFSFileSystem for FATFS<'a> {
|
|||||||
as usize;
|
as usize;
|
||||||
} else {
|
} else {
|
||||||
return Ok(Box::new(FatFile {
|
return Ok(Box::new(FatFile {
|
||||||
fat_fs: &self,
|
fat_fs: self,
|
||||||
file_entry,
|
file_entry,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -455,17 +453,17 @@ impl<'a> VFSFileSystem for FATFS<'a> {
|
|||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_dir(&self, path: &str) -> Result<Box<dyn VFSDirectory>, ()> {
|
fn read_dir(&self, path: &str) -> Result<Box<dyn VfsDirectory>, ()> {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FatFile<'a> {
|
struct FatFile<'a> {
|
||||||
fat_fs: &'a FATFS<'a>,
|
fat_fs: &'a FatFs<'a>,
|
||||||
file_entry: FileEntry,
|
file_entry: FileEntry,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VFSFile for FatFile<'a> {
|
impl<'a> VfsFile for FatFile<'a> {
|
||||||
fn read(&self) -> Result<Arc<[u8]>, ()> {
|
fn read(&self) -> Result<Arc<[u8]>, ()> {
|
||||||
let mut file: Vec<u8> = Vec::with_capacity(self.file_entry.file_size as usize);
|
let mut file: Vec<u8> = Vec::with_capacity(self.file_entry.file_size as usize);
|
||||||
let mut file_ptr_index = 0;
|
let mut file_ptr_index = 0;
|
||||||
@@ -512,12 +510,12 @@ impl<'a> VFSFile for FatFile<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct FatDirectory<'a> {
|
struct FatDirectory<'a> {
|
||||||
fat_fs: &'a FATFS<'a>,
|
fat_fs: &'a FatFs<'a>,
|
||||||
directory_cluster: usize,
|
directory_cluster: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VFSDirectory for FatDirectory<'a> {
|
impl<'a> VfsDirectory for FatDirectory<'a> {
|
||||||
fn list_files(&self) -> Result<Arc<[Box<dyn VFSFile>]>, ()> {
|
fn list_files(&self) -> Result<Arc<[Box<dyn VfsFile>]>, ()> {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,19 +7,20 @@ enum ZlibCompressionLevel {
|
|||||||
Best,
|
Best,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<ZlibCompressionLevel> for u8 {
|
impl From<u8> for ZlibCompressionLevel {
|
||||||
fn into(self) -> ZlibCompressionLevel {
|
fn from(value: u8) -> Self {
|
||||||
match self {
|
match value {
|
||||||
0 => ZlibCompressionLevel::Fastest,
|
0 => Self::Fastest,
|
||||||
1 => ZlibCompressionLevel::Fast,
|
1 => Self::Fast,
|
||||||
2 => ZlibCompressionLevel::Default,
|
2 => Self::Default,
|
||||||
3 => ZlibCompressionLevel::Best,
|
3 => Self::Best,
|
||||||
_ => panic!("Unexpected compression level {self}"),
|
_ => panic!("Unexpected compression level {value}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ZLIB steam, see RFC 1950
|
// RFC 1950: "ZLIB Compressed Data Format Specification"
|
||||||
|
// RFC 1951: "DEFLATE Compressed Data Format Specification"
|
||||||
pub fn uncompress_data(bytes: &[u8]) -> &[u8] {
|
pub fn uncompress_data(bytes: &[u8]) -> &[u8] {
|
||||||
assert!(bytes.len() > 2);
|
assert!(bytes.len() > 2);
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
pub mod compressors;
|
pub mod compressors;
|
||||||
|
|
||||||
use core::{
|
use core::fmt::{self, Debug};
|
||||||
fmt::{self, Debug},
|
|
||||||
ops::{Index, Range, RangeFrom, RangeFull},
|
|
||||||
};
|
|
||||||
|
|
||||||
use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
||||||
use limine::ModuleRequest;
|
use limine::ModuleRequest;
|
||||||
|
|
||||||
use crate::libs::math::ceil;
|
use crate::libs::math::ceil;
|
||||||
|
|
||||||
use super::vfs::{VFSDirectory, VFSFile, VFSFileSystem};
|
use super::vfs::{VfsDirectory, VfsFile, VfsFileSystem};
|
||||||
|
|
||||||
pub static MODULE_REQUEST: ModuleRequest = ModuleRequest::new(0);
|
pub static MODULE_REQUEST: ModuleRequest = ModuleRequest::new(0);
|
||||||
|
|
||||||
@@ -98,7 +95,7 @@ impl Squashfs<'_> {
|
|||||||
|
|
||||||
let squashfs_data: &[u8] = unsafe { core::slice::from_raw_parts(ptr, length) };
|
let squashfs_data: &[u8] = unsafe { core::slice::from_raw_parts(ptr, length) };
|
||||||
|
|
||||||
let superblock = SquashfsSuperblock::new(&squashfs_data)?;
|
let superblock = SquashfsSuperblock::new(squashfs_data)?;
|
||||||
|
|
||||||
let data_table = &squashfs_data
|
let data_table = &squashfs_data
|
||||||
[core::mem::size_of::<SquashfsSuperblock>()..superblock.inode_table as usize];
|
[core::mem::size_of::<SquashfsSuperblock>()..superblock.inode_table as usize];
|
||||||
@@ -158,7 +155,7 @@ impl Squashfs<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn read_inode(&self, inode_num: u32) -> Inode {
|
fn read_inode(&self, inode_num: u32) -> Inode {
|
||||||
let inode_table = &self.get_decompressed_table(&self.inode_table, (true, None));
|
let inode_table = &self.get_decompressed_table(self.inode_table, (true, None));
|
||||||
|
|
||||||
let inode_offset = inode_num as usize;
|
let inode_offset = inode_num as usize;
|
||||||
|
|
||||||
@@ -211,14 +208,10 @@ impl Squashfs<'_> {
|
|||||||
let mut buffer: Vec<u8> = Vec::with_capacity(8192);
|
let mut buffer: Vec<u8> = Vec::with_capacity(8192);
|
||||||
|
|
||||||
if table_is_compressed {
|
if table_is_compressed {
|
||||||
let bytes = if metadata_block.0 {
|
let bytes = if metadata_block.0 { &table[2..] } else { table };
|
||||||
&table[2..]
|
|
||||||
} else {
|
|
||||||
&table
|
|
||||||
};
|
|
||||||
|
|
||||||
match self.superblock.compressor {
|
match self.superblock.compressor {
|
||||||
SquashfsCompressionType::GZIP => {
|
SquashfsCompressionType::Gzip => {
|
||||||
buffer.extend_from_slice(compressors::gzip::uncompress_data(bytes));
|
buffer.extend_from_slice(compressors::gzip::uncompress_data(bytes));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -241,8 +234,8 @@ impl Squashfs<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VFSFileSystem for Squashfs<'a> {
|
impl<'a> VfsFileSystem for Squashfs<'a> {
|
||||||
fn open(&self, path: &str) -> Result<Box<dyn VFSFile + '_>, ()> {
|
fn open(&self, path: &str) -> Result<Box<dyn VfsFile + '_>, ()> {
|
||||||
let path_components: Vec<&str> = path.trim_start_matches('/').split('/').collect();
|
let path_components: Vec<&str> = path.trim_start_matches('/').split('/').collect();
|
||||||
let mut current_dir = self.read_root_dir();
|
let mut current_dir = self.read_root_dir();
|
||||||
|
|
||||||
@@ -273,7 +266,7 @@ impl<'a> VFSFileSystem for Squashfs<'a> {
|
|||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_dir(&self, path: &str) -> Result<Box<dyn VFSDirectory>, ()> {
|
fn read_dir(&self, path: &str) -> Result<Box<dyn VfsDirectory>, ()> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -486,7 +479,7 @@ impl<'a> BasicFileInode<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VFSFile for BasicFileInode<'a> {
|
impl<'a> VfsFile for BasicFileInode<'a> {
|
||||||
fn read(&self) -> Result<Arc<[u8]>, ()> {
|
fn read(&self) -> Result<Arc<[u8]>, ()> {
|
||||||
// TODO: handle tail end packing (somehow?)
|
// TODO: handle tail end packing (somehow?)
|
||||||
let block_count =
|
let block_count =
|
||||||
@@ -584,23 +577,23 @@ enum InodeFileType {
|
|||||||
ExtendedSocked = 13,
|
ExtendedSocked = 13,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<InodeFileType> for u16 {
|
impl From<u16> for InodeFileType {
|
||||||
fn into(self) -> InodeFileType {
|
fn from(value: u16) -> Self {
|
||||||
match self {
|
match value {
|
||||||
1 => InodeFileType::BasicDirectory,
|
1 => Self::BasicDirectory,
|
||||||
2 => InodeFileType::BasicFile,
|
2 => Self::BasicFile,
|
||||||
3 => InodeFileType::BasicSymlink,
|
3 => Self::BasicSymlink,
|
||||||
4 => InodeFileType::BasicBlockDevice,
|
4 => Self::BasicBlockDevice,
|
||||||
5 => InodeFileType::BasicCharDevice,
|
5 => Self::BasicCharDevice,
|
||||||
6 => InodeFileType::BasicPipe,
|
6 => Self::BasicPipe,
|
||||||
7 => InodeFileType::BasicSocked,
|
7 => Self::BasicSocked,
|
||||||
8 => InodeFileType::ExtendedDirectory,
|
8 => Self::ExtendedDirectory,
|
||||||
9 => InodeFileType::ExtendedFile,
|
9 => Self::ExtendedFile,
|
||||||
10 => InodeFileType::ExtendedSymlink,
|
10 => Self::ExtendedSymlink,
|
||||||
11 => InodeFileType::ExtendedBlockDevice,
|
11 => Self::ExtendedBlockDevice,
|
||||||
12 => InodeFileType::ExtendedPipe,
|
12 => Self::ExtendedPipe,
|
||||||
13 => InodeFileType::ExtendedSocked,
|
13 => Self::ExtendedSocked,
|
||||||
_ => panic!("Unexpected Inode file type {self}!"),
|
_ => panic!("Unexpected Inode file type {value}!"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -608,12 +601,12 @@ impl Into<InodeFileType> for u16 {
|
|||||||
#[repr(u16)]
|
#[repr(u16)]
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
enum SquashfsCompressionType {
|
enum SquashfsCompressionType {
|
||||||
GZIP = 1,
|
Gzip = 1,
|
||||||
LZMA = 2,
|
Lzma = 2,
|
||||||
LZO = 3,
|
Lzo = 3,
|
||||||
XZ = 4,
|
Xz = 4,
|
||||||
LZ4 = 5,
|
Lz4 = 5,
|
||||||
ZSTD = 6,
|
Zstd = 6,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(u16)]
|
#[repr(u16)]
|
||||||
@@ -632,6 +625,7 @@ enum SquashfsFlags {
|
|||||||
UncompressedIDTable = 0x0800,
|
UncompressedIDTable = 0x0800,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct SquashfsFeatures {
|
struct SquashfsFeatures {
|
||||||
uncompressed_inodes: bool,
|
uncompressed_inodes: bool,
|
||||||
@@ -648,15 +642,15 @@ struct SquashfsFeatures {
|
|||||||
uncompressed_id_table: bool,
|
uncompressed_id_table: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<SquashfsCompressionType> for u16 {
|
impl From<u16> for SquashfsCompressionType {
|
||||||
fn into(self) -> SquashfsCompressionType {
|
fn from(value: u16) -> Self {
|
||||||
match self {
|
match value {
|
||||||
1 => SquashfsCompressionType::GZIP,
|
1 => Self::Gzip,
|
||||||
2 => SquashfsCompressionType::LZMA,
|
2 => Self::Lzma,
|
||||||
3 => SquashfsCompressionType::LZO,
|
3 => Self::Lzo,
|
||||||
4 => SquashfsCompressionType::XZ,
|
4 => Self::Xz,
|
||||||
5 => SquashfsCompressionType::LZ4,
|
5 => Self::Lz4,
|
||||||
6 => SquashfsCompressionType::ZSTD,
|
6 => Self::Zstd,
|
||||||
_ => panic!("Unexpected Squashfs compression type!"),
|
_ => panic!("Unexpected Squashfs compression type!"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,38 +2,37 @@ use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
|||||||
|
|
||||||
use crate::libs::mutex::Mutex;
|
use crate::libs::mutex::Mutex;
|
||||||
|
|
||||||
pub trait VFSFileSystem {
|
pub trait VfsFileSystem {
|
||||||
fn open(&self, path: &str) -> Result<Box<dyn VFSFile + '_>, ()>;
|
fn open(&self, path: &str) -> Result<Box<dyn VfsFile + '_>, ()>;
|
||||||
fn read_dir(&self, path: &str) -> Result<Box<dyn VFSDirectory>, ()>;
|
fn read_dir(&self, path: &str) -> Result<Box<dyn VfsDirectory>, ()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait VFSFile {
|
pub trait VfsFile {
|
||||||
fn read(&self) -> Result<Arc<[u8]>, ()>;
|
fn read(&self) -> Result<Arc<[u8]>, ()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait VFSDirectory {
|
pub trait VfsDirectory {
|
||||||
fn list_files(&self) -> Result<Arc<[Box<dyn VFSFile>]>, ()>;
|
fn list_files(&self) -> Result<Arc<[Box<dyn VfsFile>]>, ()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static VFS_INSTANCES: Mutex<Vec<VFS>> = Mutex::new(Vec::new());
|
pub static VFS_INSTANCES: Mutex<Vec<Vfs>> = Mutex::new(Vec::new());
|
||||||
|
|
||||||
pub struct VFS {
|
pub struct Vfs {
|
||||||
file_system: Box<dyn VFSFileSystem>,
|
file_system: Box<dyn VfsFileSystem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VFS {
|
impl Vfs {
|
||||||
pub fn new(file_system: Box<dyn VFSFileSystem>) -> Self {
|
pub fn new(file_system: Box<dyn VfsFileSystem>) -> Self {
|
||||||
return Self { file_system };
|
return Self { file_system };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open(&self, path: &str) -> Result<Box<dyn VFSFile + '_>, ()> {
|
pub fn open(&self, path: &str) -> Result<Box<dyn VfsFile + '_>, ()> {
|
||||||
return self.file_system.open(path);
|
return self.file_system.open(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_dir(&self, path: &str) -> Result<Box<dyn VFSDirectory>, ()> {
|
pub fn read_dir(&self, path: &str) -> Result<Box<dyn VfsDirectory>, ()> {
|
||||||
return self.file_system.read_dir(path);
|
return self.file_system.read_dir(path);
|
||||||
}
|
}
|
||||||
// Add more VFS methods as needed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -170,15 +170,13 @@ fn check_function(bus: u8, device: u8, func: u8) {
|
|||||||
.write()
|
.write()
|
||||||
.push(PciDevice::new(bus, device, func));
|
.push(PciDevice::new(bus, device, func));
|
||||||
|
|
||||||
let class_code: u8;
|
let _secondary_bus: u8;
|
||||||
let subclass_code: u8;
|
|
||||||
let secondary_bus: u8;
|
|
||||||
|
|
||||||
class_code = read_pci_class_code(bus, device, func);
|
let class_code = read_pci_class_code(bus, device, func);
|
||||||
subclass_code = read_pci_subclass_code(bus, device, func);
|
let subclass_code = read_pci_subclass_code(bus, device, func);
|
||||||
|
|
||||||
if class_code == 0x06 && subclass_code == 0x04 {
|
if class_code == 0x06 && subclass_code == 0x04 {
|
||||||
secondary_bus = read_pci_to_pci_secondary_bus(bus, device, func);
|
_secondary_bus = read_pci_to_pci_secondary_bus(bus, device, func);
|
||||||
// TODO: This causes an infinite loop on baremetal
|
// TODO: This causes an infinite loop on baremetal
|
||||||
// check_bus(secondary_bus);
|
// check_bus(secondary_bus);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,16 +20,16 @@ pub static POISONED: AtomicBool = AtomicBool::new(false);
|
|||||||
pub fn init_serial() -> u8 {
|
pub fn init_serial() -> u8 {
|
||||||
outb(PORT + 1, 0x00);
|
outb(PORT + 1, 0x00);
|
||||||
outb(PORT + 3, 0x80);
|
outb(PORT + 3, 0x80);
|
||||||
outb(PORT + 0, 0x03);
|
outb(PORT, 0x03);
|
||||||
outb(PORT + 1, 0x00);
|
outb(PORT + 1, 0x00);
|
||||||
outb(PORT + 3, 0x03);
|
outb(PORT + 3, 0x03);
|
||||||
outb(PORT + 2, 0xC7);
|
outb(PORT + 2, 0xC7);
|
||||||
outb(PORT + 4, 0x0B);
|
outb(PORT + 4, 0x0B);
|
||||||
outb(PORT + 4, 0x1E);
|
outb(PORT + 4, 0x1E);
|
||||||
outb(PORT + 0, 0xAE);
|
outb(PORT, 0xAE);
|
||||||
|
|
||||||
// Check if serial is faulty
|
// Check if serial is faulty
|
||||||
if inb(PORT + 0) != 0xAE {
|
if inb(PORT) != 0xAE {
|
||||||
crate::log_error!("Serial Driver failed to initialize");
|
crate::log_error!("Serial Driver failed to initialize");
|
||||||
POISONED.store(true, core::sync::atomic::Ordering::Relaxed);
|
POISONED.store(true, core::sync::atomic::Ordering::Relaxed);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use alloc::sync::Arc;
|
|||||||
pub trait BlockDevice {
|
pub trait BlockDevice {
|
||||||
fn sector_count(&self) -> u64;
|
fn sector_count(&self) -> u64;
|
||||||
fn read(&self, sector: u64, sector_count: usize) -> Result<Arc<[u8]>, ()>;
|
fn read(&self, sector: u64, sector_count: usize) -> Result<Arc<[u8]>, ()>;
|
||||||
fn write(&self, sector: u64, data: &[u8]) -> Result<(), ()>;
|
fn write(&self, sector: u64, data: &mut [u8]) -> Result<(), ()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use core::mem::size_of;
|
|||||||
use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::io::{inb, insw, inw, outb},
|
arch::io::{inb, insw, inw, outb, outsw, outw},
|
||||||
drivers::{
|
drivers::{
|
||||||
fs::fat,
|
fs::fat,
|
||||||
storage::drive::{GPTBlock, GPTPartitionEntry},
|
storage::drive::{GPTBlock, GPTPartitionEntry},
|
||||||
@@ -161,29 +161,7 @@ enum ATADriveDirection {
|
|||||||
Write = 0x01,
|
Write = 0x01,
|
||||||
}
|
}
|
||||||
|
|
||||||
static DRIVE_ID: Mutex<[[u16; 256]; 2]> = Mutex::new([[0u16; 256]; 2]);
|
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
// for pci_device in super::pci::PCI_DEVICES.lock().read() {
|
|
||||||
// if pci_device.class_code != 0x01 || pci_device.subclass_code != 0x01 {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let (bar0, bar1, bar2, bar3, bar4, _) =
|
|
||||||
// super::pci::get_pci_bar_addresses(pci_device.bus, pci_device.device, pci_device.func);
|
|
||||||
|
|
||||||
// crate::println!(
|
|
||||||
// "bar0: {} bar1: {} bar2: {} bar3: {} bar4: {}",
|
|
||||||
// bar0,
|
|
||||||
// bar1,
|
|
||||||
// bar2,
|
|
||||||
// bar3,
|
|
||||||
// bar4
|
|
||||||
// );
|
|
||||||
|
|
||||||
// ide_initialize(bar0, bar1, bar2, bar3, bar4);
|
|
||||||
// }
|
|
||||||
// crate::println!("{:?}", ata_identify_drive(0xB0));
|
|
||||||
ide_initialize(0x1F0, 0x3F6, 0x170, 0x376, 0x000);
|
ide_initialize(0x1F0, 0x3F6, 0x170, 0x376, 0x000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,7 +171,7 @@ struct ATABus {
|
|||||||
control_bar: u16,
|
control_bar: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ATABus {
|
impl ATABus {
|
||||||
fn new(io_bar: u16, control_bar: u16) -> Arc<Self> {
|
fn new(io_bar: u16, control_bar: u16) -> Arc<Self> {
|
||||||
let io_bar = io_bar & 0xFFFC;
|
let io_bar = io_bar & 0xFFFC;
|
||||||
let control_bar = control_bar & 0xFFFC;
|
let control_bar = control_bar & 0xFFFC;
|
||||||
@@ -207,7 +185,7 @@ impl<'a> ATABus {
|
|||||||
pub fn select(&self, drive: u8) {
|
pub fn select(&self, drive: u8) {
|
||||||
outb(
|
outb(
|
||||||
self.io_bar + ATADriveDataRegister::DeviceSelect as u16,
|
self.io_bar + ATADriveDataRegister::DeviceSelect as u16,
|
||||||
drive as u8,
|
drive,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,6 +288,50 @@ impl<'a> ATABus {
|
|||||||
sector: u64,
|
sector: u64,
|
||||||
sector_count: usize,
|
sector_count: usize,
|
||||||
) -> Result<Arc<[u8]>, ()> {
|
) -> Result<Arc<[u8]>, ()> {
|
||||||
|
let mut buffer: Vec<u8> = Vec::with_capacity(ATA_SECTOR_SIZE * sector_count);
|
||||||
|
unsafe { buffer.set_len(buffer.capacity()) };
|
||||||
|
|
||||||
|
self.ide_access(
|
||||||
|
drive,
|
||||||
|
sector,
|
||||||
|
sector_count,
|
||||||
|
ATADriveDirection::Read,
|
||||||
|
buffer.as_mut_slice(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
return Ok(Arc::from(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write(
|
||||||
|
&self,
|
||||||
|
drive: ATADriveType,
|
||||||
|
sector: u64,
|
||||||
|
sector_count: usize,
|
||||||
|
buffer: &mut [u8],
|
||||||
|
) -> Result<(), ()> {
|
||||||
|
if buffer.len() < ATA_SECTOR_SIZE * sector_count {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.ide_access(
|
||||||
|
drive,
|
||||||
|
sector,
|
||||||
|
sector_count,
|
||||||
|
ATADriveDirection::Write,
|
||||||
|
buffer,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ide_access(
|
||||||
|
&self,
|
||||||
|
drive: ATADriveType,
|
||||||
|
sector: u64,
|
||||||
|
sector_count: usize,
|
||||||
|
direction: ATADriveDirection,
|
||||||
|
buffer: &mut [u8],
|
||||||
|
) -> Result<(), ()> {
|
||||||
self.await_busy();
|
self.await_busy();
|
||||||
|
|
||||||
let using_lba48 = sector >= (1 << 28) - 1;
|
let using_lba48 = sector >= (1 << 28) - 1;
|
||||||
@@ -342,7 +364,7 @@ impl<'a> ATABus {
|
|||||||
);
|
);
|
||||||
outb(
|
outb(
|
||||||
self.io_bar + ATADriveDataRegister::LBA0 as u16,
|
self.io_bar + ATADriveDataRegister::LBA0 as u16,
|
||||||
(sector >> 16) as u8,
|
sector as u8,
|
||||||
);
|
);
|
||||||
outb(
|
outb(
|
||||||
self.io_bar + ATADriveDataRegister::LBA1 as u16,
|
self.io_bar + ATADriveDataRegister::LBA1 as u16,
|
||||||
@@ -350,10 +372,13 @@ impl<'a> ATABus {
|
|||||||
);
|
);
|
||||||
outb(
|
outb(
|
||||||
self.io_bar + ATADriveDataRegister::LBA2 as u16,
|
self.io_bar + ATADriveDataRegister::LBA2 as u16,
|
||||||
sector as u8,
|
(sector >> 16) as u8,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.send_command(ATADriveCommand::ReadPIOExt);
|
match direction {
|
||||||
|
ATADriveDirection::Read => self.send_command(ATADriveCommand::ReadPIOExt),
|
||||||
|
ATADriveDirection::Write => self.send_command(ATADriveCommand::WritePIOExt),
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.select(0xE0 | (drive as u8) | ((sector >> 24) as u8 & 0x0F));
|
self.select(0xE0 | (drive as u8) | ((sector >> 24) as u8 & 0x0F));
|
||||||
|
|
||||||
@@ -374,39 +399,64 @@ impl<'a> ATABus {
|
|||||||
(sector >> 16) as u8,
|
(sector >> 16) as u8,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.send_command(ATADriveCommand::ReadPIO);
|
match direction {
|
||||||
|
ATADriveDirection::Read => self.send_command(ATADriveCommand::ReadPIO),
|
||||||
|
ATADriveDirection::Write => self.send_command(ATADriveCommand::WritePIO),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sector count * 512 = bytes in array
|
// sector count * 512 = bytes in array
|
||||||
let array_size = (sector_count as usize) * ATA_SECTOR_SIZE;
|
let array_size = (sector_count) * ATA_SECTOR_SIZE;
|
||||||
|
|
||||||
|
// Since this is an internal function, this should never fail
|
||||||
|
assert!(buffer.len() >= array_size);
|
||||||
|
|
||||||
// Allocate memory for the array that stores the sector data
|
// Allocate memory for the array that stores the sector data
|
||||||
let mut buffer = Vec::new();
|
let mut buffer_offset = 0;
|
||||||
buffer.reserve_exact(array_size);
|
|
||||||
|
|
||||||
for i in 0..sector_count {
|
for i in 0..sector_count {
|
||||||
self.wait_for_drive_ready()
|
self.wait_for_drive_ready()
|
||||||
.map_err(|_| crate::log_error!("Error reading IDE Device"))?;
|
.map_err(|_| crate::log_error!("Error reading IDE Device"))?;
|
||||||
|
|
||||||
// # Safety
|
// # Safety
|
||||||
//
|
//
|
||||||
// We know that buffer is the exact size of count, so it will never panic:tm:
|
// We know that buffer is at least sector_count * ATA_SECTOR_SIZE, so it will never panic:tm:
|
||||||
unsafe {
|
// unsafe {
|
||||||
insw(
|
// match direction {
|
||||||
self.io_bar + ATADriveDataRegister::Data as u16,
|
// ATADriveDirection::Read => insw(
|
||||||
(buffer.as_mut_ptr() as *mut u16)
|
// self.io_bar + ATADriveDataRegister::Data as u16,
|
||||||
.add((i as usize * ATA_SECTOR_SIZE) / size_of::<u16>()),
|
// (buffer.as_mut_ptr() as *mut u16)
|
||||||
ATA_SECTOR_SIZE / size_of::<u16>() as usize,
|
// .add((i * ATA_SECTOR_SIZE) / size_of::<u16>()),
|
||||||
);
|
// ATA_SECTOR_SIZE / size_of::<u16>(),
|
||||||
|
// ),
|
||||||
|
// ATADriveDirection::Write => outsw(
|
||||||
|
// self.io_bar + ATADriveDataRegister::Data as u16,
|
||||||
|
// (buffer.as_mut_ptr() as *mut u16)
|
||||||
|
// .add((i * ATA_SECTOR_SIZE) / size_of::<u16>()),
|
||||||
|
// ATA_SECTOR_SIZE / size_of::<u16>(),
|
||||||
|
// ),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
buffer.set_len(buffer.len() + ATA_SECTOR_SIZE);
|
for chunk in
|
||||||
|
buffer[buffer_offset..(buffer_offset + ATA_SECTOR_SIZE)].chunks_exact_mut(2)
|
||||||
|
{
|
||||||
|
match direction {
|
||||||
|
ATADriveDirection::Read => {
|
||||||
|
let word =
|
||||||
|
inw(self.io_bar + ATADriveDataRegister::Data as u16).to_le_bytes();
|
||||||
|
chunk.copy_from_slice(&word);
|
||||||
|
}
|
||||||
|
ATADriveDirection::Write => {
|
||||||
|
let word = u16::from_le_bytes(chunk.try_into().unwrap());
|
||||||
|
outw(self.io_bar + ATADriveDataRegister::Data as u16, word);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buffer_offset += ATA_SECTOR_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Turn Vec into Arc in favor of Arc's constant time copy
|
return Ok(());
|
||||||
let arc_data: Arc<[u8]> = Arc::from(buffer);
|
|
||||||
|
|
||||||
return Ok(arc_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn software_reset(&self) {
|
fn software_reset(&self) {
|
||||||
@@ -460,7 +510,7 @@ impl ATADrive {
|
|||||||
|
|
||||||
impl BlockDevice for ATADrive {
|
impl BlockDevice for ATADrive {
|
||||||
fn read(&self, sector: u64, sector_count: usize) -> Result<Arc<[u8]>, ()> {
|
fn read(&self, sector: u64, sector_count: usize) -> Result<Arc<[u8]>, ()> {
|
||||||
if (sector + sector_count as u64) > self.sector_count() as u64 {
|
if (sector + sector_count as u64) > self.sector_count() {
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,8 +525,14 @@ impl BlockDevice for ATADrive {
|
|||||||
return unsafe { *(sectors as *const u32) } as u64;
|
return unsafe { *(sectors as *const u32) } as u64;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&self, sector: u64, data: &[u8]) -> Result<(), ()> {
|
fn write(&self, sector: u64, buffer: &mut [u8]) -> Result<(), ()> {
|
||||||
panic!("TODO: ATA Drive writes");
|
let sector_count = buffer.len() / 512;
|
||||||
|
|
||||||
|
self.bus.software_reset();
|
||||||
|
|
||||||
|
return self
|
||||||
|
.bus
|
||||||
|
.write(self.drive_type, sector, sector_count, buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -500,8 +556,8 @@ fn ide_initialize(bar0: u32, bar1: u32, _bar2: u32, _bar3: u32, _bar4: u32) {
|
|||||||
|
|
||||||
let drive = ATADrive::new(bus.clone(), drive_type);
|
let drive = ATADrive::new(bus.clone(), drive_type);
|
||||||
|
|
||||||
if drive.is_ok() {
|
if let Ok(drive) = drive {
|
||||||
DRIVES.lock().write().push(drive.unwrap());
|
DRIVES.lock().write().push(drive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,7 +576,7 @@ fn ide_initialize(bar0: u32, bar1: u32, _bar2: u32, _bar3: u32, _bar4: u32) {
|
|||||||
crate::log_info!(
|
crate::log_info!(
|
||||||
"ATA: Drive 0 has {} sectors ({} MB)",
|
"ATA: Drive 0 has {} sectors ({} MB)",
|
||||||
sectors,
|
sectors,
|
||||||
(sectors as u64 * ATA_SECTOR_SIZE as u64) / 1024 / 1024
|
(sectors * ATA_SECTOR_SIZE as u64) / 1024 / 1024
|
||||||
);
|
);
|
||||||
|
|
||||||
let mbr_sector = drive.read(0, 1).expect("Failed to read first sector");
|
let mbr_sector = drive.read(0, 1).expect("Failed to read first sector");
|
||||||
@@ -601,7 +657,7 @@ fn ide_initialize(bar0: u32, bar1: u32, _bar2: u32, _bar3: u32, _bar4: u32) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for &partition in partitions.iter() {
|
for &partition in partitions.iter() {
|
||||||
let fat_fs = fat::FATFS::new(drive, partition);
|
let fat_fs = fat::FatFs::new(drive, partition);
|
||||||
|
|
||||||
if fat_fs.is_err() {
|
if fat_fs.is_err() {
|
||||||
continue;
|
continue;
|
||||||
@@ -609,14 +665,36 @@ fn ide_initialize(bar0: u32, bar1: u32, _bar2: u32, _bar3: u32, _bar4: u32) {
|
|||||||
|
|
||||||
let fat_fs = fat_fs.unwrap();
|
let fat_fs = fat_fs.unwrap();
|
||||||
|
|
||||||
let vfs = crate::drivers::fs::vfs::VFS::new(Box::new(fat_fs));
|
let vfs = crate::drivers::fs::vfs::Vfs::new(Box::new(fat_fs));
|
||||||
|
|
||||||
crate::drivers::fs::vfs::VFS_INSTANCES
|
crate::drivers::fs::vfs::VFS_INSTANCES
|
||||||
.lock()
|
.lock()
|
||||||
.write()
|
.write()
|
||||||
.push(vfs);
|
.push(vfs);
|
||||||
|
|
||||||
|
crate::println!(
|
||||||
|
"{:?}",
|
||||||
|
crate::drivers::fs::vfs::VFS_INSTANCES
|
||||||
|
.lock()
|
||||||
|
.read()
|
||||||
|
.last()
|
||||||
|
.unwrap()
|
||||||
|
.open("/example.txt")
|
||||||
|
.unwrap()
|
||||||
|
.read()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut buffer = Vec::with_capacity(4096);
|
||||||
|
unsafe { buffer.set_len(buffer.capacity()) };
|
||||||
|
buffer.fill(0x69_u8);
|
||||||
|
|
||||||
|
let _ = drive.write(0, &mut buffer);
|
||||||
|
|
||||||
|
let data = drive.read(0, 1);
|
||||||
|
|
||||||
|
crate::println!("{:X?}", data);
|
||||||
|
|
||||||
crate::println!("{:?}", partitions);
|
crate::println!("{:?}", partitions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,12 +18,8 @@ pub fn fill_screen(color: u32, mirror_buffer: Option<Framebuffer>) {
|
|||||||
let buffer_size = (framebuffer.pitch / (framebuffer.bpp / 8)) * framebuffer.height;
|
let buffer_size = (framebuffer.pitch / (framebuffer.bpp / 8)) * framebuffer.height;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
if mirror_buffer.is_some() {
|
if let Some(mirror_buffer) = mirror_buffer {
|
||||||
crate::libs::util::memset32(
|
crate::libs::util::memset32(mirror_buffer.pointer as *mut u32, color, buffer_size);
|
||||||
mirror_buffer.unwrap().pointer as *mut u32,
|
|
||||||
color,
|
|
||||||
buffer_size,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::libs::util::memset32(framebuffer_ptr as *mut u32, color, buffer_size);
|
crate::libs::util::memset32(framebuffer_ptr as *mut u32, color, buffer_size);
|
||||||
@@ -55,8 +51,8 @@ pub fn put_char(
|
|||||||
|
|
||||||
for (row_idx, &character_byte) in character_array.iter().enumerate() {
|
for (row_idx, &character_byte) in character_array.iter().enumerate() {
|
||||||
let mut byte = [bg; 8];
|
let mut byte = [bg; 8];
|
||||||
for bit in 0..8 {
|
for (i, bit) in byte.iter_mut().enumerate() {
|
||||||
byte[bit] = [bg, fg][((character_byte >> (7 - bit)) & 0b00000001) as usize]
|
*bit = [bg, fg][((character_byte >> (7 - i)) & 0b00000001) as usize]
|
||||||
}
|
}
|
||||||
|
|
||||||
let row_start_offset = (start_y as usize + row_idx) * framebuffer.pitch
|
let row_start_offset = (start_y as usize + row_idx) * framebuffer.pitch
|
||||||
@@ -198,14 +194,8 @@ pub fn get_framebuffer() -> Option<Framebuffer> {
|
|||||||
|
|
||||||
let framebuffer_response = crate::drivers::video::FRAMEBUFFER_REQUEST
|
let framebuffer_response = crate::drivers::video::FRAMEBUFFER_REQUEST
|
||||||
.get_response()
|
.get_response()
|
||||||
.get();
|
.get()?;
|
||||||
|
|
||||||
if framebuffer_response.is_none() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
// eww, variable redeclaration
|
|
||||||
let framebuffer_response = framebuffer_response.unwrap();
|
|
||||||
if framebuffer_response.framebuffer_count < 1 {
|
if framebuffer_response.framebuffer_count < 1 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@@ -215,7 +205,7 @@ pub fn get_framebuffer() -> Option<Framebuffer> {
|
|||||||
let framebuffer = Framebuffer::new(
|
let framebuffer = Framebuffer::new(
|
||||||
framebuffer_response.bpp as usize,
|
framebuffer_response.bpp as usize,
|
||||||
framebuffer_response.pitch as usize,
|
framebuffer_response.pitch as usize,
|
||||||
framebuffer_response.address.as_ptr().unwrap() as *mut u8,
|
framebuffer_response.address.as_ptr().unwrap(),
|
||||||
framebuffer_response.width as usize,
|
framebuffer_response.width as usize,
|
||||||
framebuffer_response.height as usize,
|
framebuffer_response.height as usize,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ impl<T, F: Fn() -> T> Lazy<T, F> {
|
|||||||
pub const fn new(init_func: F) -> Self {
|
pub const fn new(init_func: F) -> Self {
|
||||||
Lazy {
|
Lazy {
|
||||||
value: UnsafeCell::new(None),
|
value: UnsafeCell::new(None),
|
||||||
init_func: init_func,
|
init_func,
|
||||||
initialized: AtomicBool::new(false),
|
initialized: AtomicBool::new(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! log_info {
|
macro_rules! log_info {
|
||||||
($($arg:tt)*) => (crate::println!("\033[97m[ \033[90m? \033[97m]\033[0m {}", &alloc::format!($($arg)*)));
|
($($arg:tt)*) => ($crate::println!("\033[97m[ \033[90m? \033[97m]\033[0m {}", &alloc::format!($($arg)*)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! log_error {
|
macro_rules! log_error {
|
||||||
($($arg:tt)*) => (crate::println!("\033[97m[ \033[91m! \033[97m]\033[0m {}", &alloc::format!($($arg)*)));
|
($($arg:tt)*) => ($crate::println!("\033[97m[ \033[91m! \033[97m]\033[0m {}", &alloc::format!($($arg)*)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! log_ok {
|
macro_rules! log_ok {
|
||||||
($($arg:tt)*) => (crate::println!("\033[97m[ \033[92m* \033[97m]\033[0;m {}", &alloc::format!($($arg)*)));
|
($($arg:tt)*) => ($crate::println!("\033[97m[ \033[92m* \033[97m]\033[0;m {}", &alloc::format!($($arg)*)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,13 +66,12 @@ pub fn ceil(x: f64) -> f64 {
|
|||||||
|
|
||||||
let u: u64 = x.to_bits();
|
let u: u64 = x.to_bits();
|
||||||
let e: i64 = (u >> 52 & 0x7ff) as i64;
|
let e: i64 = (u >> 52 & 0x7ff) as i64;
|
||||||
let y: f64;
|
|
||||||
|
|
||||||
if e >= 0x3ff + 52 || x == 0. {
|
if e >= 0x3ff + 52 || x == 0. {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
y = if (u >> 63) != 0 {
|
let y = if (u >> 63) != 0 {
|
||||||
x - TOINT + TOINT - x
|
x - TOINT + TOINT - x
|
||||||
} else {
|
} else {
|
||||||
x + TOINT - TOINT - x
|
x + TOINT - TOINT - x
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ pub unsafe fn memset32(dst: *mut u32, val: u32, count: usize) {
|
|||||||
if cfg!(not(any(target_arch = "x86", target_arch = "x86_64"))) {
|
if cfg!(not(any(target_arch = "x86", target_arch = "x86_64"))) {
|
||||||
let mut buf = dst;
|
let mut buf = dst;
|
||||||
unsafe {
|
unsafe {
|
||||||
while buf < dst.offset(count as isize) {
|
while buf < dst.add(count) {
|
||||||
core::ptr::write_volatile(buf, val);
|
core::ptr::write_volatile(buf, val);
|
||||||
buf = buf.offset(1);
|
buf = buf.offset(1);
|
||||||
}
|
}
|
||||||
|
|||||||
32
src/main.rs
32
src/main.rs
@@ -56,6 +56,15 @@ pub struct KernelFeatures {
|
|||||||
pub fat_in_mem: bool,
|
pub fat_in_mem: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl KernelFeatures {
|
||||||
|
fn update_option(&mut self, option: &str, value: &str) {
|
||||||
|
match option {
|
||||||
|
"fat_in_mem" => self.fat_in_mem = value == "true",
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub static KERNEL_FEATURES: libs::lazy::Lazy<KernelFeatures> =
|
pub static KERNEL_FEATURES: libs::lazy::Lazy<KernelFeatures> =
|
||||||
libs::lazy::Lazy::new(parse_kernel_cmdline);
|
libs::lazy::Lazy::new(parse_kernel_cmdline);
|
||||||
|
|
||||||
@@ -86,24 +95,15 @@ fn parse_kernel_cmdline() -> KernelFeatures {
|
|||||||
.split_whitespace()
|
.split_whitespace()
|
||||||
.collect::<Vec<&str>>();
|
.collect::<Vec<&str>>();
|
||||||
|
|
||||||
for &arg in kernel_arguments.iter() {
|
crate::println!("{kernel_arguments:?}");
|
||||||
let arg_parts = arg.split("=").collect::<Vec<&str>>();
|
|
||||||
let mut arg_parts = arg_parts.iter().peekable();
|
|
||||||
|
|
||||||
for _ in 0..arg_parts.len() {
|
for item in kernel_arguments {
|
||||||
let part = arg_parts.next();
|
let parts: Vec<&str> = item.split('=').collect();
|
||||||
if part.is_none() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
match part {
|
if parts.len() == 2 {
|
||||||
Some(&"fat_in_mem") => {
|
let (option, value) = (parts[0], parts[1]);
|
||||||
if arg_parts.peek() == Some(&&"false") {
|
|
||||||
kernel_features.fat_in_mem = false;
|
kernel_features.update_option(option, value);
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ impl BuddyAllocator {
|
|||||||
|
|
||||||
let free_lists: Mutex<[*mut FreeBlock; HEAP_BLOCKS]> = Mutex::new(free_lists_buf);
|
let free_lists: Mutex<[*mut FreeBlock; HEAP_BLOCKS]> = Mutex::new(free_lists_buf);
|
||||||
|
|
||||||
let heap_start = AtomicPtr::new(heap_start as *mut u8);
|
let heap_start = AtomicPtr::new(heap_start);
|
||||||
let heap_size = AtomicUsize::new(heap_size);
|
let heap_size = AtomicUsize::new(heap_size);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ pub static HHDM_OFFSET: Lazy<usize> = Lazy::new(|| {
|
|||||||
});
|
});
|
||||||
|
|
||||||
pub static PHYSICAL_MEMORY_MANAGER: Lazy<PhysicalMemoryManager> =
|
pub static PHYSICAL_MEMORY_MANAGER: Lazy<PhysicalMemoryManager> =
|
||||||
Lazy::new(|| PhysicalMemoryManager::new());
|
Lazy::new(PhysicalMemoryManager::new);
|
||||||
|
|
||||||
pub struct Allocator {
|
pub struct Allocator {
|
||||||
pub inner: Lazy<BuddyAllocator>,
|
pub inner: Lazy<BuddyAllocator>,
|
||||||
@@ -134,7 +134,7 @@ pub trait LabelBytes {
|
|||||||
|
|
||||||
impl LabelBytes for usize {
|
impl LabelBytes for usize {
|
||||||
fn label_bytes(&self) -> Label {
|
fn label_bytes(&self) -> Label {
|
||||||
let bytes = self.clone();
|
let bytes = *self;
|
||||||
|
|
||||||
if bytes >> 30 > 0 {
|
if bytes >> 30 > 0 {
|
||||||
return Label {
|
return Label {
|
||||||
|
|||||||
@@ -28,15 +28,12 @@ impl PhysicalMemoryManager {
|
|||||||
let mut highest_addr: usize = 0;
|
let mut highest_addr: usize = 0;
|
||||||
|
|
||||||
for entry in super::MEMMAP.lock().read().iter() {
|
for entry in super::MEMMAP.lock().read().iter() {
|
||||||
match entry.typ {
|
if entry.typ == limine::MemoryMapEntryType::Usable {
|
||||||
limine::MemoryMapEntryType::Usable => {
|
pmm.usable_pages
|
||||||
pmm.usable_pages
|
.fetch_add(entry.len as usize / PAGE_SIZE, Ordering::SeqCst);
|
||||||
.fetch_add(entry.len as usize / PAGE_SIZE, Ordering::SeqCst);
|
if highest_addr < (entry.base + entry.len) as usize {
|
||||||
if highest_addr < (entry.base + entry.len) as usize {
|
highest_addr = (entry.base + entry.len) as usize;
|
||||||
highest_addr = (entry.base + entry.len) as usize;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +80,7 @@ impl PhysicalMemoryManager {
|
|||||||
let mut p: usize = 0;
|
let mut p: usize = 0;
|
||||||
|
|
||||||
while self.last_used_page_idx.load(Ordering::SeqCst) < limit {
|
while self.last_used_page_idx.load(Ordering::SeqCst) < limit {
|
||||||
if self.bitmap_test(self.last_used_page_idx.fetch_add(1, Ordering::SeqCst)) == true {
|
if self.bitmap_test(self.last_used_page_idx.fetch_add(1, Ordering::SeqCst)) {
|
||||||
p = 0;
|
p = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ impl ModStatusBits {
|
|||||||
let status = self.status.load(Ordering::SeqCst);
|
let status = self.status.load(Ordering::SeqCst);
|
||||||
|
|
||||||
return ModStatus {
|
return ModStatus {
|
||||||
win: ((status >> 0) & 1) != 0,
|
win: (status & 1) != 0,
|
||||||
ctrl: ((status >> 1) & 1) != 0,
|
ctrl: ((status >> 1) & 1) != 0,
|
||||||
alt: ((status >> 2) & 1) != 0,
|
alt: ((status >> 2) & 1) != 0,
|
||||||
shift: ((status >> 3) & 1) != 0,
|
shift: ((status >> 3) & 1) != 0,
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ impl Console {
|
|||||||
let framebuffer = crate::drivers::video::get_framebuffer();
|
let framebuffer = crate::drivers::video::get_framebuffer();
|
||||||
|
|
||||||
// Enable serial if it initialized correctly
|
// Enable serial if it initialized correctly
|
||||||
if crate::drivers::serial::POISONED.load(Ordering::SeqCst) == false {
|
if !crate::drivers::serial::POISONED.load(Ordering::SeqCst) {
|
||||||
self.feature_bits.store(
|
self.feature_bits.store(
|
||||||
self.feature_bits.load(Ordering::SeqCst) | 1 << 1,
|
self.feature_bits.load(Ordering::SeqCst) | 1 << 1,
|
||||||
Ordering::SeqCst,
|
Ordering::SeqCst,
|
||||||
@@ -121,7 +121,7 @@ impl Console {
|
|||||||
let mut in_escape_sequence = false;
|
let mut in_escape_sequence = false;
|
||||||
let mut color_code_buffer = String::new();
|
let mut color_code_buffer = String::new();
|
||||||
|
|
||||||
for (_i, character) in string.chars().enumerate() {
|
for character in string.chars() {
|
||||||
if in_escape_sequence {
|
if in_escape_sequence {
|
||||||
if character == 'm' {
|
if character == 'm' {
|
||||||
in_escape_sequence = false;
|
in_escape_sequence = false;
|
||||||
@@ -251,11 +251,7 @@ impl Console {
|
|||||||
screen_size - skip,
|
screen_size - skip,
|
||||||
);
|
);
|
||||||
|
|
||||||
crate::libs::util::memset32(
|
crate::libs::util::memset32(second_buffer.add(screen_size - skip), 0x000000, skip);
|
||||||
second_buffer.add(screen_size - skip) as *mut u32,
|
|
||||||
0x000000,
|
|
||||||
skip,
|
|
||||||
);
|
|
||||||
|
|
||||||
core::ptr::copy_nonoverlapping(second_buffer, framebuffer, screen_size);
|
core::ptr::copy_nonoverlapping(second_buffer, framebuffer, screen_size);
|
||||||
}
|
}
|
||||||
@@ -267,11 +263,7 @@ impl Console {
|
|||||||
screen_size - skip,
|
screen_size - skip,
|
||||||
);
|
);
|
||||||
|
|
||||||
crate::libs::util::memset32(
|
crate::libs::util::memset32(framebuffer.add(screen_size - skip), 0x000000, skip);
|
||||||
framebuffer.add(screen_size - skip) as *mut u32,
|
|
||||||
0x000000,
|
|
||||||
skip,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -416,14 +408,14 @@ fn color_to_hex(color: u8) -> u32 {
|
|||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! println {
|
macro_rules! println {
|
||||||
() => (crate::print!("\n"));
|
() => ($crate::print!("\n"));
|
||||||
($($arg:tt)*) => (crate::print!("{}\n", &alloc::format!($($arg)*)));
|
($($arg:tt)*) => ($crate::print!("{}\n", &alloc::format!($($arg)*)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! print {
|
macro_rules! print {
|
||||||
($($arg:tt)*) => (
|
($($arg:tt)*) => (
|
||||||
crate::usr::tty::CONSOLE.puts(&alloc::format!($($arg)*))
|
$crate::usr::tty::CONSOLE.puts(&alloc::format!($($arg)*))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -441,7 +433,7 @@ impl InputBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop(&mut self) {
|
pub fn pop(&mut self) {
|
||||||
if self.buffer.len() > 0 {
|
if !self.buffer.is_empty() {
|
||||||
self.buffer.pop();
|
self.buffer.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -495,7 +487,7 @@ pub fn handle_key(key: crate::drivers::keyboard::Key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if key.character.unwrap() == '\u{0008}' {
|
if key.character.unwrap() == '\u{0008}' {
|
||||||
if input_buffer.buffer.len() == 0 {
|
if input_buffer.buffer.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -513,7 +505,7 @@ pub fn handle_key(key: crate::drivers::keyboard::Key) {
|
|||||||
pub fn exec(command: &str) {
|
pub fn exec(command: &str) {
|
||||||
let (command, args) = parse_input(command.trim());
|
let (command, args) = parse_input(command.trim());
|
||||||
|
|
||||||
if command == "" {
|
if command.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -531,7 +523,7 @@ pub fn exec(command: &str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if command == "memalloc" {
|
if command == "memalloc" {
|
||||||
if args.len() == 0 {
|
if args.is_empty() {
|
||||||
println!("Allocation size is required. See --help for detailed instructions.");
|
println!("Allocation size is required. See --help for detailed instructions.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -556,7 +548,7 @@ pub fn exec(command: &str) {
|
|||||||
let layout = core::alloc::Layout::from_size_align(size.unwrap(), 16).unwrap();
|
let layout = core::alloc::Layout::from_size_align(size.unwrap(), 16).unwrap();
|
||||||
|
|
||||||
let mem = unsafe { alloc(layout) as *mut u16 };
|
let mem = unsafe { alloc(layout) as *mut u16 };
|
||||||
unsafe { *(mem as *mut u16) = 42 };
|
unsafe { *(mem) = 42 };
|
||||||
println!("{mem:p} val: {}", unsafe { *(mem) });
|
println!("{mem:p} val: {}", unsafe { *(mem) });
|
||||||
} else {
|
} else {
|
||||||
// deallocate
|
// deallocate
|
||||||
@@ -569,7 +561,7 @@ pub fn exec(command: &str) {
|
|||||||
let mut size = 0;
|
let mut size = 0;
|
||||||
|
|
||||||
for arg in args {
|
for arg in args {
|
||||||
if arg.starts_with("-") {
|
if arg.starts_with('-') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -604,7 +596,7 @@ pub fn exec(command: &str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if command == "memtest" {
|
if command == "memtest" {
|
||||||
if args.len() == 0 {
|
if args.is_empty() {
|
||||||
println!("Memory address to test is required.");
|
println!("Memory address to test is required.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -643,7 +635,7 @@ pub fn exec(command: &str) {
|
|||||||
if command == "echo" {
|
if command == "echo" {
|
||||||
let mut input = "";
|
let mut input = "";
|
||||||
|
|
||||||
if args.len() != 0 {
|
if !args.is_empty() {
|
||||||
input = args[0].as_str();
|
input = args[0].as_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -683,7 +675,7 @@ pub fn exec(command: &str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if command == "read" {
|
if command == "read" {
|
||||||
if args.len() < 1 {
|
if args.is_empty() {
|
||||||
println!("read: usage error: at least one argument is required!");
|
println!("read: usage error: at least one argument is required!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -809,9 +801,9 @@ fn parse_escaped_char(next_char: char) -> char {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_memory_address(input: &str) -> Option<u64> {
|
fn parse_memory_address(input: &str) -> Option<u64> {
|
||||||
if input.starts_with("0x") {
|
if let Some(stripped) = input.strip_prefix("0x") {
|
||||||
u64::from_str_radix(&input[2..], 16).ok()
|
return u64::from_str_radix(stripped, 16).ok();
|
||||||
} else {
|
} else {
|
||||||
None
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user