mem: implement PageBox<T>

This commit is contained in:
Mark Poliakov 2023-12-10 20:54:15 +02:00
parent 4d23cc5c74
commit 6aa18a1fa2
19 changed files with 342 additions and 177 deletions

View File

@ -7,3 +7,4 @@ edition = "2021"
[dependencies]
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
log = "0.4.20"

View File

@ -6,9 +6,10 @@ extern "Rust" {
pub fn __acquire_irq_guard() -> bool;
pub fn __release_irq_guard(mask: bool);
pub fn __allocate_2m_page() -> u64;
pub fn __allocate_page() -> u64;
pub fn __free_page(page: u64);
pub fn __allocate_2m_page() -> Result<PhysicalAddress, Error>;
pub fn __allocate_page() -> Result<PhysicalAddress, Error>;
pub fn __allocate_contiguous_pages(count: usize) -> Result<PhysicalAddress, Error>;
pub fn __free_page(page: PhysicalAddress);
pub fn __virtualize(phys: u64) -> usize;
pub fn __physicalize(virt: usize) -> u64;

View File

@ -1,5 +1,12 @@
#![no_std]
#![feature(maybe_uninit_slice, step_trait, const_trait_impl, effects)]
#![feature(
maybe_uninit_slice,
step_trait,
const_trait_impl,
effects,
slice_ptr_get,
strict_provenance
)]
extern crate alloc;

View File

@ -1,3 +1,221 @@
use core::{
alloc::Layout,
fmt,
mem::{size_of, MaybeUninit},
ops::{Deref, DerefMut},
};
use yggdrasil_abi::error::Error;
use crate::api::{__allocate_contiguous_pages, __free_page, __physicalize};
use self::address::{AsPhysicalAddress, PhysicalAddress};
pub mod address;
pub mod device;
pub mod pointer;
pub mod table;
pub struct PageBox<T: ?Sized> {
value: *mut T,
page_count: usize,
}
impl<T> PageBox<T> {
#[inline]
fn alloc_slice(count: usize) -> Result<(PhysicalAddress, usize), Error> {
// TODO hardcoded page sizes
let layout = Layout::array::<T>(count).unwrap();
let page_count = (layout.size() + 0xFFF) / 0x1000;
Ok((
unsafe { __allocate_contiguous_pages(page_count) }?,
page_count,
))
}
#[inline]
fn alloc() -> Result<(PhysicalAddress, usize), Error> {
let page_count = (size_of::<T>() + 0xFFF) / 0x1000;
Ok((
unsafe { __allocate_contiguous_pages(page_count) }?,
page_count,
))
}
pub fn new(init: T) -> Result<PageBox<T>, Error> {
let (base, page_count) = Self::alloc()?;
let value = base.virtualize_raw() as *mut T;
unsafe {
value.write(init);
}
let result = PageBox { value, page_count };
result.trace_created();
Ok(result)
}
pub fn new_slice(item: T, count: usize) -> Result<PageBox<[T]>, Error>
where
T: Copy,
{
let (base, page_count) = Self::alloc_slice(count)?;
let base_virt_ptr = base.virtualize_raw() as *mut T;
let value = core::ptr::slice_from_raw_parts_mut(base_virt_ptr, count);
for i in 0..count {
unsafe {
value.get_unchecked_mut(i).write(item);
}
}
let result = PageBox { value, page_count };
result.trace_created();
Ok(result)
}
pub fn new_uninit() -> Result<PageBox<MaybeUninit<T>>, Error> {
let (base, page_count) = PageBox::<MaybeUninit<T>>::alloc()?;
let value = base.virtualize_raw() as *mut MaybeUninit<T>;
let result = PageBox { value, page_count };
result.trace_created();
Ok(result)
}
pub fn new_uninit_slice(count: usize) -> Result<PageBox<[MaybeUninit<T>]>, Error> {
let (base, page_count) = PageBox::<MaybeUninit<T>>::alloc_slice(count)?;
let base_virt_ptr = base.virtualize_raw() as *mut MaybeUninit<T>;
let value = core::ptr::slice_from_raw_parts_mut(base_virt_ptr, count);
let result = PageBox { value, page_count };
result.trace_created();
Ok(result)
}
}
impl<T: ?Sized> PageBox<T> {
#[inline]
pub fn as_ptr(&self) -> *const T {
self.value as _
}
#[inline]
fn trace_created(&self) {
log::trace!(
"Alloc PageBox<{}> @ {:p}, {}",
core::any::type_name::<T>(),
self.value,
self.page_count
);
}
#[inline]
fn trace_dropped(&self) {
log::trace!(
"Free PageBox<{}> @ {:p}, {}",
core::any::type_name::<T>(),
self.value,
self.page_count
);
}
}
impl<T> PageBox<MaybeUninit<T>> {
pub unsafe fn assume_init(self) -> PageBox<T> {
// SAFETY: Memory-safe, as:
// 1. MaybeUninit<T> is transparent
// 2. self.value still points to the same memory and is not deallocated
let page_count = self.page_count;
let value = MaybeUninit::assume_init_mut(&mut *self.value);
// Prevent deallocation of the PageBox with MaybeUninit
core::mem::forget(self);
PageBox { value, page_count }
}
}
impl<T> PageBox<[MaybeUninit<T>]> {
pub unsafe fn assume_init_slice(self) -> PageBox<[T]> {
// SAFETY: Memory-safe, as:
// 1. MaybeUninit<T> is transparent
// 2. self.value still points to the same memory and is not deallocated
let page_count = self.page_count;
let value = MaybeUninit::slice_assume_init_mut(&mut *self.value);
core::mem::forget(self);
PageBox { value, page_count }
}
pub unsafe fn assume_init_slice_ref(&self) -> &[T] {
MaybeUninit::slice_assume_init_ref(self.deref())
}
pub unsafe fn assume_init_slice_mut(&mut self) -> &mut [T] {
MaybeUninit::slice_assume_init_mut(self.deref_mut())
}
}
impl<T: ?Sized> AsPhysicalAddress for PageBox<T> {
#[inline]
unsafe fn as_physical_address(&self) -> PhysicalAddress {
PhysicalAddress(__physicalize(self.value.addr()))
}
}
impl<T: ?Sized> Deref for PageBox<T> {
type Target = T;
#[inline(always)]
fn deref(&self) -> &Self::Target {
unsafe { &*self.value }
}
}
impl<T: ?Sized> DerefMut for PageBox<T> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *self.value }
}
}
impl<T: ?Sized> Drop for PageBox<T> {
fn drop(&mut self) {
self.trace_dropped();
unsafe {
core::ptr::drop_in_place(self.value);
}
// SAFETY: Safe, pointer obtained through "virtualize"
let base = PhysicalAddress(unsafe { __physicalize(self.value.addr()) });
for i in 0..self.page_count {
// SAFETY: Safe, page allocated only by this PageBox
unsafe {
__free_page(base.add(0x1000 * i));
}
}
}
}
impl<T: ?Sized> fmt::Pointer for PageBox<T> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.value.fmt(f)
}
}
impl<T: ?Sized + fmt::Debug> fmt::Debug for PageBox<T> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.deref(), f)
}
}
impl<T: ?Sized + fmt::Display> fmt::Display for PageBox<T> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self.deref(), f)
}
}
unsafe impl<T: ?Sized + Send> Send for PageBox<T> {}
unsafe impl<T: ?Sized + Sync> Sync for PageBox<T> {}

