Skip to content

Commit

Permalink
refactor: scheduler, context switching and signal handling
Browse files Browse the repository at this point in the history
  • Loading branch information
llenotre committed Nov 3, 2024
1 parent f8add6c commit 44349b9
Show file tree
Hide file tree
Showing 22 changed files with 615 additions and 472 deletions.
100 changes: 0 additions & 100 deletions kernel/arch/x86/src/context.s

This file was deleted.

37 changes: 0 additions & 37 deletions kernel/arch/x86_64/src/context.s

This file was deleted.

4 changes: 3 additions & 1 deletion kernel/src/arch/x86/gdt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ pub const KERNEL_CS: usize = 8;
pub const KERNEL_DS: usize = 16;
/// The offset of the user code segment.
pub const USER_CS: usize = 24;
/// The offset of the user data segment.
/// The offset of the user data segment (32 bits).
pub const USER_DS: usize = 32;
/// The offset of the Task State Segment (TSS).
pub const TSS_OFFSET: usize = 40;
/// The offset of Thread Local Storage (TLS) entries.
pub const TLS_OFFSET: usize = 56;
/// The offset of the user data segment (64 bits).
pub const USER_CS64: usize = 88;

/// A GDT entry.
#[repr(C, align(8))]
Expand Down
126 changes: 69 additions & 57 deletions kernel/src/arch/x86/idt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
//! storing the list of interrupt handlers, allowing to catch and handle
//! interruptions.

