Compare commits
No commits in common. "184030a45e0f8ddc4256bf67d6efbf334f89897c" and "e5eb05eb3db4ad94dc292a94262c49a9df3985d1" have entirely different histories.
184030a45e
...
e5eb05eb3d
@ -170,7 +170,7 @@ p2_table:
|
|||||||
resb 4096
|
resb 4096
|
||||||
|
|
||||||
stack_bottom:
|
stack_bottom:
|
||||||
resb 100 * 4096
|
resb 4 * 4096
|
||||||
stack_top:
|
stack_top:
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,24 +3,26 @@ use core::pin::Pin;
|
|||||||
use core::sync::atomic::{AtomicBool, Ordering};
|
use core::sync::atomic::{AtomicBool, Ordering};
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
|
|
||||||
use futures_util::task::AtomicWaker;
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
use futures_util::task::AtomicWaker;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref INTERRUPT_FUTURE: InterruptFuture = InterruptFuture::new();
|
pub static ref INTERRUPT_FUTURE: InterruptFuture = InterruptFuture::new();
|
||||||
|
|
||||||
static ref INTERRUPT: AtomicBool = AtomicBool::new(false);
|
static ref INTERRUPT: AtomicBool = AtomicBool::new(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static WAKER: AtomicWaker = AtomicWaker::new();
|
static WAKER: AtomicWaker = AtomicWaker::new();
|
||||||
|
|
||||||
|
|
||||||
pub(crate) fn mark_interrupt() {
|
pub(crate) fn mark_interrupt() {
|
||||||
INTERRUPT.store(true, Ordering::Relaxed);
|
INTERRUPT.store(true, Ordering::Relaxed);
|
||||||
WAKER.wake();
|
WAKER.wake();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy,Clone)]
|
||||||
pub struct InterruptFuture {
|
pub struct InterruptFuture {
|
||||||
_private: (),
|
_private:(),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InterruptFuture {
|
impl InterruptFuture {
|
||||||
@ -49,7 +51,7 @@ impl Future for InterruptFuture {
|
|||||||
true => {
|
true => {
|
||||||
WAKER.take();
|
WAKER.take();
|
||||||
Poll::Ready(())
|
Poll::Ready(())
|
||||||
}
|
},
|
||||||
false => Poll::Pending,
|
false => Poll::Pending,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
pub mod interrupt;
|
|
||||||
mod scsi;
|
mod scsi;
|
||||||
|
pub mod interrupt;
|
||||||
|
|
||||||
use crate::{println, serial_println};
|
use crate::{println, serial_println};
|
||||||
use interrupt::INTERRUPT_FUTURE;
|
use scsi::{SCSIPacket};
|
||||||
use scsi::SCSIPacket;
|
use interrupt::{INTERRUPT_FUTURE};
|
||||||
|
|
||||||
use core::convert::TryInto;
|
use core::convert::TryInto;
|
||||||
|
|
||||||
use crate::utils::AsyncMutex;
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
use crate::utils::AsyncMutex;
|
||||||
use x86_64::instructions::port::Port;
|
use x86_64::instructions::port::Port;
|
||||||
|
|
||||||
const CD_SECTOR_SIZE: usize = 2048;
|
const CD_SECTOR_SIZE: usize = 2048;
|
||||||
|
|
||||||
// Data buses
|
// Data buses
|
||||||
const ATA_BUS_PRIMARY: u16 = 0x1f0;
|
const ATA_BUS_PRIMARY: u16= 0x1f0;
|
||||||
const ATA_BUS_SECONDARY: u16 = 0x170;
|
const ATA_BUS_SECONDARY: u16 = 0x170;
|
||||||
|
|
||||||
// Drives
|
// Drives
|
||||||
@ -54,13 +54,16 @@ static ATAPI_SIG: [u8; 4] = [
|
|||||||
ATAPI_SIG_SC,
|
ATAPI_SIG_SC,
|
||||||
ATAPI_SIG_LBA_LO,
|
ATAPI_SIG_LBA_LO,
|
||||||
ATAPI_SIG_LBA_MI,
|
ATAPI_SIG_LBA_MI,
|
||||||
ATAPI_SIG_LBA_HI,
|
ATAPI_SIG_LBA_HI
|
||||||
];
|
];
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref DRIVE: AsyncMutex<Option<ATABus>> = AsyncMutex::new(ATABus::discover_atapi_drive());
|
pub static ref DRIVE: AsyncMutex<Option<ATABus>> = {
|
||||||
|
AsyncMutex::new(ATABus::discover_atapi_drive())
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub async fn init() {
|
pub async fn init() {
|
||||||
println!("Detecting drives");
|
println!("Detecting drives");
|
||||||
match DRIVE.lock().await.as_ref() {
|
match DRIVE.lock().await.as_ref() {
|
||||||
@ -69,12 +72,12 @@ pub async fn init() {
|
|||||||
let drive_type = match drive.current_drive {
|
let drive_type = match drive.current_drive {
|
||||||
ATA_DRIVE_MASTER => "master",
|
ATA_DRIVE_MASTER => "master",
|
||||||
ATA_DRIVE_SLAVE => "slave",
|
ATA_DRIVE_SLAVE => "slave",
|
||||||
_ => "bad",
|
_ => "bad"
|
||||||
};
|
};
|
||||||
let bus = match drive.base_port {
|
let bus = match drive.base_port {
|
||||||
ATA_BUS_PRIMARY => "primary",
|
ATA_BUS_PRIMARY => "primary",
|
||||||
ATA_BUS_SECONDARY => "secondary",
|
ATA_BUS_SECONDARY => "secondary",
|
||||||
_ => "bad",
|
_ => "bad"
|
||||||
};
|
};
|
||||||
println!("Detected {} drive on {} bus", drive_type, bus);
|
println!("Detected {} drive on {} bus", drive_type, bus);
|
||||||
}
|
}
|
||||||
@ -201,7 +204,7 @@ impl ATABus {
|
|||||||
self.wait_packet_request();
|
self.wait_packet_request();
|
||||||
|
|
||||||
for i in (0..raw_packet.len()).step_by(2) {
|
for i in (0..raw_packet.len()).step_by(2) {
|
||||||
let word = u16::from_le_bytes(raw_packet[i..i + 2].try_into().unwrap());
|
let word = u16::from_le_bytes(raw_packet[i..i+2].try_into().unwrap());
|
||||||
unsafe {
|
unsafe {
|
||||||
self.data.write(word);
|
self.data.write(word);
|
||||||
}
|
}
|
||||||
@ -320,12 +323,9 @@ impl ATABus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub async fn print_block(lba: u32) {
|
pub async fn print_block(lba: u32) {
|
||||||
let block = DRIVE.lock().await.as_mut().unwrap().read_block(lba).await;
|
let block = DRIVE.lock().await.as_mut().unwrap().read_block(lba).await;
|
||||||
serial_println!("{:x?}", block);
|
serial_println!("{:x?}", block);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn read_block(lba: u32) -> [u8; CD_SECTOR_SIZE] {
|
|
||||||
DRIVE.lock().await.as_mut().unwrap().read_block(lba).await
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
use postcard::to_vec;
|
use postcard::{to_vec};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
#[derive(Default, Serialize, Deserialize, Debug, Eq, PartialEq)]
|
#[derive(Default, Serialize, Deserialize, Debug, Eq, PartialEq)]
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
@ -15,7 +15,7 @@ pub struct SCSIPacket {
|
|||||||
transfer_length_milo: u8,
|
transfer_length_milo: u8,
|
||||||
transfer_length_lo: u8,
|
transfer_length_lo: u8,
|
||||||
flags_hi: u8,
|
flags_hi: u8,
|
||||||
control: u8,
|
control: u8
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SCSIPacket {
|
impl SCSIPacket {
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
pub mod atapi;
|
|
||||||
pub mod serial;
|
pub mod serial;
|
||||||
pub mod vga;
|
pub mod vga;
|
||||||
|
pub mod atapi;
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
use crate::println;
|
use crate::println;
|
||||||
use crate::utils::AsyncMutex;
|
use crate::utils::AsyncMutex;
|
||||||
|
|
||||||
use alloc::{boxed::Box, collections::BTreeMap, sync::Arc};
|
use alloc::{collections::BTreeMap, sync::Arc, boxed::Box};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
use core::sync::atomic::{AtomicU32, Ordering};
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
pub type FDt = Arc<RefCell<dyn FileDescriptor>>;
|
pub type FDt = Arc<RefCell<dyn FileDescriptor>>;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref FD_TABLE: AsyncMutex<FDTable> = AsyncMutex::new(FDTable::new());
|
pub static ref FD_TABLE: AsyncMutex<FDTable> = {
|
||||||
|
AsyncMutex::new(FDTable::new())
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct FDId(u32);
|
pub struct FDId(u64);
|
||||||
|
|
||||||
impl FDId {
|
impl FDId {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
// TODO: search for first available fd
|
// TODO: search for first available fd
|
||||||
static NEXT_ID: AtomicU32 = AtomicU32::new(0);
|
FDId(1)
|
||||||
FDId(NEXT_ID.fetch_add(1, Ordering::Relaxed))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,25 +30,13 @@ pub struct FDTable {
|
|||||||
|
|
||||||
impl FDTable {
|
impl FDTable {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
FDTable {
|
FDTable { table: BTreeMap::new() }
|
||||||
table: BTreeMap::new(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unregister_fd(&mut self, fd: &dyn FileDescriptor) {
|
pub async fn register_fd(&mut self, fd: FDt) {
|
||||||
self.table.remove(&fd.get_fd());
|
// TODO
|
||||||
println!(
|
|
||||||
"Unregistered fd: {:?}",
|
|
||||||
fd.get_fd()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register_fd(&mut self, fd: FDt) {
|
|
||||||
self.table.insert(fd.borrow().get_fd(), fd.clone());
|
self.table.insert(fd.borrow().get_fd(), fd.clone());
|
||||||
println!(
|
println!("Registered fd: {:?}", self.table.get(&FDId(1)).unwrap().borrow().get_fd());
|
||||||
"Registered fd: {:?}",
|
|
||||||
self.table.get(&FDId(0)).unwrap().borrow().get_fd()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +44,5 @@ impl FDTable {
|
|||||||
pub trait FileDescriptor {
|
pub trait FileDescriptor {
|
||||||
fn get_fd(&self) -> FDId;
|
fn get_fd(&self) -> FDId;
|
||||||
async fn write(&mut self, buf: &[u8], count: usize) -> isize;
|
async fn write(&mut self, buf: &[u8], count: usize) -> isize;
|
||||||
async fn read(&mut self, buf: &mut [u8], count: usize) -> isize;
|
async fn read(&mut self, buf: &[u8], count: usize) -> isize;
|
||||||
async fn close(&mut self);
|
|
||||||
async fn lseek(&mut self, offset: i32, whence: u32) -> i32;
|
|
||||||
}
|
}
|
@ -1,30 +1,19 @@
|
|||||||
use crate::drivers::atapi::read_block;
|
use crate::println;
|
||||||
use crate::fd::{FDId, FDt, FileDescriptor, FD_TABLE};
|
use crate::fd::{FDId, FileDescriptor, FDt};
|
||||||
|
|
||||||
use super::iso9660::{IsoDir, ISO_BLOCK_SIZE};
|
use alloc::{sync::Arc, boxed::Box};
|
||||||
|
|
||||||
use alloc::{boxed::Box, sync::Arc};
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
|
|
||||||
pub struct IsoFD {
|
pub struct IsoFD {
|
||||||
pub fd: FDId,
|
pub fd: FDId,
|
||||||
offset: u32,
|
|
||||||
lba: u32,
|
|
||||||
size: u32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IsoFD {
|
impl IsoFD {
|
||||||
pub async fn new(entry: &IsoDir) -> FDt {
|
pub fn new() -> FDt {
|
||||||
let fd = Arc::new(RefCell::new(IsoFD {
|
Arc::new(RefCell::new(IsoFD {
|
||||||
fd: FDId::new(),
|
fd: FDId::new(),
|
||||||
offset: 0,
|
}))
|
||||||
lba: entry.data_blk.le,
|
|
||||||
size: entry.file_size.le,
|
|
||||||
}));
|
|
||||||
|
|
||||||
FD_TABLE.lock().await.register_fd(fd.clone());
|
|
||||||
fd
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,45 +23,12 @@ impl FileDescriptor for IsoFD {
|
|||||||
self.fd
|
self.fd
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn write(&mut self, _buf: &[u8], _count: usize) -> isize {
|
async fn write(&mut self, buf: &[u8], count: usize) -> isize {
|
||||||
-1
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unaligned_references)]
|
async fn read(&mut self, buf: &[u8], count: usize) -> isize {
|
||||||
async fn read(&mut self, buf: &mut [u8], count: usize) -> isize {
|
println!("Read from fd");
|
||||||
let mut block_offset = self.offset / ISO_BLOCK_SIZE;
|
0
|
||||||
let mut content = read_block(self.lba + block_offset).await;
|
|
||||||
let mut read: isize = 0;
|
|
||||||
for _ in 0..count {
|
|
||||||
if self.offset >= self.size {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf[read as usize] = content[(self.offset % ISO_BLOCK_SIZE) as usize];
|
|
||||||
read += 1;
|
|
||||||
self.offset += 1;
|
|
||||||
|
|
||||||
if self.offset % ISO_BLOCK_SIZE == 0 {
|
|
||||||
block_offset += 1;
|
|
||||||
content = read_block(self.lba + block_offset).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
read
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn close(&mut self) {
|
|
||||||
FD_TABLE.lock().await.unregister_fd(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn lseek(&mut self, offset: i32, whence: u32) -> i32 {
|
|
||||||
use crate::syscalls::io::*;
|
|
||||||
match whence {
|
|
||||||
w if w == SEEK_SET => self.offset = offset as u32,
|
|
||||||
w if w == SEEK_CUR => self.offset = (self.offset as i32 + offset) as u32,
|
|
||||||
w if w == SEEK_END => self.offset = (self.size as i32 + offset) as u32,
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
self.offset as i32
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,21 +1,22 @@
|
|||||||
pub const ISO_BLOCK_SIZE: u32 = 2048;
|
const ISO_BLOCK_SIZE: usize = 2048;
|
||||||
|
|
||||||
// Twin values structs
|
// Twin values structs
|
||||||
|
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct MultiEndian32 {
|
pub struct MultiEndian32 {
|
||||||
pub le: u32, // Little endian value
|
le: u32, // Little endian value
|
||||||
pub be: u32, // Big endian value
|
be: u32, // Big endian value
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct MultiEndian16 {
|
pub struct MultiEndian16 {
|
||||||
pub le: u16, // Little endian value
|
le: u16, // Little endian value
|
||||||
pub be: u16, // Big endian value
|
be: u16, // Big endian value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Path table structure
|
// Path table structure
|
||||||
|
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
@ -25,77 +26,63 @@ struct IsoPathTable {
|
|||||||
ext_size: u8, // Extended attribute record length
|
ext_size: u8, // Extended attribute record length
|
||||||
data_blk: u8, // File data block index
|
data_blk: u8, // File data block index
|
||||||
parent_dir: u16, // Number of the parent dir
|
parent_dir: u16, // Number of the parent dir
|
||||||
idf: [u8; 0], // Directory name, of size Self::idf_len
|
idf: [u8; 0] // Directory name, of size Self::idf_len
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
impl IsoPathTable {
|
impl IsoPathTable {
|
||||||
#[allow(unaligned_references)]
|
#[allow(unaligned_references)]
|
||||||
pub fn get_idf(&self) -> &[u8] {
|
pub fn get_idf(&self) -> &[u8] {
|
||||||
unsafe { core::slice::from_raw_parts(self.idf.as_ptr(), self.idf_len as usize) }
|
unsafe {
|
||||||
|
core::slice::from_raw_parts(self.idf.as_ptr(), self.idf_len as usize)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Directory structure
|
// Directory structure
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
const ISO_MAX_DIR_DEPTH: usize = 8;
|
|
||||||
const ISO_DATE_LEN: usize = 7;
|
const ISO_DATE_LEN: usize = 7;
|
||||||
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
#[derive(Copy, Clone)]
|
||||||
#[allow(dead_code)]
|
enum IsoFileType {
|
||||||
pub enum IsoFileType {
|
|
||||||
HIDDEN = 0x1, // Hidden file
|
HIDDEN = 0x1, // Hidden file
|
||||||
ISDIR = 0x2, // Directory
|
ISDIR = 0x2, // Directory
|
||||||
ASSOCIAT = 0x4, // Associated
|
ASSOCIAT = 0x4, // Associated
|
||||||
USEEXT = 0x8, //
|
USEEXT = 0x8, //
|
||||||
USEPERM = 0x10, //
|
USEPERM = 0x10, //
|
||||||
MULTIDIR = 0x80, //
|
MULTIDIR = 0x80 //
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct IsoDir {
|
pub struct IsoDir {
|
||||||
pub dir_size: u8, // Length of directory record
|
dir_size: u8, // Length of directory record
|
||||||
pub ext_size: u8, // Length of extended attribute record
|
ext_size: u8, // Length of extended attribute record
|
||||||
pub data_blk: MultiEndian32, // File data block index
|
data_blk: MultiEndian32, // File data block index
|
||||||
pub file_size: MultiEndian32, // File size
|
file_size: MultiEndian32, // File size
|
||||||
pub date: [u8; ISO_DATE_LEN],
|
date: [u8; ISO_DATE_LEN],
|
||||||
pub file_type: IsoFileType,
|
file_type: IsoFileType,
|
||||||
|
|
||||||
pub unit_size: u8,
|
unit_size: u8,
|
||||||
pub gap_size: u8,
|
gap_size: u8,
|
||||||
|
|
||||||
pub vol_seq: MultiEndian16,
|
vol_seq: MultiEndian16,
|
||||||
|
|
||||||
pub idf_len: u8, // File name length
|
idf_len: u8, // File name length
|
||||||
pub idf: [u8; 0], // File name
|
idf: [u8; 0], // File name
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IsoDir {
|
impl IsoDir {
|
||||||
#[allow(unaligned_references)]
|
#[allow(unaligned_references)]
|
||||||
pub fn get_idf(&self) -> &[u8] {
|
pub fn get_idf(&self) -> &[u8] {
|
||||||
let mut len: usize = self.idf_len as usize;
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut idf = core::slice::from_raw_parts(self.idf.as_ptr(), len as usize);
|
core::slice::from_raw_parts(self.idf.as_ptr(), self.idf_len as usize)
|
||||||
if len > 2 && idf[len - 2] == b';' && idf[len - 1] == b'1' {
|
|
||||||
len -= 2;
|
|
||||||
idf = core::slice::from_raw_parts(self.idf.as_ptr(), len as usize);
|
|
||||||
}
|
}
|
||||||
idf
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next_entry(&self) -> &IsoDir {
|
|
||||||
crate::utils::ref_raw_offset(self, self.dir_size as isize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn matches(&self, path: &str) -> bool {
|
|
||||||
self.get_idf() == path.as_bytes()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Primary volume descriptor structure
|
// Primary volume descriptor structure
|
||||||
|
|
||||||
pub const ISO_PRIM_VOLDESC_BLOCK: u32 = 16;
|
pub const ISO_PRIM_VOLDESC_BLOCK: u32 = 16;
|
||||||
|
@ -1,83 +1,37 @@
|
|||||||
mod fd;
|
|
||||||
pub mod iso9660;
|
pub mod iso9660;
|
||||||
|
mod fd;
|
||||||
|
|
||||||
use crate::drivers::atapi::read_block;
|
use crate::println;
|
||||||
use crate::fd::{FDt};
|
use crate::drivers::atapi::{DRIVE};
|
||||||
|
use crate::fd::{FD_TABLE, FDt};
|
||||||
use crate::utils::unserialize;
|
use crate::utils::unserialize;
|
||||||
|
|
||||||
use super::FileSystem;
|
use iso9660::{IsoPrimVolDesc, IsoDir};
|
||||||
use fd::IsoFD;
|
use fd::IsoFD;
|
||||||
use iso9660::{IsoDir, IsoPrimVolDesc};
|
|
||||||
|
|
||||||
use alloc::{boxed::Box, string::String, vec::Vec};
|
pub async fn get_prim_vol_desc() -> IsoPrimVolDesc {
|
||||||
use async_trait::async_trait;
|
let desc_block = DRIVE
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.read_block(iso9660::ISO_PRIM_VOLDESC_BLOCK)
|
||||||
|
.await;
|
||||||
|
*unserialize::<IsoPrimVolDesc>(desc_block.as_ptr())
|
||||||
|
}
|
||||||
|
|
||||||
pub struct IsoFS {}
|
pub async fn open(path: &str, flags: u32) -> Option<FDt> {
|
||||||
|
|
||||||
#[async_trait(?Send)]
|
|
||||||
#[allow(unaligned_references)]
|
|
||||||
impl FileSystem for IsoFS {
|
|
||||||
async fn open(&mut self, path: &str, flags: u32) -> Option<FDt> {
|
|
||||||
// ISO is a read only file system
|
|
||||||
if flags != crate::syscalls::io::O_RDONLY {
|
if flags != crate::syscalls::io::O_RDONLY {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let voldesc = get_prim_vol_desc().await;
|
let voldesc = get_prim_vol_desc().await;
|
||||||
|
|
||||||
// Invalid ISO
|
|
||||||
if voldesc.std_identifier != "CD001".as_bytes() {
|
if voldesc.std_identifier != "CD001".as_bytes() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let root: &IsoDir = &voldesc.root_dir;
|
let fd = IsoFD::new();
|
||||||
let mut curr_entry_block: [u8; iso9660::ISO_BLOCK_SIZE as usize] = read_block(root.data_blk.le).await;
|
FD_TABLE.lock().await.register_fd(fd.clone()).await;
|
||||||
|
Some(fd)
|
||||||
let mut curr_entry: &IsoDir = unserialize(curr_entry_block.as_ptr());
|
|
||||||
|
|
||||||
let path_s: String = String::from(path);
|
|
||||||
let path_split: Vec<&str> = path_s.split("/").collect();
|
|
||||||
let path_it = path_s
|
|
||||||
.split("/")
|
|
||||||
.filter(|p| p != &"");
|
|
||||||
|
|
||||||
for path_component in path_it {
|
|
||||||
let mut found = false;
|
|
||||||
while curr_entry.idf_len != 0 {
|
|
||||||
|
|
||||||
// Found entry
|
|
||||||
if curr_entry.matches(path_component) {
|
|
||||||
found = true;
|
|
||||||
|
|
||||||
// Not the last component, go 1 directory deeper
|
|
||||||
if path_component != path_split[path_split.len() - 1] {
|
|
||||||
// Not a directory
|
|
||||||
if curr_entry.file_type != iso9660::IsoFileType::ISDIR {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
// Deeper entries
|
|
||||||
curr_entry_block = read_block(curr_entry.data_blk.le).await;
|
|
||||||
curr_entry = unserialize(curr_entry_block.as_ptr());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next entry
|
|
||||||
curr_entry = curr_entry.next_entry();
|
|
||||||
}
|
|
||||||
|
|
||||||
// File not found
|
|
||||||
if !found {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(IsoFD::new(curr_entry).await)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub async fn get_prim_vol_desc() -> IsoPrimVolDesc {
|
|
||||||
let desc_block = read_block(iso9660::ISO_PRIM_VOLDESC_BLOCK).await;
|
|
||||||
*unserialize::<IsoPrimVolDesc>(desc_block.as_ptr())
|
|
||||||
}
|
}
|
@ -1,39 +1 @@
|
|||||||
pub mod iso;
|
pub mod iso;
|
||||||
|
|
||||||
use crate::fd::FDt;
|
|
||||||
use crate::utils::mutex::AsyncMutex;
|
|
||||||
|
|
||||||
use alloc::{boxed::Box, sync::Arc};
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use core::cell::RefCell;
|
|
||||||
use lazy_static::lazy_static;
|
|
||||||
|
|
||||||
pub type FSt = Arc<RefCell<dyn FileSystem>>;
|
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
pub static ref VIRTUAL_FS: AsyncMutex<VirtualFS> = AsyncMutex::new(VirtualFS::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait(?Send)]
|
|
||||||
pub trait FileSystem {
|
|
||||||
async fn open(&mut self, path: &str, flags: u32) -> Option<FDt>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct VirtualFS {
|
|
||||||
fs: FSt,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl VirtualFS {
|
|
||||||
fn new() -> Self {
|
|
||||||
VirtualFS {
|
|
||||||
fs: Arc::new(RefCell::new(iso::IsoFS {})),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait(?Send)]
|
|
||||||
impl FileSystem for VirtualFS {
|
|
||||||
async fn open(&mut self, path: &str, flags: u32) -> Option<FDt> {
|
|
||||||
self.fs.borrow_mut().open(path, flags).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -4,8 +4,12 @@ use crate::memory::gdt;
|
|||||||
use crate::println;
|
use crate::println;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use pic::{
|
use pic::{
|
||||||
disk1_interrupt_handler, disk2_interrupt_handler, init_pic, keyboard_interrupt_handler,
|
init_pic,
|
||||||
timer_interrupt_handler, InterruptIndex,
|
keyboard_interrupt_handler,
|
||||||
|
timer_interrupt_handler,
|
||||||
|
disk1_interrupt_handler,
|
||||||
|
disk2_interrupt_handler,
|
||||||
|
InterruptIndex
|
||||||
};
|
};
|
||||||
use x86_64::structures::idt::PageFaultErrorCode;
|
use x86_64::structures::idt::PageFaultErrorCode;
|
||||||
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
use crate::println;
|
use crate::println;
|
||||||
pub use disk::{disk1_interrupt_handler, disk2_interrupt_handler};
|
|
||||||
pub use keyboard::keyboard_interrupt_handler;
|
pub use keyboard::keyboard_interrupt_handler;
|
||||||
use pic8259::ChainedPics;
|
use pic8259::ChainedPics;
|
||||||
pub use pit::timer_interrupt_handler;
|
pub use pit::timer_interrupt_handler;
|
||||||
|
pub use disk::{disk1_interrupt_handler, disk2_interrupt_handler};
|
||||||
|
|
||||||
pub mod disk;
|
|
||||||
pub mod keyboard;
|
pub mod keyboard;
|
||||||
pub mod pit;
|
pub mod pit;
|
||||||
|
pub mod disk;
|
||||||
|
|
||||||
pub const PIC_1_OFFSET: u8 = 32;
|
pub const PIC_1_OFFSET: u8 = 32;
|
||||||
pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8;
|
pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8;
|
||||||
|
28
src/lib.rs
28
src/lib.rs
@ -4,19 +4,18 @@
|
|||||||
#![feature(alloc_error_handler)]
|
#![feature(alloc_error_handler)]
|
||||||
|
|
||||||
mod drivers;
|
mod drivers;
|
||||||
mod fd;
|
|
||||||
mod fs;
|
|
||||||
mod interrupts;
|
mod interrupts;
|
||||||
mod memory;
|
mod memory;
|
||||||
mod syscalls;
|
|
||||||
mod task;
|
mod task;
|
||||||
|
mod fs;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
mod fd;
|
||||||
|
mod syscalls;
|
||||||
|
|
||||||
//#[macro_use]
|
//#[macro_use]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
extern crate multiboot2;
|
extern crate multiboot2;
|
||||||
|
|
||||||
use crate::fs::FileSystem;
|
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
use drivers::vga::{self, Color, ColorCode};
|
use drivers::vga::{self, Color, ColorCode};
|
||||||
use multiboot2::BootInformation;
|
use multiboot2::BootInformation;
|
||||||
@ -64,23 +63,8 @@ pub extern "C" fn julios_main(multiboot_info_addr: usize) -> ! {
|
|||||||
executor.run();
|
executor.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async fn get_file() {
|
async fn get_file() {
|
||||||
let fd = fs::VIRTUAL_FS
|
let fd = fs::iso::open("test", syscalls::io::O_RDONLY).await.unwrap();
|
||||||
.lock()
|
fd.borrow_mut().read(&[], 0).await;
|
||||||
.await
|
|
||||||
.open("///boot/grub//grub.cfg", syscalls::io::O_RDONLY)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let mut buf: [u8; 100] = [0; 100];
|
|
||||||
let read = fd.borrow_mut().read(&mut buf, 100).await;
|
|
||||||
|
|
||||||
serial_println!("{:?}", read);
|
|
||||||
serial_println!("{}", alloc::str::from_utf8(&buf).unwrap());
|
|
||||||
|
|
||||||
fd.borrow_mut().lseek(10, syscalls::io::SEEK_SET).await;
|
|
||||||
|
|
||||||
fd.borrow_mut().read(&mut buf, 100).await;
|
|
||||||
serial_println!("{}", alloc::str::from_utf8(&buf).unwrap());
|
|
||||||
|
|
||||||
fd.borrow_mut().close().await;
|
|
||||||
}
|
}
|
@ -2,6 +2,9 @@
|
|||||||
pub const O_RDONLY: u32 = 0;
|
pub const O_RDONLY: u32 = 0;
|
||||||
|
|
||||||
// seek flags
|
// seek flags
|
||||||
|
#[allow(dead_code)]
|
||||||
pub const SEEK_SET: u32 = 0;
|
pub const SEEK_SET: u32 = 0;
|
||||||
|
#[allow(dead_code)]
|
||||||
pub const SEEK_CUR: u32 = 1;
|
pub const SEEK_CUR: u32 = 1;
|
||||||
|
#[allow(dead_code)]
|
||||||
pub const SEEK_END: u32 = 2;
|
pub const SEEK_END: u32 = 2;
|
@ -1,19 +1,5 @@
|
|||||||
pub mod mutex;
|
|
||||||
pub mod serialize;
|
pub mod serialize;
|
||||||
|
pub mod mutex;
|
||||||
|
|
||||||
pub use mutex::AsyncMutex;
|
|
||||||
pub use serialize::unserialize;
|
pub use serialize::unserialize;
|
||||||
|
pub use mutex::AsyncMutex;
|
||||||
pub fn ref_offset<T>(r: &T, off: isize) -> &T {
|
|
||||||
let ref_ptr: *const T = r;
|
|
||||||
unsafe {
|
|
||||||
return &*ref_ptr.offset(off);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ref_raw_offset<T>(r: &T, off: isize) -> &T {
|
|
||||||
let ref_ptr: *const T = r;
|
|
||||||
unsafe {
|
|
||||||
return &*ref_ptr.cast::<u8>().offset(off).cast::<T>();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +1,10 @@
|
|||||||
use alloc::sync::Arc;
|
|
||||||
use core::cell::UnsafeCell;
|
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
use core::ops::{Deref, DerefMut, Drop};
|
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
|
use core::cell::UnsafeCell;
|
||||||
|
use core::ops::{Deref, DerefMut, Drop};
|
||||||
use core::sync::atomic::{AtomicBool, Ordering};
|
use core::sync::atomic::{AtomicBool, Ordering};
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
|
use alloc::sync::Arc;
|
||||||
|
|
||||||
use futures_util::task::AtomicWaker;
|
use futures_util::task::AtomicWaker;
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ struct Lock {
|
|||||||
waker: Arc<AtomicWaker>,
|
waker: Arc<AtomicWaker>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AsyncMutex<T: ?Sized> {
|
pub struct AsyncMutex<T> {
|
||||||
lock: Lock,
|
lock: Lock,
|
||||||
inner: UnsafeCell<T>,
|
inner: UnsafeCell<T>,
|
||||||
}
|
}
|
||||||
@ -23,7 +23,7 @@ pub struct AsyncMutexGuard<'a, T>
|
|||||||
where
|
where
|
||||||
T: 'a,
|
T: 'a,
|
||||||
{
|
{
|
||||||
mutex: &'a AsyncMutex<T>,
|
mutex: &'a AsyncMutex<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Lock {
|
impl Lock {
|
||||||
@ -58,7 +58,7 @@ impl Future for Lock {
|
|||||||
false => {
|
false => {
|
||||||
self.waker.take();
|
self.waker.take();
|
||||||
Poll::Ready(())
|
Poll::Ready(())
|
||||||
}
|
},
|
||||||
true => Poll::Pending,
|
true => Poll::Pending,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,12 +98,16 @@ impl<T> Drop for AsyncMutexGuard<'_, T> {
|
|||||||
impl<T> Deref for AsyncMutexGuard<'_, T> {
|
impl<T> Deref for AsyncMutexGuard<'_, T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
unsafe { &*self.mutex.inner.get() }
|
unsafe {
|
||||||
|
&*self.mutex.inner.get()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> DerefMut for AsyncMutexGuard<'_, T> {
|
impl<T> DerefMut for AsyncMutexGuard<'_, T> {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
unsafe { &mut *self.mutex.inner.get() }
|
unsafe {
|
||||||
|
&mut *self.mutex.inner.get()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,6 @@
|
|||||||
pub fn unserialize<T>(ptr: *const u8) -> &'static T {
|
pub fn unserialize<T>(ptr: *const u8) -> &'static T {
|
||||||
let path_table_ptr: *const T = ptr as *const T;
|
let path_table_ptr: *const T = ptr as *const T;
|
||||||
unsafe { &*path_table_ptr }
|
unsafe {
|
||||||
|
&*path_table_ptr
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user