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:
parent
c2fb6cf90d
commit
080a529f01
@ -5,8 +5,7 @@
|
|||||||
|
|
||||||
use crate::{kmem::{kfree, kmalloc, talloc, tfree},
|
use crate::{kmem::{kfree, kmalloc, talloc, tfree},
|
||||||
page::{zalloc, PAGE_SIZE},
|
page::{zalloc, PAGE_SIZE},
|
||||||
process::{add_kernel_process_args, set_running, set_waiting},
|
process::{add_kernel_process_args, set_running, set_waiting, get_by_pid},
|
||||||
syscall::syscall_exit,
|
|
||||||
virtio,
|
virtio,
|
||||||
virtio::{Descriptor, MmioOffsets, Queue, StatusField, VIRTIO_RING_SIZE}};
|
virtio::{Descriptor, MmioOffsets, Queue, StatusField, VIRTIO_RING_SIZE}};
|
||||||
use core::mem::size_of;
|
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.
|
// A PID of 0 means that we don't have a watcher.
|
||||||
if pid_of_watcher > 0 {
|
if pid_of_watcher > 0 {
|
||||||
set_running(pid_of_watcher);
|
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.
|
// TODO: Set GpA0 to the value of the return status.
|
||||||
}
|
}
|
||||||
kfree(rq as *mut u8);
|
kfree(rq as *mut u8);
|
||||||
|
@ -122,7 +122,7 @@ impl MinixFileSystem {
|
|||||||
// top portion of our buffer. Since we won't be using the super block and inode
|
// top portion of our buffer. Since we won't be using the super block and inode
|
||||||
// simultaneously, we can overlap the memory regions.
|
// simultaneously, we can overlap the memory regions.
|
||||||
let super_block = unsafe { &*(buffer.get_mut() as *mut SuperBlock) };
|
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
|
// 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.
|
// the boot block (first 1024 bytes). This is where the superblock sits.
|
||||||
syc_read(desc, buffer.get_mut(), 512, 1024);
|
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)
|
// have to skip the bitmaps blocks. We have a certain number of inode map blocks (imap)
|
||||||
// and zone map blocks (zmap).
|
// and zone map blocks (zmap).
|
||||||
// The inode comes to us as a NUMBER, not an index. So, we need to subtract 1.
|
// 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
|
let inode_offset =
|
||||||
* BLOCK_SIZE as usize + (inode_num as usize - 1) * size_of::<Inode>();
|
(2 + super_block.imap_blocks + super_block.zmap_blocks) as usize * BLOCK_SIZE as usize;
|
||||||
|
|
||||||
// Now, we read the inode itself.
|
// 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);
|
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
|
// If we get here, some result wasn't OK. Either the super block
|
||||||
// or the inode itself.
|
// or the inode itself.
|
||||||
@ -174,9 +184,11 @@ impl FileSystem for MinixFileSystem {
|
|||||||
else {
|
else {
|
||||||
size
|
size
|
||||||
};
|
};
|
||||||
println!("Bytes left = {}", bytes_left);
|
|
||||||
let mut bytes_read = 0u32;
|
let mut bytes_read = 0u32;
|
||||||
let mut block_buffer = BlockBuffer::new(BLOCK_SIZE);
|
let mut block_buffer = BlockBuffer::new(BLOCK_SIZE);
|
||||||
|
// ////////////////////////////////////////////
|
||||||
|
// // DIRECT ZONES
|
||||||
|
// ////////////////////////////////////////////
|
||||||
// In Rust, our for loop automatically "declares" i from 0 to < 7. The syntax
|
// 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
|
// 0..7 means 0 through to 7 but not including 7. If we want to include 7, we
|
||||||
// would use the syntax 0..=7.
|
// would use the syntax 0..=7.
|
||||||
@ -206,7 +218,6 @@ impl FileSystem for MinixFileSystem {
|
|||||||
else {
|
else {
|
||||||
BLOCK_SIZE - offset_byte
|
BLOCK_SIZE - offset_byte
|
||||||
};
|
};
|
||||||
println!("Copy {} bytes", read_this_many);
|
|
||||||
unsafe {
|
unsafe {
|
||||||
memcpy(
|
memcpy(
|
||||||
buffer.add(bytes_read as usize,),
|
buffer.add(bytes_read as usize,),
|
||||||
@ -220,9 +231,60 @@ impl FileSystem for MinixFileSystem {
|
|||||||
if bytes_left == 0 {
|
if bytes_left == 0 {
|
||||||
return bytes_read;
|
return bytes_read;
|
||||||
}
|
}
|
||||||
|
println!("Bytes left = {}", bytes_left);
|
||||||
}
|
}
|
||||||
blocks_seen += 1;
|
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
|
bytes_read
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
use crate::{block::block_op,
|
use crate::{block::block_op,
|
||||||
cpu::TrapFrame,
|
cpu::TrapFrame,
|
||||||
minixfs,
|
minixfs,
|
||||||
process::{delete_process, set_sleeping}};
|
process::{delete_process, set_sleeping, set_waiting}};
|
||||||
|
|
||||||
pub fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
pub fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
||||||
let syscall_number;
|
let syscall_number;
|
||||||
@ -62,6 +62,7 @@ pub fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
|||||||
// (*frame).regs[12],
|
// (*frame).regs[12],
|
||||||
// (*frame).regs[13]
|
// (*frame).regs[13]
|
||||||
// );
|
// );
|
||||||
|
set_waiting((*frame).pid as u16);
|
||||||
let _ = block_op((*frame).regs[10],
|
let _ = block_op((*frame).regs[10],
|
||||||
(*frame).regs[11] as *mut u8,
|
(*frame).regs[11] as *mut u8,
|
||||||
(*frame).regs[12] as u32,
|
(*frame).regs[12] as u32,
|
||||||
|
@ -4,11 +4,12 @@ use crate::syscall::syscall_fs_read;
|
|||||||
|
|
||||||
pub fn test_block() {
|
pub fn test_block() {
|
||||||
// Let's test the block driver!
|
// 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);
|
println!("Started test block process, buffer is at {:p}.", buffer);
|
||||||
unsafe {
|
unsafe {
|
||||||
syscall_fs_read(8, 12, buffer, 1024, 0);
|
syscall_fs_read(8, 5, buffer, bytes_to_read as u32, 0);
|
||||||
for i in 0..32 {
|
for i in 0..16*4 {
|
||||||
print!("{:02x} ", buffer.add(i).read());
|
print!("{:02x} ", buffer.add(i).read());
|
||||||
if (i+1) % 16 == 0 {
|
if (i+1) % 16 == 0 {
|
||||||
println!();
|
println!();
|
||||||
|
Loading…
Reference in New Issue
Block a user