From 080a529f0168199414a009f4068a4b770f1c752b Mon Sep 17 00:00:00 2001 From: Stephen Marz Date: Sat, 25 Apr 2020 15:15:25 -0400 Subject: [PATCH] Reading up to indirect pointers --- risc_v/src/block.rs | 5 +-- risc_v/src/minixfs.rs | 74 +++++++++++++++++++++++++++++++++++++++---- risc_v/src/syscall.rs | 3 +- risc_v/src/test.rs | 7 ++-- 4 files changed, 77 insertions(+), 12 deletions(-) diff --git a/risc_v/src/block.rs b/risc_v/src/block.rs index af77dd3..a776861 100755 --- a/risc_v/src/block.rs +++ b/risc_v/src/block.rs @@ -5,8 +5,7 @@ use crate::{kmem::{kfree, kmalloc, talloc, tfree}, page::{zalloc, PAGE_SIZE}, - process::{add_kernel_process_args, set_running, set_waiting}, - syscall::syscall_exit, + process::{add_kernel_process_args, set_running, set_waiting, get_by_pid}, virtio, virtio::{Descriptor, MmioOffsets, Queue, StatusField, VIRTIO_RING_SIZE}}; use core::mem::size_of; @@ -365,6 +364,8 @@ pub fn pending(bd: &mut BlockDevice) { // A PID of 0 means that we don't have a watcher. if pid_of_watcher > 0 { set_running(pid_of_watcher); + let proc = get_by_pid(pid_of_watcher); + (*(*proc).get_frame()).regs[10] = (*rq).status.status as usize; // TODO: Set GpA0 to the value of the return status. } kfree(rq as *mut u8); diff --git a/risc_v/src/minixfs.rs b/risc_v/src/minixfs.rs index c7cba45..e9c224b 100755 --- a/risc_v/src/minixfs.rs +++ b/risc_v/src/minixfs.rs @@ -122,7 +122,7 @@ impl MinixFileSystem { // top portion of our buffer. Since we won't be using the super block and inode // simultaneously, we can overlap the memory regions. let super_block = unsafe { &*(buffer.get_mut() as *mut SuperBlock) }; - let inode = unsafe { &*(buffer.get_mut() as *mut Inode) }; + let inode = buffer.get_mut() as *mut Inode; // Read from the block device. The size is 1 sector (512 bytes) and our offset is past // the boot block (first 1024 bytes). This is where the superblock sits. syc_read(desc, buffer.get_mut(), 512, 1024); @@ -132,12 +132,22 @@ impl MinixFileSystem { // have to skip the bitmaps blocks. We have a certain number of inode map blocks (imap) // and zone map blocks (zmap). // The inode comes to us as a NUMBER, not an index. So, we need to subtract 1. - let inode_offset = (2 + super_block.imap_blocks + super_block.zmap_blocks) as usize - * BLOCK_SIZE as usize + (inode_num as usize - 1) * size_of::(); + let inode_offset = + (2 + super_block.imap_blocks + super_block.zmap_blocks) as usize * BLOCK_SIZE as usize; // Now, we read the inode itself. + // The block driver requires that our offset be a multiple of 512. We do that with the + // inode_offset. However, we're going to be reading a group of inodes. syc_read(desc, buffer.get_mut(), 512, inode_offset as u32); - return Some(*inode); + + // There are 512 / size_of() inodes in each read that we can do. However, we + // need to figure out which inode in that group we need to read. We just take + // the % of this to find out. + let read_this_node = (inode_num as usize - 1) % (512 / size_of::()); + + // We copy the inode over. This might not be the best thing since the Inode will + // eventually have to change after writing. + return unsafe { Some(*(inode.add(read_this_node))) }; } // If we get here, some result wasn't OK. Either the super block // or the inode itself. @@ -174,9 +184,11 @@ impl FileSystem for MinixFileSystem { else { size }; - println!("Bytes left = {}", bytes_left); let mut bytes_read = 0u32; let mut block_buffer = BlockBuffer::new(BLOCK_SIZE); + // //////////////////////////////////////////// + // // DIRECT ZONES + // //////////////////////////////////////////// // In Rust, our for loop automatically "declares" i from 0 to < 7. The syntax // 0..7 means 0 through to 7 but not including 7. If we want to include 7, we // would use the syntax 0..=7. @@ -206,7 +218,6 @@ impl FileSystem for MinixFileSystem { else { BLOCK_SIZE - offset_byte }; - println!("Copy {} bytes", read_this_many); unsafe { memcpy( buffer.add(bytes_read as usize,), @@ -220,9 +231,60 @@ impl FileSystem for MinixFileSystem { if bytes_left == 0 { return bytes_read; } + println!("Bytes left = {}", bytes_left); } blocks_seen += 1; } + // //////////////////////////////////////////// + // // SINGLY INDIRECT ZONES + // //////////////////////////////////////////// + // Each indirect zone is a list of pointers, each 4 bytes. These then + // point to zones where the data can be found. + if inode.zones[7] != 0 { + let mut indirect_buffer = BlockBuffer::new(BLOCK_SIZE); + syc_read(desc, indirect_buffer.get_mut(), BLOCK_SIZE, BLOCK_SIZE * inode.zones[7]); + let num_indirect_pointers = BLOCK_SIZE as usize / 4; + let izones = indirect_buffer.get() as *const u32; + for i in 0..num_indirect_pointers { + unsafe { + if izones.add(i).read() != 0 { + if offset_block <= blocks_seen { + syc_read( + desc, + block_buffer.get_mut(), + BLOCK_SIZE, + BLOCK_SIZE * izones.add(i,).read(), + ); + let read_this_many = if BLOCK_SIZE - offset_byte > bytes_left { + bytes_left + } + else { + BLOCK_SIZE - offset_byte + }; + memcpy( + buffer.add(bytes_read as usize,), + block_buffer.get().add(offset_byte as usize,), + read_this_many as usize, + ); + bytes_read += read_this_many; + bytes_left -= read_this_many; + println!("Bytes left = {}", bytes_left); + offset_byte = 0; + if bytes_left == 0 { + return bytes_read; + } + } + blocks_seen += 1; + } + } + } + } + // //////////////////////////////////////////// + // // DOUBLY INDIRECT ZONES + // //////////////////////////////////////////// + // //////////////////////////////////////////// + // // TRIPLY INDIRECT ZONES + // //////////////////////////////////////////// bytes_read } diff --git a/risc_v/src/syscall.rs b/risc_v/src/syscall.rs index 15b8fe3..59bc3b4 100755 --- a/risc_v/src/syscall.rs +++ b/risc_v/src/syscall.rs @@ -6,7 +6,7 @@ use crate::{block::block_op, cpu::TrapFrame, minixfs, - process::{delete_process, set_sleeping}}; + process::{delete_process, set_sleeping, set_waiting}}; pub fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize { let syscall_number; @@ -62,6 +62,7 @@ pub fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize { // (*frame).regs[12], // (*frame).regs[13] // ); + set_waiting((*frame).pid as u16); let _ = block_op((*frame).regs[10], (*frame).regs[11] as *mut u8, (*frame).regs[12] as u32, diff --git a/risc_v/src/test.rs b/risc_v/src/test.rs index 0c75a3c..f6e5a60 100644 --- a/risc_v/src/test.rs +++ b/risc_v/src/test.rs @@ -4,11 +4,12 @@ use crate::syscall::syscall_fs_read; pub fn test_block() { // Let's test the block driver! - let buffer = crate::kmem::kmalloc(1024); + let bytes_to_read = 1024 * 14; + let buffer = crate::kmem::kmalloc(bytes_to_read); println!("Started test block process, buffer is at {:p}.", buffer); unsafe { - syscall_fs_read(8, 12, buffer, 1024, 0); - for i in 0..32 { + syscall_fs_read(8, 5, buffer, bytes_to_read as u32, 0); + for i in 0..16*4 { print!("{:02x} ", buffer.add(i).read()); if (i+1) % 16 == 0 { println!();