Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions src/arch/i686/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,9 @@ pub unsafe fn sti()
{
asm!("sti");
}

#[inline(always)]
pub unsafe fn cli()
{
asm!("cli");
}
14 changes: 11 additions & 3 deletions src/arch/i686/interrupts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ pub unsafe fn enable()
{
instructions::sti();
}
#[inline(always)]
pub unsafe fn disable()
{
instructions::cli();
}

#[derive(Copy, Clone, Debug)]
#[repr(C, packed)]
Expand Down Expand Up @@ -74,26 +79,29 @@ impl State
}

#[no_mangle]
pub unsafe extern "C" fn interrupt_handler(state: &State)
pub unsafe extern "C" fn interrupt_handler(state: &State) -> usize
{
let interrupt = state.interrupt;
match interrupt
{
0x00..=0x1f =>
{
exceptions::handler(state);
0
},
0x20..=0x2f =>
{
irq::handler(state);
0
}
0x30 | 0x80 =>
{
software::handler(state);
software::handler(state)
}
_ =>
{
crate::serial_println!("Got unhandled interrupt {:02x}", interrupt);
0
}
};
}
}
39 changes: 30 additions & 9 deletions src/arch/i686/interrupts/software.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,72 @@
use super::State;

use crate::arch;

use core::slice;

#[derive(Copy, Clone)]
pub struct Syscall
{
name: &'static str,
pub handler: unsafe fn(u32, u32, u32)
pub handler: unsafe fn(u32, u32, u32) -> usize
}

pub static SYSCALLS: [Syscall; 2] =
[
Syscall {name: "read", handler: sys_dummy},
Syscall {name: "read", handler: sys_read},
Syscall {name: "write", handler: sys_write}
];


pub unsafe fn handler(state: &State)
pub unsafe fn handler(state: &State) -> usize
{
syscall(state.eax, state.ebx, state.ecx, state.edx);
syscall(state.eax, state.ebx, state.ecx, state.edx)
}

unsafe fn syscall(syscall_number: u32, arg1: u32, arg2: u32, arg3: u32)
unsafe fn syscall(syscall_number: u32, arg1: u32, arg2: u32, arg3: u32) -> usize
{
if (syscall_number as usize) < SYSCALLS.len()
{
let syscall = SYSCALLS[syscall_number as usize];
crate::serial_println!("Called syscall {}({}, {}, {})", syscall.name, arg1, arg2, arg3);
(syscall.handler)(arg1, arg2, arg3);
//crate::serial_println!("Called syscall {}({}, {}, {})", syscall.name, arg1, arg2, arg3);
return (syscall.handler)(arg1, arg2, arg3);
}
else
{
panic!("Invalid syscall {}({}, {}, {})", syscall_number, arg1, arg2, arg3);
}
}

unsafe fn sys_dummy(_arg1: u32, _arg2: u32, _arg3: u32)
unsafe fn sys_dummy(_arg1: u32, _arg2: u32, _arg3: u32) -> usize
{
0
}

unsafe fn sys_read(_file_descriptor: u32, buffer: u32, len: u32) -> usize
{
let len = len as usize;
let buffer = slice::from_raw_parts_mut(buffer as *mut u8, len);
let buf = &mut crate::keyboard::BUFFER.assume_init_mut();
while buf.len() < len
{
super::enable();
arch::halt();
super::disable();
}
for i in 0..len
{
buffer[i] = buf.remove(0) as u8;
}
return len;
}

unsafe fn sys_write(_file_descriptor: u32, buffer: u32, len: u32)
unsafe fn sys_write(_file_descriptor: u32, buffer: u32, len: u32) -> usize
{
let len = len as usize;
let buffer = slice::from_raw_parts(buffer as *const u8, len);
for i in 0..len
{
crate::log!("{}", buffer[i] as char);
}
0
}
4 changes: 4 additions & 0 deletions src/arch/i686/isr.asm
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,9 @@ isr_no_error 253
isr_no_error 254
isr_no_error 255

global retval
retval: dd 0

isr_common:
cli
; push eax, ecx, edx, ebx, esi, edi
Expand All @@ -298,6 +301,7 @@ isr_common:
push esp ; pass the saved args to the function via the old stack pointer
extern interrupt_handler
call interrupt_handler
mov [retval], eax
add esp, 4

pop eax
Expand Down
1 change: 1 addition & 0 deletions src/arch/i686/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub mod gdt;
pub mod instructions;
pub mod interrupts;
pub mod port;
pub mod syscall;

