asdf idk uhhhhh
This commit is contained in:
parent
354012852a
commit
c22758f860
|
@ -6,7 +6,8 @@ build-std = ["core", "compiler_builtins", "alloc"]
|
||||||
build-std-features = ["compiler-builtins-mem"]
|
build-std-features = ["compiler-builtins-mem"]
|
||||||
|
|
||||||
[alias]
|
[alias]
|
||||||
qemu = "run --target x86_64-unknown-uefi"
|
qemu = "run --bin bootloader --target x86_64-unknown-uefi"
|
||||||
|
test-qemu = "test --bin test --target x86_64-unknown-uefi"
|
||||||
|
|
||||||
[target.'x86_64-unknown-uefi']
|
[target.'x86_64-unknown-uefi']
|
||||||
rustflags = ["-Ctarget-feature=+sse,+mmx,+sse2,-soft-float"]
|
rustflags = ["-Ctarget-feature=+sse,+mmx,+sse2,-soft-float"]
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["bootloader"]
|
members = ["bootloader", "kibble", "btrfs"]
|
|
@ -5,8 +5,13 @@ edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[lib]
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "read_btrfs"
|
||||||
|
path = "src/bin/read_btrfs.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
anyhow = {version = "1.0", default-features = false}
|
anyhow = {version = "1.0", default-features = false}
|
||||||
thiserror = {path = "../../nostd/thiserror", default-features = false}
|
thiserror = {path = "../../nostd/thiserror", default-features = false}
|
||||||
|
@ -15,17 +20,23 @@ itertools = {version = "0.10", default-features = false, features = ["use_alloc"
|
||||||
volatile = "0.4"
|
volatile = "0.4"
|
||||||
bitfield = "0.14"
|
bitfield = "0.14"
|
||||||
bytemuck = "1.12.3"
|
bytemuck = "1.12.3"
|
||||||
|
bitflags = "1.3.1"
|
||||||
|
|
||||||
num-complex = {version = "0.4", default-features = false, features = ["libm"]}
|
num-complex = {version = "0.4", default-features = false, features = ["libm"]}
|
||||||
fontdue = {version = "0.7"}
|
fontdue = {version = "0.7"}
|
||||||
goblin = {version = "0.6", default-features = false, features = ["alloc", "pe32", "pe64"]}
|
goblin = {version = "0.6", default-features = false, features = ["alloc", "pe32", "pe64"]}
|
||||||
|
|
||||||
uefi = { version = "0.18", features = ["alloc", "logger", "exts"] }
|
# uefi = { version = "0.19", features = ["alloc", "logger", "unstable"] }
|
||||||
uefi-services = "0.15"
|
# uefi-services = "0.16"
|
||||||
|
uefi = {path = "../../../uefi-rs/uefi", features = ["alloc", "logger", "unstable"] }
|
||||||
|
uefi-services = {path = "../../../uefi-rs/uefi-services" }
|
||||||
raw-cpuid = "10.0"
|
raw-cpuid = "10.0"
|
||||||
x86_64 = "0.14"
|
x86_64 = "0.14"
|
||||||
|
|
||||||
ucs2 = {path = "../../nostd/ucs2-rs"}
|
ucs2 = {path = "../../nostd/ucs2-rs"}
|
||||||
terminal = {path = "../../nostd/terminal"}
|
terminal = {path = "../../nostd/terminal"}
|
||||||
serde_ini = {path = "../../nostd/serde-ini"}
|
toml = {path = "../../nostd/toml/crates/toml", default-features = false}
|
||||||
serde = {version = "1.0", default-features = false, features = ["alloc", "derive"]}
|
serde = {version = "1.0", default-features = false, features = ["alloc", "derive"]}
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
x86_64 = "0.14"
|
|
@ -1,8 +1,14 @@
|
||||||
use uefi::{
|
use uefi::{
|
||||||
prelude::BootServices, proto::loaded_image::LoadedImage, table::boot::ScopedProtocol, Handle,
|
prelude::BootServices,
|
||||||
|
proto::{device_path::DevicePath, loaded_image::LoadedImage},
|
||||||
|
table::boot::ScopedProtocol,
|
||||||
|
CString16, Handle,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::Result;
|
use crate::{
|
||||||
|
device_path::{DevicePathBuf, DevicePathBufBuilder},
|
||||||
|
Result,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct Context<'a> {
|
pub struct Context<'a> {
|
||||||
handle: Handle,
|
handle: Handle,
|
||||||
|
@ -20,4 +26,57 @@ impl<'a> Context<'a> {
|
||||||
image,
|
image,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn handle(&self) -> Handle {
|
||||||
|
self.handle
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn image(&self) -> &ScopedProtocol<LoadedImage> {
|
||||||
|
&self.image
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn boot_services(&self) -> &BootServices {
|
||||||
|
self.boot_services
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn file_path(&self) -> Option<&DevicePath> {
|
||||||
|
self.image().file_path()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn device_path(&self) -> Result<DevicePathBuf> {
|
||||||
|
let device_path = self
|
||||||
|
.boot_services()
|
||||||
|
.open_protocol_exclusive::<DevicePath>(self.image().device())?;
|
||||||
|
|
||||||
|
Ok(DevicePathBufBuilder::new()
|
||||||
|
.with_device_path(&*device_path)?
|
||||||
|
.finalize()?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_driver(&self, path: &str) -> Result<Handle> {
|
||||||
|
let driver_path = CString16::try_from(path)?;
|
||||||
|
|
||||||
|
let driver_device_path = DevicePathBufBuilder::new()
|
||||||
|
.with_device_path(self.device_path().expect("device path"))
|
||||||
|
.and_then(|builder| builder.with_file_path(&driver_path))
|
||||||
|
.and_then(|builder| builder.finalize())
|
||||||
|
.expect("device path");
|
||||||
|
|
||||||
|
let handle = self
|
||||||
|
.boot_services()
|
||||||
|
.load_image(
|
||||||
|
self.handle(),
|
||||||
|
uefi::table::boot::LoadImageSource::FromFilePath {
|
||||||
|
file_path: &driver_device_path,
|
||||||
|
from_boot_manager: false,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("btrfs_driver_load");
|
||||||
|
|
||||||
|
self.boot_services()
|
||||||
|
.start_image(handle)
|
||||||
|
.expect("start btrfs driver");
|
||||||
|
|
||||||
|
Ok(handle)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,10 @@ pub enum Error {
|
||||||
NoAlignedSubslice,
|
NoAlignedSubslice,
|
||||||
#[error("No Mode found for this GOP")]
|
#[error("No Mode found for this GOP")]
|
||||||
NoModeFound,
|
NoModeFound,
|
||||||
|
#[error("supplied buffer was too small, needs to be at least {0} bytes wide.")]
|
||||||
|
BufferTooSmall(usize),
|
||||||
|
#[error(transparent)]
|
||||||
|
Utf8Error(#[from] core::str::Utf8Error),
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
FontError(&'static str),
|
FontError(&'static str),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
@ -23,6 +27,10 @@ pub enum Error {
|
||||||
AllocError(#[from] alloc::alloc::AllocError),
|
AllocError(#[from] alloc::alloc::AllocError),
|
||||||
#[error("FromStrWithBufError: {0:?}")]
|
#[error("FromStrWithBufError: {0:?}")]
|
||||||
FromStrWithBufError(uefi::data_types::FromStrWithBufError),
|
FromStrWithBufError(uefi::data_types::FromStrWithBufError),
|
||||||
|
#[error("FromStrError: {0:?}")]
|
||||||
|
FromStrError(#[from] uefi::data_types::FromStrError),
|
||||||
|
#[error("DevicePathBuildError: {0:?}")]
|
||||||
|
DevicePathBuildError(uefi::proto::device_path::build::BuildError),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
@ -36,6 +44,12 @@ impl From<uefi::data_types::FromStrWithBufError> for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<uefi::proto::device_path::build::BuildError> for Error {
|
||||||
|
fn from(value: uefi::proto::device_path::build::BuildError) -> Self {
|
||||||
|
Self::DevicePathBuildError(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<uefi::Error> for Error {
|
impl From<uefi::Error> for Error {
|
||||||
fn from(inner: uefi::Error) -> Self {
|
fn from(inner: uefi::Error) -> Self {
|
||||||
Self::UefiError(UefiError { inner })
|
Self::UefiError(UefiError { inner })
|
||||||
|
|
|
@ -1,85 +1,26 @@
|
||||||
use core::{
|
use core::cell::{Ref, RefCell, RefMut};
|
||||||
alloc::{AllocError, Allocator, Layout},
|
|
||||||
borrow::{Borrow, BorrowMut},
|
|
||||||
cell::{Ref, RefCell, RefMut},
|
|
||||||
mem::MaybeUninit,
|
|
||||||
ops::{Deref, DerefMut},
|
|
||||||
ptr::NonNull,
|
|
||||||
};
|
|
||||||
|
|
||||||
use alloc::{borrow::ToOwned, boxed::Box, sync::Arc, vec, vec::Vec};
|
use alloc::{boxed::Box, sync::Arc, vec};
|
||||||
use log::{debug, info};
|
|
||||||
use uefi::{
|
use uefi::{
|
||||||
data_types::Align,
|
|
||||||
proto::media::{
|
proto::media::{
|
||||||
file::{Directory as UefiDirectory, File, FileAttribute, FileHandle, FileInfo, FileMode},
|
file::{Directory as UefiDirectory, File, FileAttribute, FileHandle, FileInfo, FileMode},
|
||||||
fs::SimpleFileSystem,
|
fs::SimpleFileSystem,
|
||||||
},
|
},
|
||||||
table::boot::ScopedProtocol,
|
table::boot::ScopedProtocol,
|
||||||
CStr16, ResultExt, Status,
|
CStr16,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::error::{Error, Result};
|
use crate::error::Result;
|
||||||
|
|
||||||
pub struct FileSystem<'a> {
|
pub struct FileSystem<'a> {
|
||||||
inner: RefCell<ScopedProtocol<'a, SimpleFileSystem>>,
|
inner: RefCell<ScopedProtocol<'a, SimpleFileSystem>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FileInfoIterator {
|
|
||||||
dir: Directory,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FileInfoIterator {
|
|
||||||
pub fn new(dir: Directory) -> Self {
|
|
||||||
Self { dir }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next_entry(&mut self) -> Result<Option<Box<FileInfo>>> {
|
|
||||||
let layout = Layout::from_size_align(0, FileInfo::alignment())?;
|
|
||||||
let mut ptr = alloc::alloc::Global.allocate(layout)?;
|
|
||||||
|
|
||||||
if let Some(error) = self.dir.read_entry(unsafe { ptr.as_mut() }).err() {
|
|
||||||
match error.status() {
|
|
||||||
Status::BUFFER_TOO_SMALL => {
|
|
||||||
let layout = Layout::from_size_align(
|
|
||||||
error.data().expect("no size given after buffer_too_small!"),
|
|
||||||
FileInfo::alignment(),
|
|
||||||
)?;
|
|
||||||
let mut ptr = alloc::alloc::Global.allocate(layout)?;
|
|
||||||
|
|
||||||
let file_info = self
|
|
||||||
.dir
|
|
||||||
.read_entry(unsafe { ptr.as_mut() })
|
|
||||||
.map(|info| {
|
|
||||||
info.map(|info| unsafe { Box::<FileInfo>::from_raw(info as *mut _) })
|
|
||||||
.ok_or_else(|| unsafe {
|
|
||||||
alloc::alloc::Global.deallocate(ptr.cast(), layout);
|
|
||||||
AllocError
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.discard_errdata()??;
|
|
||||||
Ok(Some(file_info))
|
|
||||||
}
|
|
||||||
_ => Err(error).discard_errdata()?,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub mod dir {
|
pub mod dir {
|
||||||
use core::{
|
use core::ops::Deref;
|
||||||
alloc::{AllocError, Allocator, Layout},
|
|
||||||
ops::Deref,
|
|
||||||
};
|
|
||||||
|
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use uefi::{
|
use uefi::proto::media::file::{File, FileAttribute, FileHandle, FileInfo, FileMode};
|
||||||
data_types::Align,
|
|
||||||
proto::media::file::{File, FileAttribute, FileHandle, FileInfo, FileMode},
|
|
||||||
ResultExt, Status,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
|
@ -130,37 +71,7 @@ pub mod dir {
|
||||||
|
|
||||||
impl Directory {
|
impl Directory {
|
||||||
pub fn next_entry(&mut self) -> Result<Option<Box<FileInfo>>> {
|
pub fn next_entry(&mut self) -> Result<Option<Box<FileInfo>>> {
|
||||||
let layout = Layout::from_size_align(0, FileInfo::alignment())?;
|
Ok(self.get_entry()?)
|
||||||
let mut ptr = alloc::alloc::Global.allocate(layout)?;
|
|
||||||
|
|
||||||
if let Some(error) = self.read_entry(unsafe { ptr.as_mut() }).err() {
|
|
||||||
match error.status() {
|
|
||||||
Status::BUFFER_TOO_SMALL => {
|
|
||||||
let layout = Layout::from_size_align(
|
|
||||||
error.data().expect("no size given after buffer_too_small!"),
|
|
||||||
FileInfo::alignment(),
|
|
||||||
)?;
|
|
||||||
let mut ptr = alloc::alloc::Global.allocate(layout)?;
|
|
||||||
|
|
||||||
let file_info = self
|
|
||||||
.read_entry(unsafe { ptr.as_mut() })
|
|
||||||
.map(|info| {
|
|
||||||
info.map(|info| unsafe {
|
|
||||||
Box::<FileInfo>::from_raw(info as *mut _)
|
|
||||||
})
|
|
||||||
.ok_or_else(|| unsafe {
|
|
||||||
alloc::alloc::Global.deallocate(ptr.cast(), layout);
|
|
||||||
AllocError
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.discard_errdata()??;
|
|
||||||
Ok(Some(file_info))
|
|
||||||
}
|
|
||||||
_ => Err(error).discard_errdata()?,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,14 +90,6 @@ pub mod dir {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for FileInfoIterator {
|
|
||||||
type Item = Box<FileInfo>;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
self.next_entry().ok().flatten()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Directory {
|
pub struct Directory {
|
||||||
|
@ -211,11 +114,8 @@ impl Directory {
|
||||||
self.get_mut().open(filename, open_mode, attributes)
|
self.get_mut().open(filename, open_mode, attributes)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_entry<'buf>(
|
pub fn get_entry(&mut self) -> uefi::Result<Option<Box<FileInfo>>> {
|
||||||
&mut self,
|
self.get_mut().read_entry_boxed()
|
||||||
buffer: &'buf mut [u8],
|
|
||||||
) -> uefi::Result<Option<&'buf mut FileInfo>, Option<usize>> {
|
|
||||||
self.get_mut().read_entry(buffer)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,58 +1,50 @@
|
||||||
#![feature(abi_efiapi)]
|
#![feature(
|
||||||
#![feature(allocator_api)]
|
allocator_api,
|
||||||
#![feature(error_in_core)]
|
ptr_metadata,
|
||||||
#![feature(alloc_error_handler)]
|
error_in_core,
|
||||||
#![feature(negative_impls)]
|
alloc_error_handler,
|
||||||
#![feature(int_roundings)]
|
negative_impls,
|
||||||
#![feature(core_intrinsics)]
|
int_roundings,
|
||||||
#![feature(iter_intersperse)]
|
core_intrinsics
|
||||||
|
)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use alloc::{collections::BTreeMap, string::String, vec};
|
use alloc::{collections::BTreeMap, vec};
|
||||||
use graphics::GraphicsOutput;
|
|
||||||
use log::info;
|
use log::info;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use uefi::{
|
use uefi::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
proto::{
|
proto::{
|
||||||
console::gop,
|
console::gop,
|
||||||
media::file::{File, FileAttribute, FileMode},
|
device_path::DevicePath,
|
||||||
|
loaded_image::LoadedImage,
|
||||||
|
media::{
|
||||||
|
file::{File, FileAttribute, FileInfo, FileMode},
|
||||||
|
fs::SimpleFileSystem,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
table::{
|
table::{
|
||||||
boot::{OpenProtocolAttributes, OpenProtocolParams, SearchType},
|
boot::{OpenProtocolAttributes, OpenProtocolParams, SearchType},
|
||||||
Boot, SystemTable,
|
Boot, SystemTable,
|
||||||
},
|
},
|
||||||
Identify, Status,
|
CString16, Identify, Status,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
mod context;
|
use bootloader::{
|
||||||
mod error;
|
device_path::{DevicePathBuf, DevicePathBufBuilder},
|
||||||
mod fpu;
|
fpu::enable_fpu,
|
||||||
mod fs;
|
fs,
|
||||||
mod graphics;
|
graphics::GraphicsOutput,
|
||||||
mod input;
|
Result,
|
||||||
|
};
|
||||||
use error::{Error, Result};
|
|
||||||
|
|
||||||
use crate::fpu::enable_fpu;
|
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(rename_all = "PascalCase")]
|
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
#[serde(rename = "FREELOADER")]
|
timeout: Option<u64>,
|
||||||
freeloader: FreeLoaderConfig,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
#[serde(rename_all = "PascalCase")]
|
|
||||||
pub struct FreeLoaderConfig {
|
|
||||||
timeout: u64,
|
|
||||||
#[serde(rename = "DefaultOS")]
|
|
||||||
default_os: String,
|
|
||||||
font_path: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -63,10 +55,24 @@ pub struct Context {
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
pub fn new(handle: Handle, mut st: SystemTable<Boot>) -> uefi::Result<Self> {
|
pub fn new(handle: Handle, mut st: SystemTable<Boot>) -> uefi::Result<Self> {
|
||||||
uefi_services::init(&mut st)?;
|
uefi_services::init(&mut st).expect("services");
|
||||||
|
enable_fpu().expect("no FPU/SSE/SSE2!");
|
||||||
Ok(Self { handle, st })
|
Ok(Self { handle, st })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn device_path(&self) -> Result<DevicePathBuf> {
|
||||||
|
let loaded_image = self
|
||||||
|
.boot_services()
|
||||||
|
.open_protocol_exclusive::<LoadedImage>(self.handle())?;
|
||||||
|
let device_path = self
|
||||||
|
.boot_services()
|
||||||
|
.open_protocol_exclusive::<DevicePath>(loaded_image.device())?;
|
||||||
|
|
||||||
|
Ok(DevicePathBufBuilder::new()
|
||||||
|
.with_device_path(&*device_path)?
|
||||||
|
.finalize()?)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fs(&self) -> Result<fs::FileSystem> {
|
pub fn fs(&self) -> Result<fs::FileSystem> {
|
||||||
let file_system = self.st.boot_services().get_image_file_system(self.handle)?;
|
let file_system = self.st.boot_services().get_image_file_system(self.handle)?;
|
||||||
|
|
||||||
|
@ -128,37 +134,80 @@ impl Context {
|
||||||
GraphicsOutput::from_gop_with_mode(gop, mode)
|
GraphicsOutput::from_gop_with_mode(gop, mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn load_driver(&self, path: &str) -> Result<Handle> {
|
||||||
|
let driver_path = CString16::try_from(path)?;
|
||||||
|
|
||||||
|
let driver_device_path = DevicePathBufBuilder::new()
|
||||||
|
.with_device_path(self.device_path().expect("device path"))
|
||||||
|
.and_then(|builder| builder.with_file_path(&driver_path))
|
||||||
|
.and_then(|builder| builder.finalize())
|
||||||
|
.expect("device path");
|
||||||
|
|
||||||
|
let handle = self
|
||||||
|
.boot_services()
|
||||||
|
.load_image(
|
||||||
|
self.handle(),
|
||||||
|
uefi::table::boot::LoadImageSource::FromFilePath {
|
||||||
|
file_path: &driver_device_path,
|
||||||
|
from_boot_manager: false,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("btrfs_driver_load");
|
||||||
|
|
||||||
|
self.boot_services()
|
||||||
|
.start_image(handle)
|
||||||
|
.expect("start btrfs driver");
|
||||||
|
|
||||||
|
Ok(handle)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn run(mut self) -> Result<Status> {
|
pub fn run(mut self) -> Result<Status> {
|
||||||
info!("Hello, UEFI!");
|
info!("Hello, UEFI!");
|
||||||
self.system_table_mut().stdin().reset(false)?;
|
self.system_table_mut().stdin().reset(false)?;
|
||||||
|
|
||||||
enable_fpu().expect("no FPU/SSE/SSE2!");
|
|
||||||
|
|
||||||
let fs = self.fs()?;
|
let fs = self.fs()?;
|
||||||
|
|
||||||
for entry in fs.root_dir()?.into_iter() {
|
let filename = CString16::try_from("config.toml").unwrap();
|
||||||
info!("{:#?}", entry);
|
let mut config_file =
|
||||||
if !entry.attribute().contains(FileAttribute::DIRECTORY) {
|
fs.root_dir()?
|
||||||
let mut file = entry
|
.open(&filename, FileMode::Read, FileAttribute::empty())?;
|
||||||
.open(FileMode::Read, None)?
|
|
||||||
.into_regular_file()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut buf = vec![0u8; entry.file_size() as usize];
|
let mut buffer = vec![0; config_file.get_boxed_info::<FileInfo>()?.file_size() as usize];
|
||||||
_ = file.read(&mut buf).unwrap();
|
config_file
|
||||||
let s = String::from_utf8_lossy(&buf);
|
.into_regular_file()
|
||||||
info!("{:?}", s);
|
.unwrap()
|
||||||
}
|
.read(&mut buffer)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let config = toml::from_str::<Config>(&core::str::from_utf8(&buffer).expect("from_utf8"))
|
||||||
|
.expect("toml parse");
|
||||||
|
|
||||||
|
info!("config: {:?}", config);
|
||||||
|
|
||||||
|
drop(fs);
|
||||||
|
|
||||||
|
self.load_driver("bootloader\\drivers\\btrfs_x64.efi")
|
||||||
|
.expect("driver");
|
||||||
|
|
||||||
|
let handles = self
|
||||||
|
.boot_services()
|
||||||
|
.find_handles::<SimpleFileSystem>()
|
||||||
|
.expect("SFS handles");
|
||||||
|
|
||||||
|
for handle in handles {
|
||||||
|
if let Ok(mut sfs) = self
|
||||||
|
.boot_services()
|
||||||
|
.open_protocol_exclusive::<SimpleFileSystem>(handle)
|
||||||
|
{
|
||||||
|
let mut dir = sfs.open_volume().expect("root dir");
|
||||||
|
let info = dir.get_boxed_info::<FileInfo>();
|
||||||
|
|
||||||
|
info!("{:?}", info);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut display = self.get_graphics_output()?;
|
info!("done");
|
||||||
let (width, height) = display.resolution();
|
|
||||||
|
|
||||||
info!("creating terminal");
|
|
||||||
|
|
||||||
loop {}
|
loop {}
|
||||||
|
|
||||||
Ok(Status::SUCCESS)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
[FREELOADER]
|
|
||||||
TimeOut=10
|
|
||||||
DefaultOS=Windows
|
|
20
qemu.sh
20
qemu.sh
|
@ -2,15 +2,31 @@
|
||||||
|
|
||||||
mkdir -vp esp/EFI/BOOT
|
mkdir -vp esp/EFI/BOOT
|
||||||
cp $1 esp/EFI/BOOT/BOOTX64.EFI
|
cp $1 esp/EFI/BOOT/BOOTX64.EFI
|
||||||
|
shift
|
||||||
|
|
||||||
exec qemu-system-x86_64 -accel kvm \
|
echo "$(pwd)"
|
||||||
|
|
||||||
|
qemu-system-x86_64 -accel kvm \
|
||||||
-m 4G \
|
-m 4G \
|
||||||
-cpu host \
|
-cpu host \
|
||||||
-smp 2,sockets=1,dies=1,cores=2,threads=1 \
|
-smp 2,sockets=1,dies=1,cores=2,threads=1 \
|
||||||
-vga virtio \
|
-vga virtio \
|
||||||
|
-nodefaults \
|
||||||
-no-reboot \
|
-no-reboot \
|
||||||
-serial stdio \
|
-serial stdio \
|
||||||
-usb -device usb-mouse \
|
-usb -device usb-mouse \
|
||||||
-drive if=pflash,format=raw,readonly=on,file=/usr/share/ovmf/x64/OVMF_CODE.fd \
|
-drive if=pflash,format=raw,readonly=on,file=/usr/share/ovmf/x64/OVMF_CODE.fd \
|
||||||
-drive if=pflash,format=raw,readonly=on,file=/usr/share/ovmf/x64/OVMF_VARS.fd \
|
-drive if=pflash,format=raw,readonly=on,file=/usr/share/ovmf/x64/OVMF_VARS.fd \
|
||||||
-drive format=raw,file=fat:rw:esp
|
-device isa-debug-exit,iobase=0xf4,iosize=0x04 \
|
||||||
|
-drive format=qcow2,file=btrfs.qcow2 \
|
||||||
|
-drive format=qcow2,file=ntfs.qcow2 \
|
||||||
|
-drive format=raw,file=fat:rw:esp $@ \
|
||||||
|
-drive format=qcow2,file=windows.qcow2
|
||||||
|
|
||||||
|
case $? in
|
||||||
|
33)
|
||||||
|
exit 0;;
|
||||||
|
*)
|
||||||
|
exit $?;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue