From 612439b3675bf5a66d168163eb64df7c812295bf Mon Sep 17 00:00:00 2001 From: GZTimeWalker Date: Tue, 10 May 2022 19:28:57 +0800 Subject: [PATCH] wip: update, sys_read wait for fixing --- Cargo.lock | 33 ++++++- Cargo.toml | 3 +- Makefile | 8 +- pkg/app/hello/.cargo/config | 6 ++ pkg/app/hello/Cargo.toml | 10 ++ pkg/app/hello/src/main.rs | 15 +++ pkg/app/sh/src/main.rs | 52 +++++++++- pkg/kernel/.cargo/config | 3 + pkg/kernel/Cargo.toml | 3 +- pkg/kernel/src/drivers/console.rs | 1 - pkg/kernel/src/drivers/input.rs | 13 ++- pkg/kernel/src/interrupt/handlers.rs | 15 +-- pkg/kernel/src/interrupt/syscall/mod.rs | 87 ++++++----------- pkg/kernel/src/interrupt/syscall/service.rs | 101 ++++++++++++++++++-- pkg/kernel/src/main.rs | 51 +--------- pkg/kernel/src/process/manager.rs | 8 +- pkg/kernel/src/process/mod.rs | 40 +++++--- pkg/kernel/src/process/process.rs | 4 + pkg/kernel/src/utils/logger.rs | 1 + pkg/kernel/src/utils/mod.rs | 9 ++ pkg/kernel/src/utils/regs.rs | 19 ++-- pkg/kernel/src/utils/resource.rs | 1 + pkg/lib/Cargo.toml | 1 + pkg/lib/src/io.rs | 6 +- pkg/lib/src/lib.rs | 7 +- pkg/lib/src/macros.rs | 16 ++-- pkg/lib/src/syscall.rs | 30 +++++- 27 files changed, 360 insertions(+), 183 deletions(-) create mode 100644 pkg/app/hello/.cargo/config create mode 100644 pkg/app/hello/Cargo.toml create mode 100644 pkg/app/hello/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index f3f7faa..3979203 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,6 +130,9 @@ dependencies = [ [[package]] name = "gglib" version = "0.1.0" +dependencies = [ + "chrono", +] [[package]] name = "ggos_boot" @@ -153,9 +156,16 @@ dependencies = [ "xmas-elf", ] +[[package]] +name = "ggos_hello" +version = "0.1.0" +dependencies = [ + "gglib", +] + [[package]] name = "ggos_kernel" -version = "0.6.4" +version = "0.7.0" dependencies = [ "bit_field", "bitflags", @@ -170,6 +180,7 @@ dependencies = [ "linked_list_allocator", "log", "micromath 2.0.0", + "num_enum", "paste", "pc-keyboard", "spin 0.9.3", @@ -269,6 +280,26 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_enum" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "paste" version = "1.0.7" diff --git a/Cargo.toml b/Cargo.toml index 3dfc416..b7fb2e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,5 +5,6 @@ members = [ "pkg/fs", "pkg/kernel", "pkg/lib", - "pkg/app/sh" + "pkg/app/sh", + "pkg/app/hello" ] diff --git a/Makefile b/Makefile index 8ceec9e..32b7035 100644 --- a/Makefile +++ b/Makefile @@ -61,16 +61,16 @@ $(ESP)/KERNEL.ELF: target/x86_64-unknown-none/$(MODE)/ggos_kernel cp $< $@ $(ESP)/APP: target/x86_64-unknown-ggos/$(MODE) @for app in $(APPS); do \ - mkdir -p $(@D)/APP; \ - cp $"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +lib = { path="../../lib", package="gglib"} diff --git a/pkg/app/hello/src/main.rs b/pkg/app/hello/src/main.rs new file mode 100644 index 0000000..379f3e3 --- /dev/null +++ b/pkg/app/hello/src/main.rs @@ -0,0 +1,15 @@ +#![no_std] +#![no_main] + +use lib::*; + +extern crate lib; + +fn main() { + println!("Hello, world!!!"); + let time = lib::sys_time(); + println!("Now at: {}", time); + lib::sys_exit(0); +} + +entry!(main); diff --git a/pkg/app/sh/src/main.rs b/pkg/app/sh/src/main.rs index d3e044a..2e7f91b 100644 --- a/pkg/app/sh/src/main.rs +++ b/pkg/app/sh/src/main.rs @@ -1,11 +1,59 @@ #![no_std] #![no_main] -#[macro_use] +extern crate alloc; + +use lib::*; +use alloc::vec::Vec; +use alloc::string::*; +use lib::io::stdin; + extern crate lib; fn main() { - println!("Hello, world!"); + let mut root_dir = String::from("/APP/"); + + loop { + print!("[{}] ", root_dir); + let input = stdin().read_line(); + let line: Vec<&str> = input.trim().split(' ').collect(); + match line[0] { + "exit" => break, + "ps" => sys_stat(), + "ls" => sys_list_dir(root_dir.as_str()), + "cat" => { + // ggos::filesystem::cat(root_dir.as_str(), line[1]); + } + "cd" => { + match line[1] { + ".." => { + if root_dir.as_str() == "/" { + break; + } + root_dir.pop(); + let pos = root_dir.rfind('/').unwrap(); + root_dir = root_dir[..pos + 1].to_string(); + }, + _ => { + root_dir.push_str(line[1]); + root_dir.push('/'); + root_dir = root_dir.to_ascii_uppercase(); + } + } + } + "exec" => { + let path = root_dir.clone() + line[1]; + let pid = sys_spawn(path.as_str()); + if pid == 0 { + println!("failed to spawn process: {}#{}", line[1], pid); + } else { + println!("spawned process: {}#{}", line[1], pid); + } + } + _ => println!("[=] {}", input), + } + } + lib::sys_exit(0); } diff --git a/pkg/kernel/.cargo/config b/pkg/kernel/.cargo/config index f2d21f7..57640b2 100644 --- a/pkg/kernel/.cargo/config +++ b/pkg/kernel/.cargo/config @@ -7,3 +7,6 @@ build-std = ["core", "compiler_builtins", "alloc"] [env] LOG_LEVEL = "debug" + +[profile.release] +debug = true diff --git a/pkg/kernel/Cargo.toml b/pkg/kernel/Cargo.toml index 94dea67..2889156 100644 --- a/pkg/kernel/Cargo.toml +++ b/pkg/kernel/Cargo.toml @@ -6,7 +6,7 @@ authors = ["GZTime "] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -boot = { path = "../boot", package = "ggos_boot", default-features = false } +boot = { path = "../boot", package = "ggos_boot", default-features = false } fs = { path = "../fs", package = "ggfs" } elf = { package = "ggos_elf", path = "../elf" } embedded-graphics = { version = "0.7.1", features = ['fixed_point'] } @@ -26,3 +26,4 @@ pc-keyboard = "0.5.1" crossbeam-queue = { version = "0.3.5", default-features = false, features = ["alloc"] } volatile = "0.4.4" xmas-elf = "0.8" +num_enum = { version = "0.5.7", default-features = false } diff --git a/pkg/kernel/src/drivers/console.rs b/pkg/kernel/src/drivers/console.rs index a06231a..a217bd0 100644 --- a/pkg/kernel/src/drivers/console.rs +++ b/pkg/kernel/src/drivers/console.rs @@ -184,7 +184,6 @@ impl Device for Console { if offset + size >= buf.len() { return Err(DeviceError::ReadError); } - x86_64::instructions::interrupts::without_interrupts(|| { let stdin = get_input_buf_for_sure(); let mut read_count = 0; diff --git a/pkg/kernel/src/drivers/input.rs b/pkg/kernel/src/drivers/input.rs index c504dbc..fd4ddb0 100644 --- a/pkg/kernel/src/drivers/input.rs +++ b/pkg/kernel/src/drivers/input.rs @@ -1,8 +1,8 @@ +use crate::drivers::{console, serial}; +use alloc::string::String; use crossbeam_queue::ArrayQueue; use pc_keyboard::DecodedKey; -use crate::drivers::{serial, console}; use x86_64::instructions::interrupts; -use alloc::string::String; once_mutex!(pub INPUT_BUF: ArrayQueue); @@ -26,9 +26,12 @@ pub fn try_get_key() -> Option { pub fn get_key() -> DecodedKey { loop { - if let Some(k) = try_get_key() { - return k; - } + crate::utils::halt(); + interrupts::without_interrupts(|| { + if let Some(k) = try_get_key() { + return k; + } + }) } } diff --git a/pkg/kernel/src/interrupt/handlers.rs b/pkg/kernel/src/interrupt/handlers.rs index 5c66eea..f8954c2 100644 --- a/pkg/kernel/src/interrupt/handlers.rs +++ b/pkg/kernel/src/interrupt/handlers.rs @@ -27,7 +27,8 @@ pub unsafe fn reg_idt(idt: &mut InterruptDescriptorTable) { idt.page_fault.set_handler_fn(page_fault_handler); idt.alignment_check.set_handler_fn(alignment_check_handler); idt.machine_check.set_handler_fn(machine_check_handler); - idt.simd_floating_point.set_handler_fn(simd_floating_point_handler); + idt.simd_floating_point + .set_handler_fn(simd_floating_point_handler); idt[(consts::Interrupts::IRQ0 as u8 + consts::IRQ::Timer as u8) as usize] .set_handler_fn(clock_handler) @@ -157,15 +158,9 @@ pub extern "C" fn clock(mut regs: Registers, mut sf: InterruptStackFrame) { as_handler!(clock); pub extern "C" fn syscall(mut regs: Registers, mut sf: InterruptStackFrame) { - let args = - super::syscall::SyscallArgs::new(Syscall::from(regs.rax), regs.rdi, regs.rsi, regs.rdx); - trace!("{}", args); - unsafe { - x86_64::instructions::interrupts::without_interrupts(|| { - super::syscall::dispatcher(args, &mut regs, &mut sf); - }) - } - super::ack(consts::Interrupts::Syscall as u8); + x86_64::instructions::interrupts::without_interrupts(|| { + super::syscall::dispatcher(&mut regs, &mut sf); + }); } as_handler!(syscall); diff --git a/pkg/kernel/src/interrupt/syscall/mod.rs b/pkg/kernel/src/interrupt/syscall/mod.rs index 7fbcab1..b316604 100644 --- a/pkg/kernel/src/interrupt/syscall/mod.rs +++ b/pkg/kernel/src/interrupt/syscall/mod.rs @@ -1,24 +1,28 @@ use crate::utils::*; -use core::alloc::Layout; use x86_64::structures::idt::InterruptStackFrame; +use num_enum::TryFromPrimitive; +use core::convert::TryFrom; mod service; use service::*; -#[derive(Clone, Debug)] +#[repr(u8)] +#[derive(Clone, Debug, TryFromPrimitive)] pub enum Syscall { - SpwanProcess = 1, + SpawnProcess = 1, ExitProcess = 2, Read = 3, Write = 4, Open = 5, Close = 6, Stat = 7, - Clock = 8, - Draw = 9, + Time = 8, + DirectoryList = 9, Allocate = 10, Deallocate = 11, - None = 0xdeadbeef, + Draw = 12, + #[num_enum(default)] + None = 255, } #[derive(Clone, Debug)] @@ -29,61 +33,32 @@ pub struct SyscallArgs { pub arg2: usize, } -#[allow(unused_variables)] -pub unsafe fn dispatcher(args: SyscallArgs, regs: &mut Registers, sf: &mut InterruptStackFrame) { +pub fn dispatcher(regs: &mut Registers, sf: &mut InterruptStackFrame) { + let args = super::syscall::SyscallArgs::new( + Syscall::try_from(regs.rax as u8).unwrap(), + regs.rdi, + regs.rsi, + regs.rdx + ); + debug!("{}", args); + debug!("{:#?}\n{:#?}", sf, regs); + match args.syscall { - Syscall::SpwanProcess => {} - Syscall::ExitProcess => exit_process(regs, sf), // todo: handle exit code - Syscall::Read => match args.arg0 { - 0 => {} - fd => warn!("SYSCALL: cannot read from fd: {}", fd), - }, - Syscall::Write => { - let s = core::str::from_utf8_unchecked(core::slice::from_raw_parts( - args.arg1 as *const u8, - args.arg2, - )); - match args.arg0 { - 1 => print!("{}", s), - fd => warn!("SYSCALL: cannot write to fd: {}", fd), - } - } + Syscall::SpawnProcess => regs.set_rax(spawn_process(&args)), + Syscall::ExitProcess => exit_process(regs, sf), + Syscall::Read => regs.set_rax(sys_read(&args)), + Syscall::Write => sys_write(&args), Syscall::Open => {} Syscall::Close => {} - Syscall::Stat => {} - Syscall::Clock => regs.set_rax(sys_clock() as usize), - Syscall::Draw => sys_draw(args.arg0, args.arg1, args.arg2), - Syscall::Allocate => { - regs.set_rax(sys_allocate((args.arg0 as *const Layout).as_ref().unwrap()) as usize) - } - Syscall::Deallocate => sys_deallocate( - args.arg0 as *mut u8, - (args.arg1 as *const Layout).as_ref().unwrap(), - ), + Syscall::Stat => list_process(), + Syscall::Time => regs.set_rax(sys_clock() as usize), + Syscall::DirectoryList => list_dir(&args), + Syscall::Allocate => regs.set_rax(sys_allocate(&args)), + Syscall::Deallocate => sys_deallocate(&args), + Syscall::Draw => sys_draw(&args), Syscall::None => {} } -} - -impl From for Syscall { - fn from(num: usize) -> Self { - match num { - 1 => Self::SpwanProcess, - 2 => Self::ExitProcess, - 3 => Self::Read, - 4 => Self::Write, - 5 => Self::Open, - 6 => Self::Close, - 7 => Self::Stat, - 8 => Self::Clock, - 9 => Self::Draw, - 10 => Self::Allocate, - 11 => Self::Deallocate, - _ => { - warn!("Unknown SYSCALL: {}", num); - Self::None - } - } - } + debug!("syscall finished."); } impl SyscallArgs { diff --git a/pkg/kernel/src/interrupt/syscall/service.rs b/pkg/kernel/src/interrupt/syscall/service.rs index ab8f50d..758aab3 100644 --- a/pkg/kernel/src/interrupt/syscall/service.rs +++ b/pkg/kernel/src/interrupt/syscall/service.rs @@ -1,39 +1,122 @@ +use core::alloc::Layout; + use crate::{utils::*, display::get_display_for_sure}; use embedded_graphics::prelude::*; use x86_64::structures::idt::InterruptStackFrame; use crate::utils::Registers; +use super::SyscallArgs; + pub fn sys_clock() -> i64 { clock::now().timestamp_nanos() } -pub fn sys_draw(x: usize, y: usize, color: usize) { +pub fn sys_draw(args: &SyscallArgs) { let _ = get_display_for_sure().draw_pixel_u32( - Point::new(x as i32, y as i32), - color as u32 + Point::new(args.arg0 as i32, args.arg1 as i32), + args.arg2 as u32 ); } -pub fn sys_allocate(layout: &core::alloc::Layout) -> *mut u8 { - debug!("sys_allocate: \n{:#?}", layout); +pub fn sys_allocate(args: &SyscallArgs) -> usize { + let layout = unsafe { + (args.arg0 as *const Layout).as_ref().unwrap() + }; + trace!("sys_allocate: \n{:#?}", layout); let ptr = crate::allocator::ALLOCATOR .lock() .allocate_first_fit(layout.clone()) .unwrap() .as_ptr(); - debug!("allocated {:x}", ptr as u64); - ptr + trace!("allocated {:x}", ptr as u64); + ptr as usize } -pub fn sys_deallocate(ptr: *mut u8, layout: &core::alloc::Layout) { +pub fn sys_deallocate(args: &SyscallArgs) { + let ptr = args.arg0 as *mut u8; + let layout = unsafe{ (args.arg1 as *const Layout).as_ref().unwrap() }; + unsafe { crate::allocator::ALLOCATOR .lock() .deallocate(core::ptr::NonNull::new_unchecked(ptr), layout.clone()); } - debug!("deallocated {:x}", ptr as u64); + trace!("deallocated {:x}", ptr as u64); +} + +pub fn spawn_process(args: &SyscallArgs) -> usize { + let path = unsafe { + core::str::from_utf8_unchecked(core::slice::from_raw_parts( + args.arg1 as *const u8, + args.arg2, + ))}; + + let file = crate::filesystem::try_get_file(path); + + if file.is_err() { + warn!("spawn_process: file not found: {}", path); + return 0; + } + let file = file.unwrap(); + + let pid = crate::process::spawn(&file); + + if pid.is_err() { + warn!("spawn_process: failed to spawn process: {}", path); + return 0; + } + pid.unwrap() as usize +} + +pub fn sys_read(args: &SyscallArgs) -> usize { + let fd = get_handle(args.arg0 as u8); + if let Some(res) = fd { + let buf = unsafe { + core::slice::from_raw_parts_mut(args.arg1 as *mut u8, args.arg2) + }; + return if let Ok(size) = res.read(buf) { + debug!( + "read {} bytes: {:?}", + size, + unsafe{ core::str::from_utf8_unchecked(&buf[..size]) } + ); + size + } else { + 0 + } + } else { + 0 + } +} + +pub fn sys_write(args: &SyscallArgs) { + let s = unsafe{ core::str::from_utf8_unchecked(core::slice::from_raw_parts( + args.arg1 as *const u8, + args.arg2, + ))}; + match args.arg0 { + 1 => print!("{}", s), + 2 => print_warn!("{}", s), + fd => warn!("SYSCALL: cannot write to fd: {}", fd), + } } pub fn exit_process(regs: &mut Registers, sf: &mut InterruptStackFrame) { crate::process::process_exit(regs, sf); } + +pub fn list_process() { + crate::process::print_process_list(); +} + +pub fn list_dir(args: &SyscallArgs) { + let root = unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts( + args.arg0 as *const u8, + args.arg1, + )) }; + crate::filesystem::ls(root); +} + +pub fn get_handle(fd: u8) -> Option { + crate::process::handle(fd) +} diff --git a/pkg/kernel/src/main.rs b/pkg/kernel/src/main.rs index 53226e2..c8baf67 100644 --- a/pkg/kernel/src/main.rs +++ b/pkg/kernel/src/main.rs @@ -1,10 +1,7 @@ #![no_std] #![no_main] -use alloc::string::*; -use alloc::vec::Vec; use ggos_kernel as ggos; -use ggos::*; extern crate alloc; @@ -14,51 +11,11 @@ pub fn kernal_main(boot_info: &'static boot::BootInfo) -> ! { ggos::init(boot_info); let sh_file = ggos::filesystem::try_get_file("/APP/SH").unwrap(); + let pid = ggos::process::spawn(&sh_file).unwrap(); - x86_64::instructions::interrupts::without_interrupts(|| { - ggos::process::spawn(&sh_file).unwrap(); - }); - - let mut test_num = 0; - let mut root_dir = String::from("/"); - - loop { - print!("[{}] ", root_dir); - let input = input::get_line(); - let line: Vec<&str> = input.trim().split(' ').collect(); - match line[0] { - "exit" => break, - "ps" => { - ggos::process::print_process_list(); - } - "t" => { - ggos::new_test_thread(format!("{}", test_num).as_str()); - test_num += 1; - } - "ls" => { - ggos::filesystem::ls(root_dir.as_str()); - } - "cat" => { - ggos::filesystem::cat(root_dir.as_str(), line[1]); - } - "cd" => { - match line[1] { - ".." => { - if root_dir.as_str() == "/" { - break; - } - root_dir.pop(); - let pos = root_dir.rfind('/').unwrap(); - root_dir = root_dir[..pos + 1].to_string(); - }, - _ => { - root_dir.push_str(line[1]); - root_dir.push('/'); - root_dir = root_dir.to_ascii_uppercase(); - } - } - } - _ => println!("[=] {}", input), + while ggos::process::still_alive(pid) { + unsafe { + core::arch::asm!("hlt"); } } diff --git a/pkg/kernel/src/process/manager.rs b/pkg/kernel/src/process/manager.rs index a99781e..a52258f 100644 --- a/pkg/kernel/src/process/manager.rs +++ b/pkg/kernel/src/process/manager.rs @@ -50,7 +50,7 @@ impl ProcessManager { current.tick(); current.save(regs, sf); } - // trace!("Paused process #{}", self.cur_pid); + debug!("Paused process #{}", self.cur_pid); } fn get_next_pos(&self) -> usize { @@ -67,11 +67,15 @@ impl ProcessManager { } } + pub fn still_alive(&self, pid: u16) -> bool { + self.processes.iter().any(|x| x.pid() == pid) + } + pub fn switch_next(&mut self, regs: &mut Registers, sf: &mut InterruptStackFrame) { let pos = self.get_next_pos(); let p = &mut self.processes[pos]; - // trace!("Next process {} #{}", p.name(), p.pid()); + debug!("Next process {} #{}", p.name(), p.pid()); if p.pid() == self.cur_pid { // the next process to be resumed is the same as the current one p.resume(); diff --git a/pkg/kernel/src/process/mod.rs b/pkg/kernel/src/process/mod.rs index 46891b7..94881ea 100644 --- a/pkg/kernel/src/process/mod.rs +++ b/pkg/kernel/src/process/mod.rs @@ -9,7 +9,7 @@ use process::*; pub use process::ProcessData; pub use scheduler::*; -use crate::{filesystem::get_volume, Registers}; +use crate::{filesystem::get_volume, Registers, Resource}; use alloc::string::String; use x86_64::structures::{idt::InterruptStackFrame, paging::FrameAllocator}; @@ -60,20 +60,30 @@ pub fn process_exit(regs: &mut Registers, sf: &mut InterruptStackFrame) { }) } +pub fn handle(fd: u8) -> Option { + x86_64::instructions::interrupts::without_interrupts(|| { + get_process_manager_for_sure().current().handle(fd) + }) +} + +pub fn still_alive(pid: u16) -> bool { + x86_64::instructions::interrupts::without_interrupts(|| { + get_process_manager_for_sure().still_alive(pid) + }) +} + pub fn spawn(file: &File) -> Result { let size = file.length(); let data = { let pages = (size as usize + 0x1000 - 1) / 0x1000; let allocator = &mut *crate::memory::get_frame_alloc_for_sure(); - let mem_start = allocator.allocate_frame().unwrap() - .start_address().as_u64(); + let mem_start = allocator.allocate_frame().unwrap().start_address().as_u64(); - trace!("alloc = 0x{:016x}", mem_start); + trace!("alloc = 0x{:016x}", mem_start); for _ in 1..pages { - let addr = allocator.allocate_frame().unwrap() - .start_address().as_u64(); + let addr = allocator.allocate_frame().unwrap().start_address().as_u64(); trace!("alloc = 0x{:016x}", addr); } @@ -90,14 +100,16 @@ pub fn spawn(file: &File) -> Result { const STACK_PAGES: u64 = 512; const STACK_TOP: u64 = STACK_BOT + STACK_PAGES * 0x1000; - let mut manager = get_process_manager_for_sure(); + let pid = x86_64::instructions::interrupts::without_interrupts(|| { + let mut manager = get_process_manager_for_sure(); - let parent = manager.current().pid(); - let pid = manager.spawn( - &elf, - file.entry.filename(), - parent, - Some(ProcessData::new()), - ); + let parent = manager.current().pid(); + manager.spawn( + &elf, + file.entry.filename(), + parent, + Some(ProcessData::new()), + ) + }); Ok(pid) } diff --git a/pkg/kernel/src/process/process.rs b/pkg/kernel/src/process/process.rs index 2ee94ad..abdc14d 100644 --- a/pkg/kernel/src/process/process.rs +++ b/pkg/kernel/src/process/process.rs @@ -95,6 +95,10 @@ impl Process { self.status = ProgramStatus::Ready; } + pub fn handle(&self, fd: u8) -> Option { + self.proc_data.file_handles.get(&fd).cloned() + } + pub fn restore(&mut self, regs: &mut Registers, sf: &mut InterruptStackFrame) { unsafe { regs.as_mut().write(self.regs); diff --git a/pkg/kernel/src/utils/logger.rs b/pkg/kernel/src/utils/logger.rs index 689edc3..470064a 100644 --- a/pkg/kernel/src/utils/logger.rs +++ b/pkg/kernel/src/utils/logger.rs @@ -13,6 +13,7 @@ pub fn init() { }); info!("Current log level: {}", log::max_level()); + info!("Logger Initialized."); } diff --git a/pkg/kernel/src/utils/mod.rs b/pkg/kernel/src/utils/mod.rs index 5d0cb7b..7e30ac2 100644 --- a/pkg/kernel/src/utils/mod.rs +++ b/pkg/kernel/src/utils/mod.rs @@ -16,6 +16,7 @@ pub mod resource; pub use resource::Resource; pub use macros::*; pub use regs::*; +use x86_64::instructions::interrupts; pub const fn get_ascii_header() -> &'static str { concat!(" @@ -32,3 +33,11 @@ pub const fn get_ascii_header() -> &'static str { pub const fn get_header() -> &'static str { concat!(">>> GGOS v", env!("CARGO_PKG_VERSION")) } + +pub fn halt() { + let disabled = !interrupts::are_enabled(); + interrupts::enable_and_hlt(); + if disabled { + interrupts::disable(); + } +} diff --git a/pkg/kernel/src/utils/regs.rs b/pkg/kernel/src/utils/regs.rs index 35fc15b..86fab4d 100644 --- a/pkg/kernel/src/utils/regs.rs +++ b/pkg/kernel/src/utils/regs.rs @@ -19,12 +19,12 @@ pub struct RegistersValue { pub rcx: usize, pub rbx: usize, pub rax: usize, - pub rbp: usize + pub rbp: usize, } #[repr(C)] pub struct Registers { - value: RegistersValue + value: RegistersValue, } impl Registers { @@ -34,7 +34,7 @@ impl Registers { } #[inline] - pub unsafe fn set_rax(&mut self, value: usize) { + pub fn set_rax(&mut self, value: usize) { self.value.rax = value; } } @@ -60,13 +60,13 @@ impl fmt::Debug for RegistersValue { write!(f, "Registers {{\n")?; write!(f, " r15: 0x{:016x}, ", self.r15)?; write!(f, " r14: 0x{:016x}, ", self.r14)?; - write!(f, " r13: 0x{:016x}, ", self.r13)?; - write!(f, " r12: 0x{:016x},\n", self.r12)?; + write!(f, " r13: 0x{:016x},\n", self.r13)?; + write!(f, " r12: 0x{:016x}, ", self.r12)?; write!(f, " r11: 0x{:016x}, ", self.r11)?; - write!(f, " r10: 0x{:016x}, ", self.r10)?; + write!(f, " r10: 0x{:016x},\n", self.r10)?; write!(f, " r9 : 0x{:016x}, ", self.r9)?; - write!(f, " r8 : 0x{:016x},\n", self.r8)?; - write!(f, " rdi: 0x{:016x}, ", self.rdi)?; + write!(f, " r8 : 0x{:016x}, ", self.r8)?; + write!(f, " rdi: 0x{:016x},\n", self.rdi)?; write!(f, " rsi: 0x{:016x}, ", self.rsi)?; write!(f, " rdx: 0x{:016x}, ", self.rdx)?; write!(f, " rcx: 0x{:016x},\n", self.rcx)?; @@ -78,7 +78,6 @@ impl fmt::Debug for RegistersValue { } } - #[macro_export] macro_rules! as_handler { ($fn: ident) => { @@ -123,5 +122,5 @@ macro_rules! as_handler { } } } - } + }; } diff --git a/pkg/kernel/src/utils/resource.rs b/pkg/kernel/src/utils/resource.rs index 4f34fe6..d1ea777 100644 --- a/pkg/kernel/src/utils/resource.rs +++ b/pkg/kernel/src/utils/resource.rs @@ -22,6 +22,7 @@ impl Resource { if buf.len() < 4 { return Ok(0); } + let mut s = if buf.len() == 4 { if let DecodedKey::Unicode(c) = input::get_key() { c.to_string() diff --git a/pkg/lib/Cargo.toml b/pkg/lib/Cargo.toml index 478886b..5cef3ca 100644 --- a/pkg/lib/Cargo.toml +++ b/pkg/lib/Cargo.toml @@ -7,3 +7,4 @@ authors = ["GZTime "] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +chrono = { version = "0.4.19", default-features = false } diff --git a/pkg/lib/src/io.rs b/pkg/lib/src/io.rs index 86d50be..09e6e2c 100644 --- a/pkg/lib/src/io.rs +++ b/pkg/lib/src/io.rs @@ -15,8 +15,7 @@ impl Stdin { let mut buf = vec![0; 4]; if let Some(bytes) = sys_read(0, &mut buf) { if bytes > 0 { - buf.resize(bytes, 0); - return Some(String::from_utf8_lossy(&buf).to_string().remove(0)); + return Some(String::from_utf8_lossy(&buf[..bytes]).to_string().remove(0)); } } None @@ -25,8 +24,7 @@ impl Stdin { pub fn read_line(&self) -> String { let mut buf = vec![0; 256]; if let Some(bytes) = sys_read(0, &mut buf) { - buf.resize(bytes, 0); - String::from_utf8_lossy(&buf).to_string() + String::from_utf8_lossy(&buf[..bytes]).to_string() } else { String::new() } diff --git a/pkg/lib/src/lib.rs b/pkg/lib/src/lib.rs index f61f369..0953e5c 100644 --- a/pkg/lib/src/lib.rs +++ b/pkg/lib/src/lib.rs @@ -20,17 +20,18 @@ use alloc::format; #[derive(Clone, Debug)] pub enum Syscall { - SpwanProcess = 1, + SpawnProcess = 1, ExitProcess = 2, Read = 3, Write = 4, Open = 5, Close = 6, Stat = 7, - Clock = 8, - Draw = 9, + Time = 8, + DirectoryList = 9, Allocate = 10, Deallocate = 11, + Draw = 12 } #[macro_export] diff --git a/pkg/lib/src/macros.rs b/pkg/lib/src/macros.rs index 13fedc0..9d9049c 100644 --- a/pkg/lib/src/macros.rs +++ b/pkg/lib/src/macros.rs @@ -3,8 +3,8 @@ use crate::alloc::string::ToString; use core::arch::asm; #[doc(hidden)] -pub fn syscall0(n: Syscall) -> isize { - let ret: isize; +pub fn syscall0(n: Syscall) -> usize { + let ret: usize; unsafe { asm!( "int 0x80", in("rax") n as usize, @@ -15,8 +15,8 @@ pub fn syscall0(n: Syscall) -> isize { } #[doc(hidden)] -pub fn syscall1(n: Syscall, arg0: usize) -> isize { - let ret: isize; +pub fn syscall1(n: Syscall, arg0: usize) -> usize { + let ret: usize; unsafe { asm!( "int 0x80", in("rax") n as usize, @@ -28,8 +28,8 @@ pub fn syscall1(n: Syscall, arg0: usize) -> isize { } #[doc(hidden)] -pub fn syscall2(n: Syscall, arg0: usize, arg1: usize) -> isize { - let ret: isize; +pub fn syscall2(n: Syscall, arg0: usize, arg1: usize) -> usize { + let ret: usize; unsafe { asm!( "int 0x80", in("rax") n as usize, @@ -41,8 +41,8 @@ pub fn syscall2(n: Syscall, arg0: usize, arg1: usize) -> isize { } #[doc(hidden)] -pub fn syscall3(n: Syscall, arg0: usize, arg1: usize, arg2: usize) -> isize { - let ret: isize; +pub fn syscall3(n: Syscall, arg0: usize, arg1: usize, arg2: usize) -> usize { + let ret: usize; unsafe { asm!( "int 0x80", in("rax") n as usize, diff --git a/pkg/lib/src/syscall.rs b/pkg/lib/src/syscall.rs index 99d9425..b3eb737 100644 --- a/pkg/lib/src/syscall.rs +++ b/pkg/lib/src/syscall.rs @@ -1,11 +1,12 @@ -use crate::Syscall; +use crate::{Syscall, println}; +use chrono::naive::*; -pub fn sys_draw(x: i32, y: i32, color: u32) -> isize { +pub fn sys_draw(x: i32, y: i32, color: u32) -> usize { syscall!(Syscall::Draw, x as usize, y as usize, color as usize) } pub fn sys_write(fd: u64, buf: &[u8]) -> Option { - let ret = syscall!(Syscall::Write, fd, buf.as_ptr() as u64, buf.len() as u64); + let ret = syscall!(Syscall::Write, fd, buf.as_ptr() as u64, buf.len() as u64) as isize; if ret.is_negative() { None } else { @@ -14,7 +15,8 @@ pub fn sys_write(fd: u64, buf: &[u8]) -> Option { } pub fn sys_read(fd: u64, buf: &mut [u8]) -> Option { - let ret = syscall!(Syscall::Read, fd, buf.as_ptr() as u64, buf.len() as u64); + let ret = syscall!(Syscall::Read, fd, buf.as_ptr() as u64, buf.len() as u64) as isize; + println!("{}: {:?}", ret, buf); if ret.is_negative() { None } else { @@ -29,7 +31,7 @@ pub fn sys_allocate(layout: &core::alloc::Layout) -> *mut u8 { ) as *mut u8 } -pub fn sys_deallocate(ptr: *mut u8, layout: &core::alloc::Layout) -> isize { +pub fn sys_deallocate(ptr: *mut u8, layout: &core::alloc::Layout) -> usize { syscall!( Syscall::Deallocate, ptr, @@ -40,3 +42,21 @@ pub fn sys_deallocate(ptr: *mut u8, layout: &core::alloc::Layout) -> isize { pub fn sys_exit(code: usize) { syscall!(Syscall::ExitProcess, code); } + +pub fn sys_time() -> NaiveDateTime { + let time = syscall!(Syscall::Time) as i64; + const BILLION: i64 = 1_000_000_000; + NaiveDateTime::from_timestamp(time / BILLION, (time % BILLION) as u32) +} + +pub fn sys_list_dir(root: &str) { + syscall!(Syscall::DirectoryList, root.as_ptr() as u64, root.len() as u64); +} + +pub fn sys_stat() { + syscall!(Syscall::Stat); +} + +pub fn sys_spawn(path: &str) -> u16 { + syscall!(Syscall::SpawnProcess, path.as_ptr() as u64, path.len() as u64) as u16 +}