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

Merge branch 'next'

This commit is contained in:
Stephen Marz 2020-04-25 14:16:09 -04:00
commit 17303a0d63
4 changed files with 66 additions and 31 deletions

View File

@ -242,5 +242,19 @@ pub fn get_mtime() -> usize {
}
}
/// Copy one data from one memory location to another.
pub unsafe fn memcpy(dest: *mut u8, src: *const u8, bytes: usize) {
let bytes_as_8 = bytes / 8;
let bytes_as_1 = bytes % 8;
let dest_as_8 = dest as *mut u64;
let src_as_8 = src as *const u64;
for i in 0..bytes_as_8 {
*(dest_as_8.add(i)) = *(src_as_8.add(i));
}
let bytes_remaining = bytes_as_8 * 8;
for i in bytes_remaining..bytes_remaining+bytes_as_1 {
*(dest.add(i)) = *(src.add(i));
}
}

View File

@ -5,9 +5,10 @@
use crate::{fs::{Descriptor, FileSystem, FsError, Stat},
kmem::{kfree, kmalloc, talloc, tfree},
process::{add_kernel_process_args, set_running, set_waiting, get_by_pid},
process::{add_kernel_process_args, get_by_pid, set_running, set_waiting},
syscall::syscall_block_read};
use crate::cpu::memcpy;
use alloc::string::String;
use core::{mem::size_of, ptr::null_mut};
@ -156,10 +157,9 @@ impl FileSystem for MinixFileSystem {
fn read(desc: &Descriptor, buffer: *mut u8, size: u32, offset: u32) -> u32 {
let mut blocks_seen = 0u32;
let offset_block = offset / BLOCK_SIZE;
let offset_byte = offset % BLOCK_SIZE;
let mut offset_byte = offset % BLOCK_SIZE;
let inode_result = Self::get_inode(desc, desc.node);
let mut block_buffer = BlockBuffer::new(BLOCK_SIZE);
if inode_result.is_none() {
// The inode couldn't be read, for some reason.
return 0;
@ -174,8 +174,9 @@ impl FileSystem for MinixFileSystem {
else {
size
};
let mut bytes_left = 0;
println!("Bytes left = {}", bytes_left);
let mut bytes_read = 0u32;
let mut block_buffer = BlockBuffer::new(BLOCK_SIZE);
// 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.
@ -198,6 +199,27 @@ impl FileSystem for MinixFileSystem {
let zone_offset = zone_num * BLOCK_SIZE;
println!("Zone #{} -> #{} -> {}", i, zone_num, zone_offset);
syc_read(desc, block_buffer.get_mut(), BLOCK_SIZE, zone_offset);
let read_this_many = if BLOCK_SIZE - offset_byte > bytes_left {
bytes_left
}
else {
BLOCK_SIZE - offset_byte
};
println!("Copy {} bytes", read_this_many);
unsafe {
memcpy(
buffer.add(bytes_read as usize,),
block_buffer.get().add(offset_byte as usize,),
read_this_many as usize,
);
}
offset_byte = 0;
bytes_read += read_this_many;
bytes_left -= read_this_many;
if bytes_left == 0 {
return bytes_read;
}
}
blocks_seen += 1;
}
@ -245,7 +267,7 @@ fn read_proc(args_addr: usize) {
size: 500,
pid: args.pid, };
let bytes = MinixFileSystem::read(&desc, args.buffer, args.offset, args.size);
let bytes = MinixFileSystem::read(&desc, args.buffer, args.size, args.offset);
// Let's write the return result into regs[10], which is A0.
let ptr = unsafe { get_by_pid(args.pid) };

View File

@ -4,8 +4,8 @@
// 27 Nov 2019
use crate::{cpu::{build_satp, get_mtime, satp_fence_asid, CpuMode, SatpMode, TrapFrame},
page::{alloc, dealloc, map, unmap, zalloc, EntryBits, Table, PAGE_SIZE}};
use crate::syscall::syscall_exit;
page::{alloc, dealloc, map, unmap, zalloc, EntryBits, Table, PAGE_SIZE},
syscall::syscall_exit};
use alloc::collections::vec_deque::VecDeque;
use core::ptr::null_mut;
@ -152,15 +152,13 @@ fn init_process() {
// We can't do much here until we have system calls because
// we're running in User space.
loop {
// Eventually, this will be a sleep system call.
unsafe {
extern "C" {
fn make_syscall(sysno: usize, duration: usize) -> usize;
}
println!("Init is still here :), alright, back to sleep.");
for _ in 0..500 {
llvm_asm!("wfi");
}
// Alright, I forgot. We cannot put init to sleep since the
// scheduler will loop until it finds a process to run. Since
// the scheduler is called in an interrupt context, nothing else
// can happen until a process becomes available.
println!("Init is still here :), alright, back to sleep.");
for _ in 0..500 {
unsafe { asm!("wfi") };
}
}
}
@ -213,8 +211,8 @@ pub fn add_kernel_process(func: fn()) -> u16 {
// println!("func_addr = {:x} -> {:x}", func_addr, func_vaddr);
// We will convert NEXT_PID below into an atomic increment when
// we start getting into multi-hart processing. For now, we want
// a process. Get it to work, then improve it!
let my_pid = unsafe {NEXT_PID};
// a process. Get it to work, then improve it!
let my_pid = unsafe { NEXT_PID };
let mut ret_proc = Process { frame: zalloc(1) as *mut TrapFrame,
stack: zalloc(STACK_PAGES),
pid: my_pid,
@ -246,7 +244,9 @@ pub fn add_kernel_process(func: fn()) -> u16 {
// Now, we no longer need the owned Deque, so we hand it
// back by replacing the PROCESS_LIST's None with the
// Some(pl).
unsafe { PROCESS_LIST.replace(pl); }
unsafe {
PROCESS_LIST.replace(pl);
}
my_pid
}
else {
@ -258,6 +258,11 @@ pub fn add_kernel_process(func: fn()) -> u16 {
}
}
/// A kernel process is just a function inside of the kernel. Each
/// function will perform a "ret" or return through the return address
/// (ra) register. This function address is what it will return to, which
/// in turn calls exit. If we don't exit, the process will most likely
/// fault.
fn ra_delete_proc() {
syscall_exit();
}
@ -282,8 +287,8 @@ pub fn add_kernel_process_args(func: fn(args_ptr: usize), args: usize) -> u16 {
// println!("func_addr = {:x} -> {:x}", func_addr, func_vaddr);
// We will convert NEXT_PID below into an atomic increment when
// we start getting into multi-hart processing. For now, we want
// a process. Get it to work, then improve it!
let my_pid = unsafe {NEXT_PID};
// a process. Get it to work, then improve it!
let my_pid = unsafe { NEXT_PID };
let mut ret_proc = Process { frame: zalloc(1) as *mut TrapFrame,
stack: zalloc(STACK_PAGES),
pid: my_pid,
@ -316,7 +321,9 @@ pub fn add_kernel_process_args(func: fn(args_ptr: usize), args: usize) -> u16 {
// Now, we no longer need the owned Deque, so we hand it
// back by replacing the PROCESS_LIST's None with the
// Some(pl).
unsafe { PROCESS_LIST.replace(pl); }
unsafe {
PROCESS_LIST.replace(pl);
}
my_pid
}
else {
@ -328,7 +335,6 @@ pub fn add_kernel_process_args(func: fn(args_ptr: usize), args: usize) -> u16 {
}
}
/// This should only be called once, and its job is to create
/// the init process. Right now, this process is in the kernel,
/// but later, it should call the shell.
@ -360,7 +366,6 @@ pub fn init() -> usize {
// Waiting - means that the process is waiting on I/O
// Dead - We should never get here, but we can flag a process as Dead and clean
// it out of the list later.
#[repr(u8)]
pub enum ProcessState {
Running,
Sleeping,
@ -368,12 +373,6 @@ pub enum ProcessState {
Dead,
}
// Let's represent this in C ABI. We do this
// because we need to access some of the fields
// in assembly. Rust gets to choose how it orders
// the fields unless we represent the structure in
// C-style ABI.
#[repr(C)]
pub struct Process {
frame: *mut TrapFrame,
stack: *mut u8,

View File

@ -7,7 +7,7 @@ pub fn test_block() {
let buffer = crate::kmem::kmalloc(1024);
println!("Started test block process, buffer is at {:p}.", buffer);
unsafe {
syscall_fs_read(8, 1, buffer, 0, 1024);
syscall_fs_read(8, 12, buffer, 1024, 0);
for i in 0..32 {
print!("{:02x} ", buffer.add(i).read());
if (i+1) % 16 == 0 {