Compare commits
No commits in common. "develop" and "mommy" have entirely different histories.
29 changed files with 53 additions and 732 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["liblbos"]
|
members = ["liblbos"]
|
||||||
exclude = ["blood", "turntable", "makeddi", "ddi", "example"]
|
exclude = ["turntable", "makeddi", "ddi", "example"]
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "lbos"
|
name = "lbos"
|
||||||
|
|
@ -24,7 +24,7 @@ panic = "abort"
|
||||||
opt-level = "z"
|
opt-level = "z"
|
||||||
debug-assertions = false
|
debug-assertions = false
|
||||||
overflow-checks = false
|
overflow-checks = false
|
||||||
strip = false
|
strip = true
|
||||||
lto = true
|
lto = true
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
|
|
||||||
|
|
|
||||||
2
blood/.gitignore
vendored
2
blood/.gitignore
vendored
|
|
@ -1,2 +0,0 @@
|
||||||
/target
|
|
||||||
/.idea
|
|
||||||
14
blood/Cargo.lock
generated
14
blood/Cargo.lock
generated
|
|
@ -1,14 +0,0 @@
|
||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 4
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "blood"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"liblbos",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "liblbos"
|
|
||||||
version = "0.1.1"
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "blood"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2024"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
liblbos = { path = "../liblbos" }
|
|
||||||
|
|
||||||
[profile.dev]
|
|
||||||
panic = "abort"
|
|
||||||
opt-level = "s"
|
|
||||||
debug-assertions = false
|
|
||||||
overflow-checks = false
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
panic = "abort"
|
|
||||||
opt-level = "z"
|
|
||||||
debug-assertions = false
|
|
||||||
overflow-checks = false
|
|
||||||
lto = true
|
|
||||||
codegen-units = 1
|
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["arch_riscv32"]
|
|
||||||
arch_riscv32 = ["liblbos/arch_riscv32"]
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
fn main() {
|
|
||||||
let arch = std::env::var("LBOS_ARCH").unwrap_or("riscv32".to_string());
|
|
||||||
println!("cargo:rerun-if-env-changed=LBOS_ARCH");
|
|
||||||
println!("cargo:rustc-cfg=feature=\"arch_{}\"", arch);
|
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed=src/arch/{}/asm", arch);
|
|
||||||
|
|
||||||
// specify the linker.ld script
|
|
||||||
println!("cargo:rustc-link-arg=-Tsrc/arch/{arch}/asm/linker.ld");
|
|
||||||
|
|
||||||
// output relocation info
|
|
||||||
println!("cargo:rustc-link-arg=--emit-relocs");
|
|
||||||
|
|
||||||
// don't page align sections
|
|
||||||
println!("cargo:rustc-link-arg=-n");
|
|
||||||
}
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
#[cfg(feature = "arch_riscv32")]
|
|
||||||
mod riscv32;
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
OUTPUT_FORMAT( "elf32-littleriscv" )
|
|
||||||
OUTPUT_ARCH( "riscv" )
|
|
||||||
|
|
||||||
ENTRY( _start )
|
|
||||||
|
|
||||||
MEMORY
|
|
||||||
{
|
|
||||||
program (wxa) : ORIGIN = 0x0, LENGTH = 20480
|
|
||||||
}
|
|
||||||
|
|
||||||
PHDRS
|
|
||||||
{
|
|
||||||
prg PT_LOAD ;
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTIONS {
|
|
||||||
.text : {
|
|
||||||
. = ALIGN(512);
|
|
||||||
*(.text .text.*)
|
|
||||||
} >program AT>program :prg
|
|
||||||
|
|
||||||
.rodata : {
|
|
||||||
*(.rodata .rodata.*)
|
|
||||||
} >program AT>program :prg
|
|
||||||
|
|
||||||
.data : {
|
|
||||||
*(.sdata .sdata.*) *(.data .data.*)
|
|
||||||
} >program AT>program :prg
|
|
||||||
|
|
||||||
.bss : {
|
|
||||||
*(.sbss .sbss.*)
|
|
||||||
*(.bss .bss.*)
|
|
||||||
} >program AT>program :prg
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
use crate::main;
|
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
|
||||||
extern "C" fn _start() -> isize {
|
|
||||||
unsafe {
|
|
||||||
main();
|
|
||||||
}
|
|
||||||
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
#![no_std]
|
|
||||||
#![no_main]
|
|
||||||
|
|
||||||
use liblbos::fs::{DirectoryReader, FileSystem};
|
|
||||||
|
|
||||||
#[panic_handler]
|
|
||||||
fn panic(info: &core::panic::PanicInfo) -> ! {
|
|
||||||
liblbos::syscalls::write_terminal(b"abort\n");
|
|
||||||
loop {}
|
|
||||||
}
|
|
||||||
mod arch;
|
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
|
||||||
extern "C" fn main() {
|
|
||||||
loop {
|
|
||||||
const TURNTBL: &str = "TURNTBL.DDI";
|
|
||||||
let mut fs = FileSystem::empty();
|
|
||||||
if liblbos::ktask::ktask_fsopen(&mut fs) != 0 {
|
|
||||||
liblbos::syscalls::write_terminal(b"failed to open fs\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let mut dir = DirectoryReader::empty();
|
|
||||||
if liblbos::ktask::ktask_fsopendir(&fs, &mut dir, b"/") != 0 {
|
|
||||||
liblbos::syscalls::write_terminal(b"failed to open dir\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let mut record = liblbos::fs::Record {
|
|
||||||
name: [0; 12],
|
|
||||||
record_type: 0,
|
|
||||||
target: 0,
|
|
||||||
total_size_bytes: 0,
|
|
||||||
};
|
|
||||||
fn namecmp(record: &liblbos::fs::Record, name: &[u8]) -> bool {
|
|
||||||
for (i, &x) in record.name.iter().enumerate() {
|
|
||||||
if x == 0 {
|
|
||||||
return &record.name[..i] == name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
while !namecmp(&record, TURNTBL.as_bytes()) {
|
|
||||||
if liblbos::ktask::ktask_fsreaddir(&fs, &mut dir, &mut record) != 0 {
|
|
||||||
liblbos::syscalls::write_terminal(b"failed to read dir\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if record.record_type == 0 {
|
|
||||||
liblbos::syscalls::write_terminal(b"unexpected eod\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// found turntable, load it
|
|
||||||
let mut reader = liblbos::fs::FileReader::empty();
|
|
||||||
if liblbos::ktask::ktask_fsopenfile(&fs, &record, &mut reader) != 0 {
|
|
||||||
liblbos::syscalls::write_terminal(b"failed to open file\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let size = record.total_size_bytes as usize;
|
|
||||||
let buf = liblbos::syscalls::alloc_blocks(size.div_ceil(512));
|
|
||||||
if liblbos::ktask::ktask_fsreadfile(&fs, &mut reader, unsafe { core::slice::from_raw_parts_mut(buf as *mut _, size) }) != 0 {
|
|
||||||
liblbos::syscalls::write_terminal(b"failed to read file\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut task_setup = liblbos::TaskSetup {
|
|
||||||
epc: 0,
|
|
||||||
stack_block_count: 2,
|
|
||||||
ddi_first_addr: 0,
|
|
||||||
ddi_size: 0,
|
|
||||||
environment: 0,
|
|
||||||
wait_for_task_exit: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
if liblbos::ktask::ktask_loadddifile(buf, size, &mut task_setup as *mut _ as usize) != 0 {
|
|
||||||
liblbos::syscalls::write_terminal(b"failed to load ddi\n");
|
|
||||||
liblbos::syscalls::free_blocks(buf, size.div_ceil(512));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
liblbos::syscalls::free_blocks(buf, size.div_ceil(512));
|
|
||||||
|
|
||||||
liblbos::syscalls::create_task(task_setup);
|
|
||||||
|
|
||||||
liblbos::syscalls::wait_until_alone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
6
build.rs
6
build.rs
|
|
@ -1,12 +1,6 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
// define LBOS_FONT
|
|
||||||
if std::env::var("LBOS_FONT").is_err() {
|
|
||||||
println!("cargo:rustc-env=LBOS_FONT=charset1.data");
|
|
||||||
}
|
|
||||||
|
|
||||||
let arch = std::env::var("LBOS_ARCH").unwrap_or("virt".to_string());
|
let arch = std::env::var("LBOS_ARCH").unwrap_or("virt".to_string());
|
||||||
println!("cargo:rerun-if-env-changed=LBOS_ARCH");
|
println!("cargo:rerun-if-env-changed=LBOS_ARCH");
|
||||||
println!("cargo:rerun-if-env-changed=LBOS_FONT");
|
|
||||||
println!("cargo:rustc-cfg=feature=\"arch_{}\"", arch);
|
println!("cargo:rustc-cfg=feature=\"arch_{}\"", arch);
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed=src/arch/{}/asm", arch);
|
println!("cargo:rerun-if-changed=src/arch/{}/asm", arch);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ mkdir -p mount
|
||||||
mount "${storage_device}" mount
|
mount "${storage_device}" mount
|
||||||
|
|
||||||
echo "COPYING..."
|
echo "COPYING..."
|
||||||
cp -v blood/target/riscv32imac-unknown-none-elf/release/BLOOD.DDI mount
|
|
||||||
cp -v turntable/target/riscv32imac-unknown-none-elf/release/TURNTBL.DDI mount
|
cp -v turntable/target/riscv32imac-unknown-none-elf/release/TURNTBL.DDI mount
|
||||||
cp -v example/target/riscv32imac-unknown-none-elf/release/EXAMPLE.DDI mount
|
cp -v example/target/riscv32imac-unknown-none-elf/release/EXAMPLE.DDI mount
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,11 +98,6 @@ pub fn apply_relocation(segment_buffer: &mut [u8], current_segment_base: u32, ta
|
||||||
x if x == RiscVRelocationType::None as u16 => {
|
x if x == RiscVRelocationType::None as u16 => {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
x if x == RiscVRelocationType::R32 as u16 => {
|
|
||||||
let ptr = relocation_header.relocation_pointer as usize;
|
|
||||||
let addr = relocation_header.target_pointer as u32 + target_segment_base;
|
|
||||||
segment_buffer[ptr..ptr+4].copy_from_slice(&addr.to_le_bytes());
|
|
||||||
}
|
|
||||||
x if x == RiscVRelocationType::CallPLT as u16 || x == RiscVRelocationType::Call as u16 => {
|
x if x == RiscVRelocationType::CallPLT as u16 || x == RiscVRelocationType::Call as u16 => {
|
||||||
// these are relative, do nothing for now
|
// these are relative, do nothing for now
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
pub const C_LIFEBLOOD_CAT: char = (b'~' + 1) as char;
|
|
||||||
pub const C_SMILE: char = (b'~' + 2) as char;
|
|
||||||
pub const C_FEARFUL: char = (b'~' + 3) as char;
|
|
||||||
pub const C_SUNGLASSES: char = (b'~' + 4) as char;
|
|
||||||
pub const C_COLONTHREE: char = (b'~' + 5) as char;
|
|
||||||
pub const C_FOLDER: char = (b'~' + 6) as char;
|
|
||||||
pub const C_FILE: char = (b'~' + 7) as char;
|
|
||||||
pub const C_BLOOD: char = (b'~' + 8) as char;
|
|
||||||
pub const C_WINK: char = (b'~' + 9) as char;
|
|
||||||
pub const C_CONFUSED: char = (b'~' + 10) as char;
|
|
||||||
pub const C_COLOND: char = (b'~' + 11) as char;
|
|
||||||
|
|
@ -1,95 +0,0 @@
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct Keymap {
|
|
||||||
pub alpha: u16,
|
|
||||||
pub beta: u32,
|
|
||||||
pub gamma: u16,
|
|
||||||
pub delta: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(u16)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub enum KeymapSection {
|
|
||||||
Alpha = 1,
|
|
||||||
Beta = 2,
|
|
||||||
Gamma = 3,
|
|
||||||
Delta = 4,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(u16)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub enum KeyAlpha {
|
|
||||||
Esc = 1 << 0,
|
|
||||||
Key1 = 1 << 1,
|
|
||||||
Key2 = 1 << 2,
|
|
||||||
Key3 = 1 << 3,
|
|
||||||
Key4 = 1 << 4,
|
|
||||||
Key5 = 1 << 5,
|
|
||||||
Key6 = 1 << 6,
|
|
||||||
Key7 = 1 << 7,
|
|
||||||
Key8 = 1 << 8,
|
|
||||||
Key9 = 1 << 9,
|
|
||||||
Key0 = 1 << 10,
|
|
||||||
Minus = 1 << 11,
|
|
||||||
Equal = 1 << 12,
|
|
||||||
Backspace = 1 << 13,
|
|
||||||
Tab = 1 << 14,
|
|
||||||
Enter = 1 << 15,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(u32)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub enum KeyBeta {
|
|
||||||
A = 1 << 0,
|
|
||||||
B = 1 << 1,
|
|
||||||
C = 1 << 2,
|
|
||||||
D = 1 << 3,
|
|
||||||
E = 1 << 4,
|
|
||||||
F = 1 << 5,
|
|
||||||
G = 1 << 6,
|
|
||||||
H = 1 << 7,
|
|
||||||
I = 1 << 8,
|
|
||||||
J = 1 << 9,
|
|
||||||
K = 1 << 10,
|
|
||||||
L = 1 << 11,
|
|
||||||
M = 1 << 12,
|
|
||||||
N = 1 << 13,
|
|
||||||
O = 1 << 14,
|
|
||||||
P = 1 << 15,
|
|
||||||
Q = 1 << 16,
|
|
||||||
R = 1 << 17,
|
|
||||||
S = 1 << 18,
|
|
||||||
T = 1 << 19,
|
|
||||||
U = 1 << 20,
|
|
||||||
V = 1 << 21,
|
|
||||||
W = 1 << 22,
|
|
||||||
X = 1 << 23,
|
|
||||||
Y = 1 << 24,
|
|
||||||
Z = 1 << 25,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(u16)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub enum KeyGamma {
|
|
||||||
LeftBracket = 1 << 0,
|
|
||||||
RightBracket = 1 << 1,
|
|
||||||
Semicolon = 1 << 2,
|
|
||||||
Apostrophe = 1 << 3,
|
|
||||||
Grave = 1 << 4,
|
|
||||||
Backslash = 1 << 5,
|
|
||||||
Comma = 1 << 6,
|
|
||||||
Dot = 1 << 7,
|
|
||||||
Slash = 1 << 8,
|
|
||||||
Space = 1 << 9,
|
|
||||||
Control = 1 << 10,
|
|
||||||
Shift = 1 << 11,
|
|
||||||
Alt = 1 << 12,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(u16)]
|
|
||||||
pub enum KeyDelta {
|
|
||||||
UpArrow = 1 << 0,
|
|
||||||
DownArrow = 1 << 1,
|
|
||||||
LeftArrow = 1 << 12,
|
|
||||||
RightArrow = 1 << 13,
|
|
||||||
}
|
|
||||||
|
|
@ -3,15 +3,11 @@
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
pub mod ktask;
|
pub mod ktask;
|
||||||
pub mod syscalls;
|
pub mod syscalls;
|
||||||
pub mod characters;
|
|
||||||
pub mod keymap;
|
|
||||||
mod arch;
|
mod arch;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct TaskSetup {
|
pub struct TaskSetup {
|
||||||
pub epc: usize,
|
pub epc: usize,
|
||||||
pub stack_block_count: usize,
|
|
||||||
/// MUST BE NON-ZERO
|
|
||||||
pub ddi_first_addr: usize,
|
pub ddi_first_addr: usize,
|
||||||
pub ddi_size: usize,
|
pub ddi_size: usize,
|
||||||
pub environment: usize,
|
pub environment: usize,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::arch::{stall, syscall};
|
use crate::arch::{stall, syscall};
|
||||||
use crate::keymap::Keymap;
|
|
||||||
use crate::TaskSetup;
|
use crate::TaskSetup;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|
@ -81,11 +80,7 @@ pub enum SysCall {
|
||||||
/// flushes changes done within the given rectangle to the framebuffer
|
/// flushes changes done within the given rectangle to the framebuffer
|
||||||
/// if there is no device providing a gpu, this will not do anything
|
/// if there is no device providing a gpu, this will not do anything
|
||||||
FlushFramebufferRect = 18,
|
FlushFramebufferRect = 18,
|
||||||
/// fills the given struct with the current keymap info
|
|
||||||
GetCurrentKeymap = 19,
|
|
||||||
|
|
||||||
/// doens't return until all other tasks besides the current task and the ktask have exited
|
|
||||||
WaitUntilAlone = 333,
|
|
||||||
/// initializes kernel, ONLY CALL ONCE! IN FACT, YOU PROBABLY NEVER NEED TO CALL THIS
|
/// initializes kernel, ONLY CALL ONCE! IN FACT, YOU PROBABLY NEVER NEED TO CALL THIS
|
||||||
InitKernel = 666
|
InitKernel = 666
|
||||||
}
|
}
|
||||||
|
|
@ -115,8 +110,6 @@ pub fn usize2sc(u: usize) -> SysCall {
|
||||||
16 => SysCall::EnableFramebufferConsole,
|
16 => SysCall::EnableFramebufferConsole,
|
||||||
17 => SysCall::FramebufferPointer,
|
17 => SysCall::FramebufferPointer,
|
||||||
18 => SysCall::FlushFramebufferRect,
|
18 => SysCall::FlushFramebufferRect,
|
||||||
19 => SysCall::GetCurrentKeymap,
|
|
||||||
333 => SysCall::WaitUntilAlone,
|
|
||||||
666 => SysCall::InitKernel,
|
666 => SysCall::InitKernel,
|
||||||
_ => SysCall::NoAction,
|
_ => SysCall::NoAction,
|
||||||
}
|
}
|
||||||
|
|
@ -206,14 +199,6 @@ pub fn flush_framebuffer_rect(x: usize, y: usize, w: usize, h: usize) {
|
||||||
syscall(SysCall::FlushFramebufferRect, x, y, w, h, 0, 0);
|
syscall(SysCall::FlushFramebufferRect, x, y, w, h, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_current_keymap(keymap: &mut Keymap) {
|
|
||||||
syscall(SysCall::GetCurrentKeymap, keymap as *mut Keymap as usize, 0, 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn wait_until_alone() {
|
|
||||||
syscall(SysCall::WaitUntilAlone, 0, 0, 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init_kernel() {
|
pub fn init_kernel() {
|
||||||
syscall(SysCall::InitKernel, 0, 0, 0, 0, 0, 0);
|
syscall(SysCall::InitKernel, 0, 0, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -17,7 +17,7 @@ global_asm!(include_str!("asm/trap.s"));
|
||||||
extern "C" fn eh_personality() {}
|
extern "C" fn eh_personality() {}
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
#[cfg(feature = "debug_messages")]
|
//#[cfg(feature = "debug_messages")]
|
||||||
fn panic(info: &core::panic::PanicInfo) -> ! {
|
fn panic(info: &core::panic::PanicInfo) -> ! {
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
let mut uart = UART::new(0x1000_0000);
|
let mut uart = UART::new(0x1000_0000);
|
||||||
|
|
@ -38,6 +38,7 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
#[cfg(not(feature = "debug_messages"))]
|
#[cfg(not(feature = "debug_messages"))]
|
||||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||||
|
|
@ -51,6 +52,7 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
pub fn virt_rough_panic(errcode: [char; 3]) -> ! {
|
pub fn virt_rough_panic(errcode: [char; 3]) -> ! {
|
||||||
let uart = UART::new(0x1000_0000);
|
let uart = UART::new(0x1000_0000);
|
||||||
for c in b"PANIC".iter() {
|
for c in b"PANIC".iter() {
|
||||||
|
|
@ -81,7 +83,6 @@ extern "C" fn _virt_init() -> ! {
|
||||||
|
|
||||||
create_task(TaskSetup {
|
create_task(TaskSetup {
|
||||||
epc: ktask as usize,
|
epc: ktask as usize,
|
||||||
stack_block_count: 2,
|
|
||||||
ddi_first_addr: 0,
|
ddi_first_addr: 0,
|
||||||
ddi_size: 0,
|
ddi_size: 0,
|
||||||
environment: 0,
|
environment: 0,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::arch::virt::{plic, serial_port};
|
use crate::arch::virt::{plic, serial_port};
|
||||||
use crate::rough_panic;
|
use crate::rough_panic;
|
||||||
use crate::syscalls::usize2sc;
|
use crate::syscalls::usize2sc;
|
||||||
use crate::trafficcontrol::{TC, context_switch, handle_syscall, MAX_TASKS, TrafficControl, Task};
|
use crate::trafficcontrol::{TC, context_switch, handle_syscall, MAX_TASKS};
|
||||||
use core::arch::asm;
|
use core::arch::asm;
|
||||||
use crate::spinlock::Spinlock;
|
use crate::spinlock::Spinlock;
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 1.6 KiB |
|
|
@ -1,9 +1,9 @@
|
||||||
use crate::dev::framebuffer::{fb_clear_area, fb_clearscreen, fb_write_char_array, CHAR_SIZE};
|
use crate::dev::framebuffer::{fb_clear_area, fb_clearscreen, fb_write_char_array};
|
||||||
use crate::spinlock::Spinlock;
|
use crate::spinlock::Spinlock;
|
||||||
use crate::trafficcontrol::TrafficControl;
|
use crate::trafficcontrol::TrafficControl;
|
||||||
|
|
||||||
pub struct FramebufferConsole {
|
pub struct FramebufferConsole {
|
||||||
pub buffer: [[u8; 26]; 20], // our font is 16x16, 320x240 is the standard res, so 20x15
|
pub buffer: [[char; 20]; 15], // our font is 16x16, 320x240 is the standard res, so 20x15
|
||||||
pub cursor: (usize, usize), // (x, y)
|
pub cursor: (usize, usize), // (x, y)
|
||||||
pub need_screen_clear: bool,
|
pub need_screen_clear: bool,
|
||||||
pub need_line_clear: bool,
|
pub need_line_clear: bool,
|
||||||
|
|
@ -14,7 +14,7 @@ pub static FBCONSOLE: Spinlock<FramebufferConsole> = Spinlock::new(FramebufferCo
|
||||||
impl FramebufferConsole {
|
impl FramebufferConsole {
|
||||||
pub const fn empty() -> Self {
|
pub const fn empty() -> Self {
|
||||||
Self {
|
Self {
|
||||||
buffer: [[b' '; 26]; 20],
|
buffer: [[' '; 20]; 15],
|
||||||
cursor: (0, 0),
|
cursor: (0, 0),
|
||||||
need_screen_clear: true,
|
need_screen_clear: true,
|
||||||
need_line_clear: false,
|
need_line_clear: false,
|
||||||
|
|
@ -27,24 +27,23 @@ impl FramebufferConsole {
|
||||||
let copy_from = self.buffer[line_num + 1];
|
let copy_from = self.buffer[line_num + 1];
|
||||||
self.buffer[line_num] = copy_from;
|
self.buffer[line_num] = copy_from;
|
||||||
}
|
}
|
||||||
self.buffer[self.buffer.len() - 1] = [b' '; 26];
|
self.buffer[self.buffer.len() - 1] = [' '; 20];
|
||||||
self.need_screen_clear = true;
|
self.need_screen_clear = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DOES send a framebuffer update!
|
// DOES send a framebuffer update!
|
||||||
pub fn clear_terminal(&mut self, tc: &mut TrafficControl) {
|
pub fn clear_terminal(&mut self, tc: &mut TrafficControl) {
|
||||||
self.need_screen_clear = true;
|
self.need_screen_clear = true;
|
||||||
self.buffer = [[b' '; 26]; 20];
|
self.buffer = [[' '; 20]; 15];
|
||||||
self.cursor = (0, 0);
|
self.cursor = (0, 0);
|
||||||
self.render(tc, true);
|
self.render(tc, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// DOES send a framebuffer update!
|
// DOES send a framebuffer update!
|
||||||
pub fn printstr(&mut self, tc: &mut TrafficControl, str: &[u8]) {
|
pub fn printstr(&mut self, tc: &mut TrafficControl, str: &str) {
|
||||||
for c in str {
|
for c in str.chars() {
|
||||||
let c = *c;
|
|
||||||
let mut was_special_char = false;
|
let mut was_special_char = false;
|
||||||
if c == b'\n' || c == b'\r' {
|
if c == '\n' || c == '\r' {
|
||||||
was_special_char = true;
|
was_special_char = true;
|
||||||
self.cursor.0 = 0;
|
self.cursor.0 = 0;
|
||||||
self.cursor.1 += 1;
|
self.cursor.1 += 1;
|
||||||
|
|
@ -54,7 +53,7 @@ impl FramebufferConsole {
|
||||||
self.cursor.1 = self.buffer.len() - 1;
|
self.cursor.1 = self.buffer.len() - 1;
|
||||||
self.scroll_terminal();
|
self.scroll_terminal();
|
||||||
}
|
}
|
||||||
if c == b'\x08' {
|
if c == '\x08' {
|
||||||
was_special_char = true;
|
was_special_char = true;
|
||||||
// we don't clear the character, that's up to the terminal
|
// we don't clear the character, that's up to the terminal
|
||||||
self.need_line_clear = true;
|
self.need_line_clear = true;
|
||||||
|
|
@ -91,12 +90,12 @@ impl FramebufferConsole {
|
||||||
self.need_screen_clear = false;
|
self.need_screen_clear = false;
|
||||||
}
|
}
|
||||||
if self.need_line_clear {
|
if self.need_line_clear {
|
||||||
fb_clear_area(tc, 0, self.cursor.1 * CHAR_SIZE, 320, CHAR_SIZE, refresh_whole_screen);
|
fb_clear_area(tc, 0, self.cursor.1 * 16, 320, 16, refresh_whole_screen);
|
||||||
self.need_line_clear = false;
|
self.need_line_clear = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (y, line) in self.buffer.iter().enumerate() {
|
for (y, line) in self.buffer.iter().enumerate() {
|
||||||
fb_write_char_array(tc, 0, y * CHAR_SIZE, line);
|
fb_write_char_array(tc, 0, y * 16, line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,9 @@ use core::sync::atomic::Ordering;
|
||||||
|
|
||||||
pub mod console;
|
pub mod console;
|
||||||
|
|
||||||
pub const VAPFONT: &[u8] = include_bytes!(env!("LBOS_FONT"));
|
pub const VAPFONT: &[u8] = include_bytes!("./vapfont.data");
|
||||||
pub const VAPFONT_W: usize = 184;
|
pub const VAPFONT_W: usize = 256;
|
||||||
pub const VAPFONT_H: usize = 84;
|
pub const VAPFONT_H: usize = 112;
|
||||||
pub const CHAR_SIZE: usize = 12;
|
|
||||||
|
|
||||||
pub struct FBColor {
|
pub struct FBColor {
|
||||||
pub red: u8,
|
pub red: u8,
|
||||||
|
|
@ -35,7 +34,7 @@ impl FBColor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fb_write_char_array(tc: &mut TrafficControl, mut x: usize, y: usize, chars: &[u8]) {
|
pub fn fb_write_char_array(tc: &mut TrafficControl, mut x: usize, y: usize, chars: &[char]) {
|
||||||
let ogx = x;
|
let ogx = x;
|
||||||
let ogy = y;
|
let ogy = y;
|
||||||
const BYTES: [u8; 3] = FB_FG_COLOR.to_bytes();
|
const BYTES: [u8; 3] = FB_FG_COLOR.to_bytes();
|
||||||
|
|
@ -44,14 +43,15 @@ pub fn fb_write_char_array(tc: &mut TrafficControl, mut x: usize, y: usize, char
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let fbstride = FRAMEBUFFER_BPP.load(Ordering::Relaxed) * FRAMEBUFFER_WIDTH;
|
let fbstride = FRAMEBUFFER_BPP.load(Ordering::Relaxed) * FRAMEBUFFER_WIDTH;
|
||||||
|
const CHAR_SIZE: usize = 16;
|
||||||
for c in chars {
|
for c in chars {
|
||||||
let c = *c;
|
let c = *c;
|
||||||
if c == b' ' {
|
if c == ' ' {
|
||||||
x += CHAR_SIZE;
|
x += CHAR_SIZE;
|
||||||
} else if c as u8 > 32 {
|
} else if c as u8 > 32 {
|
||||||
let c = c as u8 - b'!';
|
let c = c as u8 - 32;
|
||||||
let cx = (c % 15) as usize * CHAR_SIZE;
|
let cx = (c % 16) as usize * CHAR_SIZE;
|
||||||
let cy = (c / 15) as usize * CHAR_SIZE;
|
let cy = (c / 16) as usize * CHAR_SIZE;
|
||||||
for row in 0..CHAR_SIZE {
|
for row in 0..CHAR_SIZE {
|
||||||
for col in 0..CHAR_SIZE {
|
for col in 0..CHAR_SIZE {
|
||||||
let coff = (VAPFONT_W * (cy + row)) + (cx + col);
|
let coff = (VAPFONT_W * (cy + row)) + (cx + col);
|
||||||
|
|
|
||||||
BIN
src/dev/framebuffer/vapfont.data
Normal file
BIN
src/dev/framebuffer/vapfont.data
Normal file
Binary file not shown.
BIN
src/dev/framebuffer/vapfont.png
Normal file
BIN
src/dev/framebuffer/vapfont.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
|
|
@ -1,5 +1,4 @@
|
||||||
use core::sync::atomic::{AtomicBool, Ordering};
|
use core::sync::atomic::{AtomicBool, Ordering};
|
||||||
use liblbos::keymap::{KeyAlpha, KeyBeta, KeyDelta, KeyGamma, KeymapSection};
|
|
||||||
use crate::dev::virtio::{
|
use crate::dev::virtio::{
|
||||||
Descriptor, VIRTIO_DESC_F_WRITE, VIRTIO_MMIO_GUEST_FEATURES, VIRTIO_MMIO_GUEST_PAGE_SIZE,
|
Descriptor, VIRTIO_DESC_F_WRITE, VIRTIO_MMIO_GUEST_FEATURES, VIRTIO_MMIO_GUEST_PAGE_SIZE,
|
||||||
VIRTIO_MMIO_QUEUE_NUM, VIRTIO_MMIO_QUEUE_NUM_MAX, VIRTIO_MMIO_QUEUE_PFN, VIRTIO_MMIO_QUEUE_SEL,
|
VIRTIO_MMIO_QUEUE_NUM, VIRTIO_MMIO_QUEUE_NUM_MAX, VIRTIO_MMIO_QUEUE_PFN, VIRTIO_MMIO_QUEUE_SEL,
|
||||||
|
|
@ -189,38 +188,6 @@ impl VirtIoInputDevice {
|
||||||
let keycode = event.code;
|
let keycode = event.code;
|
||||||
let down = event.value == 1;
|
let down = event.value == 1;
|
||||||
|
|
||||||
// update the TC keymap
|
|
||||||
{
|
|
||||||
let mut keymap = &mut tc.current_keymap;
|
|
||||||
if let Some(keycode) = LinuxKeycode::from_u16(keycode) {
|
|
||||||
if let Some(alpha) = keycode.to_alpha_key() {
|
|
||||||
if down {
|
|
||||||
keymap.alpha |= alpha as u16;
|
|
||||||
} else {
|
|
||||||
keymap.alpha &= !(alpha as u16);
|
|
||||||
}
|
|
||||||
} else if let Some(beta) = keycode.to_beta_key() {
|
|
||||||
if down {
|
|
||||||
keymap.beta |= beta as u32;
|
|
||||||
} else {
|
|
||||||
keymap.beta &= !(beta as u32);
|
|
||||||
}
|
|
||||||
} else if let Some(gamma) = keycode.to_gamma_key() {
|
|
||||||
if down {
|
|
||||||
keymap.gamma |= gamma as u16;
|
|
||||||
} else {
|
|
||||||
keymap.gamma &= !(gamma as u16);
|
|
||||||
}
|
|
||||||
} else if let Some(delta) = keycode.to_delta_key() {
|
|
||||||
if down {
|
|
||||||
keymap.delta |= delta as u16;
|
|
||||||
} else {
|
|
||||||
keymap.delta &= !(delta as u16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// first, handle shift todo: handle more control characters
|
// first, handle shift todo: handle more control characters
|
||||||
if keycode == LinuxKeycode::LeftShift as u16 || keycode == LinuxKeycode::RightShift as u16 {
|
if keycode == LinuxKeycode::LeftShift as u16 || keycode == LinuxKeycode::RightShift as u16 {
|
||||||
UPPERCASE.store(down, Ordering::Relaxed);
|
UPPERCASE.store(down, Ordering::Relaxed);
|
||||||
|
|
@ -352,254 +319,6 @@ pub enum LinuxKeycode {
|
||||||
KP3 = 81,
|
KP3 = 81,
|
||||||
KP0 = 82,
|
KP0 = 82,
|
||||||
KPDot = 83,
|
KPDot = 83,
|
||||||
UpArrow = 103,
|
|
||||||
DownArrow = 108,
|
|
||||||
RightArrow = 106,
|
|
||||||
LeftArrow = 105,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LinuxKeycode {
|
|
||||||
pub fn from_u16(keycode: u16) -> Option<LinuxKeycode> {
|
|
||||||
const KEYCODES_TO_DOT: &[LinuxKeycode] = &[
|
|
||||||
LinuxKeycode::ESC,
|
|
||||||
LinuxKeycode::Key1,
|
|
||||||
LinuxKeycode::Key2,
|
|
||||||
LinuxKeycode::Key3,
|
|
||||||
LinuxKeycode::Key4,
|
|
||||||
LinuxKeycode::Key5,
|
|
||||||
LinuxKeycode::Key6,
|
|
||||||
LinuxKeycode::Key7,
|
|
||||||
LinuxKeycode::Key8,
|
|
||||||
LinuxKeycode::Key9,
|
|
||||||
LinuxKeycode::Key0,
|
|
||||||
LinuxKeycode::Minus,
|
|
||||||
LinuxKeycode::Equal,
|
|
||||||
LinuxKeycode::Backspace,
|
|
||||||
LinuxKeycode::Tab,
|
|
||||||
LinuxKeycode::Q,
|
|
||||||
LinuxKeycode::W,
|
|
||||||
LinuxKeycode::E,
|
|
||||||
LinuxKeycode::R,
|
|
||||||
LinuxKeycode::T,
|
|
||||||
LinuxKeycode::Y,
|
|
||||||
LinuxKeycode::U,
|
|
||||||
LinuxKeycode::I,
|
|
||||||
LinuxKeycode::O,
|
|
||||||
LinuxKeycode::P,
|
|
||||||
LinuxKeycode::LeftBracket,
|
|
||||||
LinuxKeycode::RightBracket,
|
|
||||||
LinuxKeycode::Enter,
|
|
||||||
LinuxKeycode::LeftControl,
|
|
||||||
LinuxKeycode::A,
|
|
||||||
LinuxKeycode::S,
|
|
||||||
LinuxKeycode::D,
|
|
||||||
LinuxKeycode::F,
|
|
||||||
LinuxKeycode::G,
|
|
||||||
LinuxKeycode::H,
|
|
||||||
LinuxKeycode::J,
|
|
||||||
LinuxKeycode::K,
|
|
||||||
LinuxKeycode::L,
|
|
||||||
LinuxKeycode::Semicolon,
|
|
||||||
LinuxKeycode::Apostrophe,
|
|
||||||
LinuxKeycode::Grave,
|
|
||||||
LinuxKeycode::LeftShift,
|
|
||||||
LinuxKeycode::Backslash,
|
|
||||||
LinuxKeycode::Z,
|
|
||||||
LinuxKeycode::X,
|
|
||||||
LinuxKeycode::C,
|
|
||||||
LinuxKeycode::V,
|
|
||||||
LinuxKeycode::B,
|
|
||||||
LinuxKeycode::N,
|
|
||||||
LinuxKeycode::M,
|
|
||||||
LinuxKeycode::Comma,
|
|
||||||
LinuxKeycode::Dot,
|
|
||||||
LinuxKeycode::Slash,
|
|
||||||
LinuxKeycode::RightShift,
|
|
||||||
LinuxKeycode::KPAsterisk,
|
|
||||||
LinuxKeycode::LeftAlt,
|
|
||||||
LinuxKeycode::Space,
|
|
||||||
LinuxKeycode::CapsLock,
|
|
||||||
LinuxKeycode::F1,
|
|
||||||
LinuxKeycode::F2,
|
|
||||||
LinuxKeycode::F3,
|
|
||||||
LinuxKeycode::F4,
|
|
||||||
LinuxKeycode::F5,
|
|
||||||
LinuxKeycode::F6,
|
|
||||||
LinuxKeycode::F7,
|
|
||||||
LinuxKeycode::F8,
|
|
||||||
LinuxKeycode::F9,
|
|
||||||
LinuxKeycode::F10,
|
|
||||||
LinuxKeycode::NumLock,
|
|
||||||
LinuxKeycode::ScrollLock,
|
|
||||||
LinuxKeycode::KP7,
|
|
||||||
LinuxKeycode::KP8,
|
|
||||||
LinuxKeycode::KP9,
|
|
||||||
LinuxKeycode::KPMinus,
|
|
||||||
LinuxKeycode::KP4,
|
|
||||||
LinuxKeycode::KP5,
|
|
||||||
LinuxKeycode::KP6,
|
|
||||||
LinuxKeycode::KPPlus,
|
|
||||||
LinuxKeycode::KP1,
|
|
||||||
LinuxKeycode::KP2,
|
|
||||||
LinuxKeycode::KP3,
|
|
||||||
LinuxKeycode::KP0,
|
|
||||||
LinuxKeycode::KPDot,
|
|
||||||
];
|
|
||||||
if keycode > 0 && keycode <= 83 {
|
|
||||||
let idx = keycode as usize - 1;
|
|
||||||
Some(KEYCODES_TO_DOT[idx])
|
|
||||||
} else if keycode == LinuxKeycode::UpArrow as u16 {
|
|
||||||
Some(LinuxKeycode::UpArrow)
|
|
||||||
} else if keycode == LinuxKeycode::DownArrow as u16 {
|
|
||||||
Some(LinuxKeycode::DownArrow)
|
|
||||||
} else if keycode == LinuxKeycode::RightArrow as u16 {
|
|
||||||
Some(LinuxKeycode::RightArrow)
|
|
||||||
} else if keycode == LinuxKeycode::LeftArrow as u16 {
|
|
||||||
Some(LinuxKeycode::LeftArrow)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_alphabet(&self) -> bool {
|
|
||||||
// top row
|
|
||||||
(*self as u16 >= LinuxKeycode::Q as u16 && *self as u16 <= LinuxKeycode::P as u16)
|
|
||||||
|| // middle row
|
|
||||||
(*self as u16 >= LinuxKeycode::A as u16 && *self as u16 <= LinuxKeycode::L as u16)
|
|
||||||
|| // bottom row
|
|
||||||
(*self as u16 >= LinuxKeycode::Z as u16 && *self as u16 <= LinuxKeycode::M as u16)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_gamma(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
LinuxKeycode::LeftBracket => true,
|
|
||||||
LinuxKeycode::RightBracket => true,
|
|
||||||
LinuxKeycode::Semicolon => true,
|
|
||||||
LinuxKeycode::Apostrophe => true,
|
|
||||||
LinuxKeycode::Grave => true,
|
|
||||||
LinuxKeycode::Backslash => true,
|
|
||||||
LinuxKeycode::Comma => true,
|
|
||||||
LinuxKeycode::Dot => true,
|
|
||||||
LinuxKeycode::Slash => true,
|
|
||||||
LinuxKeycode::Space => true,
|
|
||||||
LinuxKeycode::LeftControl => true,
|
|
||||||
LinuxKeycode::LeftShift => true,
|
|
||||||
LinuxKeycode::LeftAlt => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_delta(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
LinuxKeycode::UpArrow => true,
|
|
||||||
LinuxKeycode::DownArrow => true,
|
|
||||||
LinuxKeycode::RightArrow => true,
|
|
||||||
LinuxKeycode::LeftArrow => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_keymap_section(&self) -> Option<KeymapSection> {
|
|
||||||
if (*self as u16 >= LinuxKeycode::ESC as u16 && *self as u16 <= LinuxKeycode::Tab as u16) || *self as u16 == LinuxKeycode::Enter as u16 {
|
|
||||||
Some(KeymapSection::Alpha)
|
|
||||||
} else if self.is_alphabet() {
|
|
||||||
Some(KeymapSection::Beta)
|
|
||||||
} else if self.is_gamma() {
|
|
||||||
Some(KeymapSection::Gamma)
|
|
||||||
} else if self.is_delta() {
|
|
||||||
Some(KeymapSection::Delta)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_alpha_key(&self) -> Option<KeyAlpha> {
|
|
||||||
const KEYCODES_TO_ALPHA: &[KeyAlpha] = &[
|
|
||||||
KeyAlpha::Esc,
|
|
||||||
KeyAlpha::Key1,
|
|
||||||
KeyAlpha::Key2,
|
|
||||||
KeyAlpha::Key3,
|
|
||||||
KeyAlpha::Key4,
|
|
||||||
KeyAlpha::Key5,
|
|
||||||
KeyAlpha::Key6,
|
|
||||||
KeyAlpha::Key7,
|
|
||||||
KeyAlpha::Key8,
|
|
||||||
KeyAlpha::Key9,
|
|
||||||
KeyAlpha::Key0,
|
|
||||||
KeyAlpha::Minus,
|
|
||||||
KeyAlpha::Equal,
|
|
||||||
KeyAlpha::Backspace,
|
|
||||||
KeyAlpha::Tab,
|
|
||||||
];
|
|
||||||
if *self as u16 >= LinuxKeycode::ESC as u16 && *self as u16 <= LinuxKeycode::Tab as u16 {
|
|
||||||
Some(KEYCODES_TO_ALPHA[*self as usize - 1])
|
|
||||||
} else if *self as u16 == LinuxKeycode::Enter as u16 {
|
|
||||||
Some(KeyAlpha::Enter)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_beta_key(&self) -> Option<KeyBeta> {
|
|
||||||
match self {
|
|
||||||
LinuxKeycode::Q => Some(KeyBeta::Q),
|
|
||||||
LinuxKeycode::W => Some(KeyBeta::W),
|
|
||||||
LinuxKeycode::E => Some(KeyBeta::E),
|
|
||||||
LinuxKeycode::R => Some(KeyBeta::R),
|
|
||||||
LinuxKeycode::T => Some(KeyBeta::T),
|
|
||||||
LinuxKeycode::Y => Some(KeyBeta::Y),
|
|
||||||
LinuxKeycode::U => Some(KeyBeta::U),
|
|
||||||
LinuxKeycode::I => Some(KeyBeta::I),
|
|
||||||
LinuxKeycode::O => Some(KeyBeta::O),
|
|
||||||
LinuxKeycode::P => Some(KeyBeta::P),
|
|
||||||
LinuxKeycode::A => Some(KeyBeta::A),
|
|
||||||
LinuxKeycode::S => Some(KeyBeta::S),
|
|
||||||
LinuxKeycode::D => Some(KeyBeta::D),
|
|
||||||
LinuxKeycode::F => Some(KeyBeta::F),
|
|
||||||
LinuxKeycode::G => Some(KeyBeta::G),
|
|
||||||
LinuxKeycode::H => Some(KeyBeta::H),
|
|
||||||
LinuxKeycode::J => Some(KeyBeta::J),
|
|
||||||
LinuxKeycode::K => Some(KeyBeta::K),
|
|
||||||
LinuxKeycode::L => Some(KeyBeta::L),
|
|
||||||
LinuxKeycode::Z => Some(KeyBeta::Z),
|
|
||||||
LinuxKeycode::X => Some(KeyBeta::X),
|
|
||||||
LinuxKeycode::C => Some(KeyBeta::C),
|
|
||||||
LinuxKeycode::V => Some(KeyBeta::V),
|
|
||||||
LinuxKeycode::B => Some(KeyBeta::B),
|
|
||||||
LinuxKeycode::N => Some(KeyBeta::N),
|
|
||||||
LinuxKeycode::M => Some(KeyBeta::M),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_gamma_key(&self) -> Option<KeyGamma> {
|
|
||||||
match self {
|
|
||||||
LinuxKeycode::LeftBracket => Some(KeyGamma::LeftBracket),
|
|
||||||
LinuxKeycode::RightBracket => Some(KeyGamma::RightBracket),
|
|
||||||
LinuxKeycode::Semicolon => Some(KeyGamma::Semicolon),
|
|
||||||
LinuxKeycode::Apostrophe => Some(KeyGamma::Apostrophe),
|
|
||||||
LinuxKeycode::Grave => Some(KeyGamma::Grave),
|
|
||||||
LinuxKeycode::Backslash => Some(KeyGamma::Backslash),
|
|
||||||
LinuxKeycode::Comma => Some(KeyGamma::Comma),
|
|
||||||
LinuxKeycode::Dot => Some(KeyGamma::Dot),
|
|
||||||
LinuxKeycode::Slash => Some(KeyGamma::Slash),
|
|
||||||
LinuxKeycode::Space => Some(KeyGamma::Space),
|
|
||||||
LinuxKeycode::LeftControl => Some(KeyGamma::Control),
|
|
||||||
LinuxKeycode::LeftShift => Some(KeyGamma::Shift),
|
|
||||||
LinuxKeycode::LeftAlt => Some(KeyGamma::Alt),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_delta_key(&self) -> Option<KeyDelta> {
|
|
||||||
match self {
|
|
||||||
LinuxKeycode::UpArrow => Some(KeyDelta::UpArrow),
|
|
||||||
LinuxKeycode::DownArrow => Some(KeyDelta::DownArrow),
|
|
||||||
LinuxKeycode::RightArrow => Some(KeyDelta::RightArrow),
|
|
||||||
LinuxKeycode::LeftArrow => Some(KeyDelta::LeftArrow),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// keys that do not map directly are handled outside of this
|
// keys that do not map directly are handled outside of this
|
||||||
|
|
|
||||||
15
src/main.rs
15
src/main.rs
|
|
@ -32,7 +32,7 @@ pub extern "C" fn ktask() -> ! {
|
||||||
syscalls::init_kernel();
|
syscalls::init_kernel();
|
||||||
print(b"kernel ready!\n");
|
print(b"kernel ready!\n");
|
||||||
|
|
||||||
// load BLOOD.DDI
|
// load TURNTBL.DDI
|
||||||
|
|
||||||
{
|
{
|
||||||
fn fserr() {
|
fn fserr() {
|
||||||
|
|
@ -62,13 +62,13 @@ pub extern "C" fn ktask() -> ! {
|
||||||
record_name == name
|
record_name == name
|
||||||
}
|
}
|
||||||
|
|
||||||
while !namecmp(&record, b"BLOOD.DDI") {
|
while !namecmp(&record, b"TURNTBL.DDI") {
|
||||||
if !fs::read_one_record(
|
if !fs::read_one_record(
|
||||||
unsafe { &*(&fs as *const _ as *const _) },
|
unsafe { &*(&fs as *const _ as *const _) },
|
||||||
unsafe { &mut *(&mut dir as *mut _ as *mut _) },
|
unsafe { &mut *(&mut dir as *mut _ as *mut _) },
|
||||||
unsafe { &mut *(&mut record as *mut _ as *mut _) }
|
unsafe { &mut *(&mut record as *mut _ as *mut _) }
|
||||||
) {
|
) {
|
||||||
print(b"BLOOD.DDI NOT FOUND ):");
|
print(b"TURNTBL.DDI NOT FOUND ):");
|
||||||
print(b"\n");
|
print(b"\n");
|
||||||
rough_panic(['t', 't', 'b']);
|
rough_panic(['t', 't', 'b']);
|
||||||
}
|
}
|
||||||
|
|
@ -89,28 +89,23 @@ pub extern "C" fn ktask() -> ! {
|
||||||
unsafe { &mut *(&mut reader as *mut _ as *mut _) },
|
unsafe { &mut *(&mut reader as *mut _ as *mut _) },
|
||||||
unsafe { core::slice::from_raw_parts_mut(buf as *mut _, size) }
|
unsafe { core::slice::from_raw_parts_mut(buf as *mut _, size) }
|
||||||
) != 0 {
|
) != 0 {
|
||||||
print(b"BLOOD.DDI READ ERROR ):");
|
print(b"TURNTBL.DDI READ ERROR ):");
|
||||||
print(b"\n");
|
print(b"\n");
|
||||||
rough_panic(['f', 'r', 'e']);
|
rough_panic(['f', 'r', 'e']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// load the ddi
|
// load the ddi
|
||||||
let file_contents = unsafe { core::slice::from_raw_parts(buf as *const _, size) };
|
let file_contents = unsafe { core::slice::from_raw_parts(buf as *const _, size) };
|
||||||
let file_size = size;
|
|
||||||
if let Ok((entrypoint, first_addr, size)) = ddi::load_ddi(&file_contents) {
|
if let Ok((entrypoint, first_addr, size)) = ddi::load_ddi(&file_contents) {
|
||||||
// free the buffer
|
|
||||||
syscalls::free_blocks(buf, file_size.div_ceil(512));
|
|
||||||
|
|
||||||
create_task(TaskSetup {
|
create_task(TaskSetup {
|
||||||
epc: entrypoint,
|
epc: entrypoint,
|
||||||
stack_block_count: 1,
|
|
||||||
ddi_first_addr: first_addr,
|
ddi_first_addr: first_addr,
|
||||||
ddi_size: size,
|
ddi_size: size,
|
||||||
environment: 0,
|
environment: 0,
|
||||||
wait_for_task_exit: false,
|
wait_for_task_exit: false,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
print(b"BLOOD.DDI INVALID DDI ):");
|
print(b"TURNTBL.DDI INVALID DDI ):");
|
||||||
print(b"\n");
|
print(b"\n");
|
||||||
rough_panic(['t', 't', 'b']);
|
rough_panic(['t', 't', 'b']);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ impl MemoryManager {
|
||||||
uart.putstr("heap_start: ");
|
uart.putstr("heap_start: ");
|
||||||
uart.put_bytes(&u32_hex(_heap_start as u32));
|
uart.put_bytes(&u32_hex(_heap_start as u32));
|
||||||
uart.putstr("totalmem: ");
|
uart.putstr("totalmem: ");
|
||||||
uart.put_bytes(&u32_hex(_heap_size as u32 / BLOCK_SIZE as u32));
|
uart.put_bytes(&u32_hex(_heap_size as u32));
|
||||||
uart.putstr("\n");
|
uart.putstr("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
use core::sync::atomic::Ordering;
|
use core::sync::atomic::Ordering;
|
||||||
use liblbos::keymap::Keymap;
|
|
||||||
use liblbos::TaskSetup;
|
use liblbos::TaskSetup;
|
||||||
use crate::arch::serial_port;
|
use crate::arch::serial_port;
|
||||||
use crate::memory::{BLOCK_SIZE, MemoryManager};
|
use crate::memory::{BLOCK_SIZE, MemoryManager};
|
||||||
|
|
@ -13,9 +12,10 @@ pub enum TaskWait {
|
||||||
HardBlockDevOperation = 1 << 0,
|
HardBlockDevOperation = 1 << 0,
|
||||||
WaitForNotification = 1 << 1,
|
WaitForNotification = 1 << 1,
|
||||||
WaitForTaskExit = 1 << 2,
|
WaitForTaskExit = 1 << 2,
|
||||||
WaitUntilAlone = 1 << 7,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const STACK_SIZE_IN_BLOCKS: usize = 8;
|
||||||
|
|
||||||
pub const MAX_TASKS: usize = 8;
|
pub const MAX_TASKS: usize = 8;
|
||||||
|
|
||||||
pub static TC: Spinlock<TrafficControl> = Spinlock::new(TrafficControl::empty());
|
pub static TC: Spinlock<TrafficControl> = Spinlock::new(TrafficControl::empty());
|
||||||
|
|
@ -69,15 +69,13 @@ pub fn handle_syscall(
|
||||||
SysCall::CreateTask => {
|
SysCall::CreateTask => {
|
||||||
let add = a1 as *mut TaskSetup;
|
let add = a1 as *mut TaskSetup;
|
||||||
|
|
||||||
let stack_size_in_blocks = unsafe { (*add).stack_block_count };
|
|
||||||
|
|
||||||
tc.init_mem_if_not();
|
tc.init_mem_if_not();
|
||||||
let sp = unsafe {
|
let sp = unsafe {
|
||||||
tc.memory_manager
|
tc.memory_manager
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap_unchecked()
|
.unwrap_unchecked()
|
||||||
.alloc_n_blocks(stack_size_in_blocks)
|
.alloc_n_blocks(STACK_SIZE_IN_BLOCKS)
|
||||||
} + (BLOCK_SIZE * stack_size_in_blocks);
|
} + (BLOCK_SIZE * STACK_SIZE_IN_BLOCKS);
|
||||||
|
|
||||||
#[cfg(feature = "arch_virt")]
|
#[cfg(feature = "arch_virt")]
|
||||||
let t = Some(Task {
|
let t = Some(Task {
|
||||||
|
|
@ -85,7 +83,6 @@ pub fn handle_syscall(
|
||||||
environment: unsafe { (*add).environment },
|
environment: unsafe { (*add).environment },
|
||||||
want_exit: false,
|
want_exit: false,
|
||||||
sp,
|
sp,
|
||||||
stack_size_in_blocks,
|
|
||||||
wait: 0,
|
wait: 0,
|
||||||
incoming_notifications: [const { None }; MAX_TASKS],
|
incoming_notifications: [const { None }; MAX_TASKS],
|
||||||
ackwait: [0; MAX_TASKS],
|
ackwait: [0; MAX_TASKS],
|
||||||
|
|
@ -93,7 +90,7 @@ pub fn handle_syscall(
|
||||||
ddi_mem_start: unsafe {
|
ddi_mem_start: unsafe {
|
||||||
(*add).ddi_first_addr
|
(*add).ddi_first_addr
|
||||||
},
|
},
|
||||||
ddi_mem_blocks_count: unsafe { (*add).ddi_size.div_ceil(BLOCK_SIZE) },
|
ddi_mem_blocks_count: unsafe { (*add).ddi_size / BLOCK_SIZE },
|
||||||
trap_frame: arch::virt::tasks::setup_task(sp),
|
trap_frame: arch::virt::tasks::setup_task(sp),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -189,7 +186,9 @@ pub fn handle_syscall(
|
||||||
if tc.use_fb_console {
|
if tc.use_fb_console {
|
||||||
let mut fbcons = crate::dev::framebuffer::console::FBCONSOLE.lock();
|
let mut fbcons = crate::dev::framebuffer::console::FBCONSOLE.lock();
|
||||||
fbcons.printstr(&mut tc, unsafe {
|
fbcons.printstr(&mut tc, unsafe {
|
||||||
core::slice::from_raw_parts(addr as *const u8, count)
|
core::str::from_utf8_unchecked(unsafe {
|
||||||
|
core::slice::from_raw_parts(addr as *const u8, count)
|
||||||
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
0
|
0
|
||||||
|
|
@ -374,18 +373,6 @@ pub fn handle_syscall(
|
||||||
crate::dev::framebuffer_push(&mut tc, x, y, w, h);
|
crate::dev::framebuffer_push(&mut tc, x, y, w, h);
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
SysCall::WaitUntilAlone => {
|
|
||||||
let ci = tc.current;
|
|
||||||
let mut task = tc.tasks[ci].as_mut().unwrap();
|
|
||||||
task.wait |= TaskWait::WaitForTaskExit as u32;
|
|
||||||
suspend = true;
|
|
||||||
0
|
|
||||||
}
|
|
||||||
SysCall::GetCurrentKeymap => {
|
|
||||||
let keymap_ptr = unsafe { &mut *(a1 as *mut Keymap) };
|
|
||||||
*keymap_ptr = tc.current_keymap;
|
|
||||||
0
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
suspend,
|
suspend,
|
||||||
)
|
)
|
||||||
|
|
@ -395,12 +382,7 @@ pub fn context_switch<'a>(tc: &'a mut TrafficControl, current: Task) -> Option<&
|
||||||
let ci = tc.current;
|
let ci = tc.current;
|
||||||
tc.tasks[ci] = Some(current);
|
tc.tasks[ci] = Some(current);
|
||||||
|
|
||||||
let mut remaining_tasks = 0;
|
|
||||||
|
|
||||||
for i in 0..tc.tasks.len() {
|
for i in 0..tc.tasks.len() {
|
||||||
if tc.tasks[i].is_some() {
|
|
||||||
remaining_tasks += 1;
|
|
||||||
}
|
|
||||||
let want_exit = tc.tasks[i]
|
let want_exit = tc.tasks[i]
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|task| task.want_exit)
|
.map(|task| task.want_exit)
|
||||||
|
|
@ -410,13 +392,12 @@ pub fn context_switch<'a>(tc: &'a mut TrafficControl, current: Task) -> Option<&
|
||||||
let sp = tc.tasks[i].as_ref().map(|v| v.sp).unwrap_or(0);
|
let sp = tc.tasks[i].as_ref().map(|v| v.sp).unwrap_or(0);
|
||||||
let ddi_start_block = tc.tasks[i].as_ref().map(|v| v.ddi_mem_start).unwrap_or(0);
|
let ddi_start_block = tc.tasks[i].as_ref().map(|v| v.ddi_mem_start).unwrap_or(0);
|
||||||
let ddi_blocks_count = tc.tasks[i].as_ref().map(|v| v.ddi_mem_blocks_count).unwrap_or(0);
|
let ddi_blocks_count = tc.tasks[i].as_ref().map(|v| v.ddi_mem_blocks_count).unwrap_or(0);
|
||||||
let stack_size_in_blocks = tc.tasks[i].as_ref().map(|v| v.stack_size_in_blocks).unwrap_or(0);
|
|
||||||
if sp != 0 {
|
if sp != 0 {
|
||||||
unsafe {
|
unsafe {
|
||||||
tc.memory_manager
|
tc.memory_manager
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap_unchecked()
|
.unwrap_unchecked()
|
||||||
.free_n_blocks(sp - (BLOCK_SIZE * stack_size_in_blocks), stack_size_in_blocks)
|
.free_n_blocks(sp - (BLOCK_SIZE * STACK_SIZE_IN_BLOCKS), STACK_SIZE_IN_BLOCKS)
|
||||||
};
|
};
|
||||||
unsafe {
|
unsafe {
|
||||||
tc.memory_manager.as_mut().unwrap_unchecked()
|
tc.memory_manager.as_mut().unwrap_unchecked()
|
||||||
|
|
@ -435,17 +416,6 @@ pub fn context_switch<'a>(tc: &'a mut TrafficControl, current: Task) -> Option<&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if remaining_tasks <= 2, then we need to wake up WaitUntilAlone tasks
|
|
||||||
if remaining_tasks <= 2 {
|
|
||||||
for task in &mut tc.tasks {
|
|
||||||
if let Some(task) = task {
|
|
||||||
if task.wait & TaskWait::WaitForTaskExit as u32 != 0 {
|
|
||||||
task.wait &= !(TaskWait::WaitForTaskExit as u32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut next_task = tc.current + 1;
|
let mut next_task = tc.current + 1;
|
||||||
if next_task >= MAX_TASKS {
|
if next_task >= MAX_TASKS {
|
||||||
next_task = 0;
|
next_task = 0;
|
||||||
|
|
@ -453,19 +423,6 @@ pub fn context_switch<'a>(tc: &'a mut TrafficControl, current: Task) -> Option<&
|
||||||
|
|
||||||
for _ in 0..(MAX_TASKS + 1) {
|
for _ in 0..(MAX_TASKS + 1) {
|
||||||
if let Some(task) = tc.tasks[next_task].as_ref() {
|
if let Some(task) = tc.tasks[next_task].as_ref() {
|
||||||
// check stack pointer and if it's oob
|
|
||||||
#[cfg(feature = "arch_virt")]
|
|
||||||
{
|
|
||||||
if task.sp != 0 {
|
|
||||||
if task.trap_frame.regs[2] < task.sp - (task.stack_size_in_blocks * BLOCK_SIZE) {
|
|
||||||
let uart = serial_port();
|
|
||||||
if let Some(uart) = uart {
|
|
||||||
uart.putstr("stack overflow\n");
|
|
||||||
}
|
|
||||||
rough_panic([';', '-', ';'])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if task.wait == 0 && {
|
if task.wait == 0 && {
|
||||||
let mut waiting = false;
|
let mut waiting = false;
|
||||||
for v in &task.ackwait {
|
for v in &task.ackwait {
|
||||||
|
|
@ -500,7 +457,6 @@ pub struct TrafficControl {
|
||||||
pub inbuf_write: u8,
|
pub inbuf_write: u8,
|
||||||
pub hung_system: bool,
|
pub hung_system: bool,
|
||||||
pub use_fb_console: bool,
|
pub use_fb_console: bool,
|
||||||
pub current_keymap: Keymap,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Task {
|
pub struct Task {
|
||||||
|
|
@ -510,7 +466,6 @@ pub struct Task {
|
||||||
pub want_exit: bool,
|
pub want_exit: bool,
|
||||||
/// THE ORIGINAL STACK POINTER THAT THE TASK STARTED WITH
|
/// THE ORIGINAL STACK POINTER THAT THE TASK STARTED WITH
|
||||||
pub sp: usize,
|
pub sp: usize,
|
||||||
pub stack_size_in_blocks: usize,
|
|
||||||
pub wait: u32,
|
pub wait: u32,
|
||||||
pub incoming_notifications: [Option<usize>; MAX_TASKS],
|
pub incoming_notifications: [Option<usize>; MAX_TASKS],
|
||||||
pub ackwait: [u8; MAX_TASKS], // 3 = they have not yet received the notification, 1 = they have received the notification, 0 = we know they received the notification, or don't care
|
pub ackwait: [u8; MAX_TASKS], // 3 = they have not yet received the notification, 1 = they have received the notification, 0 = we know they received the notification, or don't care
|
||||||
|
|
@ -535,12 +490,6 @@ impl TrafficControl {
|
||||||
inbuf_write: 0,
|
inbuf_write: 0,
|
||||||
hung_system: false,
|
hung_system: false,
|
||||||
use_fb_console: false,
|
use_fb_console: false,
|
||||||
current_keymap: Keymap {
|
|
||||||
alpha: 0,
|
|
||||||
beta: 0,
|
|
||||||
gamma: 0,
|
|
||||||
delta: 0,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use core::sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize, Ordering};
|
use core::sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize, Ordering};
|
||||||
use liblbos::characters;
|
|
||||||
use crate::terminal::{print, println};
|
use crate::terminal::{print, println};
|
||||||
use liblbos::fs::{DirectoryReader, FileSystem};
|
use liblbos::fs::{DirectoryReader, FileSystem};
|
||||||
|
|
||||||
|
|
@ -113,16 +112,13 @@ fn lsdir(env: &Environment<'_>) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
print("- ");
|
print("- ");
|
||||||
let name = &record.name[..record.name.iter().position(|&x| x == 0).unwrap_or(11)];
|
|
||||||
liblbos::syscalls::write_terminal(
|
liblbos::syscalls::write_terminal(
|
||||||
name
|
&record.name[..record.name.iter().position(|&x| x == 0).unwrap_or(11)],
|
||||||
);
|
);
|
||||||
if record.record_type == liblbos::fs::RecordType::Directory as u8 {
|
if record.record_type == liblbos::fs::RecordType::Directory as u8 {
|
||||||
liblbos::syscalls::write_terminal(&[b' ', characters::C_FOLDER as u8]);
|
print("(dir)");
|
||||||
} else if &name[name.len() - 3..] == b"DDI" {
|
|
||||||
liblbos::syscalls::write_terminal(&[b' ', characters::C_BLOOD as u8]);
|
|
||||||
} else {
|
} else {
|
||||||
liblbos::syscalls::write_terminal(&[b' ', characters::C_FILE as u8]);
|
print("(file)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print("\n");
|
print("\n");
|
||||||
|
|
@ -187,16 +183,13 @@ fn attempt_run_file(env: &Environment<'_>, name: &str) {
|
||||||
current_directory_path: CURRENT_DIR_PATH.load(Ordering::Relaxed) as usize,
|
current_directory_path: CURRENT_DIR_PATH.load(Ordering::Relaxed) as usize,
|
||||||
current_directory_path_len: CURRENT_DIR_PATH_LEN.load(Ordering::Relaxed),
|
current_directory_path_len: CURRENT_DIR_PATH_LEN.load(Ordering::Relaxed),
|
||||||
};
|
};
|
||||||
// fixme: turntable task needs to exit, but it owns the environment memory.
|
|
||||||
// fixme: we need to somehow pass the environment to the task, and have it free the memory
|
|
||||||
|
|
||||||
let mut task_setup = liblbos::TaskSetup {
|
let mut task_setup = liblbos::TaskSetup {
|
||||||
epc: 0,
|
epc: 0,
|
||||||
stack_block_count: 8,
|
|
||||||
ddi_first_addr: 0,
|
ddi_first_addr: 0,
|
||||||
ddi_size: 0,
|
ddi_size: 0,
|
||||||
environment: 0,
|
environment: &e as *const _ as usize,
|
||||||
wait_for_task_exit: false,
|
wait_for_task_exit: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
if liblbos::ktask::ktask_loadddifile(buf, size, &mut task_setup as *mut _ as usize) != 0 {
|
if liblbos::ktask::ktask_loadddifile(buf, size, &mut task_setup as *mut _ as usize) != 0 {
|
||||||
|
|
@ -209,11 +202,11 @@ fn attempt_run_file(env: &Environment<'_>, name: &str) {
|
||||||
|
|
||||||
liblbos::syscalls::create_task(task_setup);
|
liblbos::syscalls::create_task(task_setup);
|
||||||
|
|
||||||
if CURRENT_DIR_PATH.load(Ordering::Relaxed) as usize != 0 {
|
// yeah we're extending its lifetime
|
||||||
// free
|
#[allow(clippy::drop_non_drop)]
|
||||||
liblbos::syscalls::free_blocks(CURRENT_DIR_PATH.load(Ordering::Relaxed) as usize, CURRENT_DIR_PATH_LEN.load(Ordering::Relaxed).div_ceil(512));
|
drop(e);
|
||||||
}
|
|
||||||
liblbos::syscalls::exit();
|
println("\ntask exited\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute(cmd: &str, environment: &mut Environment<'_>) {
|
fn execute(cmd: &str, environment: &mut Environment<'_>) {
|
||||||
|
|
@ -236,10 +229,6 @@ fn execute(cmd: &str, environment: &mut Environment<'_>) {
|
||||||
if NO_EXIT.load(Ordering::Relaxed) {
|
if NO_EXIT.load(Ordering::Relaxed) {
|
||||||
println("cannot exit as task 1");
|
println("cannot exit as task 1");
|
||||||
} else {
|
} else {
|
||||||
if CURRENT_DIR_PATH.load(Ordering::Relaxed) as usize != 0 {
|
|
||||||
// free
|
|
||||||
liblbos::syscalls::free_blocks(CURRENT_DIR_PATH.load(Ordering::Relaxed) as usize, CURRENT_DIR_PATH_LEN.load(Ordering::Relaxed).div_ceil(512));
|
|
||||||
}
|
|
||||||
liblbos::syscalls::exit();
|
liblbos::syscalls::exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -267,7 +256,8 @@ fn hex(mut n: u8) -> [u8; 2] {
|
||||||
mod arch;
|
mod arch;
|
||||||
mod terminal;
|
mod terminal;
|
||||||
|
|
||||||
fn main_wrapper() {
|
#[unsafe(no_mangle)]
|
||||||
|
extern "C" fn main() {
|
||||||
let tid = liblbos::syscalls::current_task();
|
let tid = liblbos::syscalls::current_task();
|
||||||
NO_EXIT.store(tid == 1, Ordering::Relaxed);
|
NO_EXIT.store(tid == 1, Ordering::Relaxed);
|
||||||
|
|
||||||
|
|
@ -347,12 +337,3 @@ fn main_wrapper() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
|
||||||
extern "C" fn main() {
|
|
||||||
main_wrapper();
|
|
||||||
if CURRENT_DIR_PATH.load(Ordering::Relaxed) as usize != 0 {
|
|
||||||
// free
|
|
||||||
liblbos::syscalls::free_blocks(CURRENT_DIR_PATH.load(Ordering::Relaxed) as usize, CURRENT_DIR_PATH_LEN.load(Ordering::Relaxed).div_ceil(512));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Reference in a new issue