forked from AbleOS/ableos
riscv64-virt port + fix issues with page allocator
This commit is contained in:
parent
59c34f5849
commit
11620e6499
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
|
@ -3,4 +3,5 @@
|
|||
"stddef.h": "c"
|
||||
},
|
||||
"rust-analyzer.checkOnSave.allTargets": false,
|
||||
"rust-analyzer.cargo.target": "kernel/targets/riscv64-virt-ableos.json",
|
||||
}
|
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -328,6 +328,7 @@ dependencies = [
|
|||
"crossbeam-queue",
|
||||
"limine",
|
||||
"log",
|
||||
"sbi",
|
||||
"slab",
|
||||
"spin",
|
||||
"uart_16550",
|
||||
|
@ -510,6 +511,12 @@ version = "1.0.11"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70"
|
||||
|
||||
[[package]]
|
||||
name = "sbi"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29cb0870400aca7e4487e8ec1e93f9d4288da763cb1da2cedc5102e62b6522ad"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
|
|
|
@ -8,6 +8,7 @@ slab = { version = "0.4", default-features = false }
|
|||
spin = "0.9"
|
||||
versioning = { git = "https://git.ablecorp.us/able/aos_userland" }
|
||||
log = "0.4"
|
||||
uart_16550 = "0.2"
|
||||
|
||||
[dependencies.crossbeam-queue]
|
||||
version = "0.3"
|
||||
|
@ -16,6 +17,8 @@ features = ["alloc"]
|
|||
|
||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||
limine = { version = "0.1", git = "https://github.com/limine-bootloader/limine-rs" }
|
||||
uart_16550 = "0.2"
|
||||
x86_64 = "0.14"
|
||||
x2apic = "0.4"
|
||||
|
||||
[target.'cfg(target_arch = "riscv64")'.dependencies]
|
||||
sbi = "0.2.0"
|
||||
|
|
67
kernel/lds/riscv64-virt.ld
Normal file
67
kernel/lds/riscv64-virt.ld
Normal file
|
@ -0,0 +1,67 @@
|
|||
OUTPUT_ARCH(riscv)
|
||||
ENTRY(_start)
|
||||
START_ADDRESS = 0x80200000;
|
||||
|
||||
SECTIONS {
|
||||
. = START_ADDRESS;
|
||||
|
||||
.text : {
|
||||
PROVIDE(_text_start = .);
|
||||
*(.text.entry)
|
||||
|
||||
. = ALIGN(4K);
|
||||
|
||||
*(.text .text.*)
|
||||
PROVIDE(_text_end = .);
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
|
||||
.rodata : {
|
||||
PROVIDE(_rodata_start = .);
|
||||
*(.rodata .rodata.*)
|
||||
PROVIDE(_rodata_end = .);
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
|
||||
.data : {
|
||||
PROVIDE(_data_start = .);
|
||||
*(.data .data.*)
|
||||
PROVIDE(_data_end = .);
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
|
||||
.sdata : {
|
||||
PROVIDE(_sdata_start = .);
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.srodata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
PROVIDE(_sdata_end = .);
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
|
||||
.bss : {
|
||||
PROVIDE(_bss_start = .);
|
||||
*(.sbss*)
|
||||
*(.bss.stack)
|
||||
*(.bss .bss.*)
|
||||
PROVIDE(_initial_kernel_heap_start = .);
|
||||
PROVIDE(_initial_kernel_heap_size = 1024 * 1024);
|
||||
. += _initial_kernel_heap_size;
|
||||
PROVIDE(_bss_end = .);
|
||||
}
|
||||
|
||||
/* FIXME: Currently this has to be aligned to PAGE_SIZE << MAX_ORDER */
|
||||
. = ALIGN(4M);
|
||||
PROVIDE(_usable_memory_start = .);
|
||||
PROVIDE(_usable_memory_size = 0x88000000 - .);
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.comment)
|
||||
*(.eh_frame)
|
||||
}
|
||||
}
|
|
@ -35,14 +35,6 @@ use core::{
|
|||
|
||||
use spin::Mutex;
|
||||
|
||||
extern "C" {
|
||||
fn _initial_kernel_heap_start();
|
||||
fn _initial_kernel_heap_size();
|
||||
}
|
||||
|
||||
const INITIAL_KERNEL_HEAP_START: *mut u8 = _initial_kernel_heap_start as _;
|
||||
const INITIAL_KERNEL_HEAP_SIZE: *const () = _initial_kernel_heap_size as _;
|
||||
|
||||
struct Allocator(Mutex<Option<Heap>>);
|
||||
|
||||
unsafe impl GlobalAlloc for Allocator {
|
||||
|
@ -66,10 +58,10 @@ unsafe impl GlobalAlloc for Allocator {
|
|||
#[global_allocator]
|
||||
static ALLOCATOR: Allocator = Allocator(Mutex::new(None));
|
||||
|
||||
pub fn init() {
|
||||
pub fn init(memory: *mut u8, memory_size: usize) {
|
||||
log::info!("Initialising kernel heap allocator");
|
||||
*ALLOCATOR.0.lock() =
|
||||
Some(unsafe { Heap::new(INITIAL_KERNEL_HEAP_START, INITIAL_KERNEL_HEAP_SIZE as _) });
|
||||
Some(unsafe { Heap::new(memory, memory_size) });
|
||||
}
|
||||
|
||||
// FIXME: these are arch-specific
|
||||
|
|
31
kernel/src/arch/riscv64/entry.s
Normal file
31
kernel/src/arch/riscv64/entry.s
Normal file
|
@ -0,0 +1,31 @@
|
|||
.section .text.entry
|
||||
.global _start
|
||||
_start:
|
||||
# load stack_top to sp register
|
||||
la sp, stack_top
|
||||
|
||||
# The BSS section is expected to be zero
|
||||
la a0, _bss_start
|
||||
la a1, _bss_end
|
||||
bgeu a0, a1, 2f
|
||||
1:
|
||||
sd zero, (a0)
|
||||
addi a0, a0, 8
|
||||
bltu a0, a1, 1b
|
||||
2:
|
||||
call _kernel_start
|
||||
|
||||
.section .bss.stack
|
||||
.global stack
|
||||
stack:
|
||||
# alloc stack memory
|
||||
.space 4096 * 16
|
||||
.global stack_top
|
||||
stack_top:
|
||||
.section .bss.heap
|
||||
.global _initial_kernel_heap_start
|
||||
_initial_kernel_heap_start:
|
||||
# alloc initial kmalloc memory
|
||||
.space 4096 * 64
|
||||
.global _initial_kernel_heap_end
|
||||
_initial_kernel_heap_end:
|
35
kernel/src/arch/riscv64/memory_regions.s
Normal file
35
kernel/src/arch/riscv64/memory_regions.s
Normal file
|
@ -0,0 +1,35 @@
|
|||
.section .rodata
|
||||
.global TEXT_START
|
||||
TEXT_START: .quad _text_start
|
||||
.global TEXT_END
|
||||
TEXT_END: .quad _text_end
|
||||
|
||||
.global RODATA_START
|
||||
RODATA_START: .quad _rodata_start
|
||||
.global RODATA_END
|
||||
RODATA_END: .quad _rodata_end
|
||||
|
||||
.global DATA_START
|
||||
DATA_START: .quad _data_start
|
||||
.global DATA_END
|
||||
DATA_END: .quad _data_end
|
||||
|
||||
.global SDATA_START
|
||||
SDATA_START: .quad _sdata_start
|
||||
.global SDATA_END
|
||||
SDATA_END: .quad _sdata_end
|
||||
|
||||
.global BSS_START
|
||||
BSS_START: .quad _bss_start
|
||||
.global BSS_END
|
||||
BSS_END: .quad _bss_end
|
||||
|
||||
.global INITIAL_KERNEL_HEAP_START
|
||||
INITIAL_KERNEL_HEAP_START: .quad _initial_kernel_heap_start
|
||||
.global INITIAL_KERNEL_HEAP_SIZE
|
||||
INITIAL_KERNEL_HEAP_SIZE: .quad _initial_kernel_heap_size
|
||||
|
||||
.global USABLE_MEMORY_START
|
||||
USABLE_MEMORY_START: .quad _usable_memory_start
|
||||
.global USABLE_MEMORY_SIZE
|
||||
USABLE_MEMORY_SIZE: .quad _usable_memory_size
|
|
@ -1 +1,92 @@
|
|||
//!
|
||||
use core::{arch::{asm, global_asm}, fmt::Write};
|
||||
use alloc::vec;
|
||||
use sbi::system_reset::{ResetType, ResetReason, system_reset};
|
||||
use spin::{Mutex, Once};
|
||||
use uart_16550::MmioSerialPort;
|
||||
|
||||
use crate::{allocator, memory::MemoryManager};
|
||||
|
||||
global_asm!(include_str!("entry.s"));
|
||||
global_asm!(include_str!("memory_regions.s"));
|
||||
|
||||
pub const PAGE_SIZE: usize = 4096;
|
||||
|
||||
extern {
|
||||
static TEXT_START: usize;
|
||||
static TEXT_END: usize;
|
||||
|
||||
static RODATA_START: usize;
|
||||
static RODATA_END: usize;
|
||||
|
||||
static DATA_START: usize;
|
||||
static DATA_END: usize;
|
||||
|
||||
static SDATA_START: usize;
|
||||
static SDATA_END: usize;
|
||||
|
||||
static BSS_START: usize;
|
||||
static BSS_END: usize;
|
||||
|
||||
static INITIAL_KERNEL_HEAP_START: *mut u8;
|
||||
static INITIAL_KERNEL_HEAP_SIZE: usize;
|
||||
|
||||
static USABLE_MEMORY_START: usize;
|
||||
static USABLE_MEMORY_SIZE: usize;
|
||||
}
|
||||
|
||||
static SERIAL_CONSOLE: Once<Mutex<MmioSerialPort>> = Once::new();
|
||||
|
||||
mod memory {
|
||||
use spin::{Mutex, Once};
|
||||
use crate::memory::MemoryManager;
|
||||
|
||||
pub static MEMORY_MANAGER: Once<Mutex<MemoryManager>> = Once::new();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern fn _kernel_start() -> ! {
|
||||
SERIAL_CONSOLE.call_once(|| Mutex::new(unsafe { MmioSerialPort::new(0x1000_0000) }));
|
||||
crate::logger::init().expect("failed to set logger");
|
||||
log::info!("Initialising AKern {}", crate::VERSION);
|
||||
|
||||
unsafe {
|
||||
allocator::init(INITIAL_KERNEL_HEAP_START, INITIAL_KERNEL_HEAP_SIZE);
|
||||
}
|
||||
|
||||
let mut memory_manager = MemoryManager::new();
|
||||
unsafe {
|
||||
log::debug!("USABLE_MEMORY_START = 0x{USABLE_MEMORY_START:x}");
|
||||
memory_manager.add_range(USABLE_MEMORY_START, USABLE_MEMORY_SIZE / PAGE_SIZE);
|
||||
}
|
||||
memory::MEMORY_MANAGER.call_once(|| Mutex::new(memory_manager));
|
||||
|
||||
unsafe {
|
||||
let mut mm = memory::MEMORY_MANAGER.get().unwrap().lock();
|
||||
let alloc_0 = mm.allocate_pages(0).unwrap();
|
||||
log::debug!("Addr: {:p}", alloc_0);
|
||||
let alloc_1 = mm.allocate_pages(0).unwrap();
|
||||
log::debug!("Addr: {:p}", alloc_1);
|
||||
mm.deallocate_pages(alloc_0, 0);
|
||||
let alloc_2 = mm.allocate_pages(1).unwrap();
|
||||
log::debug!("Addr: {:p}", alloc_2);
|
||||
mm.deallocate_pages(alloc_1, 0);
|
||||
mm.deallocate_pages(alloc_2, 1);
|
||||
let alloc_3 = mm.allocate_pages(1).unwrap();
|
||||
log::debug!("Addr: {:p}", alloc_3);
|
||||
mm.deallocate_pages(alloc_3, 1);
|
||||
}
|
||||
|
||||
system_reset(ResetType::Shutdown, ResetReason::NoReason).unwrap();
|
||||
loop {}
|
||||
}
|
||||
|
||||
/// Spin loop
|
||||
pub fn sloop() -> ! {
|
||||
loop {
|
||||
unsafe { asm!("wfi") }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn log(args: core::fmt::Arguments<'_>) -> core::fmt::Result {
|
||||
SERIAL_CONSOLE.get().unwrap().lock().write_fmt(args)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use core::sync::atomic::AtomicU64;
|
|||
use limine::{LimineMemmapEntry, LimineMemoryMapEntryType, NonNullPtr};
|
||||
use spin::{Mutex, Once};
|
||||
use x86_64::{structures::paging::OffsetPageTable, VirtAddr};
|
||||
use crate::memory::MemoryManager;
|
||||
use crate::memory::{MemoryManager, MAX_ORDER};
|
||||
|
||||
pub const PAGE_SIZE: usize = 4096;
|
||||
|
||||
|
@ -36,8 +36,17 @@ pub fn initialize(mmap: &'static [NonNullPtr<LimineMemmapEntry>]) {
|
|||
continue;
|
||||
}
|
||||
|
||||
let alignment = PAGE_SIZE << MAX_ORDER;
|
||||
let start_addr_unaligned = entry.base as usize;
|
||||
let diff = alignment - start_addr_unaligned % alignment;
|
||||
if diff > entry.len as usize {
|
||||
continue;
|
||||
}
|
||||
let start_addr = start_addr_unaligned + diff;
|
||||
let page_count = (entry.len as usize - diff) / PAGE_SIZE;
|
||||
|
||||
unsafe {
|
||||
memory_manager.add_range(entry.base as usize, entry.len as usize / PAGE_SIZE);
|
||||
memory_manager.add_range(start_addr, page_count);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,21 @@ mod logging;
|
|||
pub use logging::log;
|
||||
pub use memory::PAGE_SIZE;
|
||||
|
||||
use crate::{allocator, arch::memory::MEMORY_MANAGER};
|
||||
use crate::allocator;
|
||||
use memory::MEMORY_MANAGER;
|
||||
use limine::{
|
||||
LimineHhdmRequest, LimineKernelFileRequest, LimineMemmapRequest, LimineModuleRequest,
|
||||
};
|
||||
use x86_64::VirtAddr;
|
||||
|
||||
extern "C" {
|
||||
fn _initial_kernel_heap_start();
|
||||
fn _initial_kernel_heap_size();
|
||||
}
|
||||
|
||||
const INITIAL_KERNEL_HEAP_START: *mut u8 = _initial_kernel_heap_start as _;
|
||||
const INITIAL_KERNEL_HEAP_SIZE: *const () = _initial_kernel_heap_size as _;
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn _kernel_start() -> ! {
|
||||
logging::init();
|
||||
|
@ -27,7 +36,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
|
|||
.offset,
|
||||
));
|
||||
|
||||
allocator::init();
|
||||
allocator::init(INITIAL_KERNEL_HEAP_START, INITIAL_KERNEL_HEAP_SIZE as _);
|
||||
|
||||
static MMAP_REQ: LimineMemmapRequest = LimineMemmapRequest::new(0);
|
||||
memory::initialize(
|
||||
|
|
|
@ -32,9 +32,9 @@ pub const VERSION: Version = Version {
|
|||
#[panic_handler]
|
||||
fn panic(info: &core::panic::PanicInfo) -> ! {
|
||||
// TODO: Better panic handler
|
||||
let _ = crate::arch::log(format_args!(
|
||||
"\r\n\x1b[1m\x1b[4m\x1b[38;5;125mKernel Panic\x1b[0m\r\n",
|
||||
));
|
||||
// let _ = crate::arch::log(format_args!(
|
||||
// "\r\n\x1b[1m\x1b[4m\x1b[38;5;125mKernel Panic\x1b[0m\r\n",
|
||||
// ));
|
||||
|
||||
if let Some(loc) = info.location() {
|
||||
let _ = crate::arch::log(format_args!(
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
//! The Memory Manager
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use alloc::collections::VecDeque;
|
||||
|
||||
pub use crate::arch::PAGE_SIZE;
|
||||
pub const MAX_ORDER: usize = 10;
|
||||
|
||||
pub struct MemoryManager {
|
||||
free_lists: [Vec<usize>; MAX_ORDER + 1],
|
||||
free_lists: [VecDeque<usize>; MAX_ORDER + 1],
|
||||
}
|
||||
|
||||
impl MemoryManager {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
free_lists: [const { Vec::new() }; MAX_ORDER + 1],
|
||||
free_lists: [const { VecDeque::new() }; MAX_ORDER + 1],
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,18 +23,18 @@ impl MemoryManager {
|
|||
/// # Safety
|
||||
/// This method assumes that `address` is in range of this allocator
|
||||
pub unsafe fn deallocate_pages(&mut self, address: *mut u8, order: usize) {
|
||||
self.free_lists[order].push(address as usize);
|
||||
self.free_lists[order].push_front(address as usize);
|
||||
self.merge_buddies(order, address as usize)
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
/// This method assumes that the given address range,
|
||||
/// a) starts at an address aligned to page boundaries,
|
||||
/// a) starts and ends at an address aligned to page boundaries,
|
||||
/// b) are valid free pages not already added,
|
||||
/// FIXME: c) has a multiple of `1 << MAX_ORDER` number of pages
|
||||
/// FIXME: c) starts and ends at an address aligned to `PAGE_SIZE << MAX_ORDER`
|
||||
pub unsafe fn add_range(&mut self, start_addr: usize, page_count: usize) {
|
||||
for i in 0..page_count / 1024 {
|
||||
self.free_lists[MAX_ORDER].push(start_addr + i * 1024 * PAGE_SIZE);
|
||||
self.free_lists[MAX_ORDER].push_back(start_addr + i * 1024 * PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,11 +45,11 @@ impl MemoryManager {
|
|||
}
|
||||
|
||||
if self.free_lists[order].len() > 0 {
|
||||
return self.free_lists[order].pop();
|
||||
return self.free_lists[order].pop_front();
|
||||
}
|
||||
|
||||
self.get_free_pages(order + 1).map(|addr| {
|
||||
self.free_lists[order].push(addr ^ (PAGE_SIZE << order));
|
||||
self.free_lists[order].push_front(addr ^ (PAGE_SIZE << order));
|
||||
addr
|
||||
})
|
||||
}
|
||||
|
@ -66,11 +66,11 @@ impl MemoryManager {
|
|||
.iter()
|
||||
.position(|blk| *blk == buddy_address)
|
||||
{
|
||||
self.free_lists[order].pop();
|
||||
self.free_lists[order].pop_front();
|
||||
self.free_lists[order].remove(buddy_index);
|
||||
let new_address = address.min(buddy_address);
|
||||
log::debug!("Merging 0x{address:x} @ {order} with 0x{buddy_address:x} at 0x{new_address:x}");
|
||||
self.free_lists[order + 1].push(new_address);
|
||||
self.free_lists[order + 1].push_front(new_address);
|
||||
self.merge_buddies(order + 1, new_address)
|
||||
}
|
||||
}
|
||||
|
|
22
kernel/targets/riscv64-virt-ableos.json
Normal file
22
kernel/targets/riscv64-virt-ableos.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"arch": "riscv64",
|
||||
"code-model": "medium",
|
||||
"cpu": "generic-rv64",
|
||||
"data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
|
||||
"eh-frame-header": false,
|
||||
"emit-debug-gdb-scripts": false,
|
||||
"features": "+m,+a,+f,+d,+c",
|
||||
"linker": "rust-lld",
|
||||
"linker-flavor": "ld.lld",
|
||||
"llvm-abiname": "lp64d",
|
||||
"llvm-target": "riscv64",
|
||||
"max-atomic-width": 64,
|
||||
"panic-strategy": "abort",
|
||||
"relocation-model": "static",
|
||||
"target-pointer-width": "64",
|
||||
"pre-link-args": {
|
||||
"ld.lld": [
|
||||
"--script=kernel/lds/riscv64-virt.ld"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -8,19 +8,34 @@ fn main() -> Result<(), Error> {
|
|||
args.next();
|
||||
|
||||
match args.next().as_deref() {
|
||||
Some("build" | "b") => build(
|
||||
args.next()
|
||||
.map(|x| x == "-r" || x == "--release")
|
||||
.unwrap_or_default(),
|
||||
)
|
||||
.change_context(Error::Build),
|
||||
Some("build" | "b") => {
|
||||
let mut release = false;
|
||||
let mut target = Target::X86_64;
|
||||
for arg in args {
|
||||
if arg == "-r" || arg == "--release" {
|
||||
release = true;
|
||||
}
|
||||
if arg == "rv64" || arg == "riscv64" || arg == "riscv64-virt" {
|
||||
target = Target::Riscv64Virt;
|
||||
}
|
||||
}
|
||||
|
||||
build(release, target).change_context(Error::Build)
|
||||
},
|
||||
Some("run" | "r") => {
|
||||
build(
|
||||
args.next()
|
||||
.map(|x| x == "-r" || x == "--release")
|
||||
.unwrap_or_default(),
|
||||
)?;
|
||||
run()
|
||||
let mut release = false;
|
||||
let mut target = Target::X86_64;
|
||||
for arg in args {
|
||||
if arg == "-r" || arg == "--release" {
|
||||
release = true;
|
||||
}
|
||||
if arg == "rv64" || arg == "riscv64" || arg == "riscv64-virt" {
|
||||
target = Target::Riscv64Virt;
|
||||
}
|
||||
}
|
||||
|
||||
build(release, target)?;
|
||||
run(release, target)
|
||||
}
|
||||
Some("help" | "h") => {
|
||||
println!(concat!(
|
||||
|
@ -30,7 +45,8 @@ fn main() -> Result<(), Error> {
|
|||
" help (h): Print this message\n",
|
||||
" run (r): Build and run AbleOS in QEMU\n\n",
|
||||
"Options for build and run:\n",
|
||||
" -r: build in release mode",
|
||||
" -r: build in release mode",
|
||||
" [target]: sets target"
|
||||
),);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -87,7 +103,7 @@ fn get_fs() -> Result<FileSystem<impl ReadWriteSeek>, io::Error> {
|
|||
Ok(fs)
|
||||
}
|
||||
|
||||
fn build(release: bool) -> Result<(), Error> {
|
||||
fn build(release: bool, target: Target) -> Result<(), Error> {
|
||||
let fs = get_fs().change_context(Error::Io)?;
|
||||
let mut com = Command::new("cargo");
|
||||
com.current_dir("kernel");
|
||||
|
@ -96,12 +112,21 @@ fn build(release: bool) -> Result<(), Error> {
|
|||
com.arg("-r");
|
||||
}
|
||||
|
||||
match target {
|
||||
Target::Riscv64Virt => { com.args(["--target", "targets/riscv64-virt-ableos.json"]); },
|
||||
_ => {}
|
||||
}
|
||||
|
||||
match com.status() {
|
||||
Ok(s) if s.code() != Some(0) => bail!(Error::Build),
|
||||
Err(e) => bail!(report!(e).change_context(Error::Build)),
|
||||
_ => (),
|
||||
}
|
||||
|
||||
if target != Target::X86_64 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
(|| -> std::io::Result<_> {
|
||||
io::copy(
|
||||
&mut File::open(
|
||||
|
@ -117,24 +142,44 @@ fn build(release: bool) -> Result<(), Error> {
|
|||
.change_context(Error::Io)
|
||||
}
|
||||
|
||||
fn run() -> Result<(), Error> {
|
||||
let mut com = Command::new("qemu-system-x86_64");
|
||||
fn run(release: bool, target: Target) -> Result<(), Error> {
|
||||
let mut com = match target {
|
||||
Target::X86_64 => Command::new("qemu-system-x86_64"),
|
||||
Target::Riscv64Virt => Command::new("qemu-system-riscv64")
|
||||
};
|
||||
|
||||
#[rustfmt::skip]
|
||||
com.args([
|
||||
"-bios",
|
||||
std::env::var("REPBUILD_QEMU_FIRMWARE_PATH")
|
||||
.as_deref()
|
||||
.unwrap_or("/usr/share/OVMF/OVMF_CODE.fd"),
|
||||
"-drive", "file=target/disk.img,format=raw",
|
||||
"-m", "4G",
|
||||
"-serial", "stdio",
|
||||
"-smp", "cores=2",
|
||||
]);
|
||||
if target == Target::X86_64 {
|
||||
#[rustfmt::skip]
|
||||
com.args([
|
||||
"-bios",
|
||||
std::env::var("REPBUILD_QEMU_FIRMWARE_PATH")
|
||||
.as_deref()
|
||||
.unwrap_or("/usr/share/OVMF/OVMF_CODE.fd"),
|
||||
"-drive", "file=target/disk.img,format=raw",
|
||||
"-m", "4G",
|
||||
"-serial", "stdio",
|
||||
"-smp", "cores=2",
|
||||
]);
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
com.args(["-enable-kvm", "-cpu", "host"]);
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
com.args(["-enable-kvm", "-cpu", "host"]);
|
||||
}
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
match com
|
||||
|
@ -147,6 +192,12 @@ fn run() -> Result<(), Error> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
enum Target {
|
||||
X86_64,
|
||||
Riscv64Virt,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Error {
|
||||
Build,
|
||||
|
|
Loading…
Reference in a new issue