use crate::{arch::x86::pic, syscall::syscall};
use crate::{
arch::x86::{gdt, pic, DEFAULT_FLAGS},
syscall::syscall,
};
use core::{
arch::{asm, global_asm},
ffi::c_void,
Expand Down Expand Up @@ -50,34 +53,40 @@ pub const SYSCALL_ENTRY: usize = 0x80;
pub const ENTRIES_COUNT: usize = 0x81;

/// Interruption stack frame, with saved registers state.
#[cfg(target_arch = "x86")]
#[repr(C)]
#[allow(missing_docs)]
#[cfg(target_arch = "x86")]
#[derive(Default)]
pub struct IntFrame {
pub eip: u32,
pub cs: u32,
pub eflags: u32,
pub esp: u32,
pub ss: u32,
// Using the prefix `r` to avoid duplicate code
pub rax: u32,
pub rbx: u32,
pub rcx: u32,
pub rdx: u32,
pub rsi: u32,
pub rdi: u32,
pub rbp: u32,

pub gs: u32,
pub fs: u32,

/// Error code, if any.
pub code: u32,
/// Interruption number.
pub int: u32,
/// Error code, if any.
pub code: u32,

pub eax: u32,
pub ebx: u32,
pub ecx: u32,
pub edx: u32,
pub esi: u32,
pub edi: u32,
pub ebp: u32,
pub rip: u32,
pub cs: u32,
pub rflags: u32,
pub rsp: u32,
pub ss: u32,
}

/// Interruption stack frame, with saved registers state.
#[repr(C)]
#[allow(missing_docs)]
#[cfg(target_arch = "x86_64")]
#[allow(missing_docs)]
#[repr(C)]
#[derive(Default)]
pub struct IntFrame {
pub rax: u64,
pub rbx: u64,
Expand All @@ -96,6 +105,9 @@ pub struct IntFrame {
pub r14: u64,
pub r15: u64,

pub gs: u32,
pub fs: u32,

/// Interruption number.
pub int: u64,
/// Error code, if any.
Expand All @@ -109,17 +121,15 @@ pub struct IntFrame {
}

impl IntFrame {
/// Tells whether the interrupted context is 32 bit.
pub const fn is_32bit(&self) -> bool {
self.cs as usize == gdt::USER_CS | 3
}

/// Returns the ID of the system call being executed.
#[inline]
pub const fn get_syscall_id(&self) -> usize {
#[cfg(target_arch = "x86")]
{
self.eax as usize
}
#[cfg(target_arch = "x86_64")]
{
self.rax as usize
}
self.rax as usize
}

/// Returns the value of the `n`th argument of the syscall being executed.
Expand All @@ -130,12 +140,12 @@ impl IntFrame {
pub const fn get_syscall_arg(&self, n: u8) -> usize {
#[cfg(target_arch = "x86")]
let val = match n {
0 => self.ebx,
1 => self.ecx,
2 => self.edx,
3 => self.esi,
4 => self.edi,
5 => self.ebp,
0 => self.rbx,
1 => self.rcx,
2 => self.rdx,
3 => self.rsi,
4 => self.rdi,
5 => self.rbp,
_ => 0,
};
#[cfg(target_arch = "x86_64")]
Expand All @@ -153,39 +163,41 @@ impl IntFrame {

/// Sets the return value of a system call.
pub fn set_syscall_return(&mut self, value: EResult<usize>) {
let val = value.map(|v| v as _).unwrap_or_else(|e| (-e.as_int()) as _);
#[cfg(target_arch = "x86")]
{
self.eax = val;
}
#[cfg(target_arch = "x86_64")]
{
self.rax = val;
}
self.rax = value.map(|v| v as _).unwrap_or_else(|e| (-e.as_int()) as _);
}

/// Returns the stack address.
pub fn get_stack_address(&self) -> usize {
self.rsp as usize
}

/// Returns the address of the instruction to be executed when the interrupt handler returns.
pub fn get_program_counter(&self) -> usize {
#[cfg(target_arch = "x86")]
{
self.eax as usize
}
#[cfg(target_arch = "x86_64")]
{
self.rax as usize
}
self.rip as usize
}

/// Sets the address of the instruction to be executed when the interrupt handler returns.
pub fn set_program_counter(&mut self, val: usize) {
#[cfg(target_arch = "x86")]
{
self.eax = val as _;
}
#[cfg(target_arch = "x86_64")]
{
self.rax = val as _;
}
self.rip = val as _;
}

/// Sets the values of `frame` so that it can be used to begin the execution of a program.
///
/// Arguments:
/// - `pc` is the program counter
/// - `sp` is the stack pointer
/// - `bit32` tells whether the program is 32 bits. If the kernel is compiled for 32 bit, this
/// value is ignored.
pub fn exec(frame: &mut Self, pc: usize, sp: usize, bit32: bool) {
let cs_segment = if bit32 { gdt::USER_CS } else { gdt::USER_CS64 };
*frame = IntFrame {
rip: pc as _,
cs: (cs_segment | 3) as _,
rflags: DEFAULT_FLAGS as _,
rsp: sp as _,
ss: (gdt::USER_DS | 3) as _,
..Default::default()
};
}
}

Expand Down
2 changes: 1 addition & 1 deletion kernel/src/elf/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::elf::relocation::Relocation;
use utils::bytes;

/// The ELF's class.
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum Class {
/// 32 bit
Bit32,
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,5 +209,5 @@ extern "C" fn interrupt_handler(frame: &mut IntFrame) {
pic::end_of_interrupt((id - ERROR_MESSAGES.len() as u32) as _);
}
drop(callbacks);
process::yield_current(ring);
process::yield_current(ring, frame);
}
7 changes: 4 additions & 3 deletions kernel/src/file/fs/proc/proc_dir/stat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use crate::{
FileLocation, FileType, Stat,
},
format_content,
memory::VirtAddr,
process::{pid::Pid, Process},
};
use core::{fmt, fmt::Formatter};
Expand All @@ -39,14 +40,12 @@ impl<'p> fmt::Display for StatDisp<'p> {
//let vmem_usage = self.0.get_vmem_usage();
let vmem_usage = 0;
let user_regs = self.0.user_regs();
let sp = user_regs.esp;
let pc = user_regs.eip;
// TODO Fill every fields with process's data
write!(
f,
"{pid} ({name}) {state_char} {ppid} {pgid} {sid} TODO TODO 0 \
0 0 0 0 {user_jiffies} {kernel_jiffies} TODO TODO {priority} {nice} {num_threads} 0 {vmem_usage} \
TODO TODO TODO TODO {sp} {pc} TODO TODO TODO TODO 0 0 0 TODO TODO TODO TODO TODO TODO TODO TODO \
TODO TODO TODO TODO {sp:?} {pc:?} TODO TODO TODO TODO 0 0 0 TODO TODO TODO TODO TODO TODO TODO TODO \
TODO TODO TODO TODO TODO TODO TODO TODO TODO",
pid = self.0.get_pid(),
name = DisplayableStr(name),
Expand All @@ -59,6 +58,8 @@ TODO TODO TODO TODO TODO TODO TODO TODO TODO",
priority = self.0.priority,
nice = self.0.nice,
num_threads = 1, // TODO
sp = VirtAddr(user_regs.get_stack_address() as _),
pc = VirtAddr(user_regs.get_program_counter() as _),
)
}
}
Expand Down
Loading

0 comments on commit 44349b9

Please sign in to comment.