feat(vfs): CoW for memfs, init start

This commit is contained in:
2021-10-26 00:59:43 +03:00
parent 6d8f0d01ef
commit c706428ed6
20 changed files with 291 additions and 71 deletions
+2 -2
View File
@@ -1,11 +1,11 @@
use crate::debug::Level;
use crate::util;
use error::Errno;
use fdt_rs::prelude::*;
use fdt_rs::{
base::DevTree,
index::{DevTreeIndex, DevTreeIndexNode, DevTreeIndexProp},
};
use libcommon::path_component_left;
#[repr(align(16))]
struct Wrap {
@@ -74,7 +74,7 @@ fn dump_node(level: Level, node: &INode, depth: usize) {
}
fn find_node<'a>(at: INode<'a>, path: &str) -> Option<INode<'a>> {
let (item, path) = util::path_component_left(path);
let (item, path) = path_component_left(path);
if item == "" {
assert_eq!(path, "");
Some(at)
+29 -11
View File
@@ -5,7 +5,9 @@ use crate::mem::{
phys::{self, PageUsage},
virt::{MapAttributes, Space},
};
use core::mem::{size_of, MaybeUninit};
use error::Errno;
use libcommon::{Read, Seek, SeekDir};
trait Elf {
type Addr;
@@ -86,12 +88,12 @@ fn map_flags(elf_flags: usize) -> MapAttributes {
unsafe fn load_bytes<F>(
space: &mut Space,
dst_virt: usize,
read: F,
mut read: F,
size: usize,
flags: usize,
) -> Result<(), Errno>
where
F: Fn(usize, &mut [u8]) -> Result<(), Errno>,
F: FnMut(usize, &mut [u8]) -> Result<(), Errno>,
{
let dst_page_off = dst_virt & 0xFFF;
let dst_page = dst_virt & !0xFFF;
@@ -125,17 +127,32 @@ where
Ok(())
}
unsafe fn read_struct<T, F: Seek + Read>(src: &mut F, pos: usize) -> Result<T, Errno> {
let mut storage: MaybeUninit<T> = MaybeUninit::uninit();
let size = size_of::<T>();
src.seek(pos as isize, SeekDir::Set)?;
let res = src.read(core::slice::from_raw_parts_mut(
storage.as_mut_ptr() as *mut u8,
size,
))?;
if res != size {
Err(Errno::InvalidArgument)
} else {
Ok(storage.assume_init())
}
}
///
pub fn load_elf(space: &mut Space, elf_base: *const u8) -> Result<usize, Errno> {
let ehdr: &Ehdr<Elf64> = unsafe { &*(elf_base as *const _) };
pub fn load_elf<F: Seek + Read>(space: &mut Space, source: &mut F) -> Result<usize, Errno> {
let ehdr: Ehdr<Elf64> = unsafe { read_struct(source, 0).unwrap() };
if &ehdr.ident[0..4] != b"\x7FELF" {
return Err(Errno::InvalidArgument);
}
for i in 0..(ehdr.phnum as usize) {
let phdr: &Phdr<Elf64> = unsafe {
&*(elf_base.add(ehdr.phoff as usize + ehdr.phentsize as usize * i) as *const _)
let phdr: Phdr<Elf64> = unsafe {
read_struct(source, ehdr.phoff as usize + ehdr.phentsize as usize * i).unwrap()
};
if phdr.typ == 1
@@ -154,11 +171,12 @@ pub fn load_elf(space: &mut Space, elf_base: *const u8) -> Result<usize, Errno>
space,
phdr.vaddr as usize,
|off, dst| {
let src = elf_base.add(phdr.offset as usize + off);
assert!(off + dst.len() <= phdr.filesz as usize);
let src_slice = core::slice::from_raw_parts(src, dst.len());
dst.copy_from_slice(src_slice);
Ok(())
source.seek(phdr.offset as isize + off as isize, SeekDir::Set)?;
if source.read(dst)? == dst.len() {
Ok(())
} else {
Err(Errno::InvalidArgument)
}
},
phdr.filesz as usize,
phdr.flags as usize,
+4 -8
View File
@@ -66,21 +66,17 @@ pub unsafe fn enter(initrd: Option<(usize, usize)>) -> ! {
let (start, end) = unsafe { *(initrd_ptr as *const (usize, usize)) };
let size = end - start;
infoln!("Constructing initrd filesystem in memory, this may take a while...");
let fs = Ramfs::open(start as *mut u8, size, MemfsBlockAlloc {}).unwrap();
infoln!("Done constructing ramfs");
let root = fs.root().unwrap();
let ioctx = Ioctx::new(root);
// Open a test file
let node = ioctx.find(None, "/test.txt").unwrap();
let node = ioctx.find(None, "/init").unwrap();
let mut file = node.open().unwrap();
let mut buf = [0u8; 16];
while let Ok(count) = file.read(&mut buf) {
if count == 0 {
break;
}
debugln!("Read {} bytes: {:?}", count, &buf[0..count]);
}
Process::execve(|space| elf::load_elf(space, &mut file), 0).unwrap();
}, initrd as usize);
}
SCHED.enter();
-9
View File
@@ -51,12 +51,3 @@ impl<T> InitOnce<T> {
}
unsafe impl<T> Sync for InitOnce<T> {}
///
pub fn path_component_left(path: &str) -> (&str, &str) {
if let Some((left, right)) = path.split_once('/') {
(left, right.trim_start_matches('/'))
} else {
(path, "")
}
}