pub fn init()
{
Expand Down
14 changes: 14 additions & 0 deletions src/arch/i686/syscall.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use core::arch::asm;

pub unsafe fn syscall(syscall_number: u32, arg1: u32, arg2: u32, arg3: u32) -> usize
{
let ret: usize;
asm!("int 0x80; mov eax, retval",
in("eax") syscall_number,
in("ebx") arg1,
in("ecx") arg2,
in("edx") arg3,
lateout("eax") ret);
ret
}

3 changes: 2 additions & 1 deletion src/arch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ pub use i686::
{
halt,
interrupts,
port
port,
syscall
};
18 changes: 14 additions & 4 deletions src/elsos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ extern crate alloc;
use core::panic::PanicInfo;
use crate::multiboot::{MULTIBOOT_MMAP, MULTIBOOT_MMAP_ENTRIES};

use alloc::string::String;

mod arch;
mod ferramenta;
mod vga;
Expand All @@ -21,6 +23,7 @@ mod serial;
mod memory;
mod libc;
mod time;
mod syscall;

static VERSION: &str = env!("VERSION");
static PATCHLEVEL: &str = env!("PATCHLEVEL");
Expand Down Expand Up @@ -61,10 +64,11 @@ pub extern "C" fn kernel_main(magic: u32, address: u32)
tty::prompt();
unsafe
{
keyboard::BUFFER.as_mut_ptr().write(String::new());
arch::interrupts::init();
arch::interrupts::enable();
}
tests();
//tests();
loop
{
arch::halt();
Expand All @@ -75,11 +79,17 @@ pub extern "C" fn kernel_main(magic: u32, address: u32)
fn tests()
{
// put tests here
vga_println!("getting one line...");
vga_println!("got line \"{}\"", ferramenta::get_line());
unsafe
{
let text = [b'H', b'e', b'l', b'l', b'o', b'\n'];
let len = 6;
ferramenta::syscall(1, 0, &text as *const _ as u32, len);
let mut text = [b'H', b'e', b'l', b'l', b'o'];
let len = 5;
syscall::write(0, text.as_ptr() as u32, len);
vga_println!();
syscall::read(0, text.as_mut_ptr() as u32, len);
syscall::write(0, text.as_ptr() as u32, len);
vga_println!();
}
}

Expand Down
30 changes: 20 additions & 10 deletions src/ferramenta.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::memory;
use crate::syscall;

use alloc::string::String;

use core::slice;
use core::arch::asm;

pub fn shutdown_qemu()
{
Expand Down Expand Up @@ -95,16 +97,24 @@ pub unsafe fn print_memory_bin(ptr: *const u8, n: usize)
crate::logln!();
}

pub unsafe fn syscall(syscall_number: u32, arg1: u32, arg2: u32, arg3: u32) -> u32
pub fn get_line() -> String
{
let ret: u32;
asm!("int 0x80",
in("eax") syscall_number,
in("ebx") arg1,
in("ecx") arg2,
in("edx") arg3,
lateout("eax") ret);
ret
let mut line = String::new();
let mut buf = [b'\0'];

while buf[0] != b'\n'
{
unsafe
{
while syscall::read(0, buf.as_mut_ptr() as u32, 1) == 0 {}
}
if buf[0] != b'\n'
{
line.push(buf[0] as char);
}
}

line
}

#[macro_export]
Expand Down
2 changes: 2 additions & 0 deletions src/keyboard/azerty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pub fn char_from_input(keyboard_input: &KeyboardInput) -> Option<char>
0x34 => Some('/'),
0x35 => Some('+'),
0x39 => Some(' '),
0x1C => Some('\n'),
_ => None,
};
}
Expand Down Expand Up @@ -113,6 +114,7 @@ pub fn char_from_input(keyboard_input: &KeyboardInput) -> Option<char>
0x34 => Some(':'),
0x35 => Some('='),
0x39 => Some(' '),
0x1C => Some('\n'),
_ => None,
};
}
Expand Down
14 changes: 13 additions & 1 deletion src/keyboard/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::arch;
use crate::tty;

use core::mem::MaybeUninit;
use alloc::string::String;

mod azerty;
mod qwerty;

Expand Down Expand Up @@ -34,18 +37,27 @@ static mut KEYBOARD_STATE: KeyboardState = KeyboardState
ctrl: false,
};


pub static mut BUFFER: MaybeUninit<String> = MaybeUninit::uninit();

pub fn char_from_input(keyboard_input: &KeyboardInput) -> Option<char>
{
unsafe
{
if crate::SETTINGS.layout == 1
let c = if crate::SETTINGS.layout == 1
{
qwerty::char_from_input(keyboard_input)
}
else
{
azerty::char_from_input(keyboard_input)
};
if let Some(key) = c
{
let buf = BUFFER.assume_init_mut();
buf.push(key);
}
c
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/keyboard/qwerty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pub fn char_from_input(keyboard_input: &KeyboardInput) -> Option<char>
0x34 => Some('>'),
0x35 => Some('?'),
0x39 => Some(' '),
0x1C => Some('\n'),
_ => None,
};
}
Expand Down Expand Up @@ -113,6 +114,7 @@ pub fn char_from_input(keyboard_input: &KeyboardInput) -> Option<char>
0x34 => Some('.'),
0x35 => Some('/'),
0x39 => Some(' '),
0x1C => Some('\n'),
_ => None,
};
}
Expand Down
6 changes: 3 additions & 3 deletions src/memory/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ unsafe impl GlobalAlloc for Allocator
{
unsafe fn alloc(&self, _layout: Layout) -> *mut u8
{
crate::serial_println!("trying to allocate {} ({:#x}) bytes...", _layout.size(), _layout.size());
//crate::serial_println!("trying to allocate {} ({:#x}) bytes...", _layout.size(), _layout.size());
let address = vmalloc(_layout.size());
crate::serial_println!("allocated {} bytes at {:p}", _layout.size(), address);
//crate::serial_println!("allocated {} bytes at {:p}", _layout.size(), address);
address as *mut u8
}

Expand All @@ -21,7 +21,7 @@ unsafe impl GlobalAlloc for Allocator

unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout)
{
crate::serial_println!("deallocating {:p}", _ptr);
//crate::serial_println!("deallocating {:p}", _ptr);
vfree(_ptr as *mut c_void);
}
}
Expand Down
19 changes: 19 additions & 0 deletions src/syscall.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use crate::arch;

#[inline(always)]
pub unsafe fn syscall(syscall_number: u32, arg1: u32, arg2: u32, arg3: u32) -> usize
{
arch::syscall::syscall(syscall_number, arg1, arg2, arg3)
}

#[inline(always)]
pub unsafe fn read(file_descriptor: u32, buffer: u32, len: u32) -> usize
{
syscall(0, file_descriptor, buffer, len)
}

#[inline(always)]
pub unsafe fn write(file_descriptor: u32, buffer: u32, len: u32) -> usize
{
syscall(1, file_descriptor, buffer, len)
}
Loading