Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add process table and exit syscall #268

Merged
merged 38 commits into from
Nov 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
f94f83c
Add process table
vinc Nov 9, 2021
e187518
Add exit syscall
vinc Nov 9, 2021
960e100
Update binaries
vinc Nov 10, 2021
6b46420
Make pid mutable
vinc Nov 11, 2021
c7d8471
Use RW lock for the process table
vinc Nov 11, 2021
26867a1
Change pid atomic ordering
vinc Nov 11, 2021
c20cc13
Fix return code
vinc Nov 11, 2021
4214038
Fix lock issue
vinc Nov 11, 2021
e4ec119
Add debug print
vinc Nov 11, 2021
f3c0cc0
Add exit to sleep binary
vinc Nov 12, 2021
0f694b4
Enable asm_sym feature
vinc Nov 12, 2021
28f6f67
Use the end of code area for stack area
vinc Nov 12, 2021
b447b37
Add debug macro
vinc Nov 12, 2021
f703eb2
Use array instead of vec for process
vinc Nov 12, 2021
b27a451
Refactor process data clone
vinc Nov 12, 2021
6e330c1
Increase max file handles to 32
vinc Nov 12, 2021
fbc6a51
Increase sleep to 5 seconds
vinc Nov 12, 2021
d3e80dc
Fix MAX_PID calculation
vinc Nov 12, 2021
a6e2c33
Merge branch 'trunk' into feature/process-table
vinc Nov 14, 2021
74ac803
Revert max file handle value to fix crash
vinc Nov 14, 2021
e7ced39
Close file handle after dup syscall
vinc Nov 14, 2021
c3eeb62
Remove init
vinc Nov 14, 2021
5368e59
Run the test in release mode
vinc Nov 14, 2021
b4263df
Refactor debug
vinc Nov 14, 2021
670a0c3
Refactor debug output of syscall
vinc Nov 21, 2021
348e7ee
Remove NULL syscall
vinc Nov 21, 2021
82441f4
Save and restore stack frame
vinc Nov 21, 2021
374c64e
Fix install
vinc Nov 21, 2021
bbd4423
Save only scratch registers to the stack
vinc Nov 21, 2021
81b5fa1
Add write volatile to registers
vinc Nov 21, 2021
57c7eb8
Overwrite rax register on exit
vinc Nov 21, 2021
ff4a892
Set pid back to 0 after exit
vinc Nov 22, 2021
a1c1e86
Add alloc_page function
vinc Nov 22, 2021
689e9fb
Remove debug output
vinc Nov 23, 2021
e20c138
Unmap pages after exit
vinc Nov 24, 2021
47645e2
Allocate memory after kernel heap
vinc Nov 24, 2021
da6fc93
Hide unmap error
vinc Nov 24, 2021
0a72ebd
Update changelog
vinc Nov 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Changelog

