forked from AbleOS/ableos
Compare commits
15 Commits
b60389ea21
...
10f8b668cd
Author | SHA1 | Date |
---|---|---|
able | 10f8b668cd | |
microtau | c7c7890788 | |
able | 7e117ebd04 | |
able | 013faa8fc8 | |
able | b1e59376b0 | |
able | ddf79b20ae | |
able | 0fbe5100bb | |
able | 78379402bb | |
JohnyTheCarrot | 01c79d3d6c | |
JohnyTheCarrot | ee4117f35e | |
JohnyTheCarrot | 58d25007a0 | |
JohnyTheCarrot | 4608b6dbed | |
able | 6c0ead4d22 | |
able | 423c75562b | |
able | cec0cdc116 |
|
@ -1 +1,2 @@
|
|||
target/
|
||||
/.idea
|
Binary file not shown.
|
@ -859,12 +859,12 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "hbbytecode"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.ablecorp.us/ableos/holey-bytes#75995422262a192f2c87713d239856e98c799f41"
|
||||
source = "git+https://git.ablecorp.us/ableos/holey-bytes#6a444bd29ea6d474ec98edbc11b27030825b86e2"
|
||||
|
||||
[[package]]
|
||||
name = "hbvm"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.ablecorp.us/ableos/holey-bytes#75995422262a192f2c87713d239856e98c799f41"
|
||||
source = "git+https://git.ablecorp.us/ableos/holey-bytes#6a444bd29ea6d474ec98edbc11b27030825b86e2"
|
||||
dependencies = [
|
||||
"delegate",
|
||||
"derive_more",
|
||||
|
|
|
@ -20,8 +20,11 @@ TODO
|
|||
- PS/2 Keyboard driver
|
||||
- VGA driver
|
||||
- SVGA driver
|
||||
- File system
|
||||
- File system
|
||||
TarFS
|
||||
Pass in a tar file as an initrd and parse it with TarFS
|
||||
- VFS
|
||||
Being (written)[https://git.ablecorp.us/bee/ableos-vfs] by Bee
|
||||
- Disk driver
|
||||
- A ton more
|
||||
```
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
qemu-system-aarch64 -m 1024 -cpu cortex-a57 \
|
||||
-M virt -pflash "AAVMF_CODE.fd" \
|
||||
-device virtio-gpu-pci \
|
||||
-device virtio-mouse-device \
|
||||
-device virtio-keyboard-device \
|
||||
-kernel limine/BOOTX64.EFI
|
||||
# -device virtio-serial-pci \
|
||||
# -drive if=none,file=target/disk.img,id=hd0 \
|
||||
# -device virtio-blk-device,drive=hd0
|
||||
|
||||
# -kernel target/aarch64-virt-ableos/debug/kernel
|
|
@ -4,7 +4,6 @@ build-std-features = ["compiler-builtins-mem"]
|
|||
|
||||
[build]
|
||||
target = "./targets/x86_64-ableos.json"
|
||||
# target = "./targets/aarch64-virt-ableos.json"
|
||||
|
||||
[target.'cfg(target_arch = "x86_64")']
|
||||
rustflags = ["-C", "target-feature=+rdrand"]
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
ENTRY(_start)
|
||||
ENTRY(_kernel_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x40080000;
|
||||
. = 0xffffffff80000000;
|
||||
.text.boot : { *(.text.boot) }
|
||||
.text : { *(.text) }
|
||||
.data : { *(.data) }
|
||||
|
@ -11,4 +12,4 @@ SECTIONS
|
|||
. = ALIGN(8);
|
||||
. = . + 0x4000;
|
||||
LD_STACK_PTR = .;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -341,5 +341,5 @@ unsafe impl Send for Heap {}
|
|||
fn alloc_error_handler(layout: alloc::alloc::Layout) -> ! {
|
||||
log::error!("allocation error: {:?}", layout);
|
||||
// Todo: Maybe panic here instead
|
||||
crate::arch::sloop()
|
||||
crate::arch::spin_loop()
|
||||
}
|
||||
|
|
|
@ -1,21 +1,32 @@
|
|||
//!
|
||||
// #[allow(deprecated)]
|
||||
// use limine::{TerminalRequest, TerminalResponse};
|
||||
use {core::arch::asm, limine::FramebufferRequest};
|
||||
|
||||
pub const PAGE_SIZE: usize = 4096;
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn _kernel_start() -> ! {
|
||||
loop {}
|
||||
static FB_REQ: FramebufferRequest = FramebufferRequest::new(0);
|
||||
let fb1 = &FB_REQ.get_response().get().unwrap().framebuffers()[0];
|
||||
|
||||
for i in 0..100_usize {
|
||||
let offset = i * fb1.pitch as usize + i * 4;
|
||||
unsafe {
|
||||
*(fb1.address.as_ptr().unwrap().offset(offset as isize) as *mut u32) = 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
spin_loop();
|
||||
}
|
||||
|
||||
pub fn spin_loop() -> ! {
|
||||
loop {
|
||||
unsafe { asm!("wfi") }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hardware_random_u64() -> u64 {
|
||||
0
|
||||
}
|
||||
|
||||
pub fn log(_args: core::fmt::Arguments<'_>) -> core::fmt::Result {
|
||||
panic!()
|
||||
}
|
||||
|
||||
pub fn sloop() -> ! {
|
||||
loop {}
|
||||
}
|
||||
pub fn hardware_random_u64() -> u64 {
|
||||
0
|
||||
}
|
||||
|
||||
pub const PAGE_SIZE: usize = 10;
|
||||
|
|
|
@ -79,7 +79,7 @@ unsafe extern fn _kernel_start() -> ! {
|
|||
}
|
||||
|
||||
/// Spin loop
|
||||
pub fn sloop() -> ! {
|
||||
pub fn spin_loop() -> ! {
|
||||
loop {
|
||||
unsafe { asm!("wfi") }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
use {
|
||||
crate::{
|
||||
arch::{pci, x86_64::cpuid},
|
||||
device_tree::DeviceTree,
|
||||
kmain::DEVICE_TREE,
|
||||
},
|
||||
limine::SmpRequest,
|
||||
xml::XMLElement,
|
||||
};
|
||||
|
||||
fn collect_cpu_info(device_tree: &mut DeviceTree) {
|
||||
use crate::alloc::string::ToString;
|
||||
|
||||
static SMP: SmpRequest = SmpRequest::new(0);
|
||||
let smp_response = SMP.get_response().get().unwrap();
|
||||
|
||||
let mut cpu = XMLElement::new("cpu");
|
||||
|
||||
// Get the amount of cores on the CPU
|
||||
let core_count = smp_response.cpu_count.to_string();
|
||||
cpu.set_attribute("core count", core_count);
|
||||
for x in 0..smp_response.cpu_count {
|
||||
let core_name = alloc::format!("core_{}", x);
|
||||
let core = XMLElement::new(core_name);
|
||||
cpu.set_child(core);
|
||||
}
|
||||
|
||||
let cpu_info = cpuid::master().unwrap();
|
||||
|
||||
let brand_string = cpu_info.brand_string().unwrap_or("Unknown").to_string();
|
||||
cpu.set_attribute("brand string", brand_string);
|
||||
|
||||
cpu.set_attribute("speed", "unknown");
|
||||
|
||||
// Get CPU features and add them to the device tree entry.
|
||||
let mut cpu_features = XMLElement::new("CPU Features");
|
||||
for (feature_key, feature_enabled) in cpu_info.features() {
|
||||
cpu_features.set_attribute(feature_key, feature_enabled.to_string());
|
||||
}
|
||||
cpu.set_child(cpu_features);
|
||||
|
||||
// CPU temperature
|
||||
if cpu_info.digital_temperature_sensor() {
|
||||
let mut temperature_child = XMLElement::new("Temperature");
|
||||
|
||||
temperature_child.set_attribute("degrees", "Unknown");
|
||||
cpu.set_child(temperature_child);
|
||||
}
|
||||
|
||||
// Add CPU to device tree
|
||||
let cpus = device_tree.devices.get_mut("CPUs").unwrap();
|
||||
cpus.push(cpu);
|
||||
}
|
||||
|
||||
pub fn collect_device_info() {
|
||||
// Lock device tree
|
||||
unsafe {
|
||||
DEVICE_TREE.force_unlock();
|
||||
}
|
||||
let device_tree = &mut DEVICE_TREE.lock();
|
||||
|
||||
// Generate device tree from PCI enumeration.
|
||||
pci::init(device_tree);
|
||||
|
||||
// Collect CPU info and add it to the device tree
|
||||
collect_cpu_info(device_tree);
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
use {limine::SmpRequest, xml::XMLElement};
|
||||
|
||||
use embedded_graphics::pixelcolor::Rgb888;
|
||||
|
||||
use crate::{arch::x86_64::graphics::DISPLAY, bootmodules::BootModule, kmain::DEVICE_TREE};
|
||||
use crate::{arch::x86_64::graphics::DISPLAY, bootmodules::BootModule};
|
||||
|
||||
pub mod memory;
|
||||
|
||||
|
@ -13,6 +11,7 @@ pub(crate) mod interrupts;
|
|||
pub mod logging;
|
||||
pub mod pci;
|
||||
pub mod virtio;
|
||||
mod device_info_collector;
|
||||
|
||||
pub use {logging::log, memory::PAGE_SIZE};
|
||||
|
||||
|
@ -62,74 +61,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
|
|||
static KFILE_REQ: KernelFileRequest = KernelFileRequest::new(0);
|
||||
static MOD_REQ: ModuleRequest = ModuleRequest::new(0);
|
||||
|
||||
static SMP: SmpRequest = SmpRequest::new(0);
|
||||
let smp = SMP.get_response().get().unwrap();
|
||||
use crate::alloc::string::ToString;
|
||||
|
||||
let cpuinfo = cpuid::master().unwrap();
|
||||
let brand_string = cpuinfo.brand_string().unwrap_or("Unknown").to_string();
|
||||
DEVICE_TREE.force_unlock();
|
||||
|
||||
pci::init();
|
||||
|
||||
let mut dt = DEVICE_TREE.lock();
|
||||
|
||||
let cpus = dt.devices.get_mut("CPUs").unwrap();
|
||||
let mut cpu = XMLElement::new("cpu");
|
||||
let core_count = smp.cpu_count.to_string();
|
||||
cpu.set_attribute("core count", core_count);
|
||||
for x in 0..smp.cpu_count {
|
||||
let core_name = alloc::format!("core_{}", x);
|
||||
let core = XMLElement::new(core_name);
|
||||
cpu.set_child(core);
|
||||
}
|
||||
|
||||
cpu.set_attribute("brand string", brand_string);
|
||||
|
||||
let _cpu_speed = 0;
|
||||
|
||||
cpu.set_attribute("speed", "unknown");
|
||||
|
||||
if false {
|
||||
// disable() // disable interrupts (if still not done)
|
||||
let _i = 0;
|
||||
let start = cpuinfo.time_stamp_counter();
|
||||
|
||||
log::info!("{:?}", start.unwrap().invariant_tsc());
|
||||
for _x in 0..1000 {}
|
||||
let _end = cpuinfo.time_stamp_counter();
|
||||
}
|
||||
|
||||
let mut cpu_features = xml::XMLElement::new("CPU Features");
|
||||
{
|
||||
cpuinfo.version_information().unwrap();
|
||||
let apic = cpuinfo.apic();
|
||||
let avx = cpuinfo.avx();
|
||||
let avx2 = cpuinfo.avx2();
|
||||
let x2 = cpuinfo.x2apic();
|
||||
|
||||
let gb_pages = cpuinfo.gigabyte_pages();
|
||||
let rdseed = cpuinfo.rdseed();
|
||||
let rdrand = cpuinfo.rdrand();
|
||||
|
||||
cpu_features.set_attribute("apic", apic.to_string());
|
||||
cpu_features.set_attribute("avx", avx.to_string());
|
||||
cpu_features.set_attribute("avx2", avx2.to_string());
|
||||
cpu_features.set_attribute("gigabyte pages", gb_pages.to_string());
|
||||
cpu_features.set_attribute("rdrand", rdrand.to_string());
|
||||
cpu_features.set_attribute("rdseed", rdseed.to_string());
|
||||
cpu_features.set_attribute("x2apic", x2.to_string());
|
||||
}
|
||||
if cpuinfo.digital_temperature_sensor() {
|
||||
let mut temperature_child = XMLElement::new("Temperature");
|
||||
|
||||
temperature_child.set_attribute("degrees", "Unknown");
|
||||
cpu.set_child(temperature_child);
|
||||
}
|
||||
|
||||
cpu.set_child(cpu_features);
|
||||
cpus.push(cpu);
|
||||
drop(dt);
|
||||
device_info_collector::collect_device_info();
|
||||
|
||||
// Graphics test
|
||||
{
|
||||
|
@ -244,7 +176,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
|
|||
}
|
||||
|
||||
/// Spin loop
|
||||
pub fn sloop() -> ! {
|
||||
pub fn spin_loop() -> ! {
|
||||
loop {
|
||||
x86_64::instructions::hlt();
|
||||
}
|
||||
|
|
|
@ -9,10 +9,10 @@ pub struct PciDeviceInfo {
|
|||
pub rev_id: u8,
|
||||
}
|
||||
use crate::alloc::string::ToString;
|
||||
|
||||
/// Enumerate PCI devices and run initialisation routines on ones we support
|
||||
pub fn init() {
|
||||
let mut dt = DEVICE_TREE.lock();
|
||||
dt.devices
|
||||
pub fn init(device_tree: &mut DeviceTree) {
|
||||
device_tree.devices
|
||||
.insert("Unidentified PCI".to_string(), alloc::vec![]);
|
||||
let mut devices = alloc::vec![];
|
||||
|
||||
|
@ -52,7 +52,7 @@ pub fn init() {
|
|||
}
|
||||
}
|
||||
for (dev_type, dev) in devices {
|
||||
if let Some(abc) = dt.devices.get_mut(dev_type) {
|
||||
if let Some(abc) = device_tree.devices.get_mut(dev_type) {
|
||||
abc.push(dev);
|
||||
}
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ impl Into<u16> for Vendor {
|
|||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Display for Vendor {
|
||||
impl Display for Vendor {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
use Vendor::*;
|
||||
|
||||
|
@ -269,9 +269,8 @@ impl core::fmt::Display for Vendor {
|
|||
|
||||
use core::fmt::Display;
|
||||
|
||||
use crate::kmain::DEVICE_TREE;
|
||||
|
||||
use x86_64::instructions::port::Port;
|
||||
use crate::device_tree::DeviceTree;
|
||||
|
||||
#[allow(non_camel_case_types, dead_code)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
|
|
|
@ -11,7 +11,7 @@ use {
|
|||
pub type Device = xml::XMLElement;
|
||||
|
||||
/// A tree of devices
|
||||
// TODO: alphabatize this list
|
||||
// TODO: alphabetize this list
|
||||
#[derive(Debug)]
|
||||
pub struct DeviceTree {
|
||||
/// The device tree
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
use {
|
||||
crate::{
|
||||
bootmodules::{build_cmd, BootModules},
|
||||
capabilities,
|
||||
device_tree::DeviceTree,
|
||||
scheduler::Scheduler,
|
||||
},
|
||||
|
@ -38,15 +37,15 @@ pub fn kmain(cmdline: &str, boot_modules: BootModules) -> ! {
|
|||
// TODO: schedule the filesystem driver from the initramfs
|
||||
// TODO: schedule the init system from the initramfs
|
||||
|
||||
capabilities::example();
|
||||
// capabilities::example();
|
||||
|
||||
let mut sched = Scheduler::new();
|
||||
// AHEM that isn't a valid HBVM program
|
||||
|
||||
sched.new_process(boot_modules[0].bytes.clone());
|
||||
sched.new_process(boot_modules[1].bytes.clone());
|
||||
|
||||
sched.run();
|
||||
// sloop();
|
||||
// spin_loop();
|
||||
}
|
||||
|
||||
pub static DEVICE_TREE: Lazy<Mutex<DeviceTree>> = Lazy::new(|| {
|
||||
|
|
|
@ -43,16 +43,34 @@ impl Scheduler<'_> {
|
|||
loop {
|
||||
// If there are no programs to run then sleep.
|
||||
if self.data.is_empty() {
|
||||
use crate::arch::sloop;
|
||||
sloop();
|
||||
use crate::arch::spin_loop;
|
||||
spin_loop();
|
||||
}
|
||||
|
||||
let mut prog = self.data.pop_front().unwrap();
|
||||
prog.run().unwrap();
|
||||
let ret = prog.run();
|
||||
match ret {
|
||||
Ok(oki) => match oki {
|
||||
hbvm::vm::VmRunOk::End => {
|
||||
log::info!(
|
||||
"Program ended. {} programs remaining.",
|
||||
// Add one here because we pop a program
|
||||
self.data.len() + 1
|
||||
)
|
||||
}
|
||||
hbvm::vm::VmRunOk::Timer => {
|
||||
log::info!("Timer exhausted. Scheduled program");
|
||||
self.data.push_back(prog);
|
||||
}
|
||||
hbvm::vm::VmRunOk::Ecall => {
|
||||
// panic!();
|
||||
log::info!("{:?}", prog.registers);
|
||||
self.data.push_back(prog);
|
||||
}
|
||||
},
|
||||
|
||||
// log::info!("VM registers {:?}", prog.registers);
|
||||
log::info!("Scheduled program");
|
||||
self.data.push_back(prog);
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
2
limine
2
limine
|
@ -1 +1 @@
|
|||
Subproject commit 751e802e173392e8637759e2b3c96bbf59456f87
|
||||
Subproject commit 2d3d7b2633b5d95ce404a177ada0d5cbee802721
|
|
@ -4,14 +4,14 @@ version = "0.2.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
cpio_reader = "0.1"
|
||||
cpio_reader = "0.1" # remove me
|
||||
derive_more = "0.99"
|
||||
env_logger = "0.10"
|
||||
error-stack = "0.2"
|
||||
fatfs = "0.3"
|
||||
log = "0.4"
|
||||
rpm = "0.11"
|
||||
zstd = "0.12"
|
||||
log = "0.4" # remove me
|
||||
rpm = "0.11" # remove me
|
||||
zstd = "0.12" # remove me
|
||||
|
||||
[dependencies.reqwest]
|
||||
version = "0.11"
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -21,5 +21,5 @@ TERM_BACKDROP=008080
|
|||
MODULE_PATH=boot:///inf_loop.hb
|
||||
MODULE_CMDLINE="diskid=123456789"
|
||||
|
||||
MODULE_PATH=boot:///inf_loop.hb
|
||||
MODULE_CMDLINE=""
|
||||
MODULE_PATH=boot:///ecall.hb
|
||||
MODULE_CMDLINE=""
|
||||
|
|
|
@ -1,18 +1,11 @@
|
|||
use {
|
||||
derive_more::{Deref, DerefMut, Display},
|
||||
error_stack::{bail, ensure, report, Context, IntoReport, Result, ResultExt},
|
||||
derive_more::Display,
|
||||
error_stack::{bail, report, Context, IntoReport, Result, ResultExt},
|
||||
fatfs::{FileSystem, FormatVolumeOptions, FsOptions, ReadWriteSeek},
|
||||
std::{
|
||||
fmt::Display,
|
||||
fs::File,
|
||||
io::{self, Write},
|
||||
path::Path,
|
||||
process::Command,
|
||||
},
|
||||
std::{fmt::Display, fs::File, io, path::Path, process::Command},
|
||||
};
|
||||
|
||||
fn main() -> Result<(), Error> {
|
||||
env_logger::init();
|
||||
let mut args = std::env::args();
|
||||
args.next();
|
||||
|
||||
|
@ -31,12 +24,12 @@ fn main() -> Result<(), Error> {
|
|||
for arg in args {
|
||||
if arg == "-r" || arg == "--release" {
|
||||
release = true;
|
||||
}
|
||||
if arg == "rv64" || arg == "riscv64" || arg == "riscv64-virt" {
|
||||
} else if arg == "rv64" || arg == "riscv64" || arg == "riscv64-virt" {
|
||||
target = Target::Riscv64Virt;
|
||||
}
|
||||
if arg == "aarch" || arg == "arm64" {
|
||||
} else if arg == "arm64" || arg == "aarch64" || arg == "aarch64-virt" {
|
||||
target = Target::Aarch64;
|
||||
} else {
|
||||
return Err(report!(Error::InvalidSubCom));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,12 +41,12 @@ fn main() -> Result<(), Error> {
|
|||
for arg in args {
|
||||
if arg == "-r" || arg == "--release" {
|
||||
release = true;
|
||||
}
|
||||
if arg == "rv64" || arg == "riscv64" || arg == "riscv64-virt" {
|
||||
} else if arg == "rv64" || arg == "riscv64" || arg == "riscv64-virt" {
|
||||
target = Target::Riscv64Virt;
|
||||
}
|
||||
if arg == "arm64" || arg == "aarch64" {
|
||||
} else if arg == "arm64" || arg == "aarch64" || arg == "aarch64-virt" {
|
||||
target = Target::Aarch64;
|
||||
} else {
|
||||
return Err(report!(Error::InvalidSubCom));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,6 +105,15 @@ fn get_fs() -> Result<FileSystem<impl ReadWriteSeek>, io::Error> {
|
|||
&mut bootdir.create_file("bootx64.efi")?,
|
||||
)?;
|
||||
|
||||
io::copy(
|
||||
&mut File::open("limine/BOOTAA64.EFI")
|
||||
.into_report()
|
||||
.attach_printable(
|
||||
"copying Limine bootloader arm version (have you pulled the submodule?)",
|
||||
)?,
|
||||
&mut bootdir.create_file("bootaa64.efi")?,
|
||||
)?;
|
||||
|
||||
io::copy(
|
||||
&mut File::open("repbuild/limine.cfg")?,
|
||||
&mut fs.root_dir().create_file("limine.cfg")?,
|
||||
|
@ -122,17 +124,20 @@ fn get_fs() -> Result<FileSystem<impl ReadWriteSeek>, io::Error> {
|
|||
&mut fs.root_dir().create_file("background.bmp")?,
|
||||
)?;
|
||||
io::copy(
|
||||
&mut File::open("repbuild/inf_loop.hb")?,
|
||||
&mut File::open("repbuild/holeybytes/inf_loop.hb")?,
|
||||
&mut fs.root_dir().create_file("inf_loop.hb")?,
|
||||
)?;
|
||||
|
||||
io::copy(
|
||||
&mut File::open("repbuild/holeybytes/ecall.hb")?,
|
||||
&mut fs.root_dir().create_file("ecall.hb")?,
|
||||
)?;
|
||||
|
||||
drop(bootdir);
|
||||
Ok(fs)
|
||||
}
|
||||
|
||||
fn build(release: bool, target: Target) -> Result<(), Error> {
|
||||
fetch_ovmf().change_context(Error::OvmfFetch)?;
|
||||
|
||||
let fs = get_fs().change_context(Error::Io)?;
|
||||
let mut com = Command::new("cargo");
|
||||
com.current_dir("kernel");
|
||||
|
@ -154,14 +159,16 @@ fn build(release: bool, target: Target) -> Result<(), Error> {
|
|||
_ => (),
|
||||
}
|
||||
|
||||
if target != Target::X86_64 {
|
||||
return Ok(());
|
||||
}
|
||||
let kernel_dir = match target {
|
||||
Target::X86_64 => "target/x86_64-ableos",
|
||||
Target::Riscv64Virt => "target/riscv64-virt-ableos",
|
||||
Target::Aarch64 => "target/aarch64-virt-ableos",
|
||||
};
|
||||
|
||||
(|| -> std::io::Result<_> {
|
||||
io::copy(
|
||||
&mut File::open(
|
||||
Path::new("target/x86_64-ableos")
|
||||
Path::new(kernel_dir)
|
||||
.join(if release { "release" } else { "debug" })
|
||||
.join("kernel"),
|
||||
)?,
|
||||
|
@ -179,55 +186,45 @@ fn run(release: bool, target: Target) -> Result<(), Error> {
|
|||
Target::Riscv64Virt => Command::new("qemu-system-riscv64"),
|
||||
Target::Aarch64 => Command::new("qemu-system-aarch64"),
|
||||
};
|
||||
let ovmf_path = fetch_ovmf(target);
|
||||
|
||||
if target == Target::X86_64 {
|
||||
#[rustfmt::skip]
|
||||
com.args([
|
||||
"-bios", "target/OVMF_CODE.fd",
|
||||
"-drive", "file=target/disk.img,format=raw",
|
||||
"-m", "4G",
|
||||
// "-serial", "stdio",
|
||||
"-smp", "cores=4",
|
||||
// "-vga", "cirrus",
|
||||
// "-device", "ati-vga",
|
||||
// "-device", "virtio-gpu-pci",
|
||||
|
||||
// "-device", "virtio-serial,id=virtio-serial0",
|
||||
// "-chardev", "stdio,id=char0,mux=on",
|
||||
// "-device", "virtconsole,chardev=char0",
|
||||
// "-device", "virtio-mouse-pci",
|
||||
|
||||
// "-device", "ati-vga", "model=rage128p"
|
||||
]);
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
|
||||
//com.args(["-enable-kvm", "-cpu", "host"]);
|
||||
match target {
|
||||
Target::X86_64 => {
|
||||
#[rustfmt::skip]
|
||||
com.args([
|
||||
"-bios", &ovmf_path.change_context(Error::OvmfFetch)?,
|
||||
"-drive", "file=target/disk.img,format=raw",
|
||||
"-m", "4G",
|
||||
"-smp", "cores=4",
|
||||
]);
|
||||
}
|
||||
Target::Riscv64Virt => {
|
||||
#[rustfmt::skip]
|
||||
com.args([
|
||||
"-M", "virt",
|
||||
"-m", "128M",
|
||||
"-serial", "stdio",
|
||||
"-kernel",
|
||||
if release {
|
||||
"target/riscv64-virt-ableos/release/kernel"
|
||||
} else {
|
||||
"target/riscv64-virt-ableos/debug/kernel"
|
||||
}
|
||||
]);
|
||||
}
|
||||
Target::Aarch64 => {
|
||||
#[rustfmt::skip]
|
||||
com.args([
|
||||
"-M", "virt",
|
||||
"-cpu", "cortex-a72",
|
||||
"-device", "ramfb",
|
||||
"-device", "qemu-xhci",
|
||||
"-device", "usb-kbd",
|
||||
"-m", "2G",
|
||||
"-bios", &ovmf_path.change_context(Error::OvmfFetch)?,
|
||||
"-drive", "file=target/disk.img,format=raw",
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if target == Target::Riscv64Virt {
|
||||
#[rustfmt::skip]
|
||||
com.args([
|
||||
"-M", "virt",
|
||||
"-m", "128M",
|
||||
"-serial", "stdio",
|
||||
"-kernel",
|
||||
if release {
|
||||
"target/riscv64-virt-ableos/release/kernel"
|
||||
} else {
|
||||
"target/riscv64-virt-ableos/debug/kernel"
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
if target == Target::Aarch64 {
|
||||
com.args([
|
||||
"-M", "virt", "-m", //
|
||||
"128M",
|
||||
// "-serial", "stdio",
|
||||
]);
|
||||
}
|
||||
|
||||
match com
|
||||
|
@ -240,80 +237,48 @@ fn run(release: bool, target: Target) -> Result<(), Error> {
|
|||
}
|
||||
}
|
||||
|
||||
fn fetch_ovmf() -> Result<(), OvmfFetchError> {
|
||||
const OVMF_RPM_URL: &str = "https://kojipkgs.fedoraproject.org/packages/edk2/20230524/3.fc38/noarch/edk2-ovmf-20230524-3.fc38.noarch.rpm";
|
||||
fn fetch_ovmf(target: Target) -> Result<String, OvmfFetchError> {
|
||||
let (ovmf_url, ovmf_path) = match target {
|
||||
Target::X86_64 => (
|
||||
"https://retrage.github.io/edk2-nightly/bin/RELEASEX64_OVMF.fd",
|
||||
"target/RELEASEX64_OVMF.fd",
|
||||
),
|
||||
Target::Riscv64Virt => return Err(OvmfFetchError::Empty.into()),
|
||||
Target::Aarch64 => (
|
||||
"https://retrage.github.io/edk2-nightly/bin/RELEASEAARCH64_QEMU_EFI.fd",
|
||||
"target/RELEASEAARCH64_QEMU_EFI.fd",
|
||||
),
|
||||
};
|
||||
|
||||
let mut file = match std::fs::metadata("target/OVMF_CODE.fd") {
|
||||
let mut file = match std::fs::metadata(ovmf_path) {
|
||||
Err(e) if e.kind() == std::io::ErrorKind::NotFound => std::fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.write(true)
|
||||
.read(true)
|
||||
.open("target/OVMF_CODE.fd")
|
||||
.open(ovmf_path)
|
||||
.into_report()
|
||||
.change_context(OvmfFetchError::Io)?,
|
||||
Ok(_) => return Ok(()),
|
||||
Ok(_) => return Ok(ovmf_path.to_owned()),
|
||||
Err(e) => return Err(report!(e).change_context(OvmfFetchError::Io)),
|
||||
};
|
||||
|
||||
log::info!("No OVMF found, downloading…");
|
||||
let rpm = rpm::RPMPackage::parse(
|
||||
&mut std::convert::identity::<reqwest::Result<_>>((|| {
|
||||
reqwest::blocking::get(OVMF_RPM_URL)?.bytes()
|
||||
})())
|
||||
let mut bytes = reqwest::blocking::get(ovmf_url)
|
||||
.into_report()
|
||||
.change_context(OvmfFetchError::Fetch)?
|
||||
.as_ref(),
|
||||
)
|
||||
.map_err(RpmError)
|
||||
.into_report()
|
||||
.change_context(OvmfFetchError::RpmParse)?;
|
||||
.change_context(OvmfFetchError::Fetch)?;
|
||||
|
||||
ensure!(
|
||||
rpm.metadata
|
||||
.get_payload_compressor()
|
||||
.map_err(RpmError)
|
||||
.into_report()
|
||||
.change_context(OvmfFetchError::RpmParse)?
|
||||
== rpm::CompressionType::Zstd,
|
||||
OvmfFetchError::UnsupportedCompression,
|
||||
);
|
||||
bytes
|
||||
.copy_to(&mut file)
|
||||
.into_report()
|
||||
.change_context(OvmfFetchError::Io)?;
|
||||
|
||||
file.write_all(
|
||||
cpio_reader::iter_files(
|
||||
&zstd::decode_all(std::io::Cursor::new(rpm.content))
|
||||
.into_report()
|
||||
.change_context(OvmfFetchError::Zstd)?,
|
||||
)
|
||||
.find(|file| file.name() == "./usr/share/edk2/ovmf/OVMF_CODE.fd")
|
||||
.ok_or_else(|| report!(OvmfFetchError::NoFileFound))?
|
||||
.file(),
|
||||
)
|
||||
.into_report()
|
||||
.change_context(OvmfFetchError::Io)?;
|
||||
|
||||
Ok(())
|
||||
Ok(ovmf_path.to_owned())
|
||||
}
|
||||
|
||||
#[derive(Debug, Display, Deref, DerefMut)]
|
||||
struct RpmError(rpm::RPMError);
|
||||
impl Context for RpmError {}
|
||||
|
||||
// Ehhh?? I am pretty sure they just forgot :ferrisClueless:
|
||||
unsafe impl Sync for RpmError {}
|
||||
unsafe impl Send for RpmError {}
|
||||
|
||||
#[derive(Debug, Display)]
|
||||
enum OvmfFetchError {
|
||||
#[display(fmt = "Failed to fetch OVMF package")]
|
||||
Fetch,
|
||||
#[display(fmt = "RPM parse error")]
|
||||
RpmParse,
|
||||
#[display(fmt = "Unsupported compression (ZSTD is the only supported one)")]
|
||||
UnsupportedCompression,
|
||||
#[display(fmt = "Decompression error")]
|
||||
Zstd,
|
||||
#[display(fmt = "Requested file not found in package")]
|
||||
NoFileFound,
|
||||
#[display(fmt = "No OVMF package available")]
|
||||
Empty,
|
||||
#[display(fmt = "IO Error")]
|
||||
Io,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue