From 2c590812fdf462ae99a10d44ee207827493fa118 Mon Sep 17 00:00:00 2001 From: Edgar Fouillet Date: Fri, 4 Nov 2022 16:08:14 +0100 Subject: [PATCH 01/10] interrupts: add cli and disable functions --- src/arch/i686/instructions.rs | 6 ++++++ src/arch/i686/interrupts/mod.rs | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/src/arch/i686/instructions.rs b/src/arch/i686/instructions.rs index 43bf791..fb2b084 100644 --- a/src/arch/i686/instructions.rs +++ b/src/arch/i686/instructions.rs @@ -12,3 +12,9 @@ pub unsafe fn sti() { asm!("sti"); } + +#[inline(always)] +pub unsafe fn cli() +{ + asm!("cli"); +} diff --git a/src/arch/i686/interrupts/mod.rs b/src/arch/i686/interrupts/mod.rs index 8112032..416c285 100644 --- a/src/arch/i686/interrupts/mod.rs +++ b/src/arch/i686/interrupts/mod.rs @@ -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)] From ecba610be0d54d8fee33ff63f8d274cebdaedc86 Mon Sep 17 00:00:00 2001 From: Edgar Fouillet Date: Fri, 4 Nov 2022 16:17:00 +0100 Subject: [PATCH 02/10] syscalls: make syscalls return --- src/arch/i686/interrupts/mod.rs | 9 ++++++--- src/arch/i686/interrupts/software.rs | 19 ++++++++++--------- src/arch/i686/isr.asm | 4 ++++ 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/arch/i686/interrupts/mod.rs b/src/arch/i686/interrupts/mod.rs index 416c285..97b62f6 100644 --- a/src/arch/i686/interrupts/mod.rs +++ b/src/arch/i686/interrupts/mod.rs @@ -79,7 +79,7 @@ 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 @@ -87,18 +87,21 @@ pub unsafe extern "C" fn interrupt_handler(state: &State) 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 } - }; + } } diff --git a/src/arch/i686/interrupts/software.rs b/src/arch/i686/interrupts/software.rs index 72a58a5..2be229b 100644 --- a/src/arch/i686/interrupts/software.rs +++ b/src/arch/i686/interrupts/software.rs @@ -6,7 +6,7 @@ use core::slice; 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] = @@ -16,18 +16,18 @@ pub static SYSCALLS: [Syscall; 2] = ]; -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 { @@ -35,12 +35,12 @@ unsafe fn syscall(syscall_number: u32, arg1: u32, arg2: u32, arg3: u32) } } -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_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); @@ -48,4 +48,5 @@ unsafe fn sys_write(_file_descriptor: u32, buffer: u32, len: u32) { crate::log!("{}", buffer[i] as char); } + 0 } diff --git a/src/arch/i686/isr.asm b/src/arch/i686/isr.asm index 9891348..0cdddb6 100644 --- a/src/arch/i686/isr.asm +++ b/src/arch/i686/isr.asm @@ -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 @@ -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 From dc8e9027ee917760a76a2356ef92660e6e58e3b8 Mon Sep 17 00:00:00 2001 From: Edgar Fouillet Date: Fri, 4 Nov 2022 16:12:28 +0100 Subject: [PATCH 03/10] syscalls: move syscalls to their module --- src/arch/i686/mod.rs | 1 + src/arch/i686/syscall.rs | 14 ++++++++++++++ src/arch/mod.rs | 3 ++- src/elsos.rs | 8 +++++--- src/ferramenta.rs | 13 ------------- src/syscall.rs | 19 +++++++++++++++++++ 6 files changed, 41 insertions(+), 17 deletions(-) create mode 100644 src/arch/i686/syscall.rs create mode 100644 src/syscall.rs diff --git a/src/arch/i686/mod.rs b/src/arch/i686/mod.rs index 1ff2cf9..8e09ed4 100644 --- a/src/arch/i686/mod.rs +++ b/src/arch/i686/mod.rs @@ -4,6 +4,7 @@ pub mod gdt; pub mod instructions; pub mod interrupts; pub mod port; +pub mod syscall; pub fn init() { diff --git a/src/arch/i686/syscall.rs b/src/arch/i686/syscall.rs new file mode 100644 index 0000000..5ac96f4 --- /dev/null +++ b/src/arch/i686/syscall.rs @@ -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 +} + diff --git a/src/arch/mod.rs b/src/arch/mod.rs index 06c4467..6a4c727 100644 --- a/src/arch/mod.rs +++ b/src/arch/mod.rs @@ -8,5 +8,6 @@ pub use i686:: { halt, interrupts, - port + port, + syscall }; diff --git a/src/elsos.rs b/src/elsos.rs index a4d1803..682c73d 100644 --- a/src/elsos.rs +++ b/src/elsos.rs @@ -21,6 +21,7 @@ mod serial; mod memory; mod libc; mod time; +mod syscall; static VERSION: &str = env!("VERSION"); static PATCHLEVEL: &str = env!("PATCHLEVEL"); @@ -77,9 +78,10 @@ fn tests() // put tests here 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 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!(); } } diff --git a/src/ferramenta.rs b/src/ferramenta.rs index d446209..46aaae9 100644 --- a/src/ferramenta.rs +++ b/src/ferramenta.rs @@ -1,7 +1,6 @@ use crate::memory; use core::slice; -use core::arch::asm; pub fn shutdown_qemu() { @@ -95,18 +94,6 @@ 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 -{ - let ret: u32; - asm!("int 0x80", - in("eax") syscall_number, - in("ebx") arg1, - in("ecx") arg2, - in("edx") arg3, - lateout("eax") ret); - ret -} - #[macro_export] macro_rules! get_reg { diff --git a/src/syscall.rs b/src/syscall.rs new file mode 100644 index 0000000..439b8b5 --- /dev/null +++ b/src/syscall.rs @@ -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) +} From 2e43c474b7c81f283162e2a304d61dadc55f89ca Mon Sep 17 00:00:00 2001 From: Edgar Fouillet Date: Fri, 4 Nov 2022 16:20:13 +0100 Subject: [PATCH 04/10] keyboard: add read buffer --- src/elsos.rs | 3 +++ src/keyboard/azerty.rs | 2 ++ src/keyboard/mod.rs | 14 +++++++++++++- src/keyboard/qwerty.rs | 2 ++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/elsos.rs b/src/elsos.rs index 682c73d..a2fec36 100644 --- a/src/elsos.rs +++ b/src/elsos.rs @@ -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; @@ -62,6 +64,7 @@ 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(); } diff --git a/src/keyboard/azerty.rs b/src/keyboard/azerty.rs index 998133f..6fc75f8 100644 --- a/src/keyboard/azerty.rs +++ b/src/keyboard/azerty.rs @@ -58,6 +58,7 @@ pub fn char_from_input(keyboard_input: &KeyboardInput) -> Option 0x34 => Some('/'), 0x35 => Some('+'), 0x39 => Some(' '), + 0x1C => Some('\n'), _ => None, }; } @@ -113,6 +114,7 @@ pub fn char_from_input(keyboard_input: &KeyboardInput) -> Option 0x34 => Some(':'), 0x35 => Some('='), 0x39 => Some(' '), + 0x1C => Some('\n'), _ => None, }; } diff --git a/src/keyboard/mod.rs b/src/keyboard/mod.rs index 06baf86..a2cb72e 100644 --- a/src/keyboard/mod.rs +++ b/src/keyboard/mod.rs @@ -1,6 +1,9 @@ use crate::arch; use crate::tty; +use core::mem::MaybeUninit; +use alloc::string::String; + mod azerty; mod qwerty; @@ -34,18 +37,27 @@ static mut KEYBOARD_STATE: KeyboardState = KeyboardState ctrl: false, }; + +pub static mut BUFFER: MaybeUninit = MaybeUninit::uninit(); + pub fn char_from_input(keyboard_input: &KeyboardInput) -> Option { 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 } } diff --git a/src/keyboard/qwerty.rs b/src/keyboard/qwerty.rs index af1e8db..ce1c0b6 100644 --- a/src/keyboard/qwerty.rs +++ b/src/keyboard/qwerty.rs @@ -58,6 +58,7 @@ pub fn char_from_input(keyboard_input: &KeyboardInput) -> Option 0x34 => Some('>'), 0x35 => Some('?'), 0x39 => Some(' '), + 0x1C => Some('\n'), _ => None, }; } @@ -113,6 +114,7 @@ pub fn char_from_input(keyboard_input: &KeyboardInput) -> Option 0x34 => Some('.'), 0x35 => Some('/'), 0x39 => Some(' '), + 0x1C => Some('\n'), _ => None, }; } From d21d50024842ab9f91462c9f2aa8522970c84fb0 Mon Sep 17 00:00:00 2001 From: Edgar Fouillet Date: Fri, 4 Nov 2022 16:19:17 +0100 Subject: [PATCH 05/10] syscalls: add read --- src/arch/i686/interrupts/software.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/arch/i686/interrupts/software.rs b/src/arch/i686/interrupts/software.rs index 2be229b..de5f182 100644 --- a/src/arch/i686/interrupts/software.rs +++ b/src/arch/i686/interrupts/software.rs @@ -1,5 +1,7 @@ use super::State; +use crate::arch; + use core::slice; #[derive(Copy, Clone)] @@ -11,7 +13,7 @@ pub struct Syscall pub static SYSCALLS: [Syscall; 2] = [ - Syscall {name: "read", handler: sys_dummy}, + Syscall {name: "read", handler: sys_read}, Syscall {name: "write", handler: sys_write} ]; @@ -40,6 +42,24 @@ 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) -> usize { let len = len as usize; From 0f5009ab3b4f2e435d9c36d38e5717718dc38b9e Mon Sep 17 00:00:00 2001 From: Edgar Fouillet Date: Fri, 4 Nov 2022 17:03:34 +0100 Subject: [PATCH 06/10] tty: support read buffer with return --- src/tty/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tty/mod.rs b/src/tty/mod.rs index 36a4c25..35b1c91 100644 --- a/src/tty/mod.rs +++ b/src/tty/mod.rs @@ -154,6 +154,11 @@ pub fn input(keyboard_input: &keyboard::KeyboardInput) { if let Some(key) = keyboard::char_from_input(keyboard_input) { + if key == '\n' + { + line_return(true); + return; + } if keyboard_input.state.ctrl { match key @@ -195,7 +200,6 @@ pub fn input(keyboard_input: &keyboard::KeyboardInput) match keyboard_input.scancode { 0x0e => backspace(), - 0x1C => line_return(true), 0x4B => cursor_left(), 0x4D => cursor_right(), 0x48 => cursor_up(), From 03c2ccaf5b7b1890628d89b322cb7e4290afa773 Mon Sep 17 00:00:00 2001 From: Edgar Fouillet Date: Fri, 4 Nov 2022 16:21:26 +0100 Subject: [PATCH 07/10] getline: add function based on read() --- src/ferramenta.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/ferramenta.rs b/src/ferramenta.rs index 46aaae9..bdc03cb 100644 --- a/src/ferramenta.rs +++ b/src/ferramenta.rs @@ -1,5 +1,7 @@ use crate::memory; +use alloc::string::String; + use core::slice; pub fn shutdown_qemu() @@ -94,6 +96,26 @@ pub unsafe fn print_memory_bin(ptr: *const u8, n: usize) crate::logln!(); } +fn get_line() -> String +{ + 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] macro_rules! get_reg { From e784496a5632ef75d5d268579dd13b566ea4d327 Mon Sep 17 00:00:00 2001 From: Edgar Fouillet Date: Fri, 4 Nov 2022 16:22:38 +0100 Subject: [PATCH 08/10] getline: add test --- src/elsos.rs | 2 ++ src/ferramenta.rs | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/elsos.rs b/src/elsos.rs index a2fec36..4d866fa 100644 --- a/src/elsos.rs +++ b/src/elsos.rs @@ -79,6 +79,8 @@ 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']; diff --git a/src/ferramenta.rs b/src/ferramenta.rs index bdc03cb..e32edf5 100644 --- a/src/ferramenta.rs +++ b/src/ferramenta.rs @@ -1,4 +1,5 @@ use crate::memory; +use crate::syscall; use alloc::string::String; @@ -96,7 +97,7 @@ pub unsafe fn print_memory_bin(ptr: *const u8, n: usize) crate::logln!(); } -fn get_line() -> String +pub fn get_line() -> String { let mut line = String::new(); let mut buf = [b'\0']; From 6c5b2bf83c4031c99c35241295bb2d36a88a0021 Mon Sep 17 00:00:00 2001 From: Edgar Fouillet Date: Fri, 4 Nov 2022 17:07:30 +0100 Subject: [PATCH 09/10] syscall: add test for read --- src/elsos.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/elsos.rs b/src/elsos.rs index 4d866fa..e238ec1 100644 --- a/src/elsos.rs +++ b/src/elsos.rs @@ -83,10 +83,13 @@ fn tests() vga_println!("got line \"{}\"", ferramenta::get_line()); unsafe { - let text = [b'H', b'e', b'l', b'l', b'o']; + 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!(); } } From 28863431c0ea4c0c50a954cd04023645d3c4d85c Mon Sep 17 00:00:00 2001 From: Edgar Fouillet Date: Fri, 4 Nov 2022 17:11:29 +0100 Subject: [PATCH 10/10] tests: disable tests and logs --- src/elsos.rs | 2 +- src/memory/allocator.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/elsos.rs b/src/elsos.rs index e238ec1..662c20d 100644 --- a/src/elsos.rs +++ b/src/elsos.rs @@ -68,7 +68,7 @@ pub extern "C" fn kernel_main(magic: u32, address: u32) arch::interrupts::init(); arch::interrupts::enable(); } - tests(); + //tests(); loop { arch::halt(); diff --git a/src/memory/allocator.rs b/src/memory/allocator.rs index d4a74e5..848e7dd 100644 --- a/src/memory/allocator.rs +++ b/src/memory/allocator.rs @@ -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 } @@ -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); } }