View File

@ -1,11 +1,9 @@
//! Pointer utilities and interfaces
use core::{
fmt,
ops::{Deref, DerefMut},
};
use kernel_util::mem::address::{AsPhysicalAddress, PhysicalAddress};
use super::address::{AsPhysicalAddress, PhysicalAddress};
/// Wrapper for immutably accessing a value at a physical address
#[repr(transparent)]

View File

@ -3,13 +3,7 @@
#![cfg_attr(not(test), no_std)]
#![allow(clippy::new_ret_no_self)]
#![deny(missing_docs)]
#![feature(
trait_upcasting,
if_let_guard,
maybe_uninit_slice,
trait_alias,
let_chains
)]
#![feature(if_let_guard, maybe_uninit_slice, trait_alias, let_chains)]
#[cfg(test)]
extern crate hosted_tests;

View File

@ -16,7 +16,10 @@ use device_api::{
Device,
};
use kernel_util::{
mem::address::{FromRaw, PhysicalAddress},
mem::{
address::{FromRaw, PhysicalAddress},
pointer::PhysicalRef,
},
sync::IrqSafeSpinlock,
util::OneTimeInit,
};
@ -27,7 +30,7 @@ use crate::{
x86_64::{smp::CPU_COUNT, IrqNumber, SHUTDOWN_FENCE},
Architecture, CpuMessage, ARCHITECTURE,
},
mem::{heap::GLOBAL_HEAP, pointer::PhysicalRef, read_memory, write_memory},
mem::{heap::GLOBAL_HEAP, read_memory, write_memory},
};
use super::intrinsics;

View File

@ -1,6 +1,7 @@
//! x86-64-specific process address space management functions
use kernel_util::mem::{
address::{AsPhysicalAddress, IntoRaw, PhysicalAddress},
pointer::PhysicalRefMut,
table::EntryLevelExt,
};
use yggdrasil_abi::error::Error;
@ -9,7 +10,6 @@ use crate::{
arch::x86_64::intrinsics,
mem::{
phys,
pointer::PhysicalRefMut,
process::ProcessAddressSpaceManager,
table::{EntryLevel, MapAttributes, NextPageTable},
},

View File

@ -6,11 +6,13 @@ use core::{
use abi::error::Error;
use bitflags::bitflags;
use kernel_util::mem::address::{AsPhysicalAddress, FromRaw, PhysicalAddress};
use kernel_util::mem::{
address::{AsPhysicalAddress, FromRaw, PhysicalAddress},
pointer::{PhysicalRef, PhysicalRefMut},
};
use crate::mem::{
phys,
pointer::{PhysicalRef, PhysicalRefMut},
table::{EntryLevel, MapAttributes, NextPageTable, NonTerminalEntryLevel},
};

View File

@ -2,7 +2,10 @@
use core::sync::atomic::{AtomicUsize, Ordering};
use acpi_lib::platform::{ProcessorInfo, ProcessorState};
use kernel_util::mem::address::{AsPhysicalAddress, FromRaw, IntoRaw, PhysicalAddress};
use kernel_util::mem::{
address::{AsPhysicalAddress, FromRaw, IntoRaw, PhysicalAddress},
pointer::PhysicalRefMut,
};
use crate::{
arch::{
@ -16,7 +19,7 @@ use crate::{
},
Architecture, ArchitectureImpl,
},
mem::{phys, pointer::PhysicalRefMut},
mem::phys,
task::Cpu,
};

View File

@ -20,7 +20,7 @@ impl NvmeDrive {
nsid: u32,
) -> Result<&'static NvmeDrive, NvmeError> {
let admin_q = controller.admin_q.get();
let identify = admin_q.request(IdentifyNamespaceRequest { nsid })?.await?;
let identify = admin_q.request(IdentifyNamespaceRequest { nsid }).await?;
let current_lba_format_idx = identify.current_lba_fmt_idx();
let current_lba_format = identify.lba_fmt(current_lba_format_idx).unwrap();
@ -49,23 +49,6 @@ impl NvmeDrive {
Ok(dev)
}
// TODO proper interface for reading/writing blocks
// pub async fn read_block(
// &self,
// lba: u64,
// block: &mut PhysicalRefMut<'_, [u8]>,
// ) -> Result<(), NvmeError> {
// self.controller.read_block(self.nsid, lba, block).await
// }
// pub async fn write_block(
// &self,
// lba: u64,
// block: &PhysicalRefMut<'_, [u8]>,
// ) -> Result<(), NvmeError> {
// self.controller.write_block(self.nsid, lba, block).await
// }
}
impl BlockDevice for NvmeDrive {

View File

@ -6,7 +6,7 @@ use alloc::{collections::BTreeMap, vec::Vec};
use device_api::{interrupt::MsiHandler, Device};
use kernel_util::{
mem::{
address::{AsPhysicalAddress, FromRaw, IntoRaw, PhysicalAddress},
address::{FromRaw, IntoRaw, PhysicalAddress},
device::{DeviceMemoryIo, DeviceMemoryIoMut},
},
sync::IrqSafeSpinlock,
@ -32,7 +32,6 @@ use crate::{
queue::{CompletionQueueEntry, SubmissionQueueEntry},
},
},
mem::pointer::PhysicalRefMut,
task::runtime,
};
@ -117,8 +116,8 @@ register_structs! {
pub struct NvmeController {
regs: IrqSafeSpinlock<DeviceMemoryIo<'static, Regs>>,
admin_q: OneTimeInit<QueuePair<'static>>,
ioqs: OneTimeInit<Vec<QueuePair<'static>>>,
admin_q: OneTimeInit<QueuePair>,
ioqs: OneTimeInit<Vec<QueuePair>>,
vector_table: IrqSafeSpinlock<DeviceMemoryIoMut<'static, [MsiXEntry]>>,
drive_table: IrqSafeSpinlock<BTreeMap<u32, &'static NvmeDrive>>,
controller_id: OneTimeInit<usize>,
@ -126,6 +125,12 @@ pub struct NvmeController {
doorbell_shift: usize,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum IoDirection {
Read,
Write,
}
impl Regs {
unsafe fn doorbell_ptr(&self, shift: usize, completion: bool, queue_index: usize) -> *mut u32 {
let doorbell_base = (self as *const Regs as *mut Regs).addr() + 0x1000;
@ -141,7 +146,7 @@ impl NvmeController {
let admin_q = self.admin_q.get();
// Identify the controller
let _identify = admin_q.request(IdentifyControllerRequest)?.await?;
let _identify = admin_q.request(IdentifyControllerRequest).await?;
// TODO do something with identify_controller
@ -185,7 +190,7 @@ impl NvmeController {
let admin_q = self.admin_q.get();
let namespaces = admin_q
.request(IdentifyActiveNamespaceIdListRequest { start_id: 0 })?
.request(IdentifyActiveNamespaceIdListRequest { start_id: 0 })
.await?;
let count = namespaces.entries.iter().position(|&x| x == 0).unwrap();
@ -205,17 +210,19 @@ impl NvmeController {
Ok(())
}
pub async fn read_block(
// TODO sane methods for IO
pub async fn perform_io(
&'static self,
nsid: u32,
lba: u64,
buffer: &mut PhysicalRefMut<'_, [u8]>,
buffer_address: PhysicalAddress,
direction: IoDirection,
) -> Result<(), NvmeError> {
let ioq = &self.ioqs.get()[0];
let buffer_address = unsafe { buffer.as_physical_address() };
debugln!("read nsid={}, lba={:#x}", nsid, lba);
let cmd_id = ioq.submit(
debugln!("{:?} nsid={}, lba={:#x}", direction, nsid, lba);
let cmd_id = match direction {
IoDirection::Read => ioq.submit(
IoRead {
nsid,
lba,
@ -223,24 +230,8 @@ impl NvmeController {
},
&[buffer_address],
true,
);
ioq.wait_for_completion(cmd_id, ()).await?;
Ok(())
}
pub async fn write_block(
&'static self,
nsid: u32,
lba: u64,
buffer: &PhysicalRefMut<'_, [u8]>,
) -> Result<(), NvmeError> {
let ioq = &self.ioqs.get()[0];
let buffer_address = unsafe { buffer.as_physical_address() };
debugln!("write nsid={}, lba={:#x}", nsid, lba);
let cmd_id = ioq.submit(
),
IoDirection::Write => ioq.submit(
IoWrite {
nsid,
lba,
@ -248,7 +239,8 @@ impl NvmeController {
},
&[buffer_address],
true,
);
),
};
ioq.wait_for_completion(cmd_id, ()).await?;

View File

@ -14,18 +14,14 @@ use bytemuck::{Pod, Zeroable};
use futures_util::Future;
use kernel_util::{
mem::{
address::{IntoRaw, PhysicalAddress},
table::EntryLevelExt,
address::{AsPhysicalAddress, IntoRaw, PhysicalAddress},
PageBox,
},
sync::IrqSafeSpinlock,
};
use static_assertions::const_assert;
use crate::{
arch::L3,
mem::{phys, pointer::PhysicalRefMut},
task::runtime::QueueWaker,
};
use crate::task::runtime::QueueWaker;
use super::{
command::{Command, Request},
@ -74,9 +70,8 @@ pub struct CompletionQueueEntry {
dw: [u32; 4],
}
pub struct Queue<'a, T> {
data: PhysicalRefMut<'a, [T]>,
pub struct Queue<T> {
data: PageBox<[T]>,
mask: usize,
head: usize,
tail: usize,
@ -86,28 +81,26 @@ pub struct Queue<'a, T> {
tail_doorbell: *mut u32,
}
struct Inner<'a> {
sq: Queue<'a, SubmissionQueueEntry>,
cq: Queue<'a, CompletionQueueEntry>,
struct Inner {
sq: Queue<SubmissionQueueEntry>,
cq: Queue<CompletionQueueEntry>,
completed: BTreeMap<u32, CompletionQueueEntry>,
pending: BTreeSet<u32>,
}
// TODO PageBox<T>?
#[allow(unused)]
pub struct QueuePair<'a> {
base: PhysicalAddress,
page_count: usize,
pub struct QueuePair {
id: u32,
#[allow(unused)]
vector: usize,
sq_base: PhysicalAddress,
cq_base: PhysicalAddress,
completion_notify: QueueWaker,
inner: IrqSafeSpinlock<Inner<'a>>,
inner: IrqSafeSpinlock<Inner>,
}
const_assert!(size_of::<CompletionQueueEntry>().is_power_of_two());
@ -166,25 +159,23 @@ impl CompletionQueueEntry {
}
}
impl<'a, T> Queue<'a, T> {
pub unsafe fn from_raw_parts(
base: PhysicalAddress,
len: usize,
impl<T> Queue<T> {
pub fn new(
data: PageBox<[T]>,
head_doorbell: *mut u32,
tail_doorbell: *mut u32,
phase: bool,
) -> Self {
// Submission queues have tail doorbells, completion queues have head doorbells
assert!(
(head_doorbell.is_null() && !tail_doorbell.is_null())
|| (!head_doorbell.is_null() && tail_doorbell.is_null())
);
Self {
data: PhysicalRefMut::map_slice(base, len),
mask: len - 1,
mask: data.len() - 1,
head: 0,
tail: 0,
data,
head_doorbell,
tail_doorbell,
phase,
@ -246,13 +237,9 @@ impl<'a, T> Queue<'a, T> {
wrapped
}
// pub fn is_empty(&self) -> bool {
// self.head == self.tail
// }
}
impl<'a> QueuePair<'a> {
impl QueuePair {
pub fn new(
id: u32,
vector: usize,
@ -260,24 +247,16 @@ impl<'a> QueuePair<'a> {
sq_doorbell: *mut u32,
cq_doorbell: *mut u32,
) -> Result<Self, Error> {
let sq_size = capacity * size_of::<SubmissionQueueEntry>();
let cq_size = capacity * size_of::<CompletionQueueEntry>();
let sq_data = PageBox::new_slice(SubmissionQueueEntry::zeroed(), capacity)?;
let cq_data = PageBox::new_slice(CompletionQueueEntry::zeroed(), capacity)?;
let page_count = sq_size.page_count::<L3>() + cq_size.page_count::<L3>();
let base = phys::alloc_pages_contiguous(page_count)?;
let sq_base = unsafe { sq_data.as_physical_address() };
let cq_base = unsafe { cq_data.as_physical_address() };
let sq_base = base;
let cq_base = base.add(sq_size.page_align_up::<L3>());
debugln!("Allocated queue pair: sq={:p}, cq={:p}", sq_data, cq_data);
debugln!(
"Allocated queue pair: sq={:x?}, cq={:x?} ({} pages)",
sq_base..sq_base.add(sq_size),
cq_base..cq_base.add(cq_size),
page_count
);
let sq = unsafe { Queue::from_raw_parts(sq_base, capacity, null_mut(), sq_doorbell, true) };
let cq = unsafe { Queue::from_raw_parts(cq_base, capacity, cq_doorbell, null_mut(), true) };
let sq = Queue::new(sq_data, null_mut(), sq_doorbell, true);
let cq = Queue::new(cq_data, cq_doorbell, null_mut(), true);
let inner = IrqSafeSpinlock::new(Inner {
sq,
@ -291,8 +270,6 @@ impl<'a> QueuePair<'a> {
id,
vector,
base,
page_count,
sq_base,
cq_base,
inner,
@ -313,12 +290,9 @@ impl<'a> QueuePair<'a> {
&'r self,
command_id: u32,
result: T,
) -> impl Future<Output = Result<T, CommandError>> + 'r
where
'r: 'a,
{
) -> impl Future<Output = Result<T, CommandError>> + 'r {
struct Fut<'r, R: Unpin + 'r> {
this: &'r QueuePair<'r>,
this: &'r QueuePair,
response: Option<R>,
command_id: u32,
}
@ -386,34 +360,22 @@ impl<'a> QueuePair<'a> {
pub fn request_no_data<'r, C: Command>(
&'r self,
req: C,
) -> impl Future<Output = Result<(), CommandError>> + 'r
where
'r: 'a,
{
) -> impl Future<Output = Result<(), CommandError>> + 'r {
let command_id = self.submit(req, &[], true);
self.wait_for_completion(command_id, ())
}
pub fn request<'r, R: Request>(
pub async fn request<'r, R: Request>(
&'r self,
req: R,
) -> Result<
impl Future<Output = Result<PhysicalRefMut<'r, R::Response>, CommandError>>,
NvmeError,
>
) -> Result<PageBox<R::Response>, NvmeError>
where
R::Response: 'r,
'r: 'a,
{
assert_ne!(size_of::<R::Response>(), 0);
assert!(size_of::<R::Response>() <= 0x1000);
let page = phys::alloc_page().map_err(NvmeError::MemoryError)?;
// TODO PageBox
let response = unsafe { PhysicalRefMut::map(page) };
let command_id = self.submit(req, &[page], true);
Ok(self.wait_for_completion(command_id, response))
let response = PageBox::new_uninit().map_err(NvmeError::MemoryError)?;
let command_id = self.submit(req, &[unsafe { response.as_physical_address() }], true);
let result = self.wait_for_completion(command_id, response).await?;
Ok(unsafe { result.assume_init() })
}
pub fn process_completions(&self) -> usize {

View File

@ -14,7 +14,6 @@ use crate::arch::{Architecture, ArchitectureImpl};
pub mod address;
pub mod heap;
pub mod phys;
pub mod pointer;
pub mod process;
pub mod table;

View File

@ -1,8 +1,9 @@
//! Physical memory manager implementation
use abi::error::Error;
use kernel_util::mem::address::{FromRaw, IntoRaw, PhysicalAddress};
use crate::mem::pointer::PhysicalRefMut;
use kernel_util::mem::{
address::{FromRaw, IntoRaw, PhysicalAddress},
pointer::PhysicalRefMut,
};
pub type BitmapWord = u64;

View File

@ -208,3 +208,13 @@ fn kernel_physical_memory_region() -> PhysicalMemoryRegion {
PhysicalMemoryRegion { base, size }
}
#[no_mangle]
fn __allocate_contiguous_pages(count: usize) -> Result<PhysicalAddress, Error> {
alloc_pages_contiguous(count)
}
#[no_mangle]
unsafe fn __free_page(page: PhysicalAddress) {
free_page(page)
}

View File

@ -7,16 +7,12 @@ use elf::{
segment::ProgramHeader,
ElfStream, ParseError,
};
use kernel_util::mem::pointer::{PhysicalRef, PhysicalRefMut};
use vfs::{FileRef, Read, Seek};
use yggdrasil_abi::{error::Error, io::SeekFrom};
use crate::{
mem::{
phys,
pointer::{PhysicalRef, PhysicalRefMut},
process::ProcessAddressSpace,
table::MapAttributes,
},
mem::{phys, process::ProcessAddressSpace, table::MapAttributes},
task::process::{ProcessImage, ProcessTlsInfo, ProcessTlsLayout},
};

View File

@ -9,13 +9,11 @@ use abi::{
process::ProgramArgumentInner,
};
use alloc::{string::String, sync::Arc, vec::Vec};
use kernel_util::mem::pointer::PhysicalRefMut;
use vfs::{FileRef, IoContext, Read, Seek};
use crate::{
mem::{
phys, pointer::PhysicalRefMut, process::ProcessAddressSpace, table::MapAttributes,
ForeignPointer,
},
mem::{phys, process::ProcessAddressSpace, table::MapAttributes, ForeignPointer},
proc,
task::{
context::TaskContextImpl,
@ -190,7 +188,9 @@ pub fn load<P: AsRef<Path>>(
let count = file.read(&mut head)?;
let head = &head[..count];
if let Some(shebang) = head.strip_prefix(b"#!") && let Some((shebang, _)) = shebang.split_once(|&ch| ch == b'\n') {
if let Some(shebang) = head.strip_prefix(b"#!")
&& let Some((shebang, _)) = shebang.split_once(|&ch| ch == b'\n')
{
let shebang = core::str::from_utf8(shebang).map_err(|_| Error::InvalidFile)?;
let mut shebang_args = shebang.split(' ').collect::<Vec<_>>();
if shebang_args.is_empty() || shebang_args.len() >= 8 {

View File

@ -5,12 +5,7 @@ use std::{
};
use bitflags::bitflags;
use bytemuck::Zeroable;
use elf::{
abi::{PF_W, PF_X, PT_LOAD},
endian::AnyEndian,
ElfStream,
};
use elf::{abi::PT_LOAD, endian::AnyEndian, ElfStream};
use memtables::x86_64::{FixedTables, KERNEL_L3_COUNT};
use crate::{GenData, GenError};
@ -36,7 +31,7 @@ pub struct X8664Builder<F: Seek + Read> {
}
impl PageFlags {
fn from_elf(flags: u32) -> Self {
fn from_elf(_flags: u32) -> Self {
let mut out = Self::empty();
// if flags & PF_W != 0 {
out |= Self::WRITABLE;