mirror of
https://github.com/iceHtwoO/novaOS.git
synced 2026-04-16 20:22:26 +00:00
feat: terminal, start app by ID
This commit is contained in:
@@ -273,7 +273,7 @@ pub fn map_page(
|
|||||||
let table = unsafe { &mut *table_ptr };
|
let table = unsafe { &mut *table_ptr };
|
||||||
|
|
||||||
if !table.0[l3_off].is_invalid() {
|
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);
|
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.
|
// Verify virtual address is available.
|
||||||
if !table.0[l2_off].is_invalid() {
|
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);
|
let new_entry = TableEntry::block_descriptor(physical_address, additional_flags);
|
||||||
@@ -392,7 +392,7 @@ fn next_table(
|
|||||||
match table.0[offset].value & 0b11 {
|
match table.0[offset].value & 0b11 {
|
||||||
0 => {
|
0 => {
|
||||||
if !create_missing {
|
if !create_missing {
|
||||||
return Err(NovaError::Paging);
|
return Err(NovaError::Paging("No table defined."));
|
||||||
}
|
}
|
||||||
let new_phys_page_table_address = reserve_page();
|
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)
|
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),
|
3 => Ok(resolve_table_addr(table.0[offset].address()) as *mut PageTable),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ pub fn reserve_page_explicit(physical_address: usize) -> Result<PhysAddr, NovaEr
|
|||||||
let word_index = page / 64;
|
let word_index = page / 64;
|
||||||
|
|
||||||
if unsafe { PAGING_BITMAP.bitmap[word_index] } & (1 << (page % 64)) > 0 {
|
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) };
|
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 {
|
for i in 0..L2_BLOCK_BITMAP_WORDS {
|
||||||
unsafe {
|
unsafe {
|
||||||
if PAGING_BITMAP.bitmap[(page / 64) + i] != 0 {
|
if PAGING_BITMAP.bitmap[(page / 64) + i] != 0 {
|
||||||
return Err(NovaError::Paging);
|
return Err(NovaError::Paging("Block PA already taken."));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::arch::asm;
|
use core::arch::asm;
|
||||||
|
use log::error;
|
||||||
|
use nova_error::NovaError;
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
|
|
||||||
pub struct Application {
|
pub struct Application {
|
||||||
@@ -28,7 +30,7 @@ impl Application {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.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)]
|
#[allow(static_mut_refs)]
|
||||||
unsafe {
|
unsafe {
|
||||||
let table = &mut *(virtual_address as *mut PageTable);
|
let table = &mut *(virtual_address as *mut PageTable);
|
||||||
@@ -40,6 +42,13 @@ impl Application {
|
|||||||
start_addr,
|
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) {
|
pub fn start(&self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
asm!("msr ELR_EL1, {}", in(reg) self.start_addr);
|
asm!("msr ELR_EL1, {}", in(reg) self.start_addr);
|
||||||
@@ -69,14 +78,27 @@ pub fn initialize_app_manager() {
|
|||||||
let mut guard = APP_MANAGER.lock();
|
let mut guard = APP_MANAGER.lock();
|
||||||
guard.apps = Some(Vec::new());
|
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() {
|
if let Some(app_list) = APP_MANAGER.lock().apps.as_mut() {
|
||||||
app_list.push(app);
|
app_list.push(app);
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(NovaError::General("AppManager not initalized."))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_app(index: usize) {
|
pub fn start_app(index: usize) -> Result<(), NovaError> {
|
||||||
if let Some(app_list) = APP_MANAGER.lock().apps.as_mut() {
|
if let Some(app) = APP_MANAGER
|
||||||
app_list[index].start();
|
.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."))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,15 @@ unsafe extern "C" fn rust_synchronous_interrupt_imm_lower_aarch64(frame: &mut Tr
|
|||||||
log_sync_exception();
|
log_sync_exception();
|
||||||
match esr.ec {
|
match esr.ec {
|
||||||
0b100100 => {
|
0b100100 => {
|
||||||
warn!("Cause: Data Abort from a lower Exception level");
|
error!("Cause: Data Abort from a lower Exception level");
|
||||||
}
|
}
|
||||||
0b010101 => {
|
0b010101 => {
|
||||||
debug!("Cause: SVC instruction execution in AArch64");
|
debug!("Cause: SVC instruction execution in AArch64");
|
||||||
return handle_svc(frame);
|
return handle_svc(frame);
|
||||||
}
|
}
|
||||||
|
0b100010 => {
|
||||||
|
error!("Cause: PC alignment fault.");
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
error!("Synchronous interrupt: Unknown Error Code: {:b}", esr.ec);
|
error!("Synchronous interrupt: Unknown Error Code: {:b}", esr.ec);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ pub extern "C" fn kernel_main() {
|
|||||||
enable_irq_source(IRQSource::UartInt);
|
enable_irq_source(IRQSource::UartInt);
|
||||||
|
|
||||||
let app = Application::new(el0 as *const () as usize);
|
let app = Application::new(el0 as *const () as usize);
|
||||||
add_app(app);
|
add_app(app).unwrap();
|
||||||
|
|
||||||
kernel_loop();
|
kernel_loop();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,14 +38,20 @@ impl Terminal {
|
|||||||
let val = self.input.clone();
|
let val = self.input.clone();
|
||||||
self.input.clear();
|
self.input.clear();
|
||||||
|
|
||||||
match val.as_str() {
|
let mut parts = val.split(" ");
|
||||||
|
|
||||||
|
match parts.next().unwrap() {
|
||||||
"temp" => {
|
"temp" => {
|
||||||
println!("{}", read_soc_temp([0]).unwrap()[1]);
|
println!("{}", read_soc_temp([0]).unwrap()[1]);
|
||||||
}
|
}
|
||||||
"el0" => unsafe {
|
"app" => unsafe {
|
||||||
let i = 69;
|
if let Some(app_id) = parts.next().and_then(|a| a.parse::<usize>().ok()) {
|
||||||
asm!("", in("x0") i);
|
let i = 69;
|
||||||
start_app(0);
|
asm!("", in("x0") i);
|
||||||
|
let _ = start_app(app_id);
|
||||||
|
} else {
|
||||||
|
println!("App ID not set.");
|
||||||
|
}
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
println!("Unknown command: \"{}\"", self.input);
|
println!("Unknown command: \"{}\"", self.input);
|
||||||
|
|||||||
@@ -5,11 +5,12 @@ use core::prelude::rust_2024::derive;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum NovaError {
|
pub enum NovaError {
|
||||||
|
General(&'static str),
|
||||||
Mailbox,
|
Mailbox,
|
||||||
HeapFull,
|
HeapFull,
|
||||||
EmptyHeapSegmentNotAllowed,
|
EmptyHeapSegmentNotAllowed,
|
||||||
Misalignment,
|
Misalignment,
|
||||||
InvalidGranularity,
|
InvalidGranularity,
|
||||||
Paging,
|
Paging(&'static str),
|
||||||
OutOfMeomory,
|
OutOfMeomory,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user