feat: terminal, start app by ID

This commit is contained in:
2026-03-26 15:27:08 +01:00
parent 804941d933
commit 02f16715bc
7 changed files with 53 additions and 19 deletions

View File

@@ -273,7 +273,7 @@ pub fn map_page(
let table = unsafe { &mut *table_ptr };
if !table.0[l3_off].is_invalid() {
return Err(NovaError::Paging);
return Err(NovaError::Paging("Page already occupied."));
}
table.0[l3_off] = TableEntry::page_descriptor(physical_address, additional_flags);
@@ -315,7 +315,7 @@ pub fn map_l2_block(
// Verify virtual address is available.
if !table.0[l2_off].is_invalid() {
return Err(NovaError::Paging);
return Err(NovaError::Paging("Block already occupied."));
}
let new_entry = TableEntry::block_descriptor(physical_address, additional_flags);
@@ -392,7 +392,7 @@ fn next_table(
match table.0[offset].value & 0b11 {
0 => {
if !create_missing {
return Err(NovaError::Paging);
return Err(NovaError::Paging("No table defined."));
}
let new_phys_page_table_address = reserve_page();
@@ -406,7 +406,9 @@ fn next_table(
Ok(resolve_table_addr(table.0[offset].address()) as *mut PageTable)
}
1 => Err(NovaError::Paging),
1 => Err(NovaError::Paging(
"Can't navigate table due to block mapping.",
)),
3 => Ok(resolve_table_addr(table.0[offset].address()) as *mut PageTable),
_ => unreachable!(),
}

View File

@@ -24,7 +24,7 @@ pub fn reserve_page_explicit(physical_address: usize) -> Result<PhysAddr, NovaEr
let word_index = page / 64;
if unsafe { PAGING_BITMAP.bitmap[word_index] } & (1 << (page % 64)) > 0 {
return Err(NovaError::Paging);
return Err(NovaError::Paging("Page PA already taken."));
}
unsafe { PAGING_BITMAP.bitmap[word_index] |= 1 << (page % 64) };
@@ -47,7 +47,7 @@ pub fn reserve_block_explicit(physical_address: usize) -> Result<(), NovaError>
for i in 0..L2_BLOCK_BITMAP_WORDS {
unsafe {
if PAGING_BITMAP.bitmap[(page / 64) + i] != 0 {
return Err(NovaError::Paging);
return Err(NovaError::Paging("Block PA already taken."));
}
};
}

View File

@@ -7,6 +7,8 @@ use crate::{
};
use alloc::vec::Vec;
use core::arch::asm;
use log::error;
use nova_error::NovaError;
use spin::Mutex;
pub struct Application {
@@ -28,7 +30,7 @@ impl Application {
)
.unwrap();
// TODO: Temporary fix, while kernel and app share some memory regions
// TODO: Temporary solution, while kernel and app share some memory regions
#[allow(static_mut_refs)]
unsafe {
let table = &mut *(virtual_address as *mut PageTable);
@@ -40,6 +42,13 @@ impl Application {
start_addr,
}
}
/// Starts an application.
///
/// `ELR_EL1` -> Exception Link Register (starting virtual address)
/// `SPSR_EL1` -> Saved Program State Register (settings for `eret` behaviour)
/// `SP_EL0` -> Stack Pointer Register (virtual_address of stack Pointer)
/// `TTBR0_EL1` -> Translation Table base Register Register
pub fn start(&self) {
unsafe {
asm!("msr ELR_EL1, {}", in(reg) self.start_addr);
@@ -69,14 +78,27 @@ pub fn initialize_app_manager() {
let mut guard = APP_MANAGER.lock();
guard.apps = Some(Vec::new());
}
pub fn add_app(app: Application) {
pub fn add_app(app: Application) -> Result<(), NovaError> {
if let Some(app_list) = APP_MANAGER.lock().apps.as_mut() {
app_list.push(app);
Ok(())
} else {
Err(NovaError::General("AppManager not initalized."))
}
}
pub fn start_app(index: usize) {
if let Some(app_list) = APP_MANAGER.lock().apps.as_mut() {
app_list[index].start();
pub fn start_app(index: usize) -> Result<(), NovaError> {
if let Some(app) = APP_MANAGER
.lock()
.apps
.as_mut()
.and_then(|am| am.get(index))
{
app.start();
unreachable!()
} else {
error!("Unable to start app due to invalid App ID.");
Err(NovaError::General("Invalid app id."))
}
}

View File

@@ -20,12 +20,15 @@ unsafe extern "C" fn rust_synchronous_interrupt_imm_lower_aarch64(frame: &mut Tr
log_sync_exception();
match esr.ec {
0b100100 => {
warn!("Cause: Data Abort from a lower Exception level");
error!("Cause: Data Abort from a lower Exception level");
}
0b010101 => {
debug!("Cause: SVC instruction execution in AArch64");
return handle_svc(frame);
}
0b100010 => {
error!("Cause: PC alignment fault.");
}
_ => {
error!("Synchronous interrupt: Unknown Error Code: {:b}", esr.ec);
}

View File

@@ -105,7 +105,7 @@ pub extern "C" fn kernel_main() {
enable_irq_source(IRQSource::UartInt);
let app = Application::new(el0 as *const () as usize);
add_app(app);
add_app(app).unwrap();
kernel_loop();
}

View File

@@ -38,14 +38,20 @@ impl Terminal {
let val = self.input.clone();
self.input.clear();
match val.as_str() {
let mut parts = val.split(" ");
match parts.next().unwrap() {
"temp" => {
println!("{}", read_soc_temp([0]).unwrap()[1]);
}
"el0" => unsafe {
let i = 69;
asm!("", in("x0") i);
start_app(0);
"app" => unsafe {
if let Some(app_id) = parts.next().and_then(|a| a.parse::<usize>().ok()) {
let i = 69;
asm!("", in("x0") i);
let _ = start_app(app_id);
} else {
println!("App ID not set.");
}
},
_ => {
println!("Unknown command: \"{}\"", self.input);

View File

@@ -5,11 +5,12 @@ use core::prelude::rust_2024::derive;
#[derive(Debug)]
pub enum NovaError {
General(&'static str),
Mailbox,
HeapFull,
EmptyHeapSegmentNotAllowed,
Misalignment,
InvalidGranularity,
Paging,
Paging(&'static str),
OutOfMeomory,
}