## Unreleased
- Add process table and exit syscall (#268)
- Improve UTF-8 support (#267)
- Bump acpi from 4.0.0 to 4.1.0 (#265)
- Add shell redirections (#262)
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ qemu:
qemu-system-x86_64 $(opts)

test:
cargo test --lib --no-default-features --features serial,$(nic) -- \
cargo test --release --lib --no-default-features --features serial,$(nic) -- \
-m 32 -display none -serial stdio -device isa-debug-exit,iobase=0xf4,iosize=0x04

clean:
Expand Down
Binary file modified dsk/bin/hello
Binary file not shown.
Binary file modified dsk/bin/sleep
Binary file not shown.
4 changes: 3 additions & 1 deletion dsk/src/bin/hello.s
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ _start:
mov rsi, msg ; addr of string
mov rdx, 14 ; size of string
int 0x80
jmp _start
mov rax, 1 ; syscall number for EXIT
mov rdi, 0 ; no error
int 0x80
6 changes: 4 additions & 2 deletions dsk/src/bin/sleep.s
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
[bits 64]
_start:
mov rax, 9 ; syscall number for SLEEP
mov rdi, __float64__(1.0) ; time to sleep in seconds
mov rdi, __float64__(5.0) ; time to sleep in seconds
mov rsi, 0
mov rdx, 0
int 0x80
jmp _start
mov rax, 1 ; syscall number for EXIT
mov rdi, 0 ; no error
int 0x80
3 changes: 2 additions & 1 deletion src/api/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ pub fn reopen(path: &str, handle: usize) -> Result<usize, ()> {
};
if let Some(old_handle) = res {
syscall::dup(old_handle, handle);
return Ok(old_handle);
syscall::close(old_handle);
return Ok(handle);
}
Err(())
}
Expand Down
17 changes: 0 additions & 17 deletions src/api/regex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,6 @@ use alloc::vec::Vec;
use core::convert::From;
use core::ops::RangeBounds;

// TODO: Remove this when tests are done
const DEBUG: bool = false;
macro_rules! debug {
($($arg:tt)*) => ({
if DEBUG {
println!("{}", format_args!($($arg)*));
}
});
}

// See "A Regular Expression Matcher" by Rob Pike and Brian Kernighan (2007)

#[derive(Debug)]
Expand Down Expand Up @@ -72,7 +62,6 @@ pub struct Regex(String);

impl Regex {
pub fn new(re: &str) -> Self {
debug!("debug: Regex::new({:?})", re);
Self(re.to_string())
}
pub fn is_match(&self, text: &str) -> bool {
Expand All @@ -92,7 +81,6 @@ impl Regex {
}

fn is_match(re: &[char], text: &[char], start: &mut usize, end: &mut usize) -> bool {
debug!("debug: is_match({:?}, {:?})", re, text);
if re.len() == 0 {
return true;
}
Expand All @@ -116,7 +104,6 @@ fn is_match(re: &[char], text: &[char], start: &mut usize, end: &mut usize) -> b
}

fn is_match_here(re: &[char], text: &[char], end: &mut usize) -> bool {
debug!("debug: is_match_here({:?}, {:?})", re, text);
if re.len() == 0 {
return true;
}
Expand Down Expand Up @@ -148,22 +135,18 @@ fn is_match_here(re: &[char], text: &[char], end: &mut usize) -> bool {
}

fn is_match_star(lazy: bool, mc: MetaChar, re: &[char], text: &[char], end: &mut usize) -> bool {
debug!("debug: is_match_star({:?}, {:?}, {:?}", mc, re, text);
is_match_char(lazy, mc, re, text, .., end)
}

fn is_match_plus(lazy: bool, mc: MetaChar, re: &[char], text: &[char], end: &mut usize) -> bool {
debug!("debug: is_match_plus({:?}, {:?}, {:?}", mc, re, text);
is_match_char(lazy, mc, re, text, 1.., end)
}

fn is_match_ques(lazy: bool, mc: MetaChar, re: &[char], text: &[char], end: &mut usize) -> bool {
debug!("debug: is_match_ques({:?}, {:?}, {:?}", mc, re, text);
is_match_char(lazy, mc, re, text, ..2, end)
}

fn is_match_char<T: RangeBounds<usize>>(lazy: bool, mc: MetaChar, re: &[char], text: &[char], range: T, end: &mut usize) -> bool {
debug!("debug: is_match_char({:?}, {:?}, {:?}", mc, re, text);
let mut i = 0;
let n = text.len();

Expand Down
4 changes: 4 additions & 0 deletions src/api/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ use crate::syscall;
use crate::sys::syscall::number::*;
use crate::sys::fs::FileStat;

pub fn exit(code: usize) -> usize {
unsafe { syscall!(EXIT, code as u64) }
}

pub fn sleep(seconds: f64) {
unsafe { syscall!(SLEEP, seconds.to_bits()) };
}
Expand Down
6 changes: 3 additions & 3 deletions src/bin/hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fn panic(_info: &PanicInfo) -> ! {

#[no_mangle]
pub unsafe extern "sysv64" fn _start() -> ! {
loop {
syscall::write(1, b"Hello, World!\n");
}
syscall::write(1, b"Hello, World!\n");
syscall::exit(0);
loop {}
}
6 changes: 3 additions & 3 deletions src/bin/sleep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fn panic(_info: &PanicInfo) -> ! {

#[no_mangle]
pub unsafe extern "sysv64" fn _start() -> ! {
loop {
syscall::sleep(1.0);
}
syscall::sleep(5.0);
syscall::exit(0);
loop {}
}
40 changes: 40 additions & 0 deletions src/sys/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,46 @@ pub fn init_heap(mapper: &mut impl Mapper<Size4KiB>, frame_allocator: &mut impl
Ok(())
}

pub fn alloc_pages(addr: u64, size: u64) {
let mut mapper = unsafe { sys::mem::mapper(VirtAddr::new(sys::mem::PHYS_MEM_OFFSET)) };
let mut frame_allocator = unsafe { sys::mem::BootInfoFrameAllocator::init(sys::mem::MEMORY_MAP.unwrap()) };
let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE | PageTableFlags::USER_ACCESSIBLE;
let pages = {
let start_page = Page::containing_address(VirtAddr::new(addr));
let end_page = Page::containing_address(VirtAddr::new(addr + size));
Page::range_inclusive(start_page, end_page)
};
for page in pages {
let frame = frame_allocator.allocate_frame().unwrap();
unsafe {
if let Ok(mapping) = mapper.map_to(page, frame, flags, &mut frame_allocator) {
mapping.flush();
} else {
debug!("Could not map {:?}", page);
}
}
}
}

use x86_64::structures::paging::page::PageRangeInclusive;

// TODO: Replace `free` by `dealloc`
pub fn free_pages(addr: u64, size: u64) {
let mut mapper = unsafe { sys::mem::mapper(VirtAddr::new(sys::mem::PHYS_MEM_OFFSET)) };
let pages: PageRangeInclusive<Size4KiB> = {
let start_page = Page::containing_address(VirtAddr::new(addr));
let end_page = Page::containing_address(VirtAddr::new(addr + size));
Page::range_inclusive(start_page, end_page)
};
for page in pages {
if let Ok((_frame, mapping)) = mapper.unmap(page) {
mapping.flush();
} else {
//debug!("Could not unmap {:?}", page);
}
}
}

#[derive(Clone)]
pub struct PhysBuf {
buf: Arc<Mutex<Vec<u8>>>,
Expand Down
64 changes: 26 additions & 38 deletions src/sys/idt.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use crate::sys;
use crate::sys::process::Registers;

use lazy_static::lazy_static;
use spin::Mutex;
use x86_64::instructions::interrupts;
use x86_64::instructions::port::Port;
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode};
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, InterruptStackFrameValue, PageFaultErrorCode};

const PIC1: u16 = 0x21;
const PIC2: u16 = 0xA1;
Expand Down Expand Up @@ -116,36 +118,14 @@ extern "x86-interrupt" fn segment_not_present_handler(stack_frame: InterruptStac
panic!("EXCEPTION: SEGMENT NOT PRESENT\n{:#?}", stack_frame);
}

// See: https://github.com/xfoxfu/rust-xos/blob/8a07a69ef/kernel/src/interrupts/handlers.rs#L92
#[repr(align(8), C)]
#[derive(Debug, Clone, Default)]
pub struct Registers {
r15: usize,
r14: usize,
r13: usize,
r12: usize,
r11: usize,
r10: usize,
r9: usize,
r8: usize,
rdi: usize,
rsi: usize,
rdx: usize,
rcx: usize,
rbx: usize,
rax: usize,
rbp: usize,
}

// See: https://github.com/xfoxfu/rust-xos/blob/8a07a69ef/kernel/src/interrupts/handlers.rs#L112
// Naked function wrapper saving all scratch registers to the stack
// See: https://os.phil-opp.com/returning-from-exceptions/#a-naked-wrapper-function
macro_rules! wrap {
($fn: ident => $w:ident) => {
#[naked]
pub unsafe extern "sysv64" fn $w() {
asm!(
"push rbp",
"push rax",
"push rbx",
"push rcx",
"push rdx",
"push rsi",
Expand All @@ -154,18 +134,10 @@ macro_rules! wrap {
"push r9",
"push r10",
"push r11",
"push r12",
"push r13",
"push r14",
"push r15",
"mov rsi, rsp", // Arg #2: register list
"mov rdi, rsp", // Arg #1: interupt frame
"add rdi, 15 * 8",
"add rdi, 9 * 8",
"call {}",
"pop r15",
"pop r14",
"pop r13",
"pop r12",
"pop r11",
"pop r10",
"pop r9",
Expand All @@ -174,9 +146,7 @@ macro_rules! wrap {
"pop rsi",
"pop rdx",
"pop rcx",
"pop rbx",
"pop rax",
"pop rbp",
"iretq",
sym $fn,
options(noreturn)
Expand All @@ -190,13 +160,31 @@ wrap!(syscall_handler => wrapped_syscall_handler);
// NOTE: We can't use "x86-interrupt" for syscall_handler because we need to
// return a result in the RAX register and it will be overwritten when the
// context of the caller is restored.
extern "sysv64" fn syscall_handler(_stack_frame: &mut InterruptStackFrame, regs: &mut Registers) {
extern "sysv64" fn syscall_handler(stack_frame: &mut InterruptStackFrame, regs: &mut Registers) {
// The registers order follow the System V ABI convention
let n = regs.rax;
let arg1 = regs.rdi;
let arg2 = regs.rsi;
let arg3 = regs.rdx;
regs.rax = sys::syscall::dispatcher(n, arg1, arg2, arg3);

if n == sys::syscall::number::SPAWN { // Backup CPU context
sys::process::set_stack_frame(stack_frame.clone());
sys::process::set_registers(regs.clone());
}

let res = sys::syscall::dispatcher(n, arg1, arg2, arg3);

if n == sys::syscall::number::EXIT { // Restore CPU context
let sf = sys::process::stack_frame();
unsafe {
//stack_frame.as_mut().write(sf);
core::ptr::write_volatile(stack_frame.as_mut().extract_inner() as *mut InterruptStackFrameValue, sf); // FIXME
core::ptr::write_volatile(regs, sys::process::registers());
}
}

regs.rax = res;

unsafe { sys::pic::PICS.lock().notify_end_of_interrupt(0x80) };
}

Expand Down
12 changes: 12 additions & 0 deletions src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ macro_rules! printk {
});
}

#[macro_export]
macro_rules! debug {
($($arg:tt)*) => ({
let csi_color = $crate::api::console::Style::color("Yellow");
let csi_reset = $crate::api::console::Style::reset();
$crate::sys::console::print_fmt(format_args!("{}DEBUG: ", csi_color));
$crate::sys::console::print_fmt(format_args!($($arg)*));
$crate::sys::console::print_fmt(format_args!("{}\n", csi_reset));
});
}

#[macro_export]
macro_rules! log {
($($arg:tt)*) => ({
Expand All @@ -14,6 +25,7 @@ macro_rules! log {
let csi_reset = $crate::api::console::Style::reset();
$crate::sys::console::print_fmt(format_args!("{}[{:.6}]{} ", csi_color, uptime, csi_reset));
$crate::sys::console::print_fmt(format_args!($($arg)*));
// TODO: Add newline
}
});
}
Expand Down
Loading