From 0b86bc74815aedf53f6c10410f2da499a492ac09 Mon Sep 17 00:00:00 2001 From: Fabian Ruhland Date: Thu, 12 Sep 2024 14:07:39 +0200 Subject: [PATCH] Implement support for C programs --- .github/workflows/build.yml | 4 +- Cargo.toml | 1 + Makefile.toml | 12 ++---- os/application/date/Makefile.toml | 3 -- os/application/hello/Makefile.toml | 3 -- os/application/hello/src/hello.rs | 7 ++-- os/application/helloc/Cargo.toml | 19 +++++++++ os/application/helloc/Makefile.toml | 55 +++++++++++++++++++++++++ os/application/helloc/build.rs | 11 +++++ os/application/helloc/src/hello.c | 14 +++++++ os/application/helloc/src/lib.rs | 6 +++ os/application/mkentry/Makefile.toml | 3 -- os/application/shell/Makefile.toml | 3 -- os/application/uptime/Makefile.toml | 3 -- os/kernel/Makefile.toml | 3 -- os/kernel/src/process/thread.rs | 27 +++++------- os/kernel/src/syscall/sys_concurrent.rs | 37 ++++++++++------- os/kernel/src/syscall/sys_naming.rs | 15 ++----- os/kernel/src/syscall/sys_terminal.rs | 7 ++-- os/kernel/src/syscall/sys_time.rs | 16 +++---- os/kernel/src/syscall/sys_vmem.rs | 4 +- os/library/concurrent/Cargo.toml | 4 +- os/library/concurrent/src/process.rs | 6 +-- os/library/graphic/Cargo.toml | 4 +- os/library/graphic/src/lfb.rs | 14 ++++--- os/library/libc/Cargo.toml | 15 +++++++ os/library/libc/src/lib.rs | 20 +++++++++ os/library/libc/src/runtime.h | 6 +++ os/library/naming/Cargo.toml | 4 +- os/library/runtime/Cargo.toml | 5 ++- os/library/runtime/src/env.rs | 34 +++++---------- os/library/runtime/src/lib.rs | 6 +-- os/library/stream/Cargo.toml | 4 +- os/library/stream/src/lib.rs | 11 +++++ os/library/syscall/Cargo.toml | 5 ++- os/library/syscall/src/lib.rs | 2 +- os/library/syscall/src/return_vals.rs | 17 ++++---- os/library/terminal/Cargo.toml | 4 +- os/library/time/Cargo.toml | 4 +- 39 files changed, 275 insertions(+), 143 deletions(-) create mode 100644 os/application/helloc/Cargo.toml create mode 100644 os/application/helloc/Makefile.toml create mode 100644 os/application/helloc/build.rs create mode 100644 os/application/helloc/src/hello.c create mode 100644 os/application/helloc/src/lib.rs create mode 100644 os/library/libc/Cargo.toml create mode 100644 os/library/libc/src/lib.rs create mode 100644 os/library/libc/src/runtime.h diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 509c4a9..b221fc5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -50,7 +50,7 @@ jobs: - name: Install packages uses: amitie10g/install-package@v1.2.3 with: - brew: x86_64-elf-binutils nasm + brew: x86_64-elf-binutils x86_64-elf-gcc nasm - name: Install Rust uses: dtolnay/rust-toolchain@nightly @@ -84,7 +84,7 @@ jobs: - name: Install packages uses: amitie10g/install-package@v1.2.3 with: - brew: x86_64-elf-binutils nasm + brew: x86_64-elf-binutils x86_64-elf-gcc nasm - name: Install Rust uses: dtolnay/rust-toolchain@nightly diff --git a/Cargo.toml b/Cargo.toml index 6613865..c5eada0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ resolver = "2" members = [ "os/kernel", "os/application/hello", + "os/application/helloc", "os/application/shell", "os/application/uptime", "os/application/date", diff --git a/Makefile.toml b/Makefile.toml index 796958b..371f9df 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -4,8 +4,8 @@ INITRD_DIRECTORY = "${BOOTLOADER_DIRECTORY}/initrd" OVMF_URL = "https://retrage.github.io/edk2-nightly/bin/RELEASEX64_OVMF.fd" TOWBOOT_VERSION = "0.9.0" TOWBOOT_URL = "https://github.com/hhuOS/towboot/releases/download/v${TOWBOOT_VERSION}/towbootctl-v${TOWBOOT_VERSION}" -LINKER = "ld" -LINKER_MAC = "x86_64-elf-ld" +TAR = { source = "${CARGO_MAKE_RUST_TARGET_OS}", default_value = "tar", mapping = { "macos" = "gtar" } } +LINKER = { source = "${CARGO_MAKE_RUST_TARGET_OS}", default_value = "ld", mapping = { "macos" = "x86_64-elf-ld" } } [tasks.default] alias = "qemu" @@ -152,15 +152,11 @@ condition = { files_not_exist = [ "${INITRD_DIRECTORY}" ] } [tasks.initrd] cwd = "${INITRD_DIRECTORY}" -command = "tar" -args = [ "-cf", "${BOOTLOADER_DIRECTORY}/initrd.tar", "hello", "shell", "uptime", "date", "mkentry" ] +command = "${TAR}" +args = [ "-cf", "${BOOTLOADER_DIRECTORY}/initrd.tar", "hello", "helloc", "shell", "uptime", "date", "mkentry" ] dependencies = [ "link-members" ] condition = { files_modified = { input = [ "${INITRD_DIRECTORY}/*" ], output = [ "${BOOTLOADER_DIRECTORY}/initrd.tar" ] } } -[tasks.initrd.mac] -cwd = "${INITRD_DIRECTORY}" -command = "gtar" - [tasks.image] cwd = "${BOOTLOADER_DIRECTORY}" command = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/towbootctl" diff --git a/os/application/date/Makefile.toml b/os/application/date/Makefile.toml index 7b1ab12..1e06801 100644 --- a/os/application/date/Makefile.toml +++ b/os/application/date/Makefile.toml @@ -39,9 +39,6 @@ args = [ "-n", "-T", "${LINKER_FILE}", "-o", "${APPLICATION}", "${RUST_OBJECT}" dependencies = [ "compile" ] condition = { files_modified = { input = [ "${BUILD_DIRECTORY}/lib${CARGO_MAKE_PROJECT_NAME}*" ], output = [ "${BOOTLOADER_DIRECTORY}/initrd/${CARGO_MAKE_PROJECT_NAME}" ] } } -[tasks.link.mac] -command = "${LINKER_MAC}" - # Cleanup tasks [tasks.clean] diff --git a/os/application/hello/Makefile.toml b/os/application/hello/Makefile.toml index 6adb7b6..ac99243 100644 --- a/os/application/hello/Makefile.toml +++ b/os/application/hello/Makefile.toml @@ -38,9 +38,6 @@ args = [ "-n", "-T", "${LINKER_FILE}", "-o", "${APPLICATION}", "${RUST_OBJECT}" dependencies = [ "compile" ] condition = { files_modified = { input = [ "${BUILD_DIRECTORY}/lib${CARGO_MAKE_PROJECT_NAME}*" ], output = [ "${BOOTLOADER_DIRECTORY}/initrd/${CARGO_MAKE_PROJECT_NAME}" ] } } -[tasks.link.mac] -command = "${LINKER_MAC}" - # Cleanup tasks [tasks.clean] diff --git a/os/application/hello/src/hello.rs b/os/application/hello/src/hello.rs index 246f9b7..ecaf6b3 100644 --- a/os/application/hello/src/hello.rs +++ b/os/application/hello/src/hello.rs @@ -12,10 +12,11 @@ pub fn main() { let process = process::current().unwrap(); let thread = thread::current().unwrap(); - println!("Hello from Thread [{}] in Process [{}]!", thread.id(), process.id()); + println!("Hello from Thread [{}] in Process [{}]!\n", thread.id(), process.id()); + println!("Arguments:"); let args = env::args(); - for (i, arg) in args.enumerate() { - println!("Arg[{}]: {}", i, arg); + for arg in args { + println!(" {}", arg); } } \ No newline at end of file diff --git a/os/application/helloc/Cargo.toml b/os/application/helloc/Cargo.toml new file mode 100644 index 0000000..bae3063 --- /dev/null +++ b/os/application/helloc/Cargo.toml @@ -0,0 +1,19 @@ +cargo-features = ["edition2024"] + +[package] +edition = "2024" +name = "helloc" +version = "0.1.0" +authors = ["Michael Schöttner , Fabian Ruhland "] +build = "build.rs" + +[lib] +crate-type = ["staticlib"] + +[dependencies] +# Local dependencies +runtime = { path = "../../library/runtime" } +libc = { path = "../../library/libc" } + +[build-dependencies] +cc = "1.1.18" \ No newline at end of file diff --git a/os/application/helloc/Makefile.toml b/os/application/helloc/Makefile.toml new file mode 100644 index 0000000..99149ef --- /dev/null +++ b/os/application/helloc/Makefile.toml @@ -0,0 +1,55 @@ +[env.development] +CARGO_CFG_TARGET_FAMILY = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/d3os_application.json" +BUILD_DIRECTORY = "${CARGO_MAKE_CRATE_TARGET_DIRECTORY}/d3os_application/debug" +CARGO_BUILD_OPTION = "--lib" + +[env.production] +CARGO_CFG_TARGET_FAMILY = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/d3os_application.json" +BUILD_DIRECTORY = "${CARGO_MAKE_CRATE_TARGET_DIRECTORY}/d3os_application/release" +CARGO_BUILD_OPTION = "--release" + +[env] +CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true +RUST_TARGET_PATH = "${CARGO_MAKE_WORKING_DIRECTORY}" +SOURCE_DIRECTORY = "${CARGO_MAKE_WORKING_DIRECTORY}/src" +LIBRARY_DIRECTORY = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/os/library" +LINKER_FILE = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/os/application/link.ld" +RUST_OBJECT = "${BUILD_DIRECTORY}/lib${CARGO_MAKE_PROJECT_NAME}.a" +APPLICATION = "${INITRD_DIRECTORY}/${CARGO_MAKE_PROJECT_NAME}" +CC = { source = "${CARGO_MAKE_RUST_TARGET_OS}", default_value = "gcc", mapping = { "macos" = "x86_64-elf-gcc" } } +CRATE_CC_NO_DEFAULTS = "true" + +# Build tasks + +[tasks.default] +alias = "link" + +[tasks.compile] +command = "cargo" +args = [ "build", "-Z", "build-std=core,alloc", "-Z", "build-std-features=compiler-builtins-mem", "--target", "${CARGO_CFG_TARGET_FAMILY}", "${CARGO_BUILD_OPTION}" ] +condition = { files_modified = { input = [ + "${CARGO_MAKE_WORKING_DIRECTORY}/Cargo.toml", "${SOURCE_DIRECTORY}/**/*.rs", + "${CARGO_MAKE_WORKING_DIRECTORY}/Cargo.toml", "${SOURCE_DIRECTORY}/**/*.c", + "${LIBRARY_DIRECTORY}/libc/Cargo.toml", "${LIBRARY_DIRECTORY}/libc/src/**/*.rs", + "${LIBRARY_DIRECTORY}/libc/Cargo.toml", "${LIBRARY_DIRECTORY}/libc/src/**/*.h", + "${LIBRARY_DIRECTORY}/runtime/Cargo.toml", "${LIBRARY_DIRECTORY}/runtime/src/**/*.rs", + "${LIBRARY_DIRECTORY}/terminal/Cargo.toml", "${LIBRARY_DIRECTORY}/terminal/src/**/*.rs", + "${LIBRARY_DIRECTORY}/concurrent/Cargo.toml", "${LIBRARY_DIRECTORY}/concurrent/src/**/*.rs", + "${LIBRARY_DIRECTORY}/syscall/Cargo.toml", "${LIBRARY_DIRECTORY}/syscall/src/**/*.rs" ], output = [ "${BUILD_DIRECTORY}/lib${CARGO_MAKE_PROJECT_NAME}*" ] } } + +[tasks.link] +command = "${LINKER}" +args = [ "-n", "-T", "${LINKER_FILE}", "-o", "${APPLICATION}", "${RUST_OBJECT}" ] +dependencies = [ "compile" ] +condition = { files_modified = { input = [ "${BUILD_DIRECTORY}/lib${CARGO_MAKE_PROJECT_NAME}*" ], output = [ "${BOOTLOADER_DIRECTORY}/initrd/${CARGO_MAKE_PROJECT_NAME}" ] } } + +# Cleanup tasks + +[tasks.clean] +command = "cargo" +args = [ "clean" ] +dependencies = [ "remove-application" ] + +[tasks.remove-application] +command = "rm" +args = [ "-f", "${APPLICATION}" ] diff --git a/os/application/helloc/build.rs b/os/application/helloc/build.rs new file mode 100644 index 0000000..a6bbd76 --- /dev/null +++ b/os/application/helloc/build.rs @@ -0,0 +1,11 @@ +fn main() { + println!("cargo:rerun-if-changed=src,../../library/libc/src/"); + + cc::Build::new() + .file("src/hello.c") + .flag("-nostdlib") + .flag("-ffreestanding") + .flag("-fno-stack-protector") + .flag("-fpic") + .compile("hello"); +} \ No newline at end of file diff --git a/os/application/helloc/src/hello.c b/os/application/helloc/src/hello.c new file mode 100644 index 0000000..4476f3b --- /dev/null +++ b/os/application/helloc/src/hello.c @@ -0,0 +1,14 @@ +#include "../../../library/libc/src/runtime.h" + +int main(int argc, char *argv[]) { + terminal_write("Hello from C!\n\n"); + + terminal_write("Arguments:\n"); + for (int i = 0; i < argc; i++) { + terminal_write(" "); + terminal_write(argv[i]); + terminal_write("\n"); + } + + return 0; +} \ No newline at end of file diff --git a/os/application/helloc/src/lib.rs b/os/application/helloc/src/lib.rs new file mode 100644 index 0000000..a52ea27 --- /dev/null +++ b/os/application/helloc/src/lib.rs @@ -0,0 +1,6 @@ +#![no_std] + +#[allow(unused_imports)] +use runtime::*; +#[allow(unused_imports)] +use libc::*; \ No newline at end of file diff --git a/os/application/mkentry/Makefile.toml b/os/application/mkentry/Makefile.toml index 7b1ab12..1e06801 100644 --- a/os/application/mkentry/Makefile.toml +++ b/os/application/mkentry/Makefile.toml @@ -39,9 +39,6 @@ args = [ "-n", "-T", "${LINKER_FILE}", "-o", "${APPLICATION}", "${RUST_OBJECT}" dependencies = [ "compile" ] condition = { files_modified = { input = [ "${BUILD_DIRECTORY}/lib${CARGO_MAKE_PROJECT_NAME}*" ], output = [ "${BOOTLOADER_DIRECTORY}/initrd/${CARGO_MAKE_PROJECT_NAME}" ] } } -[tasks.link.mac] -command = "${LINKER_MAC}" - # Cleanup tasks [tasks.clean] diff --git a/os/application/shell/Makefile.toml b/os/application/shell/Makefile.toml index 6adb7b6..ac99243 100644 --- a/os/application/shell/Makefile.toml +++ b/os/application/shell/Makefile.toml @@ -38,9 +38,6 @@ args = [ "-n", "-T", "${LINKER_FILE}", "-o", "${APPLICATION}", "${RUST_OBJECT}" dependencies = [ "compile" ] condition = { files_modified = { input = [ "${BUILD_DIRECTORY}/lib${CARGO_MAKE_PROJECT_NAME}*" ], output = [ "${BOOTLOADER_DIRECTORY}/initrd/${CARGO_MAKE_PROJECT_NAME}" ] } } -[tasks.link.mac] -command = "${LINKER_MAC}" - # Cleanup tasks [tasks.clean] diff --git a/os/application/uptime/Makefile.toml b/os/application/uptime/Makefile.toml index 7b1ab12..1e06801 100644 --- a/os/application/uptime/Makefile.toml +++ b/os/application/uptime/Makefile.toml @@ -39,9 +39,6 @@ args = [ "-n", "-T", "${LINKER_FILE}", "-o", "${APPLICATION}", "${RUST_OBJECT}" dependencies = [ "compile" ] condition = { files_modified = { input = [ "${BUILD_DIRECTORY}/lib${CARGO_MAKE_PROJECT_NAME}*" ], output = [ "${BOOTLOADER_DIRECTORY}/initrd/${CARGO_MAKE_PROJECT_NAME}" ] } } -[tasks.link.mac] -command = "${LINKER_MAC}" - # Cleanup tasks [tasks.clean] diff --git a/os/kernel/Makefile.toml b/os/kernel/Makefile.toml index 7f8a737..3ad4716 100644 --- a/os/kernel/Makefile.toml +++ b/os/kernel/Makefile.toml @@ -43,9 +43,6 @@ args = [ "-n", "-T", "${LINKER_FILE}", "-o", "${KERNEL}", "${ASM_OBJECT}", "${RU dependencies = [ "compile", "build-asm" ] condition = { files_modified = { input = [ "${BUILD_DIRECTORY}/lib${CARGO_MAKE_PROJECT_NAME}*" ], output = [ "${BOOTLOADER_DIRECTORY}/kernel.elf" ] } } -[tasks.link.mac] -command = "${LINKER_MAC}" - # Cleanup tasks [tasks.clean] diff --git a/os/kernel/src/process/thread.rs b/os/kernel/src/process/thread.rs index f629dd3..f46f31e 100644 --- a/os/kernel/src/process/thread.rs +++ b/os/kernel/src/process/thread.rs @@ -40,7 +40,6 @@ use x86_64::structures::paging::page::PageRange; use x86_64::structures::paging::{Page, PageTableFlags, Size4KiB}; use x86_64::PrivilegeLevel::Ring3; use x86_64::VirtAddr; - use crate::consts::{KERNEL_STACK_PAGES, USER_SPACE_ENV_START}; use crate::consts::MAIN_USER_STACK_START; use crate::consts::MAX_USER_STACK_SIZE; @@ -166,26 +165,20 @@ impl Thread { let args_begin_virt = env_virt_start.start_address() + size_of::() as u64 + ((args.len() + 1) * size_of::()) as u64; // Virtual start address of arguments (they will be visible here in user space) // copy program name as first argument - let mut current_arg = args_begin; - let mut current_arg_len = current_arg as *mut usize; - let mut current_arg_str = current_arg.offset(size_of::() as isize); - - current_arg_len.write_unaligned(name.len()); - current_arg_str.copy_from(name.as_bytes().as_ptr(), name.len()); + args_begin.copy_from(name.as_bytes().as_ptr(), name.len()); + args_begin.add(name.len()).write(0); // null-terminate the string for C compatibility argv.write(args_begin_virt.as_ptr()); - let mut offset = size_of::() + name.len(); - // copy remaining arguments - for i in 0..args.len() { - current_arg = args_begin.offset(offset as isize); - current_arg_len = current_arg as *mut usize; - current_arg_str = current_arg.offset(size_of::() as isize); + let mut offset = name.len() + 1; - current_arg_len.write_unaligned(args[i].len()); - current_arg_str.copy_from(args[i].as_bytes().as_ptr(), args[i].len()); + // copy remaining arguments + for (i, arg) in args.iter().enumerate() { + let target = args_begin.add(offset); + target.copy_from(arg.as_bytes().as_ptr(), arg.len()); + target.add(arg.len()).write(0); // null-terminate the string for C compatibility - argv.offset((i + 1) as isize).write((args_begin_virt + offset as u64).as_ptr()); - offset += size_of::() + args[i].len(); + argv.add(i + 1).write((args_begin_virt + offset as u64).as_ptr()); + offset += arg.len() + 1; } } diff --git a/os/kernel/src/syscall/sys_concurrent.rs b/os/kernel/src/syscall/sys_concurrent.rs index 91d6ae2..336f67c 100644 --- a/os/kernel/src/syscall/sys_concurrent.rs +++ b/os/kernel/src/syscall/sys_concurrent.rs @@ -10,57 +10,62 @@ use alloc::vec::Vec; use alloc::rc::Rc; use core::ptr::slice_from_raw_parts; use core::str::from_utf8; -use x86_64::VirtAddr; +use x86_64::VirtAddr; +use syscall::return_vals::Errno; use crate::{initrd, process_manager, scheduler}; use crate::process::thread::Thread; -pub fn sys_process_id() -> usize { - process_manager().read().current_process().id() +pub fn sys_process_id() -> isize { + process_manager().read().current_process().id() as isize } -pub fn sys_process_exit() { +pub fn sys_process_exit() -> isize { scheduler().current_thread().process().exit(); scheduler().exit(); + 0 } -#[allow(improper_ctypes_definitions)] // 'entry' takes no arguments and has no return value, so we just assume that the "C" and "Rust" ABIs act the same way in this case -pub fn sys_thread_create(kickoff_addr: u64, entry: fn()) -> usize { +pub fn sys_thread_create(kickoff_addr: u64, entry: fn()) -> isize { let thread = Thread::new_user_thread(process_manager().read().current_process(), VirtAddr::new(kickoff_addr), entry); let id = thread.id(); scheduler().ready(thread); - id + id as isize } -pub fn sys_thread_id() -> usize { - scheduler().current_thread().id() +pub fn sys_thread_id() -> isize { + scheduler().current_thread().id() as isize } -pub fn sys_thread_switch() { +pub fn sys_thread_switch() -> isize { scheduler().switch_thread_no_interrupt(); + 0 } -pub fn sys_thread_sleep(ms: usize) { +pub fn sys_thread_sleep(ms: usize) -> isize { scheduler().sleep(ms); + 0 } -pub fn sys_thread_join(id: usize) { +pub fn sys_thread_join(id: usize) -> isize { scheduler().join(id); + 0 } -pub fn sys_thread_exit() { +pub fn sys_thread_exit() -> isize { scheduler().exit(); + 0 } -pub fn sys_process_execute_binary(name_buffer: *const u8, name_length: usize, args: *const Vec<&str>) -> usize { +pub fn sys_process_execute_binary(name_buffer: *const u8, name_length: usize, args: *const Vec<&str>) -> isize { let app_name = from_utf8(unsafe { slice_from_raw_parts(name_buffer, name_length).as_ref().unwrap() }).unwrap(); match initrd().entries().find(|entry| entry.filename().as_str().unwrap() == app_name) { Some(app) => { let thread = Thread::load_application(app.data(), app_name, unsafe { args.as_ref().unwrap() }); scheduler().ready(Rc::clone(&thread)); - thread.id() + thread.id() as isize } - None => 0, + None => Errno::ENOENT.into(), } } diff --git a/os/kernel/src/syscall/sys_naming.rs b/os/kernel/src/syscall/sys_naming.rs index b2c5cd3..c769186 100644 --- a/os/kernel/src/syscall/sys_naming.rs +++ b/os/kernel/src/syscall/sys_naming.rs @@ -9,7 +9,7 @@ use alloc::vec; use core::ptr::slice_from_raw_parts; use core::str::from_utf8; -use syscall::return_vals::{convert_syscall_result_to_ret_code,SyscallResult,Errno}; +use syscall::return_vals::{convert_syscall_result_to_ret_code}; use crate::naming::name_service; @@ -19,8 +19,7 @@ pub fn sys_mkentry( path_buff: *const u8, path_buff_len: usize, name_buff: *const u8, - name_buff_len: usize, - data: usize, + name_buff_len: usize ) -> isize { let path = from_utf8(unsafe { slice_from_raw_parts(path_buff, path_buff_len) @@ -36,13 +35,5 @@ pub fn sys_mkentry( .unwrap(); let r = name_service::mkentry(path, name, vec![1]); - return convert_syscall_result_to_ret_code(r); -} - -// Wrapper function to convert Result<(), Errno> to SyscallResult -fn convert_result(result: Result<(), Errno>) -> SyscallResult { - match result { - Ok(()) => Ok(0), // Convert the success case to a meaningful u64, e.g., 0 - Err(e) => Err(e), // Forward the error directly - } + convert_syscall_result_to_ret_code(r) } diff --git a/os/kernel/src/syscall/sys_terminal.rs b/os/kernel/src/syscall/sys_terminal.rs index cc84adf..b9b1d5c 100644 --- a/os/kernel/src/syscall/sys_terminal.rs +++ b/os/kernel/src/syscall/sys_terminal.rs @@ -10,16 +10,17 @@ use core::ptr::slice_from_raw_parts; use core::str::from_utf8; use crate::terminal; -pub fn sys_terminal_read() -> usize { +pub fn sys_terminal_read() -> isize { let terminal = terminal(); match terminal.read_byte() { -1 => panic!("Input stream closed!"), - c => c as usize + c => c as isize } } -pub fn sys_terminal_write(buffer: *const u8, length: usize) { +pub fn sys_terminal_write(buffer: *const u8, length: usize) -> isize { let string = from_utf8(unsafe { slice_from_raw_parts(buffer, length).as_ref().unwrap() }).unwrap(); let terminal = terminal(); terminal.write_str(string); + 0 } diff --git a/os/kernel/src/syscall/sys_time.rs b/os/kernel/src/syscall/sys_time.rs index 6532ba7..c759c0c 100644 --- a/os/kernel/src/syscall/sys_time.rs +++ b/os/kernel/src/syscall/sys_time.rs @@ -15,11 +15,11 @@ use uefi::table::runtime::{Time, TimeParams}; use crate::{efi_system_table, timer}; -pub fn sys_get_system_time() -> usize { - timer().systime_ms() +pub fn sys_get_system_time() -> isize { + timer().systime_ms() as isize } -pub fn sys_get_date() -> usize { +pub fn sys_get_date() -> isize { if let Some(efi_system_table) = efi_system_table() { let system_table = efi_system_table.read(); let runtime_services = unsafe { system_table.runtime_services() }; @@ -41,7 +41,7 @@ pub fn sys_get_date() -> usize { DateTime::parse_from_rfc3339(format!("{}-{:0>2}-{:0>2}T{:0>2}:{:0>2}:{:0>2}.{:0>9}{}", time.year(), time.month(), time.day(), time.hour(), time.minute(), time.second(), time.nanosecond(), timezone).as_str()) .expect("Failed to parse date from EFI runtime services") - .timestamp_millis() as usize + .timestamp_millis() as isize } else { 0 } @@ -53,7 +53,7 @@ pub fn sys_get_date() -> usize { 0 } -pub fn sys_set_date(date_ms: usize) -> usize { +pub fn sys_set_date(date_ms: usize) -> isize { if let Some(efi_system_table) = efi_system_table() { let system_table = efi_system_table.write(); let runtime_services_read = unsafe { system_table.runtime_services() }; @@ -73,10 +73,10 @@ pub fn sys_set_date(date_ms: usize) -> usize { }).expect("Failed to create EFI date"); return match unsafe { runtime_services.set_time(&uefi_date) } { - Ok(_) => true as usize, - Err(_) => false as usize, + Ok(_) => true as isize, + Err(_) => false as isize, }; } - false as usize + false as isize } diff --git a/os/kernel/src/syscall/sys_vmem.rs b/os/kernel/src/syscall/sys_vmem.rs index d79b738..f3ce566 100644 --- a/os/kernel/src/syscall/sys_vmem.rs +++ b/os/kernel/src/syscall/sys_vmem.rs @@ -13,7 +13,7 @@ use crate::process_manager; use x86_64::structures::paging::PageTableFlags; -pub fn sys_map_user_heap(size: usize) -> usize { +pub fn sys_map_user_heap(size: usize) -> isize { let process = process_manager().read().current_process(); let code_areas = process.find_vmas(VmaType::Code); let code_area = code_areas.get(0).expect("Process does not have code area!"); @@ -23,6 +23,6 @@ pub fn sys_map_user_heap(size: usize) -> usize { process.address_space().map(heap_area.range(), MemorySpace::User, PageTableFlags::PRESENT | PageTableFlags::WRITABLE | PageTableFlags::USER_ACCESSIBLE); process.add_vma(heap_area); - heap_start.as_u64() as usize + heap_start.as_u64() as isize } diff --git a/os/library/concurrent/Cargo.toml b/os/library/concurrent/Cargo.toml index 09f22fb..b964406 100644 --- a/os/library/concurrent/Cargo.toml +++ b/os/library/concurrent/Cargo.toml @@ -1,5 +1,7 @@ +cargo-features = ["edition2024"] + [package] -edition = "2021" +edition = "2024" name = "concurrent" version = "0.1.0" authors = ["Michael Schöttner , Fabian Ruhland "] diff --git a/os/library/concurrent/src/process.rs b/os/library/concurrent/src/process.rs index 12a605a..db80225 100644 --- a/os/library/concurrent/src/process.rs +++ b/os/library/concurrent/src/process.rs @@ -25,11 +25,11 @@ impl Process { pub fn current() -> Option { let res = syscall(SystemCall::ProcessId, &[]); match res { - Ok(id) => Some(Process::new(id as usize)), - Err(e) => None, + Ok(id) => Some(Process::new(id)), + Err(_) => None, } } pub fn exit() { - syscall(SystemCall::ProcessExit, &[]); + syscall(SystemCall::ProcessExit, &[]).expect("Failed to exit process"); } diff --git a/os/library/graphic/Cargo.toml b/os/library/graphic/Cargo.toml index 6ebbcc3..1c32d36 100644 --- a/os/library/graphic/Cargo.toml +++ b/os/library/graphic/Cargo.toml @@ -1,5 +1,7 @@ +cargo-features = ["edition2024"] + [package] -edition = "2021" +edition = "2024" name = "graphic" version = "0.1.0" authors = ["Michael Schöttner , Fabian Ruhland "] diff --git a/os/library/graphic/src/lfb.rs b/os/library/graphic/src/lfb.rs index 0da992a..3ad68a8 100644 --- a/os/library/graphic/src/lfb.rs +++ b/os/library/graphic/src/lfb.rs @@ -166,28 +166,30 @@ unsafe fn draw_pixel_15_bit(addr: *mut u8, pitch: u32, x: u32, y: u32, color: Co let index = (x + y * (pitch / 2)) as isize; let rgb = color.rgb_15(); - (addr as *mut u16).offset(index).write(rgb); + unsafe { (addr as *mut u16).offset(index).write(rgb); } } unsafe fn draw_pixel_16_bit(addr: *mut u8, pitch: u32, x: u32, y: u32, color: Color) { let index = (x + y * (pitch / 2)) as isize; let rgb = color.rgb_16(); - (addr as *mut u16).offset(index).write(rgb); + unsafe { (addr as *mut u16).offset(index).write(rgb); } } unsafe fn draw_pixel_24_bit(addr: *mut u8, pitch: u32, x: u32, y: u32, color: Color) { let index = (x * 3 + y * pitch) as isize; let rgb = color.rgb_24(); - addr.offset(index).write((rgb & 0xff) as u8); - addr.offset(index + 1).write(((rgb >> 8) & 0xff) as u8); - addr.offset(index + 2).write(((rgb >> 16) & 0xff) as u8); + unsafe { + addr.offset(index).write((rgb & 0xff) as u8); + addr.offset(index + 1).write(((rgb >> 8) & 0xff) as u8); + addr.offset(index + 2).write(((rgb >> 16) & 0xff) as u8); + } } unsafe fn draw_pixel_32_bit(addr: *mut u8, pitch: u32, x: u32, y: u32, color: Color) { let index = (x + y * (pitch / 4)) as isize; let rgb = color.rgb_32(); - (addr as *mut u32).offset(index).write(rgb); + unsafe { (addr as *mut u32).offset(index).write(rgb); } } diff --git a/os/library/libc/Cargo.toml b/os/library/libc/Cargo.toml new file mode 100644 index 0000000..fdcde59 --- /dev/null +++ b/os/library/libc/Cargo.toml @@ -0,0 +1,15 @@ +cargo-features = ["edition2024"] + +[package] +edition = "2024" +name = "libc" +version = "0.1.0" +authors = ["Michael Schöttner , Fabian Ruhland "] + +[dependencies] +# Local dependencies +runtime = { path = "../runtime" } +terminal = { path = "../terminal" } +syscall = { path = "../syscall" } +concurrent = { path = "../concurrent" } +stream = { path = "../stream" } \ No newline at end of file diff --git a/os/library/libc/src/lib.rs b/os/library/libc/src/lib.rs new file mode 100644 index 0000000..7906ad2 --- /dev/null +++ b/os/library/libc/src/lib.rs @@ -0,0 +1,20 @@ +/* ╔═════════════════════════════════════════════════════════════════════════╗ + ║ Module: lib ║ + ╟─────────────────────────────────────────────────────────────────────────╢ + ║ Descr.: Runtime functions for C-applications. ║ + ╟─────────────────────────────────────────────────────────────────────────╢ + ║ Author: Fabian Ruhland, 31.8.2024, HHU ║ + ╚═════════════════════════════════════════════════════════════════════════╝ +*/ +#![no_std] + +use stream::strlen; +use syscall::{syscall, SystemCall}; + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn terminal_write(buffer: *const u8) { + let res = syscall(SystemCall::TerminalWrite, &[buffer as usize, strlen(buffer)]); + if res.is_err() { + panic!("Error while writing to the terminal!"); + } +} \ No newline at end of file diff --git a/os/library/libc/src/runtime.h b/os/library/libc/src/runtime.h new file mode 100644 index 0000000..2170228 --- /dev/null +++ b/os/library/libc/src/runtime.h @@ -0,0 +1,6 @@ +#ifndef TERMINAL_H +#define TERMINAL_H + +void terminal_write(const char *str); + +#endif \ No newline at end of file diff --git a/os/library/naming/Cargo.toml b/os/library/naming/Cargo.toml index 320f0b2..0c55613 100644 --- a/os/library/naming/Cargo.toml +++ b/os/library/naming/Cargo.toml @@ -1,5 +1,7 @@ +cargo-features = ["edition2024"] + [package] -edition = "2021" +edition = "2024" name = "naming" version = "0.1.0" authors = ["Michael Schöttner , Fabian Ruhland "] diff --git a/os/library/runtime/Cargo.toml b/os/library/runtime/Cargo.toml index 7eecd60..b412fce 100644 --- a/os/library/runtime/Cargo.toml +++ b/os/library/runtime/Cargo.toml @@ -1,5 +1,7 @@ +cargo-features = ["edition2024"] + [package] -edition = "2021" +edition = "2024" name = "runtime" version = "0.1.0" authors = ["Michael Schöttner , Fabian Ruhland "] @@ -9,6 +11,7 @@ authors = ["Michael Schöttner , Fabian Ruhland ()) as *const *const Argument; +pub(crate) const ARGC_PTR: *const usize = USER_SPACE_ARG_START as *const usize; +pub(crate) const ARGV_PTR: *const *const u8 = (USER_SPACE_ARG_START + size_of::<*const usize>()) as *const *const u8; pub fn args() -> Args { Args::new() } -#[repr(C, packed)] -struct Argument { - len: usize, - data: u8 -} - -impl Display for Argument { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let slice = slice_from_raw_parts(ptr::from_ref(&self.data), self.len); - let string = unsafe { from_utf8(&*slice).unwrap() }; - - f.write_str(string) - } -} - pub struct Args { index: usize } @@ -47,16 +31,18 @@ impl Iterator for Args { fn next(&mut self) -> Option { unsafe { - let argc = *ARGC_PTR ; + let argc = *ARGC_PTR; if self.index >= argc { return None; } - let arg_ptr = *ARGV_PTR.offset(self.index as isize); - let arg = arg_ptr.as_ref()?; + let arg = *ARGV_PTR.add(self.index); + let len = strlen(arg); self.index += 1; - Some(arg.to_string()) + CStr::from_bytes_with_nul(slice_from_raw_parts(arg, len + 1).as_ref()?) + .map(|cstr| cstr.to_str().expect("Invalid UTF-8 in argument").to_string()) + .ok() } } } \ No newline at end of file diff --git a/os/library/runtime/src/lib.rs b/os/library/runtime/src/lib.rs index 348a732..0855716 100644 --- a/os/library/runtime/src/lib.rs +++ b/os/library/runtime/src/lib.rs @@ -17,8 +17,8 @@ use terminal::{print, println}; use linked_list_allocator::LockedHeap; use syscall::{syscall, SystemCall}; -extern "C" { - fn main(); +unsafe extern "C" { + fn main(argc: isize, argv: *const *const u8) -> isize; } const HEAP_SIZE: usize = 0x100000; @@ -47,7 +47,7 @@ extern "C" fn entry() { } unsafe { - main(); + main(*env::ARGC_PTR as isize, env::ARGV_PTR); } process::exit(); } diff --git a/os/library/stream/Cargo.toml b/os/library/stream/Cargo.toml index 7a5b793..36f55e7 100644 --- a/os/library/stream/Cargo.toml +++ b/os/library/stream/Cargo.toml @@ -1,5 +1,7 @@ +cargo-features = ["edition2024"] + [package] -edition = "2021" +edition = "2024" name = "stream" version = "0.1.0" authors = ["Michael Schöttner , Fabian Ruhland "] \ No newline at end of file diff --git a/os/library/stream/src/lib.rs b/os/library/stream/src/lib.rs index 2a19a44..c0463d8 100644 --- a/os/library/stream/src/lib.rs +++ b/os/library/stream/src/lib.rs @@ -22,3 +22,14 @@ impl Write for dyn OutputStream { Ok(()) } } + +pub fn strlen(str: *const u8) -> usize { + let mut len = 0; + unsafe { + while *str.add(len) != 0 { + len += 1; + } + } + + len +} diff --git a/os/library/syscall/Cargo.toml b/os/library/syscall/Cargo.toml index 60af8ed..2484821 100644 --- a/os/library/syscall/Cargo.toml +++ b/os/library/syscall/Cargo.toml @@ -1,10 +1,11 @@ +cargo-features = ["edition2024"] + [package] -edition = "2021" +edition = "2024" name = "syscall" version = "0.1.0" authors = ["Michael Schöttner , Fabian Ruhland "] - [dependencies] # External depencies num_enum = { version = "0.7", default-features = false } diff --git a/os/library/syscall/src/lib.rs b/os/library/syscall/src/lib.rs index c7377ca..c0acf65 100644 --- a/os/library/syscall/src/lib.rs +++ b/os/library/syscall/src/lib.rs @@ -47,7 +47,7 @@ pub const NUM_SYSCALLS: usize = SystemCall::LastEntryMarker as usize; /// /// Return: Result \ /// success >= 0 \ -/// error, codes defined in consts.rs +/// error, codes defined in consts.rs pub fn syscall(call: SystemCall, args: &[usize]) -> SyscallResult { let ret_code: isize; diff --git a/os/library/syscall/src/return_vals.rs b/os/library/syscall/src/return_vals.rs index 4cd11ec..7aa9465 100644 --- a/os/library/syscall/src/return_vals.rs +++ b/os/library/syscall/src/return_vals.rs @@ -10,7 +10,7 @@ use num_enum::{FromPrimitive, IntoPrimitive}; #[derive(Debug, Copy, Clone, Eq, PartialEq, IntoPrimitive, FromPrimitive)] -#[repr(i64)] +#[repr(isize)] pub enum Errno { #[num_enum(default)] EUNKN = -1, // Unknown error @@ -22,23 +22,24 @@ pub enum Errno { ENOTEMPTY = -90, // Directory not empty } -pub type SyscallResult = ::core::result::Result; +pub type SyscallResult = Result; -pub fn convert_ret_code_to_syscall_result(ret_code: i64) -> SyscallResult { +pub fn convert_ret_code_to_syscall_result(ret_code: isize) -> SyscallResult { if ret_code < 0 { - return Err(Errno::from(ret_code)); + Err(Errno::from(ret_code)) } else { - return Ok(ret_code as usize); + Ok(ret_code as usize) } } pub fn convert_syscall_result_to_ret_code(syscall_result: SyscallResult) -> isize { - let ret_val: i64; + let ret_val: isize; match syscall_result { - Ok(t) => ret_val = t as i64, + Ok(t) => ret_val = t as isize, Err(e) => ret_val = e.into(), } - ret_val as isize + + ret_val } diff --git a/os/library/terminal/Cargo.toml b/os/library/terminal/Cargo.toml index 1981493..38b2dab 100644 --- a/os/library/terminal/Cargo.toml +++ b/os/library/terminal/Cargo.toml @@ -1,5 +1,7 @@ +cargo-features = ["edition2024"] + [package] -edition = "2021" +edition = "2024" name = "terminal" version = "0.1.0" authors = ["Michael Schöttner , Fabian Ruhland "] diff --git a/os/library/time/Cargo.toml b/os/library/time/Cargo.toml index e5a363b..f4dbcd4 100644 --- a/os/library/time/Cargo.toml +++ b/os/library/time/Cargo.toml @@ -1,5 +1,7 @@ +cargo-features = ["edition2024"] + [package] -edition = "2021" +edition = "2024" name = "time" version = "0.1.0" authors = ["Michael Schöttner , Fabian Ruhland "]