Skip to content

Commit

Permalink
wip: why iretq jump to 0xfff3
Browse files Browse the repository at this point in the history
  • Loading branch information
GZTimeWalker committed May 12, 2022
1 parent 3732a89 commit ae743a7
Show file tree
Hide file tree
Showing 19 changed files with 138 additions and 72 deletions.
2 changes: 2 additions & 0 deletions .gdbinit
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
file esp/KERNEL.ELF
target remote:1234
4 changes: 4 additions & 0 deletions pkg/app/sh/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ use lib::io::stdin;
extern crate lib;

fn main() {

sys_list_dir("/");

let mut root_dir = String::from("/APP/");

loop {
Expand Down Expand Up @@ -43,6 +46,7 @@ fn main() {
}
"exec" => {
let path = root_dir.clone() + line[1];
println!("ready to exec {}...", path);
let pid = sys_spawn(path.as_str());
if pid == 0 {
println!("failed to spawn process: {}#{}", line[1], pid);
Expand Down
7 changes: 6 additions & 1 deletion pkg/kernel/src/drivers/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,12 @@ impl Console {
match c {
'\n' => self.next_row(),
'\r' => self.x_pos = 0,
'\x08' => backspace(),
'\x08' => {
self.prev_char();
self.write(" ");
self.prev_char();
self.prev_char();
},
_ => self.write_char(c),
}
}
Expand Down
8 changes: 8 additions & 0 deletions pkg/kernel/src/drivers/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ pub fn init() {
info!("Input Initialized.");
}

pub fn push_key(key: DecodedKey) {
if let Some(queue) = get_input_buf() {
if let Err(_) = queue.push(key) {
warn!("Input buffer is full.");
}
}
}

pub fn try_get_key() -> Option<DecodedKey> {
interrupts::without_interrupts(|| {
if let Some(key) = get_input_buf_for_sure().pop() {
Expand Down
4 changes: 3 additions & 1 deletion pkg/kernel/src/drivers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ pub mod serial;
pub mod console;
pub mod display;
pub mod keyboard;
// pub mod input;
pub mod input;
pub mod filesystem;
pub mod ata;

pub use input::{get_key, push_key};
4 changes: 1 addition & 3 deletions pkg/kernel/src/interrupt/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,7 @@ 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) {
x86_64::instructions::interrupts::without_interrupts(|| {
super::syscall::dispatcher(&mut regs, &mut sf);
});
super::syscall::dispatcher(&mut regs, &mut sf);
}

as_handler!(syscall);
3 changes: 1 addition & 2 deletions pkg/kernel/src/interrupt/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub fn dispatcher(regs: &mut Registers, sf: &mut InterruptStackFrame) {
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::Write => regs.set_rax(sys_write(&args)),
Syscall::Open => {}
Syscall::Close => {}
Syscall::Stat => list_process(),
Expand All @@ -56,7 +56,6 @@ pub fn dispatcher(regs: &mut Registers, sf: &mut InterruptStackFrame) {
Syscall::Draw => sys_draw(&args),
Syscall::None => {}
}
// debug!("syscall finished.");
}

impl SyscallArgs {
Expand Down
55 changes: 28 additions & 27 deletions pkg/kernel/src/interrupt/syscall/service.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use core::alloc::Layout;

use crate::{utils::*, display::get_display_for_sure};
use crate::utils::Registers;
use crate::{display::get_display_for_sure, utils::*};
use embedded_graphics::prelude::*;
use x86_64::structures::idt::InterruptStackFrame;
use crate::utils::Registers;

use super::SyscallArgs;

Expand All @@ -14,14 +14,12 @@ pub fn sys_clock() -> i64 {
pub fn sys_draw(args: &SyscallArgs) {
let _ = get_display_for_sure().draw_pixel_u32(
Point::new(args.arg0 as i32, args.arg1 as i32),
args.arg2 as u32
args.arg2 as u32,
);
}

pub fn sys_allocate(args: &SyscallArgs) -> usize {
let layout = unsafe {
(args.arg0 as *const Layout).as_ref().unwrap()
};
let layout = unsafe { (args.arg0 as *const Layout).as_ref().unwrap() };
trace!("sys_allocate: \n{:#?}", layout);
let ptr = crate::allocator::ALLOCATOR
.lock()
Expand All @@ -34,7 +32,7 @@ pub fn sys_allocate(args: &SyscallArgs) -> usize {

pub fn sys_deallocate(args: &SyscallArgs) {
let ptr = args.arg0 as *mut u8;
let layout = unsafe{ (args.arg1 as *const Layout).as_ref().unwrap() };
let layout = unsafe { (args.arg1 as *const Layout).as_ref().unwrap() };

unsafe {
crate::allocator::ALLOCATOR
Expand All @@ -45,11 +43,12 @@ pub fn sys_deallocate(args: &SyscallArgs) {
}

pub fn spawn_process(args: &SyscallArgs) -> usize {
let path = unsafe {
let path = unsafe {
core::str::from_utf8_unchecked(core::slice::from_raw_parts(
args.arg1 as *const u8,
args.arg2,
))};
args.arg0 as *const u8,
args.arg1,
))
};

let file = crate::filesystem::try_get_file(path);

Expand All @@ -71,9 +70,7 @@ pub fn spawn_process(args: &SyscallArgs) -> 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)
};
let buf = unsafe { core::slice::from_raw_parts_mut(args.arg1 as *mut u8, args.arg2) };
if let Ok(size) = res.read(buf) {
size
} else {
Expand All @@ -84,15 +81,17 @@ pub fn sys_read(args: &SyscallArgs) -> usize {
}
}

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 sys_write(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) };
if let Ok(size) = res.write(buf) {
size
} else {
0
}
} else {
0
}
}

Expand All @@ -105,10 +104,12 @@ pub fn list_process() {
}

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,
)) };
let root = unsafe {
core::str::from_utf8_unchecked(core::slice::from_raw_parts(
args.arg0 as *const u8,
args.arg1,
))
};
crate::filesystem::ls(root);
}

Expand Down
1 change: 1 addition & 0 deletions pkg/kernel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub fn init(boot_info: &'static BootInfo) {
allocator::init(); // init heap allocator
process::init(); // init process manager
keyboard::init(); // init keyboard
input::init(); // init input
ata::init(); // init ata
filesystem::init(); // init filesystem

Expand Down
16 changes: 5 additions & 11 deletions pkg/kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,12 @@ boot::entry_point!(kernal_main);
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();
let mut executor = Executor::new();

// while ggos::process::still_alive(pid) {
// unsafe {
// core::arch::asm!("hlt");
// }
// }
let sh_file = ggos::filesystem::try_get_file("/APP/SH").unwrap();
let pid = ggos::process::spawn(&sh_file).unwrap();

let mut executor = Executor::new();
executor.spawn(Task::new(get_key()));
executor.run();
executor.run(pid);

// ggos::shutdown(boot_info);
ggos::shutdown(boot_info);
}
10 changes: 9 additions & 1 deletion pkg/kernel/src/process/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use alloc::format;
use alloc::vec::Vec;
use x86_64::structures::idt::InterruptStackFrame;
use x86_64::VirtAddr;
use x86_64::structures::paging::PhysFrame;
use xmas_elf::ElfFile;

once_mutex!(pub PROCESS_MANAGER: ProcessManager);
Expand Down Expand Up @@ -83,6 +84,11 @@ impl ProcessManager {
}
}

fn get_kernel_page_table(&self) -> PhysFrame {
let proc = self.processes.get(0).unwrap();
proc.page_table_addr()
}

pub fn spawn(
&mut self,
elf: &ElfFile,
Expand All @@ -94,6 +100,7 @@ impl ProcessManager {
&mut *crate::memory::get_frame_alloc_for_sure(),
name,
parent,
self.get_kernel_page_table(),
proc_data,
);
p.pause();
Expand All @@ -102,7 +109,7 @@ impl ProcessManager {
VirtAddr::new_truncate(STACK_TOP),
);
p.init_elf(elf);
info!("Spawn process: {}#{}", p.name(), p.pid());
// info!("Spawn process: {}#{}", p.name(), p.pid());
// info!("Spawn process:\n\n{:?}\n", p);
let pid = p.pid();
self.processes.push(p);
Expand All @@ -121,6 +128,7 @@ impl ProcessManager {
&mut *crate::memory::get_frame_alloc_for_sure(),
name,
parent,
self.get_kernel_page_table(),
proc_data,
);
p.pause();
Expand Down
13 changes: 11 additions & 2 deletions pkg/kernel/src/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ pub use scheduler::*;

use crate::{filesystem::get_volume, Registers, Resource};
use alloc::string::String;
use x86_64::structures::{idt::InterruptStackFrame, paging::FrameAllocator};
use x86_64::{
registers::control::Cr3,
structures::{idt::InterruptStackFrame, paging::FrameAllocator},
};

use self::manager::init_PROCESS_MANAGER;

Expand Down Expand Up @@ -56,7 +59,13 @@ impl From<ProcessId> for u16 {
pub fn init() {
let mut alloc = crate::memory::get_frame_alloc_for_sure();
// kernel process
let mut kproc = Process::new(&mut *alloc, String::from("kernel"), ProcessId(0), None);
let mut kproc = Process::new(
&mut *alloc,
String::from("kernel"),
ProcessId(0),
Cr3::read().0,
None,
);
kproc.resume();
kproc.set_page_table_with_cr3();
init_PROCESS_MANAGER(ProcessManager::new(kproc));
Expand Down
14 changes: 10 additions & 4 deletions pkg/kernel/src/process/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ impl Process {
self.page_table_addr = Cr3::read();
}

pub fn page_table_addr(&self) -> PhysFrame {
self.page_table_addr.0
}

pub fn is_running(&self) -> bool {
self.status == ProgramStatus::Running
}
Expand Down Expand Up @@ -120,18 +124,20 @@ impl Process {
frame_alloc: &mut BootInfoFrameAllocator,
name: String,
parent: ProcessId,
page_table_source: PhysFrame,
proc_data: Option<ProcessData>,
) -> Self {
let name = name.to_ascii_lowercase();
// 1. alloc a page table for process
let page_table_addr = frame_alloc
.allocate_frame()
.expect("Cannot alloc page table for new process.");
trace!("Alloc page table for {}: {:?}", name, page_table_addr);
debug!("Alloc page table for {}: {:?}", name, page_table_addr);

// 2. copy current page table to new page table
unsafe {
copy_nonoverlapping::<PageTable>(
Cr3::read().0.start_address().as_u64() as *mut PageTable,
page_table_source.start_address().as_u64() as *mut PageTable,
page_table_addr.start_address().as_u64() as *mut PageTable,
1,
);
Expand Down Expand Up @@ -230,8 +236,8 @@ impl core::fmt::Display for Process {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(
f,
"#{:3} | {:10} | {}",
self.pid, self.name, self.ticks_passed
" #{:-3}| {:10} | {}",
u16::from(self.pid), self.name, self.ticks_passed
)?;
Ok(())
}
Expand Down
22 changes: 16 additions & 6 deletions pkg/kernel/src/tasks/executor.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use crate::process;

use super::{Task, TaskId};
use alloc::{collections::BTreeMap, sync::Arc, task::Wake};
use core::task::{Context, Poll, Waker};
use core::future::Future;
use crossbeam_queue::ArrayQueue;
use crate::process::ProcessId;

pub struct Executor {
tasks: BTreeMap<TaskId, Task>,
Expand All @@ -18,18 +22,24 @@ impl Executor {
}
}

pub fn spawn(&mut self, task: Task) {
pub fn spawn(&mut self, task: impl Future<Output = ()> + 'static) {
let task = Task::new(task);
let task_id = task.id;
if self.tasks.insert(task.id, task).is_some() {
panic!("task with same ID already in tasks");
panic!("Task with same ID already in tasks");
}
self.task_queue.push(task_id).expect("queue full");
self.task_queue.push(task_id).expect("Task queue is full");
}

pub fn run(&mut self) -> ! {
/// only return when init process is not alive
pub fn run(&mut self, init: ProcessId) {
loop {
self.run_ready_tasks();
self.sleep_if_idle();
if process::still_alive(init) {
self.sleep_if_idle();
} else {
break;
}
}
}

Expand Down Expand Up @@ -80,7 +90,7 @@ impl TaskWaker {
}

fn wake_task(&self) {
self.task_queue.push(self.task_id).expect("task_queue full");
self.task_queue.push(self.task_id).expect("Task queue is full");
}
}

Expand Down
Loading

0 comments on commit ae743a7

Please sign in to comment.