1
0
mirror of https://github.com/sgmarz/osblog.git synced 2024-11-24 02:16:19 +04:00

Reading up to indirect pointers

This commit is contained in:
Stephen Marz 2020-04-25 15:15:25 -04:00
parent c2fb6cf90d
commit 080a529f01
4 changed files with 77 additions and 12 deletions

View File

@ -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);

View File

@ -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::<Inode>();
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<Inode>() 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::<Inode>());
// 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
}

View File

@ -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,

View File

@ -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!();