diff --git a/.gdbinit-qemu b/.gdbinit-qemu
index ae7aa5e95..febecfe40 100644
--- a/.gdbinit-qemu
+++ b/.gdbinit-qemu
@@ -2,7 +2,7 @@
set architecture armv7
file build/bolthur/kernel/target/raspi/kernel7_qemu.sym
#add-symbol-file build/bolthur/server/platform/raspi/iomem/iomem
-target remote | qemu-system-arm -M raspi2b -cpu cortex-a7 -m 1G -no-reboot -kernel build/bolthur/kernel/target/raspi/kernel7_qemu.img -initrd build-aux/platform/raspi/initrd -dtb config/dts/raspi/bcm2836-raspi-2-b.dtb -drive file=build-aux/platform/raspi/sdcard.img,format=raw -gdb stdio -S
+target remote | qemu-system-arm -M raspi2b -cpu cortex-a7 -m 1G -no-reboot -kernel build/bolthur/kernel/target/raspi/kernel7_qemu.img -initrd build-aux/platform/raspi/initrd -dtb config/dts/raspi/bcm2709-raspi-2-b.dtb -drive file=build-aux/platform/raspi/sdcard.img,format=raw -gdb stdio -S
display /10i $pc
#break _vector_undefined_instruction_handler
#c
diff --git a/.gdbinit-qemu-user b/.gdbinit-qemu-user
index 891123daf..ae92645b0 100644
--- a/.gdbinit-qemu-user
+++ b/.gdbinit-qemu-user
@@ -1,5 +1,5 @@
set architecture armv7
file build/bolthur/server/fs/ext/ext
-target remote | qemu-system-arm -M raspi2b -cpu cortex-a7 -m 1G -no-reboot -kernel ./build/bolthur/kernel/target/raspi/kernel7_qemu.img -initrd build-aux/platform/raspi/initrd -dtb config/dts/raspi/bcm2836-raspi-2-b.dtb -drive file=build-aux/platform/raspi/sdcard2.img,format=raw -append "coherent_pool=1M snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1 bcm2708_fb.fbwidth=1280 bcm2708_fb.fbheight=1024 bcm2708_fb.fbswap=1 vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000 root=/dev/storage/sd1 rootfstype=ext2" -gdb stdio -S
+target remote | qemu-system-arm -M raspi2b -cpu cortex-a7 -m 1G -no-reboot -kernel ./build/bolthur/kernel/target/raspi/kernel7_qemu.img -initrd build-aux/platform/raspi/initrd -dtb config/dts/raspi/bcm2709-raspi-2-b.dtb -drive file=build-aux/platform/raspi/sdcard2.img,format=raw -append "coherent_pool=1M snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1 bcm2708_fb.fbwidth=1280 bcm2708_fb.fbheight=1024 bcm2708_fb.fbswap=1 vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000 root=/dev/storage/sd1 rootfstype=ext2" -gdb stdio -S
display /10i $pc
diff --git a/.idea/editor.xml b/.idea/editor.xml
index f9a237428..a51a79e78 100644
--- a/.idea/editor.xml
+++ b/.idea/editor.xml
@@ -17,7 +17,7 @@
-
+
@@ -56,6 +56,7 @@
+
@@ -117,6 +118,7 @@
+
@@ -137,6 +139,7 @@
+
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 000000000..10d4dfa08
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/kernel.iml b/.idea/kernel.iml
new file mode 100644
index 000000000..8a72e8710
--- /dev/null
+++ b/.idea/kernel.iml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/.idea/markdown.xml b/.idea/markdown.xml
new file mode 100644
index 000000000..c61ea3346
--- /dev/null
+++ b/.idea/markdown.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 91859aca5..50f4a3027 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -23,7 +23,7 @@
-
+
diff --git a/Makefile.am b/Makefile.am
index 83010e199..e884b4915 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -8,27 +8,27 @@ SUBDIRS = bolthur
cppcheck:
cppcheck --quiet -UCMC --inline-suppr --enable=all --force \
--platform=$(CPPCHECK_PLATFORM) \
- --include=$(CPPCHECK_KERNEL_INCLUDE) \
--project=$(CPPCHECK_KERNEL_PROJECT) \
+ --include=$(CPPCHECK_KERNEL_INCLUDE) \
-U__CYGWIN__ -U__APPLE__ -U__GNU_VISIBLE -UASSEMBLER_FILE -UVMS \
-v -j4 --force --max-configs=12 \
--check-level=exhaustive
cppcheck --quiet -UCMC --inline-suppr --enable=all --force \
--platform=$(CPPCHECK_PLATFORM) \
- --include=$(CPPCHECK_LIBRARY_INCLUDE) \
--project=$(CPPCHECK_LIBRARY_PROJECT) \
+ --include=$(CPPCHECK_LIBRARY_INCLUDE) \
-U__CYGWIN__ -U__APPLE__ -UVMS -v -j4 --force --max-configs=12 \
--check-level=exhaustive
cppcheck --quiet -UCMC --inline-suppr --enable=all --force \
--platform=$(CPPCHECK_PLATFORM) \
- --include=$(CPPCHECK_SERVER_INCLUDE) \
--project=$(CPPCHECK_SERVER_PROJECT) \
+ --include=$(CPPCHECK_SERVER_INCLUDE) \
-U__CYGWIN__ -U__APPLE__ -UVMS -v -j4 --force --max-configs=12 \
--check-level=exhaustive
cppcheck --quiet -UCMC --inline-suppr --enable=all --force \
--platform=$(CPPCHECK_PLATFORM) \
- --include=$(CPPCHECK_APPLICATION_INCLUDE) \
--project=$(CPPCHECK_APPLICATION_PROJECT) \
+ --include=$(CPPCHECK_APPLICATION_INCLUDE) \
-U__CYGWIN__ -U__APPLE__ -UVMS -v -j4 --force --max-configs=12 \
--check-level=exhaustive
diff --git a/README b/README
index 37f3b4a52..7bf982ba2 100644
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
kernel
-bolthur/kernel project. Copyright (C) 2018 - 2025 bolthur project
+bolthur/kernel project. Copyright (C) 2018 - 2026 bolthur project
Supported platforms
diff --git a/README.md b/README.md
index bac7e5aa2..2aa6f4d9f 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# kernel
bolthur/kernel project.
-_Copyright (C) 2018 - 2025 bolthur project_
+_Copyright (C) 2018 - 2026 bolthur project_
## Supported platforms
@@ -52,8 +52,8 @@ autoreconf -iv
mkdir build
cd build
### configure with one of the following commands
-../configure --host arm-raspbi2b_r1-bolthur-eabi --enable-device=raspi2b_r1 --enable-debug --enable-output
-../configure --host arm-raspi0_1-bolthur-eabi --enable-device=raspi0_1 --enable-debug --enable-output
+../configure --host=arm-raspi2b_r1-bolthur-eabi --enable-device=raspi2b_r1 --enable-output --enable-silent-rules --with-debug-symbols --with-asan --with-ubsan
+../configure --host=arm-raspi0_1-bolthur-eabi --enable-device=raspi0_1 --enable-output --enable-silent-rules --with-debug-symbols --with-asan --with-ubsan
```
Possible additional parameters to `--host` and `--enable-device`:
@@ -108,13 +108,13 @@ Emulation of the kernel project with qemu during development may be done at all
```bash
# raspberry pi zero kernel emulation
-qemu-system-arm -M raspi0 -cpu arm1176 -m 512M -no-reboot -serial stdio -kernel ./bolthur/kernel/target/raspi/kernel_qemu.img -initrd ../build-aux/platform/raspi/initrd -dtb ../config/dts/raspi/bcm2708-raspi-zero.dtb -drive file=../build-aux/platform/raspi/sdcard.img,format=raw -append "root=/dev/storage/sd1 rootfstype=ext2" -usb -device usb-mouse -device usb-kbd -s -S
+qemu-system-arm -M raspi0 -cpu arm1176 -m 512M -no-reboot -serial stdio -kernel ./bolthur/kernel/target/raspi/kernel_qemu.img -initrd ../build-aux/platform/raspi/initrd -dtb ../config/dts/raspi/bcm2708-raspi-zero.dtb -drive file=../build-aux/platform/raspi/sdcard.img,format=raw -append "root=/dev/storage/sd1 rootfstype=ext2 fbwidth=1280 fbheight=1024" -usb -device usb-mouse -device usb-kbd -device usb-net -s -S
# raspberry pi 2B rev 1 kernel emulation
-qemu-system-arm -M raspi2b -cpu cortex-a7 -m 1G -no-reboot -serial stdio -kernel ./bolthur/kernel/target/raspi/kernel7_qemu.img -initrd ../build-aux/platform/raspi/initrd -dtb ../config/dts/raspi/bcm2709-raspi-2-b.dtb -drive file=../build-aux/platform/raspi/sdcard.img,format=raw -append "bcm2708_fb.fbwidth=1024 bcm2708_fb.fbheight=768 root=/dev/storage/sd1 rootfstype=ext2" -usb -device usb-mouse -device usb-kbd -s -S
+qemu-system-arm -M raspi2b -cpu cortex-a7 -m 1G -no-reboot -serial stdio -kernel ./bolthur/kernel/target/raspi/kernel7_qemu.img -initrd ../build-aux/platform/raspi/initrd -dtb ../config/dts/raspi/bcm2709-raspi-2-b.dtb -drive file=../build-aux/platform/raspi/sdcard.img,format=raw -append "root=/dev/storage/sd1 rootfstype=ext2 fbwidth=1280 fbheight=1024" -usb -device usb-mouse -device usb-kbd -device usb-net -s -S
# raspberry pi 3B kernel emulation
-qemu-system-aarch64 -M raspi3b -cpu cortex-a53 -m 1G -no-reboot -serial stdio -kernel ./bolthur/kernel/target/raspi/kernel8_qemu.img -initrd ../build-aux/platform/raspi/initrd -dtb ../config/dts/raspi/bcm2710-raspi-3-b.dtb -drive file=../build-aux/platform/raspi/sdcard.img,format=raw -append "root=/dev/storage/sd1 rootfstype=ext2" -usb -device usb-mouse -device usb-kbd -s -S
+qemu-system-aarch64 -M raspi3b -cpu cortex-a53 -m 1G -no-reboot -serial stdio -kernel ./bolthur/kernel/target/raspi/kernel8_qemu.img -initrd ../build-aux/platform/raspi/initrd -dtb ../config/dts/raspi/bcm2710-raspi-3-b.dtb -drive file=../build-aux/platform/raspi/sdcard.img,format=raw -append "root=/dev/storage/sd1 rootfstype=ext2 fbwidth=1280 fbheight=1024" -usb -device usb-mouse -device usb-kbd -device usb-net -s -S
```
### Debugging
@@ -132,3 +132,9 @@ The files can be specified by using the parameter `-x`.
```
When starting remote debugging, you need to specify the target, e.g. `target /dev/ttyUSB0` to connect to the running instance. Furthermore, you need to configure the project with option `--enable-debug`.
+
+### Users
+
+Following users are pre generated with image generation:
+- `user` with password `user`
+- `root` with password `root`
diff --git a/bolthur/application/Makefile.am b/bolthur/application/Makefile.am
index 482641f28..39c6643cb 100644
--- a/bolthur/application/Makefile.am
+++ b/bolthur/application/Makefile.am
@@ -1,4 +1,4 @@
ACLOCAL_AMFLAGS = -I ../../build-aux/m4
-SUBDIRS = usr
+SUBDIRS = bin usr
diff --git a/bolthur/application/bin/Makefile.am b/bolthur/application/bin/Makefile.am
new file mode 100644
index 000000000..0d5675606
--- /dev/null
+++ b/bolthur/application/bin/Makefile.am
@@ -0,0 +1,2 @@
+
+SUBDIRS = login
diff --git a/bolthur/application/bin/login/Makefile.am b/bolthur/application/bin/login/Makefile.am
new file mode 100644
index 000000000..984319d8d
--- /dev/null
+++ b/bolthur/application/bin/login/Makefile.am
@@ -0,0 +1,7 @@
+
+AM_CFLAGS = -DPROGRAM_NAME=\"login\"
+
+bin_PROGRAMS = login
+login_SOURCES = \
+ main.c
+login_LDFLAGS = -all-static --static
diff --git a/bolthur/application/bin/login/config.ini b/bolthur/application/bin/login/config.ini
new file mode 100644
index 000000000..934479900
--- /dev/null
+++ b/bolthur/application/bin/login/config.ini
@@ -0,0 +1,3 @@
+[general]
+type=image_root
+path=bin
diff --git a/bolthur/application/bin/login/main.c b/bolthur/application/bin/login/main.c
new file mode 100644
index 000000000..46284f394
--- /dev/null
+++ b/bolthur/application/bin/login/main.c
@@ -0,0 +1,202 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include "../../../server/libauthentication.h"
+
+/**
+ * @brief Child pid
+ */
+pid_t child = 0;
+
+/**
+ * @fn static char* build_env(const char*, const char*)
+ * @brief Helper to build env
+ * @param value environment value
+ * @param prefix prefix
+ * @return
+ */
+static char* build_env( const char* value, const char* prefix ) {
+ const size_t env_len = strlen( value ) + strlen( prefix ) + 1;
+ char* home_env = malloc( env_len );
+ if ( ! home_env ) {
+ return NULL;
+ }
+ memset( home_env, 0, env_len );
+ sprintf( home_env, "%s=%s", prefix, value );
+ return home_env;
+}
+
+/**
+ * @fn int main(int, char*[])
+ * @brief main entry point
+ *
+ * @param argc
+ * @param argv
+ * @return
+ */
+int main( [[maybe_unused]] int argc, [[maybe_unused]] char* argv[] ) {
+ /// FIXME: IMPLEMENT gethostname
+ printf( "%s login!\r\n", "bolthur" );
+ fflush( stdout );
+ // endlessly looping login shell
+ while ( true ) {
+ // allocate space for username
+ char* username = malloc( sizeof( char ) * 1024 );
+ // handle error
+ if ( ! username ) {
+ STARTUP_PRINT( "Unable to allocate memory for username!\r\n" )
+ return -1;
+ }
+ // read username
+ printf( "username: " );
+ fflush( stdout );
+ if ( ! fgets( username, 1024, stdin ) ) {
+ printf( "Login failed\r\n" );
+ fflush( stdout );
+ free( username );
+ continue;
+ }
+ // strip out newline from username
+ if ( strlen( username ) ) {
+ username[ strlen( username ) - 1 ] = '\0';
+ }
+ // drain out newline from stdin
+ char drain[2];
+ fgets( drain, 2, stdin );
+ // read password
+ const char* password = getpass( "password: " );
+ // open authentication device
+ const int fd = open( AUTHENTICATION_DEVICE, O_RDWR );
+ if ( -1 == fd ) {
+ printf( "Login failed\r\n" );
+ fflush( stdout );
+ free( username );
+ continue;
+ }
+ // allocate shared memory
+ const size_t shm_id = _syscall_memory_shared_create( sizeof( authentication_request_request_data_t ) );
+ if ( errno ) {
+ printf( "Login failed\r\n" );
+ fflush( stdout );
+ free( username );
+ close( fd );
+ continue;
+ }
+ // attach shared memory
+ authentication_request_request_data_t *request_data;
+ do {
+ request_data = _syscall_memory_shared_attach( shm_id, ( uintptr_t )NULL );
+ if ( errno ) {
+ continue;
+ }
+ break;
+ } while( true );
+ // allocate request
+ authentication_request_request_t* request = malloc( sizeof( authentication_request_request_t ) );
+ if ( ! request ) {
+ printf( "Login failed\r\n" );
+ fflush( stdout );
+ free( username );
+ close( fd );
+ continue;
+ }
+ // clear out
+ memset( request, 0, sizeof( authentication_request_request_t ) );
+ // copy over stuff
+ strncpy( request_data->user, username, 1023 );
+ strncpy( request_data->password, password, 127 );
+ request->process = getpid();
+ request->shm_id = shm_id;
+ // perform request
+ const int result = ioctl(
+ fd,
+ IOCTL_BUILD_REQUEST(
+ AUTHENTICATE_REQUEST,
+ sizeof( authentication_request_request_t ),
+ IOCTL_RDWR
+ ),
+ request
+ );
+ // handle error
+ if ( -1 == result ) {
+ const int e = errno;
+ printf( "Login failed: %s\r\n", strerror( e ) );
+ fflush( stdout );
+ free( username );
+ free( request );
+ close( fd );
+ _syscall_memory_shared_detach( shm_id );
+ continue;
+ }
+ // fork process
+ child = fork();
+ // handle error
+ if ( 0 > child ) {
+ const int e = errno;
+ printf( "Login failed: %s\r\n", strerror( e ) );
+ fflush( stdout );
+ free( username );
+ free( request );
+ close( fd );
+ _syscall_memory_shared_detach( shm_id );
+ continue;
+ }
+ // child only
+ if ( 0 == child ) {
+ char* base = basename( request_data->pw_shell );
+ if ( ! base ) {
+ exit( 1 );
+ }
+ // build command
+ char* cmd[] = { base, NULL, };
+ // build home env
+ char* home_env = build_env( request_data->pw_home, "HOME=" );
+ if ( ! home_env ) {
+ exit( 1 );
+ }
+ // build shell env
+ char* shell_env = build_env( request_data->pw_shell, "SHELL=" );
+ if ( ! shell_env ) {
+ exit( 1 );
+ }
+ char* env[] = { home_env, shell_env, NULL };
+ // exec to replace
+ if ( -1 == execve( request_data->pw_shell, cmd, env ) ) {
+ exit( 1 );
+ }
+ }
+
+ // free resources
+ free( username );
+ free( request );
+ close( fd );
+ _syscall_memory_shared_detach( shm_id );
+ // wait for rpc while child is existing
+ while ( child ) {
+ _syscall_rpc_wait_for_call();
+ }
+ }
+ // exit success
+ return 0;
+}
diff --git a/bolthur/application/config.h b/bolthur/application/config.h
index 815142ce0..955e992a0 100644
--- a/bolthur/application/config.h
+++ b/bolthur/application/config.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/application/configure.ac b/bolthur/application/configure.ac
index 1cf2017ab..d5a31b548 100644
--- a/bolthur/application/configure.ac
+++ b/bolthur/application/configure.ac
@@ -3,7 +3,7 @@ AC_PREREQ([2.71])
AC_INIT([bolthur-application], [0.1.0-dev], [https://github.com/bolthur/kernel/issues], [bolthur-application], [https://github.com/bolthur/kernel])
-AC_COPYRIGHT([Copyright (C) 2018 - 2025 bolthur project])
+AC_COPYRIGHT([Copyright (C) 2018 - 2026 bolthur project])
AC_CONFIG_AUX_DIR([_aux/config])
AC_CONFIG_MACRO_DIR([../../build-aux/m4])
@@ -51,6 +51,24 @@ AC_ARG_WITH(
[with_debug_debug_symbols=yes]
)
+AC_ARG_WITH(
+ [ubsan],
+ AS_HELP_STRING(
+ [--with-ubsan],
+ [compile with ubsan enabled]
+ ),
+ [with_ubsan_enabled=yes]
+)
+
+AC_ARG_WITH(
+ [asan],
+ AS_HELP_STRING(
+ [--with-asan],
+ [compile with asan enabled]
+ ),
+ [with_asan_enabled=yes]
+)
+
# enable output and enable remote debugging together is not allowed
AS_IF([test "x$enable_debug" == "xyes" && test "x$enable_release" == "xyes"], [
AC_MSG_ERROR([Enabled debug and release are not possible at the same time])
@@ -133,6 +151,8 @@ AM_CONDITIONAL([IS64], [test $executable_format -eq 64])
AC_CONFIG_FILES([
Makefile
+ bin/Makefile
+ bin/login/Makefile
usr/Makefile
usr/lib/Makefile
usr/lib/ld-bolthur/Makefile
diff --git a/bolthur/application/usr/lib/ld-bolthur/main.c b/bolthur/application/usr/lib/ld-bolthur/main.c
index 13e85e277..7098b998a 100644
--- a/bolthur/application/usr/lib/ld-bolthur/main.c
+++ b/bolthur/application/usr/lib/ld-bolthur/main.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/application/usr/lib/ld-bolthur/tmp/_dl-int.h b/bolthur/application/usr/lib/ld-bolthur/tmp/_dl-int.h
index 744d366a5..0a8960ab9 100644
--- a/bolthur/application/usr/lib/ld-bolthur/tmp/_dl-int.h
+++ b/bolthur/application/usr/lib/ld-bolthur/tmp/_dl-int.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -19,7 +19,6 @@
// FIXME: RESTRICT TO COMPILING NEWLIB ONLY IF NECESSARY
-#include
#include
#include
diff --git a/bolthur/application/usr/lib/ld-bolthur/tmp/dl.c b/bolthur/application/usr/lib/ld-bolthur/tmp/dl.c
index cff84b67b..b246c7a40 100644
--- a/bolthur/application/usr/lib/ld-bolthur/tmp/dl.c
+++ b/bolthur/application/usr/lib/ld-bolthur/tmp/dl.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -616,7 +616,6 @@ dl_image_handle_ptr_t dl_load_entry(
// Load headers ( either one or two )
char* memory = NULL;
- char* data = NULL;
if ( 1 == phdr_load_count ) {
offset = ( off_t )ROUND_DOWN_TO_FULL_PAGE( load_header[ 0 ].p_offset );
// FIXME: MAP SECTION IN CASE OF DEPENDENCY INTO SHARED AREA
@@ -700,7 +699,7 @@ dl_image_handle_ptr_t dl_load_entry(
)
// map data section again with only file size
// FIXME: MAP SECTION IN CASE OF DEPENDENCY INTO SHARED AREA
- data = dl_map_load_section(
+ char* data = dl_map_load_section(
( void* )( memory + data_address - text_address ),
data_file_size,
load_header[ 1 ].p_flags,
diff --git a/bolthur/application/usr/lib/ld-bolthur/tmp/stub.S b/bolthur/application/usr/lib/ld-bolthur/tmp/stub.S
index 1bbcdb976..8ab280bbc 100644
--- a/bolthur/application/usr/lib/ld-bolthur/tmp/stub.S
+++ b/bolthur/application/usr/lib/ld-bolthur/tmp/stub.S
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch.h b/bolthur/kernel/arch.h
index a377f1645..71729b2fc 100644
--- a/bolthur/kernel/arch.h
+++ b/bolthur/kernel/arch.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/arch.c b/bolthur/kernel/arch/arm/arch.c
index 2cf9d91ec..c9e17ca11 100644
--- a/bolthur/kernel/arch/arm/arch.c
+++ b/bolthur/kernel/arch/arm/arch.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/barrier.h b/bolthur/kernel/arch/arm/barrier.h
index 28779fd86..ad67138e7 100644
--- a/bolthur/kernel/arch/arm/barrier.h
+++ b/bolthur/kernel/arch/arm/barrier.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/cache.h b/bolthur/kernel/arch/arm/cache.h
index a5c7901e1..402362e85 100644
--- a/bolthur/kernel/arch/arm/cache.h
+++ b/bolthur/kernel/arch/arm/cache.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/debug/cache.c b/bolthur/kernel/arch/arm/debug/cache.c
index 6f82d61f4..2e466ad89 100644
--- a/bolthur/kernel/arch/arm/debug/cache.c
+++ b/bolthur/kernel/arch/arm/debug/cache.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/debug/cache.h b/bolthur/kernel/arch/arm/debug/cache.h
index 3083c84f1..aa1cfc930 100644
--- a/bolthur/kernel/arch/arm/debug/cache.h
+++ b/bolthur/kernel/arch/arm/debug/cache.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/delay.c b/bolthur/kernel/arch/arm/delay.c
index 8fb98f06d..8366eba39 100644
--- a/bolthur/kernel/arch/arm/delay.c
+++ b/bolthur/kernel/arch/arm/delay.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/delay.h b/bolthur/kernel/arch/arm/delay.h
index e2d8bdc5c..8f6612a69 100644
--- a/bolthur/kernel/arch/arm/delay.h
+++ b/bolthur/kernel/arch/arm/delay.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/elf.c b/bolthur/kernel/arch/arm/elf.c
index e7e412b7e..6ef6ba86c 100644
--- a/bolthur/kernel/arch/arm/elf.c
+++ b/bolthur/kernel/arch/arm/elf.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -23,15 +23,14 @@
#endif
/**
+ * @fn bool elf_arch_check(uintptr_t)
* @brief Check elf header for execution
- *
* @param elf header address to check
* @return true elf header valid
* @return false elf header invalid
*/
-bool elf_arch_check( uintptr_t elf ) {
- Elf32_Ehdr* header = ( Elf32_Ehdr* )elf;
-
+bool elf_arch_check( const uintptr_t elf ) {
+ auto const header = ( Elf32_Ehdr* )elf;
// check machine to match kernel
#if defined( ELF32 )
if ( EM_ARM != header->e_machine ) {
@@ -60,7 +59,6 @@ bool elf_arch_check( uintptr_t elf ) {
return false;
}
#endif
-
// return success
return true;
}
diff --git a/bolthur/kernel/arch/arm/firmware.c b/bolthur/kernel/arch/arm/firmware.c
index 539d24f2e..10e3844d3 100644
--- a/bolthur/kernel/arch/arm/firmware.c
+++ b/bolthur/kernel/arch/arm/firmware.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -29,7 +29,7 @@
* @fn void firmware_startup_init(void)
* @brief Handle firmware information related startup init
*/
-void firmware_startup_init( void ) {
+__bootstrap void firmware_startup_init( void ) {
// transfer to uintptr_t
uintptr_t atag_fdt = ( uintptr_t )firmware_info.atag_fdt;
// first mapping before access
diff --git a/bolthur/kernel/arch/arm/firmware.h b/bolthur/kernel/arch/arm/firmware.h
index 3b2f07b62..6ba4eebe0 100644
--- a/bolthur/kernel/arch/arm/firmware.h
+++ b/bolthur/kernel/arch/arm/firmware.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/initrd.c b/bolthur/kernel/arch/arm/initrd.c
index 82f354888..90e6862d0 100644
--- a/bolthur/kernel/arch/arm/initrd.c
+++ b/bolthur/kernel/arch/arm/initrd.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -27,13 +27,13 @@
/**
* @brief Prepare for initrd usage
*/
-void initrd_startup_init( void ) {
+__bootstrap void initrd_startup_init( void ) {
// transfer to uintptr_t
- uintptr_t atag_fdt = ( uintptr_t )firmware_info.atag_fdt;
+ const uintptr_t atag_fdt = ( uintptr_t )firmware_info.atag_fdt;
// handle atag
if ( atag_check( atag_fdt ) ) {
- atag_t* ramdisk = atag_find( ( atag_t* )atag_fdt, ATAG_TAG_INITRD2 );
+ const atag_t* ramdisk = atag_find( ( atag_t* )atag_fdt, ATAG_TAG_INITRD2 );
if ( ramdisk ) {
initrd_set_start_address( ramdisk->initrd.start );
initrd_set_size( ramdisk->initrd.size );
@@ -46,14 +46,13 @@ void initrd_startup_init( void ) {
}
} else if ( 0 == fdt_check_header( ( void* )atag_fdt ) ) {
// get chosen node
- int32_t node = fdt_path_offset( ( void* )atag_fdt, "/chosen" );
- uint32_t* prop;
+ const int32_t node = fdt_path_offset( ( void* )atag_fdt, "/chosen" );
int len;
uintptr_t initrd_start = 0;
uintptr_t initrd_end = 0;
// try to get property initrd start
- prop = ( uint32_t* )fdt_getprop(
+ const uint32_t* prop = ( uint32_t* )fdt_getprop(
( void* )atag_fdt,
node,
"linux,initrd-start",
@@ -93,7 +92,7 @@ void initrd_startup_init( void ) {
// map initrd
if ( initrd_exist() ) {
uintptr_t start = initrd_get_start_address();
- uintptr_t end = initrd_get_end_address();
+ const uintptr_t end = initrd_get_end_address();
// map 1:1
while ( start < end ) {
virt_startup_map( start, start );
diff --git a/bolthur/kernel/arch/arm/interrupt.c b/bolthur/kernel/arch/arm/interrupt.c
index cbcab6716..f680c78f2 100644
--- a/bolthur/kernel/arch/arm/interrupt.c
+++ b/bolthur/kernel/arch/arm/interrupt.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/interrupt/vector.h b/bolthur/kernel/arch/arm/interrupt/vector.h
index 72cd684c0..84183b6a4 100644
--- a/bolthur/kernel/arch/arm/interrupt/vector.h
+++ b/bolthur/kernel/arch/arm/interrupt/vector.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/io.c b/bolthur/kernel/arch/arm/io.c
index a2fcf6ed7..19e3512b4 100644
--- a/bolthur/kernel/arch/arm/io.c
+++ b/bolthur/kernel/arch/arm/io.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/mm/virt.c b/bolthur/kernel/arch/arm/mm/virt.c
index e3da937fc..8d35a510b 100644
--- a/bolthur/kernel/arch/arm/mm/virt.c
+++ b/bolthur/kernel/arch/arm/mm/virt.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/mm/virt.h b/bolthur/kernel/arch/arm/mm/virt.h
index e10656ec8..102a9ccc2 100644
--- a/bolthur/kernel/arch/arm/mm/virt.h
+++ b/bolthur/kernel/arch/arm/mm/virt.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/mm/virt/long.h b/bolthur/kernel/arch/arm/mm/virt/long.h
index 096f35b90..4041413ad 100644
--- a/bolthur/kernel/arch/arm/mm/virt/long.h
+++ b/bolthur/kernel/arch/arm/mm/virt/long.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/mm/virt/short.h b/bolthur/kernel/arch/arm/mm/virt/short.h
index 10eb8c5e5..784ec3057 100644
--- a/bolthur/kernel/arch/arm/mm/virt/short.h
+++ b/bolthur/kernel/arch/arm/mm/virt/short.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/stack.c b/bolthur/kernel/arch/arm/stack.c
index 0e487231b..b3c42ad5d 100644
--- a/bolthur/kernel/arch/arm/stack.c
+++ b/bolthur/kernel/arch/arm/stack.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -30,8 +30,8 @@ extern void stack_supervisor_mode( void );
* @return true
* @return false
*/
-bool stack_is_kernel( uintptr_t address ) {
- uintptr_t stack_start = ( uintptr_t )&stack_supervisor_mode;
- uintptr_t stack_end = stack_start + STACK_SIZE;
+bool stack_is_kernel( const uintptr_t address ) {
+ const uintptr_t stack_start = ( uintptr_t )&stack_supervisor_mode;
+ const uintptr_t stack_end = stack_start + STACK_SIZE;
return stack_start <= address && stack_end > address;
}
diff --git a/bolthur/kernel/arch/arm/stack.h b/bolthur/kernel/arch/arm/stack.h
index 6c728c7a2..fea8dd084 100644
--- a/bolthur/kernel/arch/arm/stack.h
+++ b/bolthur/kernel/arch/arm/stack.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v6/barrier.c b/bolthur/kernel/arch/arm/v6/barrier.c
index b2f14fbe8..1a8dfe498 100644
--- a/bolthur/kernel/arch/arm/v6/barrier.c
+++ b/bolthur/kernel/arch/arm/v6/barrier.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/arch.c b/bolthur/kernel/arch/arm/v7/arch.c
index 9b53eef92..5eca536c1 100644
--- a/bolthur/kernel/arch/arm/v7/arch.c
+++ b/bolthur/kernel/arch/arm/v7/arch.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/barrier.c b/bolthur/kernel/arch/arm/v7/barrier.c
index fc7997c81..e15c143a4 100644
--- a/bolthur/kernel/arch/arm/v7/barrier.c
+++ b/bolthur/kernel/arch/arm/v7/barrier.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/cache.c b/bolthur/kernel/arch/arm/v7/cache.c
index b886d043c..544834555 100644
--- a/bolthur/kernel/arch/arm/v7/cache.c
+++ b/bolthur/kernel/arch/arm/v7/cache.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/cpu.h b/bolthur/kernel/arch/arm/v7/cpu.h
index c6548b743..0e9bd1a91 100644
--- a/bolthur/kernel/arch/arm/v7/cpu.h
+++ b/bolthur/kernel/arch/arm/v7/cpu.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -104,7 +104,7 @@
} cpu_register_map_t;
#if defined( ARM_CPU_HAS_NEON )
- #define DUMP_REGISTER( context ) \
+ #define DUMP_REGISTER( context ) { \
DEBUG_OUTPUT( "CPU register dump:\r\n" ) \
DEBUG_OUTPUT( " r0: %#"PRIx32", r1: %#"PRIx32", r2: %#"PRIx32", r3: %#"PRIx32"\r\n", ( ( cpu_register_context_t* )context )->reg.r0, ( ( cpu_register_context_t* )context )->reg.r1, ( ( cpu_register_context_t* )context )->reg.r2, ( ( cpu_register_context_t* )context )->reg.r3 ) \
DEBUG_OUTPUT( " r4: %#"PRIx32", r5: %#"PRIx32", r6: %#"PRIx32", r7: %#"PRIx32"\r\n", ( ( cpu_register_context_t* )context )->reg.r4, ( ( cpu_register_context_t* )context )->reg.r5, ( ( cpu_register_context_t* )context )->reg.r6, ( ( cpu_register_context_t* )context )->reg.r7 ) \
@@ -128,7 +128,7 @@
DEBUG_OUTPUT( "d24: %#"PRIx64", d25: %#"PRIx64"\r\n", ( ( cpu_register_context_t* )context )->reg.neon[ 24 ], ( ( cpu_register_context_t* )context )->reg.neon[ 25 ] ) \
DEBUG_OUTPUT( "d26: %#"PRIx64", d27: %#"PRIx64"\r\n", ( ( cpu_register_context_t* )context )->reg.neon[ 26 ], ( ( cpu_register_context_t* )context )->reg.neon[ 27 ] ) \
DEBUG_OUTPUT( "d28: %#"PRIx64", d29: %#"PRIx64"\r\n", ( ( cpu_register_context_t* )context )->reg.neon[ 28 ], ( ( cpu_register_context_t* )context )->reg.neon[ 29 ] ) \
- DEBUG_OUTPUT( "d30: %#"PRIx64", d31: %#"PRIx64"\r\n", ( ( cpu_register_context_t* )context )->reg.neon[ 30 ], ( ( cpu_register_context_t* )context )->reg.neon[ 31 ] )
+ DEBUG_OUTPUT( "d30: %#"PRIx64", d31: %#"PRIx64"\r\n", ( ( cpu_register_context_t* )context )->reg.neon[ 30 ], ( ( cpu_register_context_t* )context )->reg.neon[ 31 ] ) }
#else
#define DUMP_REGISTER( context ) \
DEBUG_OUTPUT( \
diff --git a/bolthur/kernel/arch/arm/v7/debug/barrier.c b/bolthur/kernel/arch/arm/v7/debug/barrier.c
index 644b31204..d66a1a868 100644
--- a/bolthur/kernel/arch/arm/v7/debug/barrier.c
+++ b/bolthur/kernel/arch/arm/v7/debug/barrier.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/debug/breakpoint.c b/bolthur/kernel/arch/arm/v7/debug/breakpoint.c
index 4787d5b06..bcba20677 100644
--- a/bolthur/kernel/arch/arm/v7/debug/breakpoint.c
+++ b/bolthur/kernel/arch/arm/v7/debug/breakpoint.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/debug/cache.c b/bolthur/kernel/arch/arm/v7/debug/cache.c
index e60b5b3f0..6d1470b11 100644
--- a/bolthur/kernel/arch/arm/v7/debug/cache.c
+++ b/bolthur/kernel/arch/arm/v7/debug/cache.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/debug/debug.c b/bolthur/kernel/arch/arm/v7/debug/debug.c
index 3d15295fd..7067c9f8d 100644
--- a/bolthur/kernel/arch/arm/v7/debug/debug.c
+++ b/bolthur/kernel/arch/arm/v7/debug/debug.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/debug/debug.h b/bolthur/kernel/arch/arm/v7/debug/debug.h
index 92525492a..c9b9bd643 100644
--- a/bolthur/kernel/arch/arm/v7/debug/debug.h
+++ b/bolthur/kernel/arch/arm/v7/debug/debug.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,8 +20,6 @@
#ifndef _ARCH_ARM_V7_DEBUG_DEBUG_H
#define _ARCH_ARM_V7_DEBUG_DEBUG_H
-#include
-
bool debug_check_data_fault_status( void );
bool debug_check_instruction_fault( void );
bool debug_is_debug_exception( void );
diff --git a/bolthur/kernel/arch/arm/v7/debug/disasm.c b/bolthur/kernel/arch/arm/v7/debug/disasm.c
index 8cb9215fe..1689d62a6 100644
--- a/bolthur/kernel/arch/arm/v7/debug/disasm.c
+++ b/bolthur/kernel/arch/arm/v7/debug/disasm.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/debug/gdb.c b/bolthur/kernel/arch/arm/v7/debug/gdb.c
index 20d6b6122..6dca7ad08 100644
--- a/bolthur/kernel/arch/arm/v7/debug/gdb.c
+++ b/bolthur/kernel/arch/arm/v7/debug/gdb.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/fpu.S b/bolthur/kernel/arch/arm/v7/fpu.S
index d26262efe..6f3bee4ca 100644
--- a/bolthur/kernel/arch/arm/v7/fpu.S
+++ b/bolthur/kernel/arch/arm/v7/fpu.S
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/interrupt/handler.S b/bolthur/kernel/arch/arm/v7/interrupt/handler.S
index 4c4e9da0f..91f7c4287 100644
--- a/bolthur/kernel/arch/arm/v7/interrupt/handler.S
+++ b/bolthur/kernel/arch/arm/v7/interrupt/handler.S
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -94,7 +94,7 @@ IMPORT( task_thread_current_thread )
\privileged
.endm
-.macro push_register name:req, mode:req, fixup:req, thumb_offset:req
+.macro push_register name:req, mode:req, fixup:req
// privileged / unprivileged switch
privileged_unprivileged_switch \
4, \
@@ -108,7 +108,8 @@ _\name\()_entry_unprivileged:
get_thread_context lr
// save registers
- stmia lr, { r0 - r14 }^
+ stm lr, { r0 - r14 }^
+ // push fpu register
push_fpu_register lr
// get pushed lr and fill it into struct
@@ -118,23 +119,6 @@ _\name\()_entry_unprivileged:
ldr r0, [ sp, #4 ]
str r0, [ lr, #SPSR_OFFSET ]
- // mask mode only for comparison
- and r0, #CPSR_THUMB
- // compare to passed mode
- cmp r0, #CPSR_THUMB
- // handle thumb mode
- beq _\name\()_entry_unprivileged_thumb
- // handle arm_mode
- bne _\name\()_entry_unprivileged_arm
-
- // thumb entry
- _\name\()_entry_unprivileged_thumb:
- ldr r0, [ lr, #PC_OFFSET ]
- add r0, #\thumb_offset
- str r0, [ lr, #PC_OFFSET ]
- // arm entry
- _\name\()_entry_unprivileged_arm:
-
// adjust stack pointer back
add sp, #8
@@ -149,7 +133,8 @@ _\name\()_entry_privileged:
// allocate space for context structure
sub sp, #STACK_FRAME_SIZE
// save registers to stack
- stmia sp, { r0 - r12 }
+ stmia sp!, { r0 - r12 }
+ sub sp, #SP_OFFSET
push_fpu_register sp
// get pushed lr and fill it into struct
ldr r0, [ sp, #PRIVILEGED_PC_OFFSET ]
@@ -230,11 +215,11 @@ _\name\()_exit_privileged:
_\name\()_exit_finished:
.endm
-.macro exception_handler fixup:req, thumb_offset:req, handler:req, mode:req, name:req, nested:req
+.macro exception_handler fixup:req, handler:req, mode:req, name:req, nested:req
// switch to svc mode with fixup
switch_mode \mode, \fixup
// push register
- push_register \name, \mode, \fixup, \thumb_offset
+ push_register \name, \mode, \fixup
// remote debugging
#if defined( REMOTE_DEBUG )
@@ -257,7 +242,7 @@ _\name\()_exit_finished:
stack_unwind r0, r1, sp
// ensure stack alignment
- stack_wind r0, r1 sp
+ stack_wind r0, r1, sp
// enable interrupts
.ifc \nested, all
cpsie iaf
@@ -304,11 +289,11 @@ _\name\()_exit_finished:
// start with first fpu registers
add \register, #NEON_REGISTER_START
// backup fpu registers
- vstmia \register!, { d0 - d15 }
- vstmia \register!, { d16 - d31 }
- // restore passed register to point to begin
- sub \register, #STACK_FRAME_SIZE
+ vstmia.64 \register!, { d0 - d15 }
+ vstmia.64 \register!, { d16 - d31 }
#endif
+ // restore passed register to point to begin
+ sub \register, #STACK_FRAME_SIZE
.endm
.macro pop_fpu_register register:req
@@ -319,9 +304,9 @@ _\name\()_exit_finished:
// start with first fpu registers
add \register, #NEON_REGISTER_START
// restore fpu registers
- vldmia \register!, { d0 - d15 }
- vldmia \register!, { d16 - d31 }
- // restore passed register to point to begin
- sub \register, #STACK_FRAME_SIZE
+ vldmia.64 \register!, { d0 - d15 }
+ vldmia.64 \register!, { d16 - d31 }
#endif
+ // restore passed register to point to begin
+ sub \register, #STACK_FRAME_SIZE
.endm
diff --git a/bolthur/kernel/arch/arm/v7/interrupt/handler/data.c b/bolthur/kernel/arch/arm/v7/interrupt/handler/data.c
index 5c4b40c72..693491e6f 100644
--- a/bolthur/kernel/arch/arm/v7/interrupt/handler/data.c
+++ b/bolthur/kernel/arch/arm/v7/interrupt/handler/data.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -17,6 +17,8 @@
* along with bolthur/kernel. If not, see .
*/
+#define PRINT_EXCEPTION
+
#include "../../../../../lib/assert.h"
#include "../../../../../lib/inttypes.h"
#if defined( REMOTE_DEBUG )
@@ -58,7 +60,7 @@ static uint32_t nested_data_abort = 0;
DEBUG_OUTPUT( "cpu = %p\r\n", cpu )
#endif
// get event origin
- event_origin_t origin = EVENT_DETERMINE_ORIGIN( cpu );
+ const event_origin_t origin = EVENT_DETERMINE_ORIGIN( cpu );
// debug output
#if defined( PRINT_EXCEPTION )
DEBUG_OUTPUT( "origin = %d\r\n", origin )
@@ -79,9 +81,12 @@ static uint32_t nested_data_abort = 0;
)
)
if (EVENT_ORIGIN_USER == origin) {
- DEBUG_OUTPUT("thread context = %p, global user context = %p\r\n",
- (void*)task_thread_current_thread->process->virtual_context,
- (void*)virt_current_user_context)
+ DEBUG_OUTPUT( "thread context = %p, global user context = %p\r\n",
+ ( void* )task_thread_current_thread->process->virtual_context,
+ ( void* )virt_current_user_context )
+ DEBUG_OUTPUT( "task_thread_current_thread->stack_virtual = %"PRIxPTR" / %zx\r\n",
+ task_thread_current_thread->stack_virtual,
+ task_thread_current_thread->stack_size )
}
// dump context
DUMP_REGISTER( interrupt_get_context( cpu ) )
diff --git a/bolthur/kernel/arch/arm/v7/interrupt/handler/fiq.c b/bolthur/kernel/arch/arm/v7/interrupt/handler/fiq.c
index 9cf82e559..88873585b 100644
--- a/bolthur/kernel/arch/arm/v7/interrupt/handler/fiq.c
+++ b/bolthur/kernel/arch/arm/v7/interrupt/handler/fiq.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -43,7 +43,7 @@ void vector_fast_interrupt_handler( cpu_register_context_t* cpu ) {
nested_fast_interrupt++;
assert( nested_fast_interrupt < INTERRUPT_NESTED_MAX )
// get event origin
- event_origin_t origin = EVENT_DETERMINE_ORIGIN( cpu );
+ const event_origin_t origin = EVENT_DETERMINE_ORIGIN( cpu );
// get context
cpu = interrupt_get_context( cpu );
// debug output
diff --git a/bolthur/kernel/arch/arm/v7/interrupt/handler/irq.c b/bolthur/kernel/arch/arm/v7/interrupt/handler/irq.c
index bd1badf71..c90952950 100644
--- a/bolthur/kernel/arch/arm/v7/interrupt/handler/irq.c
+++ b/bolthur/kernel/arch/arm/v7/interrupt/handler/irq.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -45,7 +45,7 @@ void vector_interrupt_handler( cpu_register_context_t* cpu ) {
nested_interrupt++;
assert( nested_interrupt < INTERRUPT_NESTED_MAX )
// get event origin
- event_origin_t origin = EVENT_DETERMINE_ORIGIN( cpu );
+ const event_origin_t origin = EVENT_DETERMINE_ORIGIN( cpu );
// get context
cpu = interrupt_get_context( cpu );
// debug output
diff --git a/bolthur/kernel/arch/arm/v7/interrupt/handler/prefetch.c b/bolthur/kernel/arch/arm/v7/interrupt/handler/prefetch.c
index 0fd46d802..6cc47bae6 100644
--- a/bolthur/kernel/arch/arm/v7/interrupt/handler/prefetch.c
+++ b/bolthur/kernel/arch/arm/v7/interrupt/handler/prefetch.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -61,7 +61,7 @@ void vector_prefetch_abort_handler( cpu_register_context_t* cpu ) {
DEBUG_OUTPUT( "cpu = %p\r\n", cpu )
#endif
// get event origin
- event_origin_t origin = EVENT_DETERMINE_ORIGIN( cpu );
+ const event_origin_t origin = EVENT_DETERMINE_ORIGIN( cpu );
// debug output
#if defined( PRINT_EXCEPTION )
DEBUG_OUTPUT( "origin = %d\r\n", origin )
diff --git a/bolthur/kernel/arch/arm/v7/interrupt/handler/svc.c b/bolthur/kernel/arch/arm/v7/interrupt/handler/svc.c
index 61daae8d7..b15990900 100644
--- a/bolthur/kernel/arch/arm/v7/interrupt/handler/svc.c
+++ b/bolthur/kernel/arch/arm/v7/interrupt/handler/svc.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -46,7 +46,7 @@ void vector_svc_handler( cpu_register_context_t* cpu ) {
DEBUG_OUTPUT( "cpu = %p\r\n", cpu )
#endif
// get event origin
- event_origin_t origin = EVENT_DETERMINE_ORIGIN( cpu );
+ const event_origin_t origin = EVENT_DETERMINE_ORIGIN( cpu );
// debug output
#if defined( PRINT_EXCEPTION )
DEBUG_OUTPUT( "origin = %d\r\n", origin )
@@ -83,7 +83,7 @@ void vector_svc_handler( cpu_register_context_t* cpu ) {
DEBUG_OUTPUT( "cpsr = %#"PRIx32"\r\n", cpsr )
#endif
// handle bound interrupt handlers
- interrupt_handle( ( uint8_t )svc_num, INTERRUPT_SOFTWARE, cpu );
+ interrupt_handle( ( uint8_t )svc_num, INTERRUPT_SOFTWARE, cpu, false );
// enqueue cleanup
event_enqueue( EVENT_INTERRUPT_CLEANUP, origin );
// debug output
diff --git a/bolthur/kernel/arch/arm/v7/interrupt/handler/undefined.c b/bolthur/kernel/arch/arm/v7/interrupt/handler/undefined.c
index 3b10557fd..844c80918 100644
--- a/bolthur/kernel/arch/arm/v7/interrupt/handler/undefined.c
+++ b/bolthur/kernel/arch/arm/v7/interrupt/handler/undefined.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -45,7 +45,7 @@ void vector_undefined_instruction_handler( cpu_register_context_t* cpu ) {
nested_undefined++;
assert( nested_undefined < INTERRUPT_NESTED_MAX )
// get event origin
- event_origin_t origin = EVENT_DETERMINE_ORIGIN( cpu );
+ const event_origin_t origin = EVENT_DETERMINE_ORIGIN( cpu );
// get context
cpu = interrupt_get_context( cpu );
// debug output
@@ -65,7 +65,7 @@ void vector_undefined_instruction_handler( cpu_register_context_t* cpu ) {
if ( EVENT_ORIGIN_KERNEL == origin ) {
PANIC( "Undefined instruction from kernel" )
// try to restore from rpc call
- } else if ( EVENT_ORIGIN_USER == origin ) {
+ } else {
// debug output
#if defined( PRINT_EXCEPTION )
DEBUG_OUTPUT( "Undefined instruction within thread -> kill!\r\n" )
diff --git a/bolthur/kernel/arch/arm/v7/interrupt/stub.S b/bolthur/kernel/arch/arm/v7/interrupt/stub.S
index e9b5b9e60..8edb7d42d 100644
--- a/bolthur/kernel/arch/arm/v7/interrupt/stub.S
+++ b/bolthur/kernel/arch/arm/v7/interrupt/stub.S
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -68,22 +68,22 @@ IMPORT( vector_interrupt_handler )
IMPORT( vector_fast_interrupt_handler )
_vector_undefined_instruction_handler:
- exception_handler 4, 2, vector_undefined_instruction_handler, CPSR_MODE_SUPERVISOR, vector_undefined, "none"
+ exception_handler 4, vector_undefined_instruction_handler, CPSR_MODE_SUPERVISOR, vector_undefined, "none"
_vector_svc_handler:
- exception_handler 4, 2, vector_svc_handler, CPSR_MODE_SUPERVISOR, vector_svc, "none"
+ exception_handler 4, vector_svc_handler, CPSR_MODE_SUPERVISOR, vector_svc, "none"
_vector_prefetch_abort_handler:
- exception_handler 4, 0, vector_prefetch_abort_handler, CPSR_MODE_SUPERVISOR, vector_prefetch_abort, "none"
+ exception_handler 4, vector_prefetch_abort_handler, CPSR_MODE_SUPERVISOR, vector_prefetch_abort, "none"
_vector_data_abort_handler:
- exception_handler 8, 0, vector_data_abort_handler, CPSR_MODE_SUPERVISOR, vector_data_abort, "none"
+ exception_handler 8, vector_data_abort_handler, CPSR_MODE_SUPERVISOR, vector_data_abort, "none"
_vector_interrupt_handler:
- exception_handler 4, 0, vector_interrupt_handler, CPSR_MODE_SUPERVISOR, vector_interrupt, "none"
+ exception_handler 4, vector_interrupt_handler, CPSR_MODE_SUPERVISOR, vector_interrupt, "none"
_vector_fast_interrupt_handler:
- exception_handler 4, 0, vector_fast_interrupt_handler, CPSR_MODE_SUPERVISOR, vector_fast_interrupt, "none"
+ exception_handler 4, vector_fast_interrupt_handler, CPSR_MODE_SUPERVISOR, vector_fast_interrupt, "none"
EXPORT( interrupt_vector_table )
.balign 32
diff --git a/bolthur/kernel/arch/arm/v7/interrupt/vector.c b/bolthur/kernel/arch/arm/v7/interrupt/vector.c
index a5de95bb2..d0058bf0d 100644
--- a/bolthur/kernel/arch/arm/v7/interrupt/vector.c
+++ b/bolthur/kernel/arch/arm/v7/interrupt/vector.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/interrupt/vector.h b/bolthur/kernel/arch/arm/v7/interrupt/vector.h
index fc40321d1..2a7b3aa74 100644
--- a/bolthur/kernel/arch/arm/v7/interrupt/vector.h
+++ b/bolthur/kernel/arch/arm/v7/interrupt/vector.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/mm/virt.c b/bolthur/kernel/arch/arm/v7/mm/virt.c
index 40dc02b38..ff6c4fb6e 100644
--- a/bolthur/kernel/arch/arm/v7/mm/virt.c
+++ b/bolthur/kernel/arch/arm/v7/mm/virt.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -278,8 +278,8 @@ virt_context_t* virt_create_context( virt_context_type_t type ) {
return NULL;
}
// allocate bitmap for lookup
- uintptr_t min = virt_get_context_min_address( context );
- uintptr_t max = virt_get_context_max_address( context );
+ const uintptr_t min = virt_get_context_min_address( context );
+ const uintptr_t max = virt_get_context_max_address( context );
context->bitmap_length = ( max - min ) / PAGE_SIZE / VIRT_PAGE_PER_ENTRY;
context->bitmap = aligned_alloc(
sizeof( *( context->bitmap ) ),
@@ -300,8 +300,8 @@ virt_context_t* virt_create_context( virt_context_type_t type ) {
return NULL;
}
// allocate bitmap for lookup
- uintptr_t min = virt_get_context_min_address( context );
- uintptr_t max = virt_get_context_max_address( context );
+ const uintptr_t min = virt_get_context_min_address( context );
+ const uintptr_t max = virt_get_context_max_address( context );
context->bitmap_length = ( max - min ) / PAGE_SIZE / VIRT_PAGE_PER_ENTRY;
context->bitmap = aligned_alloc(
sizeof( *( context->bitmap ) ),
diff --git a/bolthur/kernel/arch/arm/v7/mm/virt/long.c b/bolthur/kernel/arch/arm/v7/mm/virt/long.c
index c0f78d215..4cf658cdf 100644
--- a/bolthur/kernel/arch/arm/v7/mm/virt/long.c
+++ b/bolthur/kernel/arch/arm/v7/mm/virt/long.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -134,24 +134,20 @@ __bootstrap void v7_long_startup_setup( void ) {
* @param phys physical address
* @param virt virtual address
*/
-__bootstrap void v7_long_startup_map( uint64_t phys, uintptr_t virt ) {
+__bootstrap void v7_long_startup_map( const uint64_t phys, const uintptr_t virt ) {
// determine index for getting middle directory
- uint32_t pmd_index = LD_VIRTUAL_PMD_INDEX( virt );
+ const uint32_t pmd_index = LD_VIRTUAL_PMD_INDEX( virt );
// determine index for getting table directory
- uint32_t tbl_index = LD_VIRTUAL_TABLE_INDEX( virt );
+ const uint32_t tbl_index = LD_VIRTUAL_TABLE_INDEX( virt );
// skip if already set
if ( 0 != initial_middle_directory[ pmd_index ].raw[ tbl_index ] ) {
return;
}
-
- ld_context_block_level2_t* section = &initial_middle_directory[ pmd_index ]
- .section[ tbl_index ];
-
// set section
- section->raw = LD_PHYSICAL_SECTION_L2_ADDRESS( phys );
- section->data.type = LD_TYPE_SECTION;
- section->data.lower_attr_access = 1;
+ initial_middle_directory[ pmd_index ].section[ tbl_index ].raw = LD_PHYSICAL_SECTION_L2_ADDRESS( phys );
+ initial_middle_directory[ pmd_index ].section[ tbl_index ].data.type = LD_TYPE_SECTION;
+ initial_middle_directory[ pmd_index ].section[ tbl_index ].data.lower_attr_access = 1;
}
/**
@@ -217,6 +213,11 @@ static uintptr_t map_temporary( uint64_t start, size_t size ) {
// stop here if not initialized
if ( true != virt_init_get() ) {
+ // map initially
+ for ( size_t i = ( size_t )start; i < start + size; i += PAGE_SIZE ) {
+ virt_startup_map( i, i );
+ }
+ // return start address
return ( uintptr_t )start;
}
@@ -267,7 +268,7 @@ static uintptr_t map_temporary( uint64_t start, size_t size ) {
if ( 0 == found_amount ) {
#if defined( PRINT_MM_VIRT )
DEBUG_OUTPUT(
- "TEMPORARY_SPACE_START = %#x, current_table * PAGE_SIZE * 512 = %#x, ( PAGE_SIZE * idx ) = %#x\r\n",
+ "TEMPORARY_SPACE_START = %#x, current_table * PAGE_SIZE * 512 = %#"PRIx32", ( PAGE_SIZE * idx ) = %#"PRIx32"\r\n",
TEMPORARY_SPACE_START, current_table * PAGE_SIZE * 512, PAGE_SIZE * idx )
#endif
start_address = TEMPORARY_SPACE_START + (
@@ -484,14 +485,14 @@ static uint64_t get_temporary_mapping( uintptr_t addr ) {
* @param table set to non zero for destroying a table
* @return address to new table or 0 if it was used for free up
*/
-static uint64_t get_new_table( uint64_t table ) {
+static uint64_t get_new_table( const uint64_t table ) {
// handle free only if set
if ( 0 != table ) {
phys_free_page( table );
return 0;
}
// get new page
- uint64_t addr = phys_find_free_page( PAGE_SIZE, PHYS_MEMORY_TYPE_NORMAL );
+ const uint64_t addr = phys_find_free_page( PAGE_SIZE, PHYS_MEMORY_TYPE_NORMAL );
// debug output
#if defined( PRINT_MM_VIRT )
DEBUG_OUTPUT( "addr = %#"PRIx64"\r\n", addr )
@@ -545,7 +546,7 @@ uint64_t v7_long_create_table(
#if defined( PRINT_MM_VIRT )
DEBUG_OUTPUT(
"create long descriptor table for address %#"PRIxPTR" for context %#"PRIxPTR"\r\n",
- addr, ctx
+ addr, ( uintptr_t )ctx
)
DEBUG_OUTPUT( "pmd_idx = %"PRIu32", tbl_idx = %"PRIu32"\r\n", pmd_idx, tbl_idx )
#endif
@@ -1149,11 +1150,13 @@ virt_context_t* v7_long_create_context( virt_context_type_t type ) {
// reserve space for context
uint64_t ctx;
if ( !virt_init_get() ) {
- ctx = ( uintptr_t )aligned_alloc( PAGE_SIZE, sizeof( ld_global_page_directory_t ) );
+ void* tmp = aligned_alloc( PAGE_SIZE, sizeof( ld_global_page_directory_t ) );
// handle error
- if ( ! ctx ) {
+ if ( ! tmp ) {
return NULL;
}
+ memset( tmp, 0, sizeof( ld_global_page_directory_t ) );
+ ctx = ( uintptr_t )tmp;
ctx = VIRT_2_PHYS( ctx );
} else {
ctx = phys_find_free_page_range( PAGE_SIZE, sizeof( ld_global_page_directory_t ), PHYS_MEMORY_TYPE_NORMAL );
diff --git a/bolthur/kernel/arch/arm/v7/mm/virt/long.h b/bolthur/kernel/arch/arm/v7/mm/virt/long.h
index 71916d9a9..720025f1d 100644
--- a/bolthur/kernel/arch/arm/v7/mm/virt/long.h
+++ b/bolthur/kernel/arch/arm/v7/mm/virt/long.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/mm/virt/short.c b/bolthur/kernel/arch/arm/v7/mm/virt/short.c
index aad9780cd..99c102b79 100644
--- a/bolthur/kernel/arch/arm/v7/mm/virt/short.c
+++ b/bolthur/kernel/arch/arm/v7/mm/virt/short.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -124,15 +124,13 @@ __bootstrap void v7_short_startup_setup( void ) {
* @param phys physical address
* @param virt virtual address
*/
-__bootstrap void v7_short_startup_map( uintptr_t phys, uintptr_t virt ) {
- uint32_t x = virt >> 20;
- uint32_t y = phys >> 20;
-
- sd_context_section_t* sec = &initial_context.section[ x ];
- sec->data.type = SD_TTBR_TYPE_SECTION;
- sec->data.execute_never = 0;
- sec->data.access_permission_0 = SD_MAC_APX0_PRIVILEGED_RW;
- sec->data.frame = y & 0xFFF;
+__bootstrap void v7_short_startup_map( const uintptr_t phys, const uintptr_t virt ) {
+ const uint32_t x = virt >> 20;
+ const uint32_t y = phys >> 20;
+ initial_context.section[ x ].data.type = SD_TTBR_TYPE_SECTION;
+ initial_context.section[ x ].data.execute_never = 0;
+ initial_context.section[ x ].data.access_permission_0 = SD_MAC_APX0_PRIVILEGED_RW;
+ initial_context.section[ x ].data.frame = y & 0xFFF;
}
/**
@@ -191,6 +189,11 @@ static uintptr_t map_temporary( uintptr_t start, size_t size ) {
// stop here if not initialized
if ( true != virt_init_get() ) {
+ // map initially
+ for ( size_t i = start; i < start + size; i += PAGE_SIZE ) {
+ virt_startup_map( i, i );
+ }
+ // return start address
return start;
}
@@ -1174,11 +1177,13 @@ virt_context_t* v7_short_create_context( virt_context_type_t type ) {
// reserve space for context
uint64_t phys;
if ( !virt_init_get() ) {
- phys = ( uintptr_t )aligned_alloc( alignment, size );
+ void* tmp = aligned_alloc( alignment, size );
// handle error
- if ( ! phys ) {
+ if ( ! tmp ) {
return NULL;
}
+ memset( tmp, 0, size );
+ phys = ( uintptr_t )tmp;
phys = VIRT_2_PHYS( phys );
} else {
phys = phys_find_free_page_range( alignment, size, PHYS_MEMORY_TYPE_NORMAL );
diff --git a/bolthur/kernel/arch/arm/v7/mm/virt/short.h b/bolthur/kernel/arch/arm/v7/mm/virt/short.h
index bf9cab0d9..f62ea3db4 100644
--- a/bolthur/kernel/arch/arm/v7/mm/virt/short.h
+++ b/bolthur/kernel/arch/arm/v7/mm/virt/short.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/register/dacr.h b/bolthur/kernel/arch/arm/v7/register/dacr.h
index fb6252208..c28b6aac8 100644
--- a/bolthur/kernel/arch/arm/v7/register/dacr.h
+++ b/bolthur/kernel/arch/arm/v7/register/dacr.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/register/sctlr.h b/bolthur/kernel/arch/arm/v7/register/sctlr.h
index e9421c0cd..a49352e34 100644
--- a/bolthur/kernel/arch/arm/v7/register/sctlr.h
+++ b/bolthur/kernel/arch/arm/v7/register/sctlr.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/register/ttbcr.h b/bolthur/kernel/arch/arm/v7/register/ttbcr.h
index 3d244c5f9..80942a48c 100644
--- a/bolthur/kernel/arch/arm/v7/register/ttbcr.h
+++ b/bolthur/kernel/arch/arm/v7/register/ttbcr.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/rpc/backup.c b/bolthur/kernel/arch/arm/v7/rpc/backup.c
index 02baf4bfb..982fabd31 100644
--- a/bolthur/kernel/arch/arm/v7/rpc/backup.c
+++ b/bolthur/kernel/arch/arm/v7/rpc/backup.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -29,7 +29,7 @@
#endif
/**
- * @fn rpc_backup_t* rpc_backup_create(task_thread_t*, task_process_t*, size_t, void*, size_t, task_thread_t*, bool, size_t, bool)
+ * @fn rpc_backup_t* rpc_backup_create(task_thread_t*, const task_process_t*, size_t, const void*, size_t, task_thread_t*, bool, size_t, bool, bool)
* @brief Helper to create rpc backup
*
* @param source
@@ -41,26 +41,31 @@
* @param sync
* @param origin_data_id
* @param disable_data
+ * @param is_interrupt
* @return
*/
rpc_backup_t* rpc_backup_create(
task_thread_t* source,
- task_process_t* target,
- size_t type,
- void* data,
- size_t data_size,
+ const task_process_t* target,
+ const size_t type,
+ const void* data,
+ const size_t data_size,
task_thread_t* target_thread,
- bool sync,
- size_t origin_data_id,
- bool disable_data
+ const bool sync,
+ const size_t origin_data_id,
+ const bool disable_data,
+ const bool is_interrupt
) {
// get first inactive thread
+ #if defined( PRINT_RPC )
+ DEBUG_OUTPUT( "%d: target->thread_manager = %p\r\n", target->id, target->thread_manager )
+ #endif
avl_node_t* current = avl_iterate_first( target->thread_manager );
task_thread_t* thread = target_thread;
// loop until usable thread has been found
while ( current && ! thread ) {
// get thread
- task_thread_t* tmp = TASK_THREAD_GET_BLOCK( current );
+ auto const tmp = TASK_THREAD_GET_BLOCK( current );
// FIXME: CHECK IF ACTIVE
thread = tmp;
// get next thread
@@ -101,7 +106,7 @@ rpc_backup_t* rpc_backup_create(
#endif
// variables
- list_item_t* current_list = target->rpc_queue->first;
+ const list_item_t* current_list = target->rpc_queue->first;
rpc_backup_t* active = NULL;
// try to find matching rpc
while( current_list ) {
@@ -113,10 +118,12 @@ rpc_backup_t* rpc_backup_create(
DEBUG_OUTPUT( "process = %d, tmp->active = %d, tmp->thread = %p, thread = %p, tmp->data_id = %zu, thread->state = %d\r\n",
tmp->thread->process->id, tmp->active ? 1 : 0, tmp->thread, thread, tmp->data_id, thread->state )
#endif
- // handle not active, different thread or wait for return
+ // handle not active, different thread, wait for return
+ // or executing interrupt
if ( ! tmp->active || tmp->thread != thread
|| thread->state == TASK_THREAD_STATE_RPC_WAIT_FOR_RETURN
|| thread->state == TASK_THREAD_STATE_RPC_HALT_SWITCH
+ || thread->handling_interrupt
) {
// get to next item
current_list = current_list->next;
@@ -163,7 +170,7 @@ rpc_backup_t* rpc_backup_create(
backup->data_id = 0;
if ( ! disable_data ) {
if ( data && data_size ) {
- int err = rpc_data_queue_add(
+ const int err = rpc_data_queue_add(
thread->process->id,
data,
data_size,
@@ -186,8 +193,8 @@ rpc_backup_t* rpc_backup_create(
)
#endif
} else {
- char dummy = '\0';
- int err = rpc_data_queue_add(
+ constexpr char dummy = '\0';
+ const int err = rpc_data_queue_add(
thread->process->id,
&dummy,
sizeof( char ),
@@ -223,8 +230,11 @@ rpc_backup_t* rpc_backup_create(
DEBUG_OUTPUT( "pid: %d, backup->thread_state = %d, thread->state = %d\r\n",
thread->process->id, backup->thread_state, thread->state )
#endif
+ // save thread state and state data
backup->thread_state = thread->state;
memcpy( &backup->thread_state_data, &thread->state_data, sizeof( task_state_data_t ) );
+ // in case thread state is rpc wait for call we need to go back to active
+ // after rpc, because it may be a sleep that is active
if ( TASK_THREAD_STATE_RPC_WAIT_FOR_CALL == backup->thread_state ) {
backup->thread_state = TASK_THREAD_STATE_ACTIVE;
}
@@ -244,6 +254,8 @@ rpc_backup_t* rpc_backup_create(
backup->sync_return_data_id = 0;
backup->sync_return_blocked_data_id = 0;
backup->sync_return_on_end = false;
+ backup->is_interrupt = is_interrupt;
+ backup->state_to_use = TASK_THREAD_STATE_RPC_QUEUED;
// return created backup
return backup;
}
diff --git a/bolthur/kernel/arch/arm/v7/rpc/generic.c b/bolthur/kernel/arch/arm/v7/rpc/generic.c
index 04066bdbb..02e12e584 100644
--- a/bolthur/kernel/arch/arm/v7/rpc/generic.c
+++ b/bolthur/kernel/arch/arm/v7/rpc/generic.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -22,6 +22,7 @@
#include "../../../../mm/virt.h"
#include "../../../../rpc/generic.h"
#include "../../../../syscall.h"
+#include "../../../../timer.h"
#include "../../../../rpc/backup.h"
#include "../../../../rpc/data.h"
#if defined( PRINT_RPC )
@@ -45,11 +46,11 @@ bool rpc_generic_restore( task_thread_t* thread ) {
return false;
}
// variables
- rpc_backup_t* backup = NULL;
+ rpc_backup_t* backup = nullptr;
bool further_rpc_enqueued = false;
// get backup for restore
for (
- list_item_t* current = thread->process->rpc_queue->first;
+ const list_item_t* current = thread->process->rpc_queue->first;
current;
current = current->next
) {
@@ -63,9 +64,13 @@ bool rpc_generic_restore( task_thread_t* thread ) {
backup = tmp;
// debug output
#if defined( PRINT_RPC )
- DEBUG_OUTPUT( "backup = %p\r\n", backup )
+ DEBUG_OUTPUT( "backup = %p / %d\r\n", backup, backup->thread->process->id )
#endif
} else {
+ // debug output
+ #if defined( PRINT_RPC )
+ DEBUG_OUTPUT( "backup = %p / %d\r\n", backup, backup->thread->process->id )
+ #endif
further_rpc_enqueued = true;
}
}
@@ -108,7 +113,7 @@ bool rpc_generic_restore( task_thread_t* thread ) {
backup->thread->process->id, backup->thread->state, backup->thread_state )
#endif
// set correct state
- backup->thread->state = backup->thread_state;
+ task_thread_set_state( backup->thread, backup->thread_state );
memcpy( &thread->state_data, &backup->thread->state_data, sizeof( task_state_data_t ) );
// handle sync return on end
@@ -139,20 +144,20 @@ bool rpc_generic_restore( task_thread_t* thread ) {
)
#endif
// finally remove found entry
- list_remove_data( thread->process->rpc_queue, backup );
+ list_remove_data( thread->process->rpc_queue, backup, true );
// handle enqueued stuff
if ( further_rpc_enqueued ) {
// get first list item
- const list_item_t* item = thread->process->rpc_queue->first;
+ auto item = thread->process->rpc_queue->first;
// initialize next backup
- rpc_backup_t* next = NULL;
+ rpc_backup_t* next = nullptr;
// loop through next
while ( item ) {
// get current item
rpc_backup_t* tmp = item->data;
// debug output
#if defined( PRINT_RPC )
- DEBUG_OUTPUT( "tmp = %p, tmp->active = %d\r\n", ( void* )tmp, tmp->active ? 1 : 0 )
+ DEBUG_OUTPUT( "%d: tmp = %p, tmp->active = %d\r\n", tmp->thread->process->id, ( void* )tmp, tmp->active ? 1 : 0 )
#endif
// handle not active
if ( ! tmp->active ) {
@@ -220,8 +225,8 @@ bool rpc_generic_prepare_invoke( rpc_backup_t* backup ) {
return true;
}
// get register context
- task_process_t* proc = backup->thread->process;
- cpu_register_context_t* cpu = backup->thread->current_context;
+ auto const proc = backup->thread->process;
+ // handle not in queue
if ( ! list_lookup_data( proc->rpc_queue, backup ) ) {
// debug output
#if defined( PRINT_RPC )
@@ -232,54 +237,124 @@ bool rpc_generic_prepare_invoke( rpc_backup_t* backup ) {
return false;
}
}
- // get active rpc
- const rpc_backup_t* existing = rpc_backup_get_active( backup->thread, 0 );
+ // evaluate wait for return block
+ bool wait_for_return_block = false;
+ [[maybe_unused]] bool deactivate_current_active_rpc = false;
+ if ( TASK_THREAD_STATE_RPC_WAIT_FOR_RETURN == backup->thread->state ) {
+ const rpc_origin_source_t* rpc_backup = nullptr;
+ if ( backup->origin_data_id ) {
+ rpc_backup = rpc_generic_source_info( backup->origin_data_id );
+ while ( rpc_backup && rpc_backup->origin_rpc_id ) {
+ rpc_backup = rpc_generic_source_info( rpc_backup->origin_rpc_id );
+ }
+ }
+ // wait for return is blocked when it's an interrupt, has no rpc backup (
+ // fired directly asynchronous ) or when pid is not backup source process (
+ // nested are only allowed within themselves )
+ wait_for_return_block = backup->is_interrupt
+ || ! rpc_backup
+ || backup->thread->process->id != rpc_backup->source_process;
+ // when an interrupt is running, block it
+ if ( backup->thread->handling_interrupt && ! wait_for_return_block ) {
+ wait_for_return_block = true;
+ }
+ // deactivation of current active rpc is bound to wait for return block
+ deactivate_current_active_rpc = ! wait_for_return_block;
+ #if defined( PRINT_RPC )
+ if ( wait_for_return_block ) {
+ DEBUG_OUTPUT( "%d is blocked\r\n", backup->thread->process->id )
+ }
+ #endif
+ }
// enqueue only when state is set
if (
TASK_THREAD_STATE_RPC_QUEUED == backup->thread->state
|| TASK_THREAD_STATE_RPC_ACTIVE == backup->thread->state
|| TASK_THREAD_STATE_RPC_HALT_SWITCH == backup->thread->state
+ || wait_for_return_block
) {
// debug output
#if defined( PRINT_RPC )
+ DEBUG_OUTPUT( "%d is blocked\r\n", backup->thread->process->id )
DEBUG_OUTPUT( "backup->thread->state = %d, pid = %d\r\n", backup->thread->state,
backup->thread->process->id )
#endif
// return success
return true;
}
+ // skip enqueue in case an interrupt is handled
+ if ( backup->thread->handling_interrupt ) {
+ // debug output
+ #if defined( PRINT_RPC )
+ DEBUG_OUTPUT( "backup->thread->handling_interrupt = %d for %d / %d\r\n",
+ backup->thread->handling_interrupt, backup->thread->process->id, backup->thread->id )
+ #endif
+ // return success
+ return true;
+ }
+ // get possible sleep timer
+ timer_callback_entry_t* timer = timer_get_by_process_id(
+ backup->thread->process->id );
+ // handle timer
+ if ( timer ) {
+ // mark as handled to prevent raise of rpc
+ timer->handled = true;
+ // adjust previous state
+ backup->thread_state = TASK_THREAD_STATE_ACTIVE;
+ }
- // handle rpc active
- if ( existing ) {
- // traverse source up to initiating process
- const rpc_origin_source_t* rpc_source = existing->rpc_info;
- while ( rpc_source && rpc_source->origin_rpc_id ) {
- rpc_source = rpc_generic_source_info( rpc_source->origin_rpc_id );
- }
- // traverse current up to initiating process
- const rpc_origin_source_t* rpc_backup = NULL;
- if ( backup->origin_data_id ) {
- rpc_backup = rpc_generic_source_info( backup->origin_data_id );
- while ( rpc_backup->origin_rpc_id ) {
- rpc_backup = rpc_generic_source_info( rpc_backup->origin_rpc_id );
+ /*// handle deactivation of current rpc
+ if ( deactivate_current_active_rpc ) {
+ // Get entry marked as active, which might be waiting for rpc
+ rpc_backup_t* active = nullptr;
+ auto active_entry = backup->thread->process->rpc_queue->first;
+ while ( active_entry ) {
+ // handle active set
+ if ( ((rpc_backup_t*)active_entry->data)->active ) {
+ active = active_entry->data;
+ break;
}
+ // get to next
+ active_entry = active_entry->next;
}
- // allow recursive rpc only for same process
- if (
- rpc_source
- && rpc_backup
- && rpc_source->source_process != rpc_backup->source_process
- && rpc_backup->source_process != backup->thread->process->id
- ) {
+ // debug output
+ //#if defined( PRINT_RPC )
+ DEBUG_OUTPUT( "active = %p\r\n", (void*)active )
+ //#endif
+ // handle active existing
+ if ( active ) {
// debug output
- #if defined( PRINT_RPC )
- DEBUG_OUTPUT( "Nested not allowed!\r\n" )
- #endif
- // return success
- return true;
+ //#if defined( PRINT_RPC )
+ DEBUG_OUTPUT( "Active rpc to push back to inactive\r\n" )
+ //#endif
+ // adjust thread state to use so that on next invoke the correct thread
+ // state is used
+ active->state_to_use = task_thread_current_thread->state;
+ // overwrite context of backup to activate
+ memcpy(
+ backup->context,
+ active->thread->current_context,
+ sizeof( cpu_register_context_t )
+ );
+ // mark state as inactive
+ active->active = false;
+ // remove current backup from list without cleanup
+ if ( ! list_remove_data( active->thread->process->rpc_queue, active, false ) ) {
+ #if defined( PRINT_RPC )
+ DEBUG_OUTPUT( "Unable to remove active from list without cleanup\r\n" )
+ #endif
+ return false;
+ }
+ // insert after current rpc
+ if ( ! list_push_after_data( active->thread->process->rpc_queue, backup, active ) ) {
+ #if defined( PRINT_RPC )
+ DEBUG_OUTPUT( "Unable to push active after backup in list\r\n" )
+ #endif
+ return false;
+ }
}
- }
-
+ }*/
+ cpu_register_context_t* cpu = backup->thread->current_context;
// debug output
#if defined( PRINT_RPC )
DUMP_REGISTER( cpu )
@@ -303,14 +378,19 @@ bool rpc_generic_prepare_invoke( rpc_backup_t* backup ) {
// add thumb mode to spsr
cpu->reg.spsr |= CPSR_THUMB;
}
- // set correct state ( set directly to active if it's the current thread )
- if ( backup->thread == task_thread_current_thread ) {
- backup->thread->state = TASK_THREAD_STATE_RPC_ACTIVE;
+ // set correct state ( set directly to active if it's the current thread
+ // and state is rpc queued )
+ if (
+ backup->thread == task_thread_current_thread
+ && backup->state_to_use == TASK_THREAD_STATE_RPC_QUEUED
+ ) {
+ task_thread_set_state( backup->thread, TASK_THREAD_STATE_RPC_ACTIVE );
} else {
- backup->thread->state = TASK_THREAD_STATE_RPC_QUEUED;
+ task_thread_set_state( backup->thread, backup->state_to_use );
}
backup->prepared = true;
backup->active = true;
+ backup->thread->handling_interrupt = backup->is_interrupt;
// debug output
#if defined( PRINT_RPC )
DUMP_REGISTER( cpu )
diff --git a/bolthur/kernel/arch/arm/v7/stub/cache.S b/bolthur/kernel/arch/arm/v7/stub/cache.S
index 4fcda0595..21f72b2b4 100644
--- a/bolthur/kernel/arch/arm/v7/stub/cache.S
+++ b/bolthur/kernel/arch/arm/v7/stub/cache.S
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/stub/stack.S b/bolthur/kernel/arch/arm/v7/stub/stack.S
index f63363c60..e412b6155 100644
--- a/bolthur/kernel/arch/arm/v7/stub/stack.S
+++ b/bolthur/kernel/arch/arm/v7/stub/stack.S
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/stub/start.S b/bolthur/kernel/arch/arm/v7/stub/start.S
index 1f8a1959a..2e926dc58 100644
--- a/bolthur/kernel/arch/arm/v7/stub/start.S
+++ b/bolthur/kernel/arch/arm/v7/stub/start.S
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/syscall.c b/bolthur/kernel/arch/arm/v7/syscall.c
index 82e55ade7..26fd89c15 100644
--- a/bolthur/kernel/arch/arm/v7/syscall.c
+++ b/bolthur/kernel/arch/arm/v7/syscall.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -28,11 +28,11 @@
* @param context
* @param value
*/
-void syscall_populate_success( void* context, size_t value ) {
+void syscall_populate_success( void* context, const size_t value ) {
// get context
context = interrupt_get_context( context );
// get cpu context
- cpu_register_context_t* cpu = ( cpu_register_context_t* )context ;
+ auto const cpu = ( cpu_register_context_t* )context ;
// set return values
cpu->reg.r0 = value;
cpu->reg.r1 = 0;
@@ -45,11 +45,11 @@ void syscall_populate_success( void* context, size_t value ) {
* @param context
* @param error
*/
-void syscall_populate_error( void* context, size_t error ) {
+void syscall_populate_error( void* context, const size_t error ) {
// get context
context = interrupt_get_context( context );
// get cpu context
- cpu_register_context_t* cpu = ( cpu_register_context_t* )context ;
+ auto const cpu = ( cpu_register_context_t* )context ;
// set return values
cpu->reg.r0 = 0;
cpu->reg.r1 = error;
@@ -63,11 +63,11 @@ void syscall_populate_error( void* context, size_t error ) {
* @param num
* @return
*/
-size_t syscall_get_parameter( void* context, size_t num ) {
+size_t syscall_get_parameter( void* context, const size_t num ) {
// get context
context = interrupt_get_context( context );
// transform to cpu structure
- cpu_register_context_t* cpu = ( cpu_register_context_t* )context;
+ auto const cpu = ( cpu_register_context_t* )context;
// number sanitize
assert( num <= CPSR )
// return value
diff --git a/bolthur/kernel/arch/arm/v7/task/process.c b/bolthur/kernel/arch/arm/v7/task/process.c
index 4777912f2..3be30a057 100644
--- a/bolthur/kernel/arch/arm/v7/task/process.c
+++ b/bolthur/kernel/arch/arm/v7/task/process.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -138,12 +138,12 @@ void task_process_schedule( [[maybe_unused]] event_origin_t origin, void* contex
}
// convert context into cpu pointer
- cpu_register_context_t* cpu = ( cpu_register_context_t* )context;
+ auto cpu = ( cpu_register_context_t* )context;
// get context
cpu = interrupt_get_context( cpu );
// debug output
#if defined( PRINT_PROCESS )
- DEBUG_OUTPUT( "cpu register context: %p\r\n", cpu )
+ DEBUG_OUTPUT( "cpu register context: %p\r\n", ( void* )cpu )
DUMP_REGISTER( cpu )
DEBUG_OUTPUT(
"process id = %d\r\n",
@@ -165,9 +165,9 @@ void task_process_schedule( [[maybe_unused]] event_origin_t origin, void* contex
running_queue->last_handled = running_thread;
// update running task to halt due to switch
if ( TASK_THREAD_STATE_ACTIVE == running_thread->state ) {
- running_thread->state = TASK_THREAD_STATE_HALT_SWITCH;
+ task_thread_set_state( running_thread, TASK_THREAD_STATE_HALT_SWITCH );
} else if ( TASK_THREAD_STATE_RPC_ACTIVE == running_thread->state ) {
- running_thread->state = TASK_THREAD_STATE_RPC_HALT_SWITCH;
+ task_thread_set_state( running_thread, TASK_THREAD_STATE_RPC_HALT_SWITCH );
}
}
@@ -206,6 +206,9 @@ void task_process_schedule( [[maybe_unused]] event_origin_t origin, void* contex
#endif
// handle no next thread
if ( ! next_thread ) {
+ #if defined( PRINT_PROCESS )
+ DEBUG_OUTPUT( "No further threads to schedule to, halting\r\n" )
+ #endif
// enable interrupts and set flag
if ( ! halt_set ) {
interrupt_enable();
@@ -252,9 +255,9 @@ void task_process_schedule( [[maybe_unused]] event_origin_t origin, void* contex
if ( running_thread ) {
// reset state to ready
if ( TASK_THREAD_STATE_HALT_SWITCH == running_thread->state ) {
- running_thread->state = TASK_THREAD_STATE_READY;
+ task_thread_set_state( running_thread, TASK_THREAD_STATE_READY );
} else if ( TASK_THREAD_STATE_RPC_HALT_SWITCH == running_thread->state ) {
- running_thread->state = TASK_THREAD_STATE_RPC_QUEUED;
+ task_thread_set_state( running_thread, TASK_THREAD_STATE_RPC_QUEUED );
}
}
// overwrite current running thread
diff --git a/bolthur/kernel/arch/arm/v7/task/stack.c b/bolthur/kernel/arch/arm/v7/task/stack.c
index 41f1239da..a53b13c0c 100644
--- a/bolthur/kernel/arch/arm/v7/task/stack.c
+++ b/bolthur/kernel/arch/arm/v7/task/stack.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/task/stub.S b/bolthur/kernel/arch/arm/v7/task/stub.S
index 4ac3d25ce..5af800501 100644
--- a/bolthur/kernel/arch/arm/v7/task/stub.S
+++ b/bolthur/kernel/arch/arm/v7/task/stub.S
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/arch/arm/v7/task/thread.c b/bolthur/kernel/arch/arm/v7/task/thread.c
index 8df604dc6..63413e101 100644
--- a/bolthur/kernel/arch/arm/v7/task/thread.c
+++ b/bolthur/kernel/arch/arm/v7/task/thread.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -34,6 +34,14 @@
#include "../../../../task/stack.h"
#include "../cpu.h"
+// simple macro to encapsulate push to stack
+#define STACK_PUSH( sp, user_sp, type, val ) \
+ { \
+ user_sp -= sizeof( type ); \
+ sp -= sizeof( type ); \
+ *(type*)sp = val; \
+ }
+
/**
* @fn task_thread_t task_thread_create*(uintptr_t, task_process_t*, size_t)
* @brief Method to create thread structure
@@ -107,8 +115,7 @@ task_thread_t* task_thread_create(
}
// cache locally
- cpu_register_context_t* current_context =
- ( cpu_register_context_t* )thread->current_context;
+ auto current_context = ( cpu_register_context_t* )thread->current_context;
// prepare area
memset( ( void* )current_context, 0, sizeof( cpu_register_context_t ) );
// set content
@@ -200,7 +207,7 @@ task_thread_t* task_thread_create(
}
// populate thread data
- thread->state = TASK_THREAD_STATE_READY;
+ task_thread_set_state( thread, TASK_THREAD_STATE_READY );
thread->entry = entry;
thread->id = task_thread_generate_id( process );
thread->priority = priority;
@@ -275,13 +282,14 @@ task_thread_t* task_thread_fork(
thread->priority = thread_to_fork->priority;
thread->stack_virtual = thread_to_fork->stack_virtual;
thread->entry = thread_to_fork->entry;
+ thread->handling_interrupt = thread_to_fork->handling_interrupt;
thread->stack_physical = virt_get_mapped_address_in_context(
thread->process->virtual_context,
thread->stack_virtual
);
thread->stack_size = thread_to_fork->stack_size;
- thread->state = TASK_THREAD_STATE_READY;
+ task_thread_set_state( thread, TASK_THREAD_STATE_READY );
// copy register context data
memcpy(
thread->current_context,
@@ -346,138 +354,167 @@ task_thread_t* task_thread_fork(
/**
* @fn bool task_thread_push_arguments(task_thread_t*, char**)
- * @brief Small helper to push parameter list for thread to stack
+ * @brief Small helper to push argument list for thread to stack
*
* @param thread
- * @param parameter
+ * @param argument
+ * @param environment
* @return
*/
bool task_thread_push_arguments(
- task_thread_t* thread,
- char** parameter,
+ const task_thread_t* thread,
+ char** argument,
char** environment
) {
- size_t total_size = 0;
- size_t entry_count = 0;
- size_t env_count = 0;
-
- // determine count
- while( parameter && parameter[ entry_count ] ) {
+ int argv_count = 0;
+ int env_count = 0;
+ // determine count of argv
+ while( argument && argument[ argv_count ] ) {
#if defined( PRINT_PROCESS )
- DEBUG_OUTPUT( "%s\r\n", parameter[ entry_count ] )
+ DEBUG_OUTPUT( "%s\r\n", argument[ argv_count ] )
#endif
- total_size += strlen( parameter[ entry_count ] ) + 1;
// increment entry count
- entry_count++;
+ argv_count++;
}
+ // determine count of env
while( environment && environment[ env_count ] ) {
#if defined( PRINT_PROCESS )
DEBUG_OUTPUT( "%s\r\n", environment[ env_count ] )
#endif
- total_size += strlen( environment[ env_count ] ) + 1;
// increment count
env_count++;
}
- // add argv and env array size
- total_size += sizeof( char* ) * entry_count + sizeof( char* ) * env_count;
- // NULL termination for argv and env
- total_size += sizeof( char* ) * 2;
- // add space for parameters argc, argv and env
- total_size += alignof( max_align_t ) + sizeof( char** ) + sizeof( char** );
-
- #if defined( PRINT_PROCESS )
- DEBUG_OUTPUT( "%"PRIx64" | %#x\r\n", thread->stack_physical, STACK_SIZE)
- #endif
+ // allocate pointer structure for env
+ uintptr_t* env_ptr = nullptr;
+ if ( 0 < env_count ) {
+ env_ptr = malloc( ( size_t )env_count * sizeof( uintptr_t ) );
+ if ( ! env_ptr ) {
+ return false;
+ }
+ memset( env_ptr, 0, ( size_t )env_count * sizeof( uintptr_t ) );
+ }
+ // allocate pointer structure for env
+ uintptr_t* argv_ptr = nullptr;
+ if ( 0 < argv_count ) {
+ argv_ptr = malloc( ( size_t )argv_count * sizeof( uintptr_t ) );
+ if ( ! argv_ptr ) {
+ free( env_ptr );
+ return false;
+ }
+ memset( argv_ptr, 0, ( size_t )argv_count * sizeof( uintptr_t ) );
+ }
// map stack temporarily
- uintptr_t stack_tmp = virt_map_temporary(
- thread->stack_physical,
- STACK_SIZE
- );
+ const uintptr_t stack_tmp = virt_map_temporary( thread->stack_physical, STACK_SIZE );
if ( !stack_tmp ) {
+ free( env_ptr );
+ free( argv_ptr );
return false;
}
- // get stack offset
- cpu_register_context_t* cpu =
- ( cpu_register_context_t* )thread->current_context;
- size_t offset = cpu->reg.sp - thread->stack_virtual;
- // debug output
+ // get top stack of temporary and user
+ uintptr_t rsp = stack_tmp + STACK_SIZE - alignof( max_align_t );
+ uintptr_t user_rsp = thread->stack_virtual + STACK_SIZE - alignof( max_align_t );
#if defined( PRINT_PROCESS )
- DEBUG_OUTPUT( "offset = %zx\r\n", offset )
+ DEBUG_OUTPUT( "rsp = %#"PRIxPTR", user_rsp = %#"PRIxPTR"\r\n", rsp, user_rsp )
#endif
- offset -= total_size;
- // debug output
+ // push env to stack
+ if ( env_count ) {
+ // iterate from last to first
+ for (int i = env_count - 1; i >= 0; i-- ) {
+ // get env length
+ const size_t len = strlen( environment[ i ] ) + 1;
+ // adjust rsp and user rsp
+ #if defined( PRINT_PROCESS )
+ DEBUG_OUTPUT( "rsp = %#"PRIxPTR", user_rsp = %#"PRIxPTR"\r\n", rsp, user_rsp )
+ #endif
+ rsp -= len;
+ user_rsp -= len;
+ #if defined( PRINT_PROCESS )
+ DEBUG_OUTPUT( "rsp = %#"PRIxPTR", user_rsp = %#"PRIxPTR"\r\n", rsp, user_rsp )
+ #endif
+ // copy over data
+ memcpy( ( void* )rsp, environment[ i ], len );
+ // store user pointer in array
+ env_ptr[ i ] = user_rsp;
+ }
+ }
+ // push argv to stack
+ if ( argv_count ) {
+ // iterate from last to first
+ for (int i = argv_count - 1; i >= 0; i-- ) {
+ // get argument length
+ const size_t len = strlen( argument[ i ] ) + 1;
+ // adjust rsp and user rsp
+ #if defined( PRINT_PROCESS )
+ DEBUG_OUTPUT( "rsp = %#"PRIxPTR", user_rsp = %#"PRIxPTR"\r\n", rsp, user_rsp )
+ #endif
+ rsp -= len;
+ user_rsp -= len;
+ #if defined( PRINT_PROCESS )
+ DEBUG_OUTPUT( "rsp = %#"PRIxPTR", user_rsp = %#"PRIxPTR"\r\n", rsp, user_rsp )
+ #endif
+ // copy over data
+ memcpy( ( void* )rsp, argument[ i ], len );
+ // store user pointer in array
+ argv_ptr[ i ] = user_rsp;
+ }
+ }
+ // determine total pushes, which is argv count + null termination as well as
+ // environment count + null termination
+ const size_t total_pushes = ( size_t )argv_count + 1 + ( size_t )env_count + 1;
+ const size_t push_space = total_pushes * sizeof( void* );
+ // align stack properly before pushing argc, argv and env
+ const uintptr_t target_rsp = rsp - push_space;
+ const uintptr_t target_user_rsp = user_rsp - push_space;
#if defined( PRINT_PROCESS )
- DEBUG_OUTPUT( "offset = %zx\r\n", offset )
+ DEBUG_OUTPUT( "target_rsp = %#"PRIxPTR", target_user_rsp = %#"PRIxPTR"\r\n", target_rsp, target_user_rsp )
#endif
- offset -= ( ( offset % sizeof( int ) ) ? ( offset % sizeof( int ) ) : 0 );
- // debug output
+ const uintptr_t aligned_rsp = rsp % alignof( max_align_t );
+ const uintptr_t aligned_user_rsp = user_rsp % alignof( max_align_t );
#if defined( PRINT_PROCESS )
- DEBUG_OUTPUT( "offset = %zx\r\n", offset )
+ DEBUG_OUTPUT( "aligned_rsp = %#"PRIxPTR", aligned_user_rsp = %#"PRIxPTR"\r\n", aligned_rsp, aligned_user_rsp )
+ DEBUG_OUTPUT( "rsp = %#"PRIxPTR", user_rsp = %#"PRIxPTR"\r\n", rsp, user_rsp )
#endif
-
- uintptr_t stack_loop = stack_tmp + offset;
- // push argc
- *( ( int* )( stack_loop ) ) = ( int )entry_count;
- // debug output
+ rsp = target_rsp - aligned_rsp;
+ user_rsp = target_user_rsp - aligned_user_rsp;
#if defined( PRINT_PROCESS )
- DEBUG_OUTPUT( "argc = %d\r\n", *( ( int* )( stack_loop ) ) )
+ DEBUG_OUTPUT( "rsp = %#"PRIxPTR", user_rsp = %#"PRIxPTR"\r\n", rsp, user_rsp )
#endif
- // get beyond argc
- stack_loop += sizeof( int );
- // get pointer to argv
- char** argv = ( char** )stack_loop;
- // get beyond argv
- stack_loop += ( sizeof( char* ) * entry_count ) + sizeof( char* );
- // get pointer to env
- char** env = ( char** )stack_loop;
- // get beyond env
- stack_loop += ( sizeof( char* ) * env_count ) + sizeof( char* );
-
- // loop through parameters
- int current_idx = 0;
- while ( parameter && parameter[ current_idx ] ) {
- // copy data
- strcpy( ( void* )stack_loop, parameter[ current_idx ] );
- // populate argv
- argv[ current_idx ] = ( char* )(
- thread->stack_virtual + ( stack_loop - stack_tmp )
- );
- // get to next place for insert
- stack_loop += strlen( parameter[ current_idx ] ) + 1;
- current_idx++;
+ // push environment to stack
+ STACK_PUSH( rsp, user_rsp, uintptr_t, 0 );
+ for ( int i = env_count - 1; i >= 0; i-- ) {
+ STACK_PUSH( rsp, user_rsp, uintptr_t, env_ptr[ i ] );
}
- argv[ current_idx ] = NULL;
- stack_loop += sizeof( NULL );
-
- // loop through environment
- current_idx = 0;
- while ( environment && environment[ current_idx ] ) {
- // copy data
- strcpy( ( void* )stack_loop, environment[ current_idx ] );
- // populate argv
- env[ current_idx ] = ( char* )(
- thread->stack_virtual + ( stack_loop - stack_tmp )
- );
- // get to next place for insert
- stack_loop += strlen( environment[ current_idx ] ) + 1;
- current_idx++;
+ // cache env start
+ const uintptr_t env_start = user_rsp;
+ // push argv to stack
+ STACK_PUSH( rsp, user_rsp, uintptr_t, 0 );
+ for ( int i = argv_count - 1; i >= 0; i-- ) {
+ STACK_PUSH( rsp, user_rsp, uintptr_t, argv_ptr[ i ] );
}
- env[ current_idx ] = NULL;
-
- // unmap again
- virt_unmap_temporary( stack_tmp, STACK_SIZE );
+ // push argv start
+ const uintptr_t argv_start = user_rsp;
+ // populate r0 - r2 ( argv, argc and env )
+ auto const cpu = ( cpu_register_context_t* )thread->current_context;
+ cpu->reg.r0 = ( uint32_t )argv_count;
+ cpu->reg.r1 = argv_start;
+ cpu->reg.r2 = env_start;
// debug output
#if defined( PRINT_PROCESS )
DEBUG_OUTPUT( "cpu->reg.sp = %#"PRIx32"\r\n", cpu->reg.sp )
DUMP_REGISTER( cpu )
#endif
- // adjust thread stack pointer register
- cpu->reg.sp = thread->stack_virtual + offset;
+ // set adjusted stack pointer
+ cpu->reg.sp = user_rsp;
+ // unmap again
+ virt_unmap_temporary( stack_tmp, STACK_SIZE );
// debug output
#if defined( PRINT_PROCESS )
DEBUG_OUTPUT( "cpu->reg.sp = %#"PRIx32"\r\n", cpu->reg.sp )
DUMP_REGISTER( cpu )
#endif
-
+ // free up env ptr and argv ptr again
+ free( env_ptr );
+ free( argv_ptr );
+ // return success
return true;
}
diff --git a/bolthur/kernel/arch/arm/yield.c b/bolthur/kernel/arch/arm/yield.c
index e43010732..342fb9610 100644
--- a/bolthur/kernel/arch/arm/yield.c
+++ b/bolthur/kernel/arch/arm/yield.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/assembly.h b/bolthur/kernel/assembly.h
index 99a417d35..95852a800 100644
--- a/bolthur/kernel/assembly.h
+++ b/bolthur/kernel/assembly.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/bss.c b/bolthur/kernel/bss.c
index 2b125cbc5..995af1c1d 100644
--- a/bolthur/kernel/bss.c
+++ b/bolthur/kernel/bss.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/bss.h b/bolthur/kernel/bss.h
index 27c9f69a2..9f9ea8210 100644
--- a/bolthur/kernel/bss.h
+++ b/bolthur/kernel/bss.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/cache.h b/bolthur/kernel/cache.h
index 2dafa6732..b4b30ec05 100644
--- a/bolthur/kernel/cache.h
+++ b/bolthur/kernel/cache.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/config.h b/bolthur/kernel/config.h
index 447b04cf0..3012108f8 100644
--- a/bolthur/kernel/config.h
+++ b/bolthur/kernel/config.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/configure.ac b/bolthur/kernel/configure.ac
index d583d2524..68a8be1b3 100644
--- a/bolthur/kernel/configure.ac
+++ b/bolthur/kernel/configure.ac
@@ -4,7 +4,7 @@ AC_PREREQ([2.71])
AC_INIT([bolthur-kernel], [0.1.0-dev], [https://github.com/bolthur/kernel/issues], [bolthur-kernel], [https://github.com/bolthur/kernel])
-AC_COPYRIGHT([Copyright (C) 2018 - 2025 bolthur project])
+AC_COPYRIGHT([Copyright (C) 2018 - 2026 bolthur project])
AC_CONFIG_AUX_DIR([_aux/config])
AC_CONFIG_MACRO_DIR([../../build-aux/m4])
@@ -223,6 +223,24 @@ AC_ARG_WITH(
[with_debug_debug_symbols=yes]
)
+AC_ARG_WITH(
+ [ubsan],
+ AS_HELP_STRING(
+ [--with-ubsan],
+ [compile with ubsan enabled]
+ ),
+ [with_ubsan_enabled=yes]
+)
+
+AC_ARG_WITH(
+ [asan],
+ AS_HELP_STRING(
+ [--with-asan],
+ [compile with asan enabled]
+ ),
+ [with_asan_enabled=yes]
+)
+
# enable output and enable remote debugging together is not allowed
AS_IF([test "x$enable_output" == "xyes" && test "x$enable_remote_debug" == "xyes"], [
AC_MSG_ERROR([Enabled kernel output and remote debug are not possible at the same time])
@@ -287,7 +305,7 @@ AC_DEFINE_UNQUOTED(
# Some compiler dependent features.
AC_DEFINE_UNQUOTED(
[__allocator],
- [__attribute__((malloc))],
+ [__attribute__((__malloc__))],
[Keyword for mark something as allocator.]
)
AC_DEFINE_UNQUOTED(
@@ -312,7 +330,7 @@ AC_DEFINE_UNQUOTED(
)
AC_DEFINE_UNQUOTED(
[__no_sanitize],
- [__attribute__((no_sanitize("undefined")))],
+ [__attribute__((no_sanitize("undefined"), no_sanitize("kernel-address")))],
[disable undefined behaviour sanitization]
)
AC_DEFINE_UNQUOTED(
@@ -322,7 +340,7 @@ AC_DEFINE_UNQUOTED(
)
AC_DEFINE_UNQUOTED(
[__bootstrap],
- [__attribute__((__section__(".text.boot"),__optimize__("O0","no-stack-protector"), no_sanitize("undefined")))],
+ [__attribute__((__section__(".text.boot"),__optimize__("O0","no-stack-protector"), no_sanitize("undefined"), no_sanitize("kernel-address")))],
[Bootstrap function]
)
AC_DEFINE_UNQUOTED(
@@ -335,6 +353,8 @@ AC_DEFINE_UNQUOTED(
AM_CONDITIONAL([IS32], [test $executable_format -eq 32])
AM_CONDITIONAL([IS64], [test $executable_format -eq 64])
+AM_CONDITIONAL([HAS_SANITIZER], [test "x$with_debug_symbols" == "xyes"])
+
AC_CONFIG_FILES([
Makefile
arch/Makefile
@@ -345,6 +365,7 @@ AC_CONFIG_FILES([
lib/Makefile
lib/atag/Makefile
lib/libc/Makefile
+ lib/kasan/Makefile
lib/tar/Makefile
platform/Makefile
platform/raspi/Makefile
diff --git a/bolthur/kernel/cpu.c b/bolthur/kernel/cpu.c
index a8cb06a44..779ea8d86 100644
--- a/bolthur/kernel/cpu.c
+++ b/bolthur/kernel/cpu.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/cpu.h b/bolthur/kernel/cpu.h
index beb9a7ac4..50f0ae2d9 100644
--- a/bolthur/kernel/cpu.h
+++ b/bolthur/kernel/cpu.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/debug/barrier.h b/bolthur/kernel/debug/barrier.h
index 4d353bb53..4819211b2 100644
--- a/bolthur/kernel/debug/barrier.h
+++ b/bolthur/kernel/debug/barrier.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/debug/breakpoint.c b/bolthur/kernel/debug/breakpoint.c
index 32e43659e..54dfb9905 100644
--- a/bolthur/kernel/debug/breakpoint.c
+++ b/bolthur/kernel/debug/breakpoint.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -101,7 +101,7 @@ bool debug_breakpoint_remove_step( void ) {
// handle only stepping breakpoints
if ( entry->step ) {
// remove from breakpoint manager list
- if ( ! list_remove_item( debug_breakpoint_manager, current ) ) {
+ if ( ! list_remove_item( debug_breakpoint_manager, current, true ) ) {
return false;
}
// free stuff
@@ -139,7 +139,7 @@ bool debug_breakpoint_remove( uintptr_t address, bool remove ) {
return false;
}
// remove from list
- if ( ! list_remove_item( debug_breakpoint_manager, item ) ) {
+ if ( ! list_remove_item( debug_breakpoint_manager, item, true ) ) {
return false;
}
// free stuff
diff --git a/bolthur/kernel/debug/breakpoint.h b/bolthur/kernel/debug/breakpoint.h
index b794b2292..a72c7b44d 100644
--- a/bolthur/kernel/debug/breakpoint.h
+++ b/bolthur/kernel/debug/breakpoint.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -21,7 +21,6 @@
#define _DEBUG_BREAKPOINT_H
#include
-#include
#include "../../library/collection/list/list.h"
typedef struct {
diff --git a/bolthur/kernel/debug/cache.h b/bolthur/kernel/debug/cache.h
index 0ea876145..5b247ff69 100644
--- a/bolthur/kernel/debug/cache.h
+++ b/bolthur/kernel/debug/cache.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/debug/debug.h b/bolthur/kernel/debug/debug.h
index 4299bbe45..caf8792e9 100644
--- a/bolthur/kernel/debug/debug.h
+++ b/bolthur/kernel/debug/debug.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -27,7 +27,7 @@
*/
#define DEBUG_OUTPUT( ... ) \
{ \
- const char* f = __func__; \
+ const char* f = ( const char* )__func__; \
if ( f ) { \
printf( "[ %s:%4d ] ", f, __LINE__ ); \
printf( __VA_ARGS__ ); \
diff --git a/bolthur/kernel/debug/disasm.h b/bolthur/kernel/debug/disasm.h
index d7eb2c85b..19bde6cd3 100644
--- a/bolthur/kernel/debug/disasm.h
+++ b/bolthur/kernel/debug/disasm.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _DEBUG_DISASM_H
#define _DEBUG_DISASM_H
-#include
#include
#define DEBUG_DISASM_MAX_INSTRUCTION 2
diff --git a/bolthur/kernel/debug/gdb.c b/bolthur/kernel/debug/gdb.c
index 0e195886f..b75327142 100644
--- a/bolthur/kernel/debug/gdb.c
+++ b/bolthur/kernel/debug/gdb.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/debug/gdb.h b/bolthur/kernel/debug/gdb.h
index a0cd2453b..2eb00a045 100644
--- a/bolthur/kernel/debug/gdb.h
+++ b/bolthur/kernel/debug/gdb.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _DEBUG_GDB_H
#define _DEBUG_GDB_H
-#include
#include
#include "../../library/collection/list/list.h"
#include "../event.h"
diff --git a/bolthur/kernel/debug/string.c b/bolthur/kernel/debug/string.c
index a10f28e90..5275ba8b8 100644
--- a/bolthur/kernel/debug/string.c
+++ b/bolthur/kernel/debug/string.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/debug/string.h b/bolthur/kernel/debug/string.h
index d0d386834..1fe5e8eab 100644
--- a/bolthur/kernel/debug/string.h
+++ b/bolthur/kernel/debug/string.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/elf.c b/bolthur/kernel/elf.c
index 3eadc6c9c..19bc533ee 100644
--- a/bolthur/kernel/elf.c
+++ b/bolthur/kernel/elf.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -141,11 +141,11 @@ static bool load_program_header( uintptr_t elf, task_process_t* process ) {
DEBUG_OUTPUT(
"type = %#"PRIx32", vaddr = %#"PRIx32", paddr = %#"PRIx32", "
"size = %#"PRIx32", offset = %#"PRIx32"!\r\n",
- program_header->p_type,
- program_header->p_vaddr,
- program_header->p_paddr,
- program_header->p_memsz,
- program_header->p_offset
+ ( uint32_t )program_header->p_type,
+ ( uint32_t )program_header->p_vaddr,
+ ( uint32_t )program_header->p_paddr,
+ ( uint32_t )program_header->p_memsz,
+ ( uint32_t )program_header->p_offset
)
#endif
// skip all sections except load
diff --git a/bolthur/kernel/elf.h b/bolthur/kernel/elf.h
index be8bb2f56..9af2d6c6e 100644
--- a/bolthur/kernel/elf.h
+++ b/bolthur/kernel/elf.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,8 +20,7 @@
#ifndef _ELF_H
#define _ELF_H
-#include
-#include
+#include "lib/inttypes.h"
#include "task/process.h"
typedef uint16_t Elf32_Half;
diff --git a/bolthur/kernel/entry.h b/bolthur/kernel/entry.h
index e440454f2..95ae2f7ab 100644
--- a/bolthur/kernel/entry.h
+++ b/bolthur/kernel/entry.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -29,6 +29,9 @@
#define KERNEL_AREA_START 0x80000000
#define KERNEL_AREA_END 0xFFFFFFFF
+
+ #define KERNEL_AREA_PROCESS_REPLACE_START 0xF3041000
+ #define KERNEL_AREA_PROCESS_REPLACE_END 0xFFFFFFFF
#elif defined( ELF64 )
#define KERNEL_OFFSET 0xffffffff80000000
#endif
diff --git a/bolthur/kernel/event.c b/bolthur/kernel/event.c
index 3d51b7c13..2a507edf1 100644
--- a/bolthur/kernel/event.c
+++ b/bolthur/kernel/event.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/event.h b/bolthur/kernel/event.h
index 5d9d4f7ae..162ddc7db 100644
--- a/bolthur/kernel/event.h
+++ b/bolthur/kernel/event.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _EVENT_H
#define _EVENT_H
-#include
#include "../library/collection/list/list.h"
#include "../library/collection/avl/avl.h"
#include "stack.h"
@@ -33,7 +32,7 @@ typedef enum {
EVENT_PROCESS = 1,
EVENT_SERIAL,
EVENT_DEBUG,
- EVENT_INTERRUPT_CLEANUP
+ EVENT_INTERRUPT_CLEANUP,
} event_type_t;
typedef enum {
diff --git a/bolthur/kernel/firmware.h b/bolthur/kernel/firmware.h
index 542abe533..94dc0a229 100644
--- a/bolthur/kernel/firmware.h
+++ b/bolthur/kernel/firmware.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/initrd.c b/bolthur/kernel/initrd.c
index a2d4e23f5..bf4b8bc64 100644
--- a/bolthur/kernel/initrd.c
+++ b/bolthur/kernel/initrd.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -21,6 +21,10 @@
#include
#include "initrd.h"
+#include "../application/usr/lib/ld-bolthur/tmp/_dl-int.h"
+#include "lib/assert.h"
+#include "mm/virt.h"
+
/**
* @brief internal initrd load address
*/
@@ -45,7 +49,7 @@ uintptr_t initrd_get_start_address( void ) {
*
* @param address
*/
-void initrd_set_start_address( uintptr_t address ) {
+void initrd_set_start_address( const uintptr_t address ) {
initrd_address = address;
}
@@ -72,7 +76,7 @@ size_t initrd_get_size( void ) {
*
* @param size
*/
-void initrd_set_size( size_t size ) {
+void initrd_set_size( const size_t size ) {
initrd_size = size;
}
@@ -85,3 +89,25 @@ void initrd_set_size( size_t size ) {
bool initrd_exist( void ) {
return 0 < initrd_size;
}
+
+/**
+ * @fn void initrd_unmap(void)
+ * @brief Helper to unmap initrd
+ */
+void initrd_unmap( void ) {
+ // skip in case no initrd is existing
+ if ( ! initrd_exist() ) {
+ return;
+ }
+ // get start address rounded up since it may be mapped directly behind
+ // the kernel
+ uintptr_t start = ROUND_UP_TO_FULL_PAGE( initrd_address );
+ const uintptr_t end = initrd_address + initrd_size;
+ while ( start < end ) {
+ // unmap with free of physical space
+ assert( virt_unmap_address( virt_current_kernel_context, start, true ) );
+ // get to next page
+ start += PAGE_SIZE;
+ }
+ /// FIXME: IMPLEMENT
+}
diff --git a/bolthur/kernel/initrd.h b/bolthur/kernel/initrd.h
index 62cbb0526..49aca113d 100644
--- a/bolthur/kernel/initrd.h
+++ b/bolthur/kernel/initrd.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _INITRD_H
#define _INITRD_H
-#include
#include
#include
@@ -31,5 +30,6 @@ size_t initrd_get_size( void );
void initrd_set_size( size_t );
bool initrd_exist( void );
void initrd_startup_init( void );
+void initrd_unmap( void );
#endif
diff --git a/bolthur/kernel/interrupt.c b/bolthur/kernel/interrupt.c
index caee9179d..361a47580 100644
--- a/bolthur/kernel/interrupt.c
+++ b/bolthur/kernel/interrupt.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -35,11 +35,11 @@
/**
* @brief Interrupt management structure
*/
-interrupt_manager_t* interrupt_manager = NULL;
+interrupt_manager_t* interrupt_manager = nullptr;
/**
+ * @fn int32_t compare_interrupt_callback(const avl_node_t*, const avl_node_t*)
* @brief Compare interrupt callback necessary for avl tree
- *
* @param a node a
* @param b node b
* @return int32_t
@@ -49,31 +49,30 @@ static int32_t compare_interrupt_callback(
const avl_node_t* b
) {
// get blocks
- interrupt_block_t* block_a = INTERRUPT_GET_BLOCK( a );
- interrupt_block_t* block_b = INTERRUPT_GET_BLOCK( b );
-
+ auto const block_a = INTERRUPT_GET_BLOCK( a );
+ auto const block_b = INTERRUPT_GET_BLOCK( b );
// -1 if address of a->interrupt is greater than address of b->interrupt
if ( block_a->interrupt > block_b->interrupt ) {
return -1;
+ }
// 1 if address of b->interrupt is greater than address of a->interrupt
- } else if ( block_b->interrupt > block_a->interrupt ) {
+ if ( block_b->interrupt > block_a->interrupt ) {
return 1;
}
-
// equal => return 0
return 0;
}
/**
+ * @fn avl_tree_t* tree_by_type(interrupt_type_t)
* @brief Helper to get interrupt manager tree by type
- *
* @param type type to get tree from
* @return avl_tree_t*
*/
static avl_tree_t* tree_by_type( interrupt_type_t type ) {
// check heap existence
if ( ! heap_init_get() ) {
- return NULL;
+ return nullptr;
}
// debug output
#if defined( PRINT_INTERRUPT )
@@ -85,34 +84,34 @@ static avl_tree_t* tree_by_type( interrupt_type_t type ) {
interrupt_manager = malloc( sizeof( *interrupt_manager ) );
// check
if ( ! interrupt_manager ) {
- return NULL;
+ return nullptr;
}
// prepare memory
memset( ( void* )interrupt_manager, 0, sizeof( *interrupt_manager ) );
// create trees for interrupt types
interrupt_manager->normal_interrupt = avl_create_tree(
- compare_interrupt_callback, NULL, NULL );
+ compare_interrupt_callback, nullptr, nullptr );
// check
if ( ! interrupt_manager->normal_interrupt ) {
free( interrupt_manager );
- return NULL;
+ return nullptr;
}
interrupt_manager->fast_interrupt = avl_create_tree(
- compare_interrupt_callback, NULL, NULL );
+ compare_interrupt_callback, nullptr, nullptr );
// check
if ( ! interrupt_manager->fast_interrupt ) {
free( interrupt_manager->normal_interrupt );
free( interrupt_manager );
- return NULL;
+ return nullptr;
}
interrupt_manager->software_interrupt = avl_create_tree(
- compare_interrupt_callback, NULL, NULL );
+ compare_interrupt_callback, nullptr, nullptr );
// check
if ( ! interrupt_manager->software_interrupt ) {
free( interrupt_manager->normal_interrupt );
free( interrupt_manager->fast_interrupt );
free( interrupt_manager );
- return NULL;
+ return nullptr;
}
// debug output
#if defined( PRINT_INTERRUPT )
@@ -133,7 +132,7 @@ static avl_tree_t* tree_by_type( interrupt_type_t type ) {
return interrupt_manager->software_interrupt;
// default: invalid
default:
- return NULL;
+ return nullptr;
}
}
@@ -141,6 +140,7 @@ static avl_tree_t* tree_by_type( interrupt_type_t type ) {
* @fn int32_t block_list_lookup(const list_item_t*, const void*)
* @brief interrupt block list cleanup helper
* @param a
+ * @param data
*/
static int32_t kernel_block_list_lookup( const list_item_t* a, const void* data ) {
// get callback from data
@@ -169,6 +169,7 @@ static void kernel_block_list_cleanup( list_item_t* a ) {
* @fn int32_t block_list_lookup(const list_item_t*, const void*)
* @brief interrupt block list cleanup helper
* @param a
+ * @param data
*/
static int32_t process_block_list_lookup( const list_item_t* a, const void* data ) {
// get callback from data
@@ -182,9 +183,8 @@ static int32_t process_block_list_lookup( const list_item_t* a, const void* data
}
/**
- * @fn bool interrupt_unregister_handler(size_t, interrupt_callback_t, task_process_t*, interrupt_type_t, bool, bool)
+ * @fn bool interrupt_unregister_handler(size_t, interrupt_callback_t, const task_process_t*, interrupt_type_t, bool, bool)
* @brief Unregister interrupt handler
- *
* @param num interrupt to unbind
* @param callback Callback to unbind
* @param process optional process if user handler
@@ -197,11 +197,11 @@ static int32_t process_block_list_lookup( const list_item_t* a, const void* data
*/
bool interrupt_unregister_handler(
size_t num,
- interrupt_callback_t callback,
- task_process_t* process,
+ const interrupt_callback_t callback,
+ const task_process_t* process,
interrupt_type_t type,
- bool post,
- bool disable
+ const bool post,
+ const bool disable
) {
if ( ! heap_init_get() ) {
return false;
@@ -261,8 +261,8 @@ bool interrupt_unregister_handler(
#if defined( PRINT_INTERRUPT )
DEBUG_OUTPUT( "Checking for not bound interrupt callback\r\n" )
#endif
- list_manager_t* list = NULL;
- list_item_t* match = NULL;
+ list_manager_t* list = nullptr;
+ list_item_t* match = nullptr;
// get matching element
if ( process ) {
list = block->process;
@@ -291,13 +291,12 @@ bool interrupt_unregister_handler(
interrupt_unmask_specific( ( int8_t )num );
}
// remove element
- return list_remove_item( list, match );
+ return list_remove_item( list, match, true );
}
/**
* @fn bool interrupt_register_handler(size_t, interrupt_callback_t, task_process_t*, interrupt_type_t, bool, bool)
* @brief Register interrupt handler
- *
* @param num Interrupt to bind
* @param callback Callback to bind
* @param process optional process if user handler
@@ -308,23 +307,28 @@ bool interrupt_unregister_handler(
*/
bool interrupt_register_handler(
size_t num,
- interrupt_callback_t callback,
+ const interrupt_callback_t callback,
task_process_t* process,
interrupt_type_t type,
- bool post,
- bool enable
+ const bool post,
+ const bool enable
) {
if ( ! heap_init_get() ) {
+ #if defined( PRINT_INTERRUPT )
+ DEBUG_OUTPUT( "No heap initialized!\r\n" )
+ #endif
return false;
}
// debug output
#if defined( PRINT_INTERRUPT )
DEBUG_OUTPUT(
- "Called interrupt_register_handler( %zu, %#"PRIxPTR", %d, %s )\r\n",
+ "Called interrupt_register_handler( %zu, %#"PRIxPTR", %#"PRIxPTR", %d, %s, %s )\r\n",
num,
( uintptr_t )callback,
+ ( uintptr_t )process,
type,
- post ? "true" : "false"
+ post ? "true" : "false",
+ enable ? "true" : "false"
)
#endif
@@ -357,12 +361,15 @@ bool interrupt_register_handler(
// try to find node
avl_node_t* node = avl_find_by_data( tree, ( void* )num );
interrupt_block_t* block;
+ bool allocated = false;
// debug output
#if defined( PRINT_INTERRUPT )
DEBUG_OUTPUT( "Found node %p\r\n", node )
#endif
// handle not yet added
if ( ! node ) {
+ // set allocated to true
+ allocated = true;
// reserve block
block = malloc( sizeof( *block ) );
// check
@@ -380,7 +387,7 @@ bool interrupt_register_handler(
block->handler = list_construct(
kernel_block_list_lookup,
kernel_block_list_cleanup,
- NULL
+ nullptr
);
// check list
if ( ! block->handler ) {
@@ -390,7 +397,7 @@ bool interrupt_register_handler(
block->post = list_construct(
kernel_block_list_lookup,
kernel_block_list_cleanup,
- NULL
+ nullptr
);
// check list
if ( ! block->post ) {
@@ -398,7 +405,7 @@ bool interrupt_register_handler(
free( block );
return false;
}
- block->process = list_construct( process_block_list_lookup, NULL, NULL );
+ block->process = list_construct( process_block_list_lookup, nullptr, nullptr );
// check list
if ( ! block->process ) {
list_destruct( block->post );
@@ -424,8 +431,8 @@ bool interrupt_register_handler(
#if defined( PRINT_INTERRUPT )
DEBUG_OUTPUT( "Checking for already bound interrupt callback\r\n" )
#endif
- list_manager_t* list = NULL;
- list_item_t* match = NULL;
+ list_manager_t* list = nullptr;
+ list_item_t* match = nullptr;
// try to find matching element
if ( process ) {
list = block->process;
@@ -435,51 +442,80 @@ bool interrupt_register_handler(
match = list_lookup_data( list, ( void* )( ( uintptr_t )callback ) );
}
// if already existing, just return success
- if ( match ) {
+ if ( ! match ) {
// debug output
#if defined( PRINT_INTERRUPT )
- DEBUG_OUTPUT( "Callback already bound, returning success\r\n" )
+ DEBUG_OUTPUT( "Callback not yet bound\r\n" )
#endif
- return true;
- }
- void* data = NULL;
- if ( process ) {
- // set data to process
- data = process;
- } else {
- // create wrapper
- interrupt_callback_wrapper_t* wrapper = malloc( sizeof( *wrapper ) );
- // check
- if ( ! wrapper ) {
- return false;
+ task_process_t* data = nullptr;
+ if ( process ) {
+ // set data to process
+ data = process;
+ // push to list
+ if ( ! list_push_back_data( list, data ) ) {
+ if ( allocated ) {
+ avl_remove_by_node( tree, &block->node );
+ list_destruct( block->process );
+ list_destruct( block->post );
+ list_destruct( block->handler );
+ free( block );
+ }
+ return false;
+ }
+ } else {
+ // create wrapper
+ interrupt_callback_wrapper_t* wrapper = malloc( sizeof( *wrapper ) );
+ // check
+ if ( ! wrapper ) {
+ if ( allocated ) {
+ avl_remove_by_node( tree, &block->node );
+ list_destruct( block->process );
+ list_destruct( block->post );
+ list_destruct( block->handler );
+ free( block );
+ }
+ return false;
+ }
+ // prepare memory
+ memset( wrapper, 0, sizeof( interrupt_callback_wrapper_t ) );
+ // populate wrapper
+ wrapper->callback = callback;
+ // debug output
+ #if defined( PRINT_INTERRUPT )
+ DEBUG_OUTPUT( "Created wrapper container at %p\r\n", wrapper )
+ #endif
+ // set data to wrapper
+ data = ( void* )wrapper;
+ // push to list
+ if ( ! list_push_back_data( list, data ) ) {
+ free( wrapper );
+ if ( allocated ) {
+ avl_remove_by_node( tree, &block->node );
+ list_destruct( block->process );
+ list_destruct( block->post );
+ list_destruct( block->handler );
+ free( block );
+ }
+ return false;
+ }
}
- // prepare memory
- memset( wrapper, 0, sizeof( interrupt_callback_wrapper_t ) );
- // populate wrapper
- wrapper->callback = callback;
- // debug output
- #if defined( PRINT_INTERRUPT )
- DEBUG_OUTPUT( "Created wrapper container at %p\r\n", wrapper )
- #endif
- // set data to wrapper
- data = ( void* )wrapper;
}
// enable interrupt if set
if ( type == INTERRUPT_NORMAL && enable ) {
interrupt_mask_specific( ( int8_t )num );
}
- // push to list
- return list_push_back_data( list, data );
+ return true;
}
/**
+ * @fn void interrupt_handle(size_t, interrupt_type_t, void*, bool)
* @brief Handle interrupt
- *
* @param num interrupt number
* @param type interrupt type
* @param context interrupt context
+ * @param disable disable pending interrupt
*/
-void interrupt_handle( size_t num, interrupt_type_t type, void* context ) {
+void interrupt_handle( size_t num, const interrupt_type_t type, void* context, const bool disable ) {
// handle no interrupt manager as not bound
if ( ! interrupt_manager ) {
return;
@@ -524,7 +560,7 @@ void interrupt_handle( size_t num, interrupt_type_t type, void* context ) {
return;
}
// get interrupt block
- interrupt_block_t* block = INTERRUPT_GET_BLOCK( node );
+ auto const block = INTERRUPT_GET_BLOCK( node );
// get first element of normal handler
list_item_t* current = block->handler->first;
@@ -555,22 +591,27 @@ void interrupt_handle( size_t num, interrupt_type_t type, void* context ) {
// handle no thread with removal and skip
if ( ! first ) {
list_item_t* next = current->next;
- list_remove_item( block->process, current );
+ list_remove_item( block->process, current, true );
current = next;
continue;
}
// get thread
- task_thread_t* thread = TASK_THREAD_GET_BLOCK( first );
+ auto const thread = TASK_THREAD_GET_BLOCK( first );
+ #if defined( PRINT_INTERRUPT )
+ DEBUG_OUTPUT( "Raising interrupt handler %zu for %d\r\n",
+ num, thread->process->id )
+ #endif
// try to raise rpc without data
rpc_backup_t* rpc = rpc_generic_raise(
thread,
process,
num,
- NULL,
+ nullptr,
0,
- NULL,
+ nullptr,
false,
0,
+ true,
true
);
// handle error by skip
@@ -609,9 +650,14 @@ void interrupt_handle( size_t num, interrupt_type_t type, void* context ) {
#if defined( PRINT_INTERRUPT )
DEBUG_OUTPUT( "Handling of callbacks finished!\r\n" )
#endif
+ if ( disable ) {
+ // disable interrupt to prevent it firing all along
+ interrupt_disable_after_handling( ( int8_t )num );
+ }
}
/**
+ * @fn void interrupt_init(void)
* @brief Generic interrupt init method
*/
void interrupt_init( void ) {
@@ -637,11 +683,11 @@ void interrupt_init( void ) {
}
/**
+ * @fn void interrupt_toggle(interrupt_toggle_state_t)
* @brief Toggle interrupt on / off
- *
* @param state
*/
-void interrupt_toggle( interrupt_toggle_state_t state ) {
+void interrupt_toggle( const interrupt_toggle_state_t state ) {
// static status flag
static bool enabled = false;
@@ -675,25 +721,19 @@ void interrupt_toggle( interrupt_toggle_state_t state ) {
/**
* @fn void interrupt_handle_possible(void*, bool)
* @brief Method to enqueue possible interrupt handler
- *
* @param context
* @param fast
*/
-void interrupt_handle_possible( void* context, bool fast ) {
+void interrupt_handle_possible( void* context, const bool fast ) {
int8_t interrupt_bit;
// get pending interrupt
while( -1 != ( interrupt_bit = interrupt_get_pending( fast ) ) ) {
- // transform bit to interrupt
- uint32_t interrupt = ( 1U << interrupt_bit );
- // debug output
- #if defined( PRINT_INTERRUPT )
- DEBUG_OUTPUT( "pending interrupt: %#"PRIx32"\r\n", interrupt )
- #endif
// call interrupt handler
interrupt_handle(
- interrupt,
+ ( size_t )interrupt_bit,
fast ? INTERRUPT_FAST : INTERRUPT_NORMAL,
- context
+ context,
+ true
);
}
}
@@ -701,7 +741,6 @@ void interrupt_handle_possible( void* context, bool fast ) {
/**
* @fn void interrupt_unregister_process(task_process_t*)
* @brief Unregister process completely
- *
* @param process
*/
void interrupt_unregister_process( task_process_t* process ) {
@@ -709,7 +748,7 @@ void interrupt_unregister_process( task_process_t* process ) {
// get first entry
avl_node_t* avl_list = avl_iterate_first( tree );
while ( avl_list ) {
- interrupt_block_t* block = INTERRUPT_GET_BLOCK( avl_list );
+ auto const block = INTERRUPT_GET_BLOCK( avl_list );
// try to find process
list_item_t* match = list_lookup_data(
block->process,
@@ -717,7 +756,7 @@ void interrupt_unregister_process( task_process_t* process ) {
);
// remove if there is a match
if ( match ) {
- list_remove_item( block->process, match );
+ list_remove_item( block->process, match, true );
}
// get next list
avl_list = avl_iterate_next( tree, avl_list );
@@ -727,7 +766,6 @@ void interrupt_unregister_process( task_process_t* process ) {
/**
* @fn void interrupt_get_context*(void*)
* @brief Method to get interrupt context
- *
* @param context
*/
void* interrupt_get_context( void* context ) {
diff --git a/bolthur/kernel/interrupt.h b/bolthur/kernel/interrupt.h
index d7372638b..61c3f1802 100644
--- a/bolthur/kernel/interrupt.h
+++ b/bolthur/kernel/interrupt.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -22,7 +22,6 @@
#include
#include
-#include
#include "../library/collection/avl/avl.h"
#include "../library/collection/list/list.h"
#include "task/thread.h"
@@ -76,17 +75,20 @@ void interrupt_disable( void );
void interrupt_enable( void );
bool interrupt_enabled( void );
bool interrupt_validate_number( size_t );
+bool interrupt_validate_number_rpc( size_t );
void interrupt_init( void );
void interrupt_arch_init( void );
void interrupt_post_init( void );
-void interrupt_handle( size_t, interrupt_type_t, void* );
+void interrupt_handle( size_t, interrupt_type_t, void*, bool );
bool interrupt_register_handler( size_t, interrupt_callback_t, task_process_t*, interrupt_type_t, bool, bool );
-bool interrupt_unregister_handler( size_t, interrupt_callback_t, task_process_t*, interrupt_type_t, bool, bool );
+bool interrupt_unregister_handler( size_t, interrupt_callback_t, const task_process_t*, interrupt_type_t, bool, bool );
void interrupt_handle_possible( void*, bool );
void interrupt_unregister_process( task_process_t* );
void* interrupt_get_context( void* );
+void interrupt_clear( int8_t );
void interrupt_mask_specific( int8_t );
void interrupt_unmask_specific( int8_t );
+void interrupt_disable_after_handling( int8_t );
#endif
diff --git a/bolthur/kernel/io.h b/bolthur/kernel/io.h
index 74df42e62..0d46ef7d1 100644
--- a/bolthur/kernel/io.h
+++ b/bolthur/kernel/io.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/Makefile.am b/bolthur/kernel/lib/Makefile.am
index 77934481f..5d3310471 100644
--- a/bolthur/kernel/lib/Makefile.am
+++ b/bolthur/kernel/lib/Makefile.am
@@ -1,11 +1,10 @@
-SUBDIRS = libc atag tar
+SUBDIRS = libc atag kasan tar
noinst_LTLIBRARIES = libubsan.la libssp.la libduplicate.la
-libubsan_la_SOURCES = \
- ubsan.c
-libssp_la_SOURCES = \
- ssp.c
-libduplicate_la_SOURCES = \
- duplicate.c
+libubsan_la_SOURCES = ubsan.c
+
+libssp_la_SOURCES = ssp.c
+
+libduplicate_la_SOURCES = duplicate.c
diff --git a/bolthur/kernel/lib/assert.h b/bolthur/kernel/lib/assert.h
index 66dc5434e..125e6328d 100644
--- a/bolthur/kernel/lib/assert.h
+++ b/bolthur/kernel/lib/assert.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/atag.h b/bolthur/kernel/lib/atag.h
index 5835f6b3b..bb57b3ea5 100644
--- a/bolthur/kernel/lib/atag.h
+++ b/bolthur/kernel/lib/atag.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -22,7 +22,6 @@
#include
#include
-#include
typedef struct atag_header atag_header_t;
typedef struct atag_core atag_core_t;
diff --git a/bolthur/kernel/lib/atag/check.c b/bolthur/kernel/lib/atag/check.c
index 7b849dd19..01f325131 100644
--- a/bolthur/kernel/lib/atag/check.c
+++ b/bolthur/kernel/lib/atag/check.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/atag/find.c b/bolthur/kernel/lib/atag/find.c
index 51b62457e..e9db0405c 100644
--- a/bolthur/kernel/lib/atag/find.c
+++ b/bolthur/kernel/lib/atag/find.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/atag/next.c b/bolthur/kernel/lib/atag/next.c
index e35259147..167d2b0d7 100644
--- a/bolthur/kernel/lib/atag/next.c
+++ b/bolthur/kernel/lib/atag/next.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/ctype.h b/bolthur/kernel/lib/ctype.h
index e8c7104ff..f057ef306 100644
--- a/bolthur/kernel/lib/ctype.h
+++ b/bolthur/kernel/lib/ctype.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/duplicate.c b/bolthur/kernel/lib/duplicate.c
index 4cdc97c07..11317baf3 100644
--- a/bolthur/kernel/lib/duplicate.c
+++ b/bolthur/kernel/lib/duplicate.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/duplicate.h b/bolthur/kernel/lib/duplicate.h
index e2e342e70..f0fd7e542 100644
--- a/bolthur/kernel/lib/duplicate.h
+++ b/bolthur/kernel/lib/duplicate.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/endian.h b/bolthur/kernel/lib/endian.h
index 1cc88e739..e8fc33696 100644
--- a/bolthur/kernel/lib/endian.h
+++ b/bolthur/kernel/lib/endian.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/inttypes.h b/bolthur/kernel/lib/inttypes.h
index 0a5d8847f..216ddd124 100644
--- a/bolthur/kernel/lib/inttypes.h
+++ b/bolthur/kernel/lib/inttypes.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -22,5 +22,6 @@
#include
#include
+#include
#endif
diff --git a/bolthur/kernel/lib/kasan/Makefile.am b/bolthur/kernel/lib/kasan/Makefile.am
new file mode 100644
index 000000000..dd817d9ee
--- /dev/null
+++ b/bolthur/kernel/lib/kasan/Makefile.am
@@ -0,0 +1,7 @@
+
+noinst_LTLIBRARIES = libkasan.la
+libkasan_la_SOURCES = \
+ aligned_alloc.c \
+ free.c \
+ kasan.c \
+ print.c
diff --git a/bolthur/kernel/lib/kasan/aligned_alloc.c b/bolthur/kernel/lib/kasan/aligned_alloc.c
new file mode 100644
index 000000000..544be72f5
--- /dev/null
+++ b/bolthur/kernel/lib/kasan/aligned_alloc.c
@@ -0,0 +1,57 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include
+
+#include "kasan.h"
+#include "../../panic.h"
+#include "../../debug/debug.h"
+
+/**
+ * @fn void* kasan_aligned_alloc_hook(size_t, size_t)
+ * @brief Aligned allocation hook
+ * @param alignment
+ * @param size
+ * @return
+ */
+__no_sanitize void* kasan_aligned_alloc_hook( const size_t alignment, const size_t size ) {
+ // for early heap skip asan
+ if ( heap_get_state() == HEAP_INIT_EARLY ) {
+ return heap_allocate( alignment, size );
+ }
+ kasan_heap_header_t* kasan_heap_header = NULL;
+ const size_t aligned_size = ( size + KASAN_SHADOW_MASK ) & ~KASAN_SHADOW_MASK;
+ const size_t total_size = aligned_size + KASAN_HEAP_HEAD_REDZONE_SIZE
+ + KASAN_HEAP_TAIL_REDZONE_SIZE;
+ //DEBUG_OUTPUT( "Allocating %#zx, original size %#zx\r\n", total_size, size )
+ // allocate some block
+ void* ptr = heap_allocate( alignment, total_size );
+ if ( ! ptr ) {
+ return NULL;
+ }
+ //DEBUG_OUTPUT( "ptr = %#"PRIxPTR"\r\n", ( uintptr_t )ptr )
+ // populate kasan information
+ kasan_heap_header = ( kasan_heap_header_t* )ptr;
+ kasan_heap_header->aligned_size = aligned_size;
+
+ kasan_unpoison_shadow( ( uintptr_t )ptr + KASAN_HEAP_HEAD_REDZONE_SIZE, size );
+ kasan_poison_shadow( ( uintptr_t )ptr, KASAN_HEAP_HEAD_REDZONE_SIZE, ASAN_SHADOW_HEAP_HEAD_REDZONE_MAGIC, false );
+ kasan_poison_shadow(( uintptr_t )ptr + KASAN_HEAP_HEAD_REDZONE_SIZE + aligned_size, KASAN_HEAP_TAIL_REDZONE_SIZE, ASAN_SHADOW_HEAP_TAIL_REDZONE_MAGIC, false );
+ return ( void* )( ( uintptr_t )ptr + KASAN_HEAP_HEAD_REDZONE_SIZE );
+}
diff --git a/bolthur/kernel/lib/kasan/free.c b/bolthur/kernel/lib/kasan/free.c
new file mode 100644
index 000000000..04b41d974
--- /dev/null
+++ b/bolthur/kernel/lib/kasan/free.c
@@ -0,0 +1,46 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include "kasan.h"
+
+/**
+ * @fn void kasan_free_hook(void*)
+ * @brief kasan free hook
+ * @param ptr
+ */
+__no_sanitize void kasan_free_hook( void* ptr ) {
+ // handle invalid address
+ if ( ! ptr ) {
+ return;
+ }
+ // for early heap skip asan
+ if ( heap_get_state() == HEAP_INIT_EARLY ) {
+ heap_free( ptr );
+ return;
+ }
+ // translate to kasan heap header
+ kasan_heap_header_t* kasan_heap_header = ( kasan_heap_header_t* )(
+ ( uintptr_t )ptr - KASAN_HEAP_HEAD_REDZONE_SIZE );
+ // extract aligned size
+ const size_t aligned_size = kasan_heap_header->aligned_size;
+ // free address
+ heap_free( kasan_heap_header );
+ // poison shadow
+ kasan_poison_shadow( ( uintptr_t )ptr, aligned_size, ASAN_SHADOW_HEAP_FREE_MAGIC, false );
+}
diff --git a/bolthur/kernel/lib/kasan/kasan.c b/bolthur/kernel/lib/kasan/kasan.c
new file mode 100644
index 000000000..44d4b113f
--- /dev/null
+++ b/bolthur/kernel/lib/kasan/kasan.c
@@ -0,0 +1,240 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include
+#include "kasan.h"
+#include "../assert.h"
+#include "../string.h"
+#include "../../../application/usr/lib/ld-bolthur/tmp/_dl-int.h"
+#include "../../debug/debug.h"
+#include "../../mm/virt.h"
+
+uintptr_t kasan_shadow_memory_start = 0;
+uintptr_t kasan_shadow_memory_end = 0;
+
+/**
+ * @fn uintptr_t kasan_get_poisoned_shadow_address(uintptr_t, size_t)
+ * @brief Wrapper to get poisoned shadow address
+ * @param addr
+ * @param size
+ * @return
+ */
+uintptr_t kasan_get_poisoned_shadow_address(
+ const uintptr_t addr,
+ const size_t size
+) {
+ const uintptr_t addr_shadow_start = KASAN_MEM_TO_SHADOW( addr );
+ const uintptr_t addr_shadow_end = KASAN_MEM_TO_SHADOW( addr + size - 1 ) + 1;
+ uintptr_t non_zero_shadow_addr = 0;
+
+ for ( uintptr_t i = 0; i < addr_shadow_end - addr_shadow_start; i++ ) {
+ if ( *( uint8_t* )( addr_shadow_start + i ) ) {
+ non_zero_shadow_addr = addr_shadow_start + i;
+ break;
+ }
+ }
+
+ if ( non_zero_shadow_addr ) {
+ const uintptr_t last_byte = addr + size - 1;
+ const int8_t *last_shadow_byte = ( int8_t* )KASAN_MEM_TO_SHADOW( last_byte );
+
+ // Non-zero bytes in shadow memory may indicate either:
+ // 1) invalid memory access (0xff, 0xfa, ...)
+ // 2) access to a 8-byte region which isn't entirely accessible, i.e. only
+ // n bytes can be read/written in the 8-byte region, where n < 8
+ // (in this case shadow byte encodes how much bytes in an 8-byte region
+ // are accessible).
+ // Thus, if there is a non-zero shadow byte we need to check if it
+ // corresponds to the last byte in the checked region:
+ // not last - OOB memory access
+ // last - check if we don't access beyond what's encoded in the shadow
+ // byte.
+ if ( non_zero_shadow_addr != ( uintptr_t )last_shadow_byte
+ || ( int8_t )( last_byte & KASAN_SHADOW_MASK ) >= *last_shadow_byte
+ ) {
+ return non_zero_shadow_addr;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * @fn void kasan_poison_shadow(uintptr_t, size_t, uint8_t, bool)
+ * @brief Poison shadow with map if set
+ * @param addr
+ * @param size
+ * @param val
+ * @param map
+ */
+void kasan_poison_shadow(
+ const uintptr_t addr,
+ const size_t size,
+ const uint8_t val,
+ const bool map
+) {
+ const uintptr_t shadow_start = KASAN_MEM_TO_SHADOW( addr );
+ const uintptr_t shadow_end = KASAN_MEM_TO_SHADOW( addr + size - 1 ) + 1;
+ const size_t shadow_length = shadow_end - shadow_start;
+ // perform map if set
+ if ( map ) {
+ // set start if not set
+ if ( kasan_shadow_memory_start == 0 ) {
+ kasan_shadow_memory_start = ROUND_DOWN_TO_FULL_PAGE( shadow_start );
+ }
+ // map it
+ for (
+ uintptr_t map_addr = ROUND_DOWN_TO_FULL_PAGE( shadow_start );
+ map_addr < shadow_end;
+ map_addr += PAGE_SIZE
+ ) {
+ // handle already mapped
+ if ( virt_is_mapped( map_addr ) ) {
+ continue;
+ }
+ // map it
+ assert( virt_map_address_random(
+ virt_current_kernel_context,
+ map_addr,
+ VIRT_MEMORY_TYPE_NORMAL_NC,
+ VIRT_PAGE_TYPE_READ | VIRT_PAGE_TYPE_WRITE
+ ) );
+ // adjust end
+ kasan_shadow_memory_end = map_addr + PAGE_SIZE;
+ }
+ }
+ memset( ( void* )shadow_start, val, shadow_length );
+}
+
+/**
+ * @fn void kasan_unpoison_shadow(uintptr_t, size_t)
+ * @brief Wrapper to unpoison shadow address
+ * @param address
+ * @param size
+ */
+void kasan_unpoison_shadow( const uintptr_t address, const size_t size ) {
+ kasan_poison_shadow(
+ address,
+ size & ~KASAN_SHADOW_MASK,
+ ASAN_SHADOW_UNPOISONED_MAGIC,
+ false
+ );
+ if (size & KASAN_SHADOW_MASK) {
+ auto const shadow = ( uint8_t* )KASAN_MEM_TO_SHADOW( address + size );
+ *shadow = size & KASAN_SHADOW_MASK;
+ }
+}
+
+/**
+ * @fn int kasan_check_memory(uintptr_t, size_t, bool, uintptr_t)
+ * @brief Kasan check memory helper
+ * @param addr
+ * @param size
+ * @param write
+ * @param pc
+ * @return
+ */
+int kasan_check_memory(
+ const uintptr_t addr,
+ const size_t size,
+ const bool write,
+ const uintptr_t pc
+) {
+ // handle no size
+ if ( ! size ) {
+ return 1;
+ }
+ // handle not in memory
+ if ( addr < HEAP_START || addr > HEAP_START + HEAP_MAX_SIZE ) {
+ return 1;
+ }
+ // get poisoned shadow address
+ const uintptr_t buggy_shadow_address = kasan_get_poisoned_shadow_address(
+ addr, size );
+ if ( ! buggy_shadow_address ) {
+ return 1;
+ }
+ // report bug
+ kasan_bug_report( addr, size, buggy_shadow_address, write, pc );
+ return 0;
+}
+
+/**
+ * @fn void kasan_init(void)
+ * @brief Kasan init method
+ */
+void kasan_init( void ) {
+ // poison heap
+ kasan_poison_shadow(
+ HEAP_START,
+ HEAP_MIN_SIZE,
+ ASAN_SHADOW_RESERVED_MAGIC,
+ true
+ );
+}
+
+void __asan_handle_no_return( void ) {}
+
+void __asan_store1_noabort( uintptr_t address ) {
+ kasan_check_memory( address, 1, true, KASAN_CALLER_PC );
+}
+
+void __asan_store2_noabort( uintptr_t address ) {
+ kasan_check_memory( address, 2, true, KASAN_CALLER_PC );
+}
+
+void __asan_store4_noabort( uintptr_t address ) {
+ kasan_check_memory( address, 4, true, KASAN_CALLER_PC );
+}
+
+void __asan_store8_noabort( uintptr_t address ) {
+ kasan_check_memory( address, 8, true, KASAN_CALLER_PC );
+}
+
+void __asan_store16_noabort( uintptr_t address ) {
+ kasan_check_memory( address, 16, true, KASAN_CALLER_PC );
+}
+
+void __asan_storeN_noabort( uintptr_t address, size_t size ) {
+ kasan_check_memory( address, size, true, KASAN_CALLER_PC );
+}
+
+void __asan_load1_noabort( uintptr_t address ) {
+ kasan_check_memory( address, 1, false, KASAN_CALLER_PC );
+}
+
+void __asan_load2_noabort( uintptr_t address ) {
+ kasan_check_memory( address, 2, false, KASAN_CALLER_PC );
+}
+
+void __asan_load4_noabort( uintptr_t address ) {
+ kasan_check_memory( address, 4, false, KASAN_CALLER_PC );
+}
+
+void __asan_load8_noabort( uintptr_t address ) {
+ kasan_check_memory( address, 8, false, KASAN_CALLER_PC );
+}
+
+void __asan_load16_noabort( uintptr_t address ) {
+ kasan_check_memory( address, 16, false, KASAN_CALLER_PC );
+}
+
+void __asan_loadN_noabort( uintptr_t address, size_t size ) {
+ kasan_check_memory( address, size, false, KASAN_CALLER_PC );
+}
diff --git a/bolthur/kernel/lib/kasan/kasan.h b/bolthur/kernel/lib/kasan/kasan.h
new file mode 100644
index 000000000..925556d6e
--- /dev/null
+++ b/bolthur/kernel/lib/kasan/kasan.h
@@ -0,0 +1,95 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#ifndef _LIB_KASAN_KASAN_H
+#define _LIB_KASAN_KASAN_H
+
+#include
+#include "../../mm/heap.h"
+
+#if defined( ELF32 )
+ #define KASAN_SHADOW_MEMORY_OFFSET 0xC6000000
+#elif defined( ELF64 )
+ #error "Shadow memory offset not defined for 64 bit"
+#endif
+
+#define KASAN_CALLER_PC ( ( uintptr_t )__builtin_return_address( 0 ) )
+
+#define KASAN_SHADOW_SHIFT 3
+#define KASAN_SHADOW_GRANULE_SIZE ( 1UL << KASAN_SHADOW_SHIFT )
+#define KASAN_SHADOW_MASK ( KASAN_SHADOW_GRANULE_SIZE - 1 )
+
+#define ASAN_SHADOW_UNPOISONED_MAGIC 0x00
+#define ASAN_SHADOW_RESERVED_MAGIC 0xff
+#define ASAN_SHADOW_GLOBAL_REDZONE_MAGIC 0xf9
+#define ASAN_SHADOW_HEAP_HEAD_REDZONE_MAGIC 0xfa
+#define ASAN_SHADOW_HEAP_TAIL_REDZONE_MAGIC 0xfb
+#define ASAN_SHADOW_HEAP_FREE_MAGIC 0xfd
+
+extern uintptr_t kasan_shadow_memory_start;
+extern uintptr_t kasan_shadow_memory_end;
+
+typedef struct {
+ size_t aligned_size;
+ size_t dummy;
+} kasan_heap_header_t;
+
+#define KASAN_HEAP_HEAD_REDZONE_SIZE sizeof( kasan_heap_header_t )
+#define KASAN_HEAP_TAIL_REDZONE_SIZE sizeof( kasan_heap_header_t )
+
+#define KASAN_MEM_TO_SHADOW( addr ) ( ( ( addr ) >> KASAN_SHADOW_SHIFT ) + KASAN_SHADOW_MEMORY_OFFSET )
+#define KASAN_SHADOW_TO_MEM( shadow ) ( ( ( shadow ) - KASAN_SHADOW_MEMORY_OFFSET ) << KASAN_SHADOW_SHIFT )
+
+// printing related functions
+void kasan_print_16_bytes_no_bug(const char*, uintptr_t );
+void kasan_print_16_bytes_with_bug(const char*, uintptr_t, uintptr_t );
+void kasan_print_shadow_memory( uintptr_t, uintptr_t, uintptr_t );
+void kasan_bug_report( uintptr_t, size_t, uintptr_t, bool, uintptr_t );
+
+// poison and check memory
+uintptr_t kasan_get_poisoned_shadow_address( uintptr_t, size_t );
+void kasan_poison_shadow( uintptr_t, size_t, uint8_t, bool );
+void kasan_unpoison_shadow( uintptr_t, size_t );
+int kasan_check_memory( uintptr_t, size_t, bool, uintptr_t );
+
+// hook functions
+void* kasan_aligned_alloc_hook( size_t, size_t );
+void kasan_free_hook( void* );
+
+// init
+void kasan_init( void );
+
+// asan functions
+void __asan_store1_noabort( uintptr_t );
+void __asan_store2_noabort( uintptr_t );
+void __asan_store4_noabort( uintptr_t );
+void __asan_store8_noabort( uintptr_t );
+void __asan_store16_noabort( uintptr_t );
+void __asan_storeN_noabort( uintptr_t, size_t );
+
+void __asan_load1_noabort( uintptr_t );
+void __asan_load2_noabort( uintptr_t );
+void __asan_load4_noabort( uintptr_t );
+void __asan_load8_noabort( uintptr_t );
+void __asan_load16_noabort( uintptr_t );
+void __asan_loadN_noabort( uintptr_t, size_t );
+
+void __asan_handle_no_return( void );
+
+#endif
diff --git a/bolthur/kernel/lib/kasan/print.c b/bolthur/kernel/lib/kasan/print.c
new file mode 100644
index 000000000..cf09aa252
--- /dev/null
+++ b/bolthur/kernel/lib/kasan/print.c
@@ -0,0 +1,124 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include "../inttypes.h"
+#include "../stdio.h"
+#include "kasan.h"
+#include "../../debug/debug.h"
+
+/**
+ * @fn void kasan_print_16_bytes_no_bug(const char*, uintptr_t)
+ * @brief Print 16 bytes no bug
+ * @param prefix
+ * @param address
+ */
+void kasan_print_16_bytes_no_bug(const char* prefix, const uintptr_t address) {
+ printf( "%s%#"PRIxPTR":", prefix, address );
+ for ( uintptr_t i = 0; i < 16; i++ ) {
+ printf( " %02"PRIx8, *( uint8_t* )( address + i ) );
+ }
+ printf( "\r\n" );
+}
+
+/**
+ * @fn void kasan_print_16_bytes_with_bug(const char*, uintptr_t, uintptr_t)
+ * @brief Print 16 bytes with bug
+ * @param prefix
+ * @param address
+ * @param buggy_offset
+ */
+void kasan_print_16_bytes_with_bug(
+ const char* prefix,
+ const uintptr_t address,
+ const uintptr_t buggy_offset
+) {
+ printf( "%s%#"PRIxPTR":", prefix, address );
+ for ( uintptr_t i = 0; i < buggy_offset; i++ ) {
+ printf( " %02"PRIx8, *( uint8_t* )( address + i ) );
+ }
+ printf( "[%02"PRIx8"]", *( uint8_t* )( address + buggy_offset ) );
+ if ( buggy_offset < 15 ) {
+ printf( "%02"PRIx8, *( uint8_t* )( address + buggy_offset + 1 ) );
+ }
+ for ( uintptr_t i = buggy_offset + 2; i < 16; i++ ) {
+ printf( " %02"PRIx8, *( uint8_t* )( address + i ) );
+ }
+ printf( "\r\n" );
+}
+
+/**
+ * @fn void kasan_print_shadow_memory(uintptr_t, uintptr_t, uintptr_t)
+ * @brief Function to print shadow memory
+ * @param addr
+ * @param before
+ * @param after
+ */
+void kasan_print_shadow_memory(
+ const uintptr_t addr,
+ uintptr_t before,
+ uintptr_t after
+) {
+ const uintptr_t shadow_address = KASAN_MEM_TO_SHADOW( addr );
+ const uintptr_t aligned_shadow = shadow_address & 0xfffffff0;
+ const uintptr_t buggy_offset = shadow_address - aligned_shadow;
+
+ printf( "[KASan] Shadow bytes around the buggy address %#"PRIxPTR" (shadow %#"PRIxPTR"):\r\n",
+ addr, shadow_address );
+ const uintptr_t max_before = shadow_address - kasan_shadow_memory_start;
+ const uintptr_t max_after = kasan_shadow_memory_start - 1 - shadow_address;
+ if ( before * 16 > max_before ) {
+ before = max_before / 16;
+ }
+ if ( after * 16 > max_after ) {
+ after = max_after / 16;
+ }
+ // print memory before
+ for (uintptr_t i = before; i > 0; i--) {
+ kasan_print_16_bytes_no_bug("[KASan] ", aligned_shadow - i * 16);
+ }
+ // print buggy memory
+ kasan_print_16_bytes_with_bug("[KASan] =>", aligned_shadow, buggy_offset);
+ // print memory after
+ for (uintptr_t i = 1; i <= after; i++) {
+ kasan_print_16_bytes_no_bug("[KASan] ", aligned_shadow + i * 16);
+ }
+}
+
+/**
+ * @fn void kasan_bug_report(uintptr_t, size_t, uintptr_t, bool, uintptr_t)
+ * @brief Wrapper to print found bug
+ * @param addr
+ * @param size
+ * @param buggy_shadow_address
+ * @param write
+ * @param pc
+ */
+void kasan_bug_report(
+ const uintptr_t addr,
+ const size_t size,
+ const uintptr_t buggy_shadow_address,
+ const bool write,
+ const uintptr_t pc
+) {
+ [[maybe_unused]] uintptr_t buggy_address = KASAN_SHADOW_TO_MEM( buggy_shadow_address );
+ printf( "[KASan] ===================================================\r\n" );
+ printf( "[KASan] ERROR: Invalid memory access: address %#"PRIxPTR", size %zu, write %d, ip %#"PRIxPTR"\r\n",
+ addr, size, write ? 1 : 0, pc );
+ kasan_print_shadow_memory( buggy_address, 3, 3 );
+}
diff --git a/bolthur/kernel/lib/libc/assert.c b/bolthur/kernel/lib/libc/assert.c
index 95a5ff46e..a5eb7ba26 100644
--- a/bolthur/kernel/lib/libc/assert.c
+++ b/bolthur/kernel/lib/libc/assert.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/ctype/isdigit.c b/bolthur/kernel/lib/libc/ctype/isdigit.c
index 1c521bc5e..f43062b4f 100644
--- a/bolthur/kernel/lib/libc/ctype/isdigit.c
+++ b/bolthur/kernel/lib/libc/ctype/isdigit.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/ctype/islower.c b/bolthur/kernel/lib/libc/ctype/islower.c
index 967d94f47..06b7b244b 100644
--- a/bolthur/kernel/lib/libc/ctype/islower.c
+++ b/bolthur/kernel/lib/libc/ctype/islower.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/ctype/isspace.c b/bolthur/kernel/lib/libc/ctype/isspace.c
index b1172139b..a1810767c 100644
--- a/bolthur/kernel/lib/libc/ctype/isspace.c
+++ b/bolthur/kernel/lib/libc/ctype/isspace.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/ctype/isupper.c b/bolthur/kernel/lib/libc/ctype/isupper.c
index 814f113b1..c818a6d9f 100644
--- a/bolthur/kernel/lib/libc/ctype/isupper.c
+++ b/bolthur/kernel/lib/libc/ctype/isupper.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/stdio/printf.c b/bolthur/kernel/lib/libc/stdio/printf.c
index 150ca8b1e..872189b8f 100644
--- a/bolthur/kernel/lib/libc/stdio/printf.c
+++ b/bolthur/kernel/lib/libc/stdio/printf.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/stdio/putchar.c b/bolthur/kernel/lib/libc/stdio/putchar.c
index 353ad2b0b..7974d961e 100644
--- a/bolthur/kernel/lib/libc/stdio/putchar.c
+++ b/bolthur/kernel/lib/libc/stdio/putchar.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/stdio/puts.c b/bolthur/kernel/lib/libc/stdio/puts.c
index ec430414f..ad0d8bc86 100644
--- a/bolthur/kernel/lib/libc/stdio/puts.c
+++ b/bolthur/kernel/lib/libc/stdio/puts.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/stdio/sprintf.c b/bolthur/kernel/lib/libc/stdio/sprintf.c
index dd5777c00..c9db577eb 100644
--- a/bolthur/kernel/lib/libc/stdio/sprintf.c
+++ b/bolthur/kernel/lib/libc/stdio/sprintf.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/stdio/vsprintf.c b/bolthur/kernel/lib/libc/stdio/vsprintf.c
index 6c440798f..57c444fba 100644
--- a/bolthur/kernel/lib/libc/stdio/vsprintf.c
+++ b/bolthur/kernel/lib/libc/stdio/vsprintf.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -167,7 +167,6 @@ static int print(
int vsprintf( char* _buffer, const char* restrict format, va_list parameter ) {
uint32_t written = 0;
int print_written;
- size_t amount;
char buf[ 256 ];
char* buffer = _buffer;
@@ -184,7 +183,7 @@ int vsprintf( char* _buffer, const char* restrict format, va_list parameter ) {
format++;
}
// amount of characters to print
- amount = 1;
+ size_t amount = 1;
while ( format[ amount ] && format[ amount ] != '%' ) {
amount++;
}
diff --git a/bolthur/kernel/lib/libc/stdlib/abort.c b/bolthur/kernel/lib/libc/stdlib/abort.c
index 654471d5e..4944f7831 100644
--- a/bolthur/kernel/lib/libc/stdlib/abort.c
+++ b/bolthur/kernel/lib/libc/stdlib/abort.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/stdlib/aligned_alloc.c b/bolthur/kernel/lib/libc/stdlib/aligned_alloc.c
index b59f07d1a..006fda4d6 100644
--- a/bolthur/kernel/lib/libc/stdlib/aligned_alloc.c
+++ b/bolthur/kernel/lib/libc/stdlib/aligned_alloc.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,6 +20,9 @@
#include
#include "../../stdlib.h"
#include "../../../mm/heap.h"
+#if defined( HAS_SANITIZER )
+ #include "../../kasan/kasan.h"
+#endif
/**
* @fn void aligned_alloc*(size_t, size_t)
@@ -34,6 +37,12 @@ __allocator void* aligned_alloc( size_t alignment, size_t size ) {
if ( 0 == size ) {
return NULL;
}
- // use heap allocation
- return heap_allocate( alignment, size );
+ // sanitizer stuff
+ #if defined( HAS_SANITIZER )
+ return kasan_aligned_alloc_hook( alignment, size );
+ // no sanitizer stuff
+ #else
+ // use heap allocation
+ return heap_allocate( alignment, size );
+ #endif
}
diff --git a/bolthur/kernel/lib/libc/stdlib/calloc.c b/bolthur/kernel/lib/libc/stdlib/calloc.c
index a5c0a18d6..2a7a1307c 100644
--- a/bolthur/kernel/lib/libc/stdlib/calloc.c
+++ b/bolthur/kernel/lib/libc/stdlib/calloc.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/stdlib/free.c b/bolthur/kernel/lib/libc/stdlib/free.c
index 0345e49e1..9a5699c91 100644
--- a/bolthur/kernel/lib/libc/stdlib/free.c
+++ b/bolthur/kernel/lib/libc/stdlib/free.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -19,6 +19,9 @@
#include "../../stdlib.h"
#include "../../../mm/heap.h"
+#if defined( HAS_SANITIZER )
+ #include "../../kasan/kasan.h"
+#endif
/**
* @fn void free(void*)
@@ -27,5 +30,11 @@
* @param ptr ptr to address to free
*/
void free( void* ptr ) {
- heap_free( ptr );
+ // sanitizer stuff
+ #if defined( HAS_SANITIZER )
+ kasan_free_hook( ptr );
+ // non sanitizer stuff
+ #else
+ heap_free( ptr );
+ #endif
}
diff --git a/bolthur/kernel/lib/libc/stdlib/malloc.c b/bolthur/kernel/lib/libc/stdlib/malloc.c
index dfffc359e..b666016f8 100644
--- a/bolthur/kernel/lib/libc/stdlib/malloc.c
+++ b/bolthur/kernel/lib/libc/stdlib/malloc.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/stdlib/strtoul.c b/bolthur/kernel/lib/libc/stdlib/strtoul.c
index 7bea721a0..1d6cea375 100644
--- a/bolthur/kernel/lib/libc/stdlib/strtoul.c
+++ b/bolthur/kernel/lib/libc/stdlib/strtoul.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/string/memchr.c b/bolthur/kernel/lib/libc/string/memchr.c
index e377a3b56..b1c305ef9 100644
--- a/bolthur/kernel/lib/libc/string/memchr.c
+++ b/bolthur/kernel/lib/libc/string/memchr.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/string/memcmp.c b/bolthur/kernel/lib/libc/string/memcmp.c
index 83b1d5fe9..7c83c116a 100644
--- a/bolthur/kernel/lib/libc/string/memcmp.c
+++ b/bolthur/kernel/lib/libc/string/memcmp.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/string/memcpy.c b/bolthur/kernel/lib/libc/string/memcpy.c
index 6a9ee4f50..d51be2f7d 100644
--- a/bolthur/kernel/lib/libc/string/memcpy.c
+++ b/bolthur/kernel/lib/libc/string/memcpy.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -21,6 +21,9 @@
#include
#include "../../string.h"
#include "../../../mm/virt.h"
+#if defined( HAS_SANITIZER )
+ #include "../../kasan/kasan.h"
+#endif
#define U64_BLOCK_SIZE sizeof( uint64_t )
#define UNALIGNED(a, b) ((( uintptr_t )a & ( U64_BLOCK_SIZE - 1 )) | (( uintptr_t )b & ( U64_BLOCK_SIZE - 1 )))
@@ -35,6 +38,11 @@
* @param size
*/
void* memcpy( void* restrict dst, const void* restrict src, size_t size ) {
+ #if defined( HAS_SANITIZER )
+ kasan_check_memory( ( uintptr_t )dst, size, 1, KASAN_CALLER_PC );
+ kasan_check_memory( ( uintptr_t )src, size, 1, KASAN_CALLER_PC );
+ #endif
+
uint8_t* u8_dst = ( uint8_t * )dst;
const uint8_t* u8_src = ( const uint8_t * )src;
// copy in 4 byte chunks
diff --git a/bolthur/kernel/lib/libc/string/memmove.c b/bolthur/kernel/lib/libc/string/memmove.c
index 3bdce3e48..87c1a2f4b 100644
--- a/bolthur/kernel/lib/libc/string/memmove.c
+++ b/bolthur/kernel/lib/libc/string/memmove.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/string/memset.c b/bolthur/kernel/lib/libc/string/memset.c
index c7bc4e633..0e4b62c6a 100644
--- a/bolthur/kernel/lib/libc/string/memset.c
+++ b/bolthur/kernel/lib/libc/string/memset.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,6 +20,9 @@
#include
#include
#include "../../string.h"
+#if defined( HAS_SANITIZER )
+ #include "../../kasan/kasan.h"
+#endif
#define U64_BLOCK_SIZE sizeof( uint64_t )
#define BUFFER_UNALIGNED(val) (( uintptr_t )val & ( U64_BLOCK_SIZE - 1 ))
@@ -34,9 +37,13 @@
* @param size length
* @return void* address to buffer
*/
-void* memset( void* buf, int value, size_t size ) {
- uint8_t* u8_buf = ( uint8_t* )buf;
- uint8_t u8_value = ( uint8_t )value;
+void* memset( void* buf, const int value, size_t size ) {
+ #if defined( HAS_SANITIZER )
+ kasan_check_memory( ( uintptr_t )buf, size, 1, KASAN_CALLER_PC );
+ #endif
+
+ auto u8_buf = ( uint8_t* )buf;
+ const uint8_t u8_value = ( uint8_t )value;
// set until alignment fits
while( BUFFER_UNALIGNED( u8_buf ) ) {
@@ -51,7 +58,7 @@ void* memset( void* buf, int value, size_t size ) {
// set in 8 byte steps as it's now aligned
if ( ! SIZE_TOO_SMALL( size ) ) {
// prepare value for set
- uint64_t u64_value = ( uint64_t )u8_value << 56
+ const uint64_t u64_value = ( uint64_t )u8_value << 56
| ( uint64_t )u8_value << 48
| ( uint64_t )u8_value << 40
| ( uint64_t )u8_value << 32
@@ -60,7 +67,7 @@ void* memset( void* buf, int value, size_t size ) {
| ( uint64_t )u8_value << 8
| ( uint64_t )u8_value;
// set pointer
- uint64_t* u64_buf = ( uint64_t* )u8_buf;
+ auto u64_buf = ( uint64_t* )u8_buf;
// set as much as possible at once
while ( size >= U64_BLOCK_SIZE * 4 ) {
*u64_buf++ = u64_value;
@@ -74,6 +81,7 @@ void* memset( void* buf, int value, size_t size ) {
*u64_buf++ = u64_value;
size -= U64_BLOCK_SIZE;
}
+ u8_buf = ( uint8_t* )u64_buf;
}
// set rest
while( size-- ) {
diff --git a/bolthur/kernel/lib/libc/string/strchr.c b/bolthur/kernel/lib/libc/string/strchr.c
index bc5744500..8cafb2cce 100644
--- a/bolthur/kernel/lib/libc/string/strchr.c
+++ b/bolthur/kernel/lib/libc/string/strchr.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/string/strcpy.c b/bolthur/kernel/lib/libc/string/strcpy.c
index a918a8e8f..5216f90f7 100644
--- a/bolthur/kernel/lib/libc/string/strcpy.c
+++ b/bolthur/kernel/lib/libc/string/strcpy.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/string/strlen.c b/bolthur/kernel/lib/libc/string/strlen.c
index c3848bab9..67e356eee 100644
--- a/bolthur/kernel/lib/libc/string/strlen.c
+++ b/bolthur/kernel/lib/libc/string/strlen.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -23,10 +23,6 @@
#include "../../../mm/virt.h"
#include "../../../debug/debug.h"
-#define U64_BLOCK_SIZE sizeof( uint64_t )
-#define BUFFER_UNALIGNED(val) ( ( uintptr_t )val & ( U64_BLOCK_SIZE - 1 ) )
-#define DETECT_NULL_ENDING(x) ( ( x - 0x0101010101010101) & ~x & 0x8080808080808080 )
-
/**
* @fn size_t strlen(const char*)
* @brief Get string length
@@ -40,22 +36,7 @@ size_t strlen( const char* str ) {
if ( ! str ) {
return 0;
}
- // loop until alignment
- while( BUFFER_UNALIGNED( str ) ) {
- // handle end reached
- if ( !*str ) {
- return ( size_t )( str - start );
- }
- // increment
- str++;
- }
- // use 64bit for checks
- uint64_t* aligned = ( uint64_t* )str;
- while ( ! DETECT_NULL_ENDING( *aligned ) ) {
- aligned++;
- }
- // update str
- str = ( const char* )aligned;
+ // loop until null termination
while ( *str ) {
str++;
}
@@ -77,7 +58,7 @@ size_t strlen_unsafe( const char* str ) {
}
// variables
uintptr_t last_check = ROUND_DOWN_TO_FULL_PAGE( str );
- const char* next_check = ( const char* )( last_check + PAGE_SIZE );
+ auto next_check = ( char* )( last_check + PAGE_SIZE );
const char* start = str;
// loop until end is reached or some memory is not mapped
do {
@@ -85,35 +66,6 @@ size_t strlen_unsafe( const char* str ) {
if ( ! virt_is_mapped_range( last_check, PAGE_SIZE ) ) {
return 0;
}
- // loop until alignment
- while( BUFFER_UNALIGNED( str ) && str < next_check ) {
- // handle end reached
- if ( !*str ) {
- return ( size_t )( str - start );
- }
- // increment
- str++;
- }
- // handle page boundary reached
- if ( str == next_check ) {
- last_check = ( uintptr_t )next_check;
- next_check = ( const char* )( last_check + PAGE_SIZE );
- continue;
- }
- // use 64bit for checks
- uint64_t* aligned = ( uint64_t* )str;
- uint64_t* aligned_end = ( uint64_t* )next_check;
- while ( ! DETECT_NULL_ENDING( *aligned ) && aligned < aligned_end ) {
- aligned++;
- }
- // update str
- str = ( const char* )aligned;
- // handle page boundary reached
- if ( str == next_check ) {
- last_check = ( uintptr_t )next_check;
- next_check = ( const char* )( last_check + PAGE_SIZE );
- continue;
- }
// continue unaligned check
while ( *str && str < next_check ) {
str++;
@@ -121,7 +73,7 @@ size_t strlen_unsafe( const char* str ) {
// handle page boundary reached
if ( str == next_check ) {
last_check = ( uintptr_t )next_check;
- next_check = ( const char* )( last_check + PAGE_SIZE );
+ next_check = ( char* )( last_check + PAGE_SIZE );
continue;
}
// return difference
diff --git a/bolthur/kernel/lib/libc/string/strncmp.c b/bolthur/kernel/lib/libc/string/strncmp.c
index 126926dca..08e757c3f 100644
--- a/bolthur/kernel/lib/libc/string/strncmp.c
+++ b/bolthur/kernel/lib/libc/string/strncmp.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/string/strnlen.c b/bolthur/kernel/lib/libc/string/strnlen.c
index 27f9206b7..9ab88354f 100644
--- a/bolthur/kernel/lib/libc/string/strnlen.c
+++ b/bolthur/kernel/lib/libc/string/strnlen.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/libc/string/strrchr.c b/bolthur/kernel/lib/libc/string/strrchr.c
index 8efff5663..740ea99a4 100644
--- a/bolthur/kernel/lib/libc/string/strrchr.c
+++ b/bolthur/kernel/lib/libc/string/strrchr.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/ssp.c b/bolthur/kernel/lib/ssp.c
index 1a78cbdb1..4a832252c 100644
--- a/bolthur/kernel/lib/ssp.c
+++ b/bolthur/kernel/lib/ssp.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/ssp.h b/bolthur/kernel/lib/ssp.h
index 9bca1ac5d..b4d77d368 100644
--- a/bolthur/kernel/lib/ssp.h
+++ b/bolthur/kernel/lib/ssp.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/stdio.h b/bolthur/kernel/lib/stdio.h
index cec44b777..0f853e342 100644
--- a/bolthur/kernel/lib/stdio.h
+++ b/bolthur/kernel/lib/stdio.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/stdlib.h b/bolthur/kernel/lib/stdlib.h
index e3e6c3d71..98ebe5a63 100644
--- a/bolthur/kernel/lib/stdlib.h
+++ b/bolthur/kernel/lib/stdlib.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -21,7 +21,6 @@
#define _LIB_STDLIB_H
#include
-#include
#include
[[noreturn]] void abort( void );
diff --git a/bolthur/kernel/lib/string.h b/bolthur/kernel/lib/string.h
index d06086cfa..8e6624a68 100644
--- a/bolthur/kernel/lib/string.h
+++ b/bolthur/kernel/lib/string.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/tar.h b/bolthur/kernel/lib/tar.h
index 2d2f49574..0c6730b02 100644
--- a/bolthur/kernel/lib/tar.h
+++ b/bolthur/kernel/lib/tar.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -21,7 +21,6 @@
#define _LIB_TAR_H
#include
-#include
#include
#define TAR_HEADER_SIZE 512
diff --git a/bolthur/kernel/lib/tar/end.c b/bolthur/kernel/lib/tar/end.c
index 09907cb26..d00b34bcf 100644
--- a/bolthur/kernel/lib/tar/end.c
+++ b/bolthur/kernel/lib/tar/end.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/tar/file.c b/bolthur/kernel/lib/tar/file.c
index 2634edb80..c0814d4e9 100644
--- a/bolthur/kernel/lib/tar/file.c
+++ b/bolthur/kernel/lib/tar/file.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/tar/helper.c b/bolthur/kernel/lib/tar/helper.c
index acfdde9ea..710dcbad0 100644
--- a/bolthur/kernel/lib/tar/helper.c
+++ b/bolthur/kernel/lib/tar/helper.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/tar/lookup.c b/bolthur/kernel/lib/tar/lookup.c
index 3d494e4c7..26156a51b 100644
--- a/bolthur/kernel/lib/tar/lookup.c
+++ b/bolthur/kernel/lib/tar/lookup.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/tar/next.c b/bolthur/kernel/lib/tar/next.c
index 62a6abeff..706c243c0 100644
--- a/bolthur/kernel/lib/tar/next.c
+++ b/bolthur/kernel/lib/tar/next.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/tar/size.c b/bolthur/kernel/lib/tar/size.c
index e9d20124e..377c6a3ed 100644
--- a/bolthur/kernel/lib/tar/size.c
+++ b/bolthur/kernel/lib/tar/size.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/ubsan.c b/bolthur/kernel/lib/ubsan.c
index 51ed5c9cb..909467bd7 100644
--- a/bolthur/kernel/lib/ubsan.c
+++ b/bolthur/kernel/lib/ubsan.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/lib/ubsan.h b/bolthur/kernel/lib/ubsan.h
index 1c2f7481d..d12f620f8 100644
--- a/bolthur/kernel/lib/ubsan.h
+++ b/bolthur/kernel/lib/ubsan.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/main.c b/bolthur/kernel/main.c
index f1ddbe586..9f7e7e9a0 100644
--- a/bolthur/kernel/main.c
+++ b/bolthur/kernel/main.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -128,14 +128,14 @@ void kernel_main( void ) {
tar_header_t* boot = tar_lookup_file( initrd_get_start_address(), "boot" );
assert( boot )
// Get file address and size
- uintptr_t elf_file = ( uintptr_t )tar_file( boot );
+ const uintptr_t elf_file = ( uintptr_t )tar_file( boot );
// Create process
DEBUG_OUTPUT( "[bolthur/kernel -> process -> init] create ...\r\n" )
task_process_t* proc = task_process_create( 0, 0 );
assert( proc )
// load flat image
- uintptr_t init_entry = elf_load( elf_file, proc );
+ const uintptr_t init_entry = elf_load( elf_file, proc );
assert( init_entry )
// add thread
assert( task_thread_create( init_entry, proc, 0 ) )
@@ -143,6 +143,10 @@ void kernel_main( void ) {
DEBUG_OUTPUT( "[bolthur/kernel -> process -> init] prepare ...\r\n" )
assert( task_process_prepare_init( proc ) )
+ // unmap initrd in kernel
+ DEBUG_OUTPUT( "[bolthur/kernel -> initrd] unmap in kernel ...\r\n" )
+ initrd_unmap();
+
// Setup timer
DEBUG_OUTPUT( "[bolthur/kernel -> timer] initialize ...\r\n" )
timer_init();
diff --git a/bolthur/kernel/mm/heap.c b/bolthur/kernel/mm/heap.c
index 3e630079b..d9c1c04bb 100644
--- a/bolthur/kernel/mm/heap.c
+++ b/bolthur/kernel/mm/heap.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -29,6 +29,9 @@
#include "../mm/heap.h"
#include "../panic.h"
#include "../debug/debug.h"
+#if defined( HAS_SANITIZER )
+ #include "../lib/kasan/kasan.h"
+#endif
void* dlmemalign( size_t, size_t );
void dlfree( void* );
@@ -48,6 +51,15 @@ bool heap_init_get( void ) {
return ( bool )kernel_heap;
}
+/**
+ * @fn heap_init_state_t heap_get_state(void)
+ * @brief Wrapper to get init state
+ * @return
+ */
+heap_init_state_t heap_get_state( void ) {
+ return kernel_heap->state;
+}
+
/**
* @fn void heap_init(heap_init_state_t)
* @brief new heap init implementation
@@ -91,6 +103,13 @@ void heap_init( heap_init_state_t state ) {
VIRT_PAGE_TYPE_READ | VIRT_PAGE_TYPE_WRITE
) )
}
+ // init kasan
+ #if defined( HAS_SANITIZER )
+ #if defined( PRINT_MM_HEAP )
+ DEBUG_OUTPUT( "Initializing kasan\r\n" )
+ #endif
+ kasan_init();
+ #endif
// set state
kernel_heap->state = state;
// skip rest
@@ -469,8 +488,11 @@ void* heap_sbrk( intptr_t increment ) {
#endif
return ( void* )-1;
}
- // clear area
- memset( ( void* )addr, 0, PAGE_SIZE );
+ // sanitizer stuff
+ #if defined( HAS_SANITIZER )
+ // poison area
+ kasan_poison_shadow( addr, PAGE_SIZE, ASAN_SHADOW_RESERVED_MAGIC, true );
+ #endif
// update max heap address
min_heap += PAGE_SIZE;
}
diff --git a/bolthur/kernel/mm/heap.h b/bolthur/kernel/mm/heap.h
index 66904eea3..2e66cce7a 100644
--- a/bolthur/kernel/mm/heap.h
+++ b/bolthur/kernel/mm/heap.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -21,7 +21,6 @@
#define _MM_HEAP_H
#include
-#include
#include "../entry.h"
#if defined( ELF32 )
@@ -33,6 +32,9 @@
#error "Heap not ready for x64"
#endif
+extern uintptr_t __initial_heap_start;
+extern uintptr_t __initial_heap_end;
+
typedef enum {
HEAP_INIT_EARLY = 0,
HEAP_INIT_NORMAL,
@@ -58,10 +60,8 @@ typedef struct {
heap_block_t* free;
} heap_manager_t;
-extern uintptr_t __initial_heap_start;
-extern uintptr_t __initial_heap_end;
-
bool heap_init_get( void );
+heap_init_state_t heap_get_state( void );
void heap_init( heap_init_state_t );
void* heap_allocate( size_t, size_t );
void heap_free( void* );
diff --git a/bolthur/kernel/mm/phys.c b/bolthur/kernel/mm/phys.c
index 25854f699..20e7cec12 100644
--- a/bolthur/kernel/mm/phys.c
+++ b/bolthur/kernel/mm/phys.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/mm/phys.h b/bolthur/kernel/mm/phys.h
index 600910297..6e04c971d 100644
--- a/bolthur/kernel/mm/phys.h
+++ b/bolthur/kernel/mm/phys.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -23,7 +23,6 @@
#include
#include
#include
-#include
#define PAGE_PER_ENTRY ( sizeof( phys_bitmap_length ) * CHAR_BIT )
#define PAGE_INDEX( address ) ( address / PAGE_PER_ENTRY )
diff --git a/bolthur/kernel/mm/shared.c b/bolthur/kernel/mm/shared.c
index a23f3c664..ff11d1695 100644
--- a/bolthur/kernel/mm/shared.c
+++ b/bolthur/kernel/mm/shared.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -44,7 +44,7 @@ avl_tree_t* shared_tree = NULL;
*/
static int32_t lookup_process( const list_item_t* a, const void* b ) {
// get blocks
- auto const shared_memory_entry_mapped_t* item = ( const shared_memory_entry_mapped_t* )
+ auto const item = ( const shared_memory_entry_mapped_t* )
a->data;
// compare process structures
if ( item->process == ( task_process_t* )b ) {
@@ -55,13 +55,13 @@ static int32_t lookup_process( const list_item_t* a, const void* b ) {
/**
* @fn void cleanup_process(list_item_t*)
- * @brief Helper to cleanup process list
+ * @brief Helper to clean up process list
*
* @param a
*/
static void cleanup_process( list_item_t* a ) {
// get blocks
- auto const shared_memory_entry_mapped_t* item = ( const shared_memory_entry_mapped_t* )a->data;
+ auto const item = ( const shared_memory_entry_mapped_t* )a->data;
// set start and end
uintptr_t start = item->start;
const uintptr_t end = start + item->size;
@@ -311,7 +311,7 @@ uintptr_t shared_memory_attach(
#endif
return 0;
}
- shared_memory_entry_t* entry = SHARED_ENTRY_GET_BLOCK( node );
+ auto entry = SHARED_ENTRY_GET_BLOCK( node );
// debug output
#if defined( PRINT_MM_SHARED )
DEBUG_OUTPUT( "node = %p, entry = %p\r\n", node, entry )
@@ -327,7 +327,7 @@ uintptr_t shared_memory_attach(
// handle already attached
if ( process_list_item ) {
// transform to mapped entry
- auto const shared_memory_entry_mapped_t* mapped = ( const shared_memory_entry_mapped_t* )
+ auto const mapped = ( const shared_memory_entry_mapped_t* )
process_list_item->data;
// debug output
#if defined( PRINT_MM_SHARED )
@@ -492,7 +492,7 @@ size_t shared_memory_size( task_process_t* process, size_t id ) {
#endif
return 0;
}
- auto shared_memory_entry_t* entry = SHARED_ENTRY_GET_BLOCK( node );
+ auto entry = SHARED_ENTRY_GET_BLOCK( node );
// debug output
#if defined( PRINT_MM_SHARED )
DEBUG_OUTPUT( "node = %p, entry = %p\r\n", node, entry )
@@ -548,7 +548,7 @@ bool shared_memory_detach( task_process_t* process, size_t id ) {
#endif
return true;
}
- auto shared_memory_entry_t* entry = SHARED_ENTRY_GET_BLOCK( node );
+ auto const entry = SHARED_ENTRY_GET_BLOCK( node );
// lookup process
list_item_t* process_list_item = list_lookup_data(
entry->process_mapping, process );
@@ -562,7 +562,7 @@ bool shared_memory_detach( task_process_t* process, size_t id ) {
return true;
}
// remove from list with destruction of item
- if ( ! list_remove_item( entry->process_mapping, process_list_item ) ) {
+ if ( ! list_remove_item( entry->process_mapping, process_list_item, true ) ) {
// debug output
#if defined( PRINT_MM_SHARED )
DEBUG_OUTPUT( "Remove of process from mapping list failed\r\n" )
@@ -615,7 +615,7 @@ bool shared_memory_phys_is_shared(
// loop until end
while ( NULL != node ) {
// get mapped entry
- auto const shared_memory_entry_t* entry = SHARED_ENTRY_GET_BLOCK( node );
+ auto const entry = SHARED_ENTRY_GET_BLOCK( node );
// lookup process
const list_item_t* process_list_item = list_lookup_data(
entry->process_mapping, process );
@@ -704,14 +704,14 @@ bool shared_memory_fork(
// loop until end
while ( NULL != node ) {
// get mapped entry
- auto const shared_memory_entry_t* entry = SHARED_ENTRY_GET_BLOCK( node );
+ auto const entry = SHARED_ENTRY_GET_BLOCK( node );
// lookup process
const list_item_t* process_list_item = list_lookup_data(
entry->process_mapping, process_to_fork );
// handle attached
if ( process_list_item ) {
// transform to mapped entry
- auto const shared_memory_entry_mapped_t* mapped_to_fork = ( const shared_memory_entry_mapped_t* )
+ auto const mapped_to_fork = ( const shared_memory_entry_mapped_t* )
process_list_item->data;
// reserve space for fork
shared_memory_entry_mapped_t* mapped_fork = malloc( sizeof( *mapped_fork ) );
@@ -750,7 +750,7 @@ bool shared_memory_cleanup_process( task_process_t* proc ) {
// loop until end
while ( NULL != node ) {
// get mapped entry
- auto const shared_memory_entry_t* entry = SHARED_ENTRY_GET_BLOCK( node );
+ auto const entry = SHARED_ENTRY_GET_BLOCK( node );
// detach shared memory
if ( ! shared_memory_detach( proc, entry->id ) ) {
return false;
diff --git a/bolthur/kernel/mm/shared.h b/bolthur/kernel/mm/shared.h
index 7bdaa4c69..12e3a202d 100644
--- a/bolthur/kernel/mm/shared.h
+++ b/bolthur/kernel/mm/shared.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -21,7 +21,6 @@
#define _MM_SHARED_H
#include
-#include
#include "../../library/collection/list/list.h"
#include "../../library/collection/avl/avl.h"
#include "../task/process.h"
diff --git a/bolthur/kernel/mm/virt.c b/bolthur/kernel/mm/virt.c
index 1a0c60467..456ae30c3 100644
--- a/bolthur/kernel/mm/virt.c
+++ b/bolthur/kernel/mm/virt.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -106,10 +106,10 @@ void virt_init( void ) {
#endif
// map initial heap similar to normal heap non cachable
- uintptr_t phys_bss_start = VIRT_2_PHYS( &__bss_start );
- uintptr_t phys_bss_end = VIRT_2_PHYS( &__bss_end );
- uintptr_t phys_data_start = VIRT_2_PHYS( &__data_start );
- uintptr_t phys_data_end = VIRT_2_PHYS( &__data_end );
+ const uintptr_t phys_bss_start = VIRT_2_PHYS( &__bss_start );
+ const uintptr_t phys_bss_end = VIRT_2_PHYS( &__bss_end );
+ const uintptr_t phys_data_start = VIRT_2_PHYS( &__data_start );
+ const uintptr_t phys_data_end = VIRT_2_PHYS( &__data_end );
// map from start to end addresses as used
while ( start < end ) {
@@ -389,7 +389,7 @@ uintptr_t virt_find_free_page_range(
#endif
for ( uint32_t idx = index; idx < ctx->bitmap_length && !stop; idx++ ) {
#if defined( PRINT_MM_VIRT )
- DEBUG_OUTPUT( "ctx->bitmap[ %d ] = %#"PRIx32"\r\n", idx, ctx->bitmap[ idx ] )
+ DEBUG_OUTPUT( "ctx->bitmap[ %"PRIu32" ] = %#"PRIx32"\r\n", idx, ctx->bitmap[ idx ] )
#endif
// skip completely used entries
if ( PHYS_ALL_PAGES_OF_INDEX_USED == ctx->bitmap[ idx ] ) {
diff --git a/bolthur/kernel/mm/virt.h b/bolthur/kernel/mm/virt.h
index 800c28db7..3289b712a 100644
--- a/bolthur/kernel/mm/virt.h
+++ b/bolthur/kernel/mm/virt.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -21,7 +21,6 @@
#define _MM_VIRT_H
#include
-#include
#include
// forward declarations
diff --git a/bolthur/kernel/panic.c b/bolthur/kernel/panic.c
index e135dec6d..c17e6b7de 100644
--- a/bolthur/kernel/panic.c
+++ b/bolthur/kernel/panic.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/panic.h b/bolthur/kernel/panic.h
index e76533b24..acdd2e35e 100644
--- a/bolthur/kernel/panic.h
+++ b/bolthur/kernel/panic.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/platform/raspi/boot.c b/bolthur/kernel/platform/raspi/boot.c
index 2b3bc7fab..227514ecc 100644
--- a/bolthur/kernel/platform/raspi/boot.c
+++ b/bolthur/kernel/platform/raspi/boot.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/platform/raspi/boot.h b/bolthur/kernel/platform/raspi/boot.h
index 2f34a6899..66b4293f1 100644
--- a/bolthur/kernel/platform/raspi/boot.h
+++ b/bolthur/kernel/platform/raspi/boot.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -23,4 +23,4 @@
void boot_serial_init( void );
void boot_serial_putc();
-#endif //_PLATFORM_RASPI_BOOT_H
+#endif
diff --git a/bolthur/kernel/platform/raspi/gpio.h b/bolthur/kernel/platform/raspi/gpio.h
index 20a2c7dd7..0228af420 100644
--- a/bolthur/kernel/platform/raspi/gpio.h
+++ b/bolthur/kernel/platform/raspi/gpio.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/platform/raspi/interrupt.c b/bolthur/kernel/platform/raspi/interrupt.c
index 3174e72d4..d0f59c851 100644
--- a/bolthur/kernel/platform/raspi/interrupt.c
+++ b/bolthur/kernel/platform/raspi/interrupt.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -23,7 +23,10 @@
#include "../../panic.h"
#include "gpio.h"
#include "peripheral.h"
+#include "../../lib/inttypes.h"
#include "../../debug/debug.h"
+#include "interrupt.h"
+#include "timer.h"
/**
* @fn bool interrupt_validate_number(size_t)
@@ -35,17 +38,57 @@
*/
bool interrupt_validate_number( const size_t num ) {
return ! (
- num != 1 && num != 8
- && num != 29 && num != 43
- && num != 45 && num != 46
- && num != 48 && num != 49
- && num != 50 && num != 51
- && num != 52 && num != 53
- && num != 54 && num != 55
- && num != 57
+ num != IRQ_MAILBOX && num != SYSTEM_TIMER_3_INTERRUPT
+ && num != IRQ_USB && num != IRQ_AUX
+ && num != IRQ_I2C_SPI && num != IRQ_PWA0
+ && num != IRQ_PWA1 && num != IRQ_SMI
+ && num != IRQ_GPIO0 && num != IRQ_GPIO1
+ && num != IRQ_GPIO2 && num != IRQ_GPIO3
+ && num != IRQ_I2C && num != IRQ_SPI
+ && num != IRQ_PCM && num != IRQ_UART
);
}
+/**
+ * @fn bool interrupt_validate_number_rpc(size_t)
+ * @brief Function to validate number for rpc
+ * @param num number to validate
+ * @return
+ */
+bool interrupt_validate_number_rpc( const size_t num ) {
+ return interrupt_validate_number( num ) && !(
+ num != IRQ_USB
+ );
+}
+
+/**
+ * @fn void interrupt_clear(int8_t)
+ * @brief Method to clear interrupt
+ * @param num interrupt number to clear
+ */
+void interrupt_clear( const int8_t num ) {
+ uint32_t interrupt = ( uint32_t )num;
+ // get peripheral base
+ const uintptr_t base = peripheral_base_get( PERIPHERAL_GPIO );
+ // get interrupt enable and pending
+ uintptr_t interrupt_pending = base;
+ if ( 32 > interrupt ) {
+ interrupt_pending += INTERRUPT_IRQ_PENDING_1;
+ } else if ( 64 > interrupt ) {
+ interrupt_pending += INTERRUPT_IRQ_PENDING_2;
+ interrupt -= 32;
+ } else {
+ PANIC( "Unsupported interrupt number!" )
+ }
+ // transform to bit
+ interrupt = 1 << interrupt;
+ // get and clear pending interrupt from memory
+ uint32_t interrupt_line = io_in32( interrupt_pending );
+ interrupt_line &= ~interrupt;
+ // write changes
+ io_out32( interrupt_pending, interrupt_line );
+}
+
/**
* @fn void interrupt_enable_specific(int8_t)
* @brief Enable specific interrupt
@@ -53,7 +96,7 @@ bool interrupt_validate_number( const size_t num ) {
* @param num interrupt number to enable
*/
void interrupt_mask_specific( const int8_t num ) {
- const uint32_t interrupt = ( uint32_t )num;
+ uint32_t interrupt = ( uint32_t )num;
// get peripheral base
const uintptr_t base = peripheral_base_get( PERIPHERAL_GPIO );
// get interrupt enable and pending
@@ -65,18 +108,30 @@ void interrupt_mask_specific( const int8_t num ) {
} else if ( 64 > interrupt ) {
interrupt_to_enable += INTERRUPT_ENABLE_IRQ_2;
interrupt_pending += INTERRUPT_IRQ_PENDING_2;
+ interrupt -= 32;
} else {
PANIC( "Unsupported interrupt number!" )
}
+ // transform to bit
+ interrupt = 1 << interrupt;
// get and set interrupt enable
uint32_t interrupt_line = io_in32( interrupt_to_enable );
+ #if defined( PRINT_INTERRUPT )
+ DEBUG_OUTPUT( "Interrupt line %#"PRIx32"\r\n", interrupt_line )
+ #endif
// stop if already set
- if ( interrupt_line & interrupt ) {
- return;
+ if ( ! ( interrupt_line & interrupt ) ) {
+ #if defined( PRINT_INTERRUPT )
+ DEBUG_OUTPUT( "Interrupt %"PRId8" not yet enabled\r\n", num )
+ #endif
+ interrupt_line |= interrupt;
+ // write changes
+ io_out32( interrupt_to_enable, interrupt_line );
}
- interrupt_line |= interrupt;
- // write changes
- io_out32( interrupt_to_enable, interrupt_line );
+ #if defined( PRINT_INTERRUPT )
+ DEBUG_OUTPUT( "Clearing interrupt %"PRId8"\r\n", num )
+ DEBUG_OUTPUT( "Interrupt line %#"PRIx32"\r\n", interrupt_line )
+ #endif
// get and clear pending interrupt from memory
interrupt_line = io_in32( interrupt_pending );
interrupt_line &= ~interrupt;
@@ -91,32 +146,32 @@ void interrupt_mask_specific( const int8_t num ) {
* @param num interrupt number to disable
*/
void interrupt_unmask_specific( const int8_t num ) {
- const uint32_t interrupt = ( uint32_t )num;
+ uint32_t interrupt = (uint32_t)num;
// get peripheral base
const uint32_t base = ( uint32_t )peripheral_base_get( PERIPHERAL_GPIO );
// get interrupt enable and pending
uint32_t interrupt_to_disable = base;
uint32_t interrupt_pending = base;
if ( 32 > interrupt ) {
- interrupt_to_disable += INTERRUPT_ENABLE_IRQ_1;
+ interrupt_to_disable += INTERRUPT_DISABLE_IRQ_1;
interrupt_pending += INTERRUPT_IRQ_PENDING_1;
} else if ( 64 > interrupt ) {
- interrupt_to_disable += INTERRUPT_ENABLE_IRQ_2;
+ interrupt_to_disable += INTERRUPT_DISABLE_IRQ_2;
interrupt_pending += INTERRUPT_IRQ_PENDING_2;
+ interrupt -= 32;
} else {
PANIC( "Unsupported interrupt number!" )
}
+ // transform to bit
+ interrupt = 1 << interrupt;
// get and clear interrupt enable
- uint32_t interrupt_line = io_in32( interrupt_to_disable );
- // stop if already set
- if ( interrupt_line & ~interrupt ) {
- return;
- }
- interrupt_line &= ~interrupt;
+ #if defined( PRINT_INTERRUPT )
+ DEBUG_OUTPUT( "Disabling interrupt %"PRId8"\r\n", num )
+ #endif
// write changes
- io_out32( interrupt_to_disable, interrupt_line );
+ io_out32( interrupt_to_disable, interrupt );
// get and clear pending interrupt from memory
- interrupt_line = io_in32( interrupt_pending );
+ uint32_t interrupt_line = io_in32( interrupt_pending );
interrupt_line &= ~interrupt;
// write changes
io_out32( interrupt_pending, interrupt_line );
@@ -131,7 +186,6 @@ void interrupt_unmask_specific( const int8_t num ) {
*/
int8_t interrupt_get_pending( const bool fast ) {
const uintptr_t base = ( uint32_t )peripheral_base_get( PERIPHERAL_GPIO );
-
// normal interrupt
if ( ! fast ) {
const uint32_t pending1 = io_in32( base + INTERRUPT_IRQ_PENDING_1 );
@@ -159,6 +213,23 @@ int8_t interrupt_get_pending( const bool fast ) {
// return interrupt
return ( int8_t )interrupt;
}
-
+ // return no interrupt
return -1;
}
+
+/**
+ * @fn void interrupt_disable_after_handling(int8_t)
+ * @brief Method to disable interrupt after successful handling
+ * @param num interrupt number to disable
+ */
+void interrupt_disable_after_handling( const int8_t num ) {
+ // skip timer or invalid interrupt
+ if (
+ SYSTEM_TIMER_3_INTERRUPT == num
+ || ! interrupt_validate_number( ( size_t )num )
+ ) {
+ return;
+ }
+ // unmask interrupt
+ interrupt_unmask_specific( num );
+}
diff --git a/bolthur/kernel/platform/raspi/interrupt.h b/bolthur/kernel/platform/raspi/interrupt.h
new file mode 100644
index 000000000..ca4be0cb0
--- /dev/null
+++ b/bolthur/kernel/platform/raspi/interrupt.h
@@ -0,0 +1,41 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#ifndef _PLATFORM_RASPI_INTERRUPT_H
+#define _PLATFORM_RASPI_INTERRUPT_H
+
+// undocumented irq
+#define IRQ_USB 9
+// documented irq
+#define IRQ_MAILBOX 1
+#define IRQ_AUX 29
+#define IRQ_I2C_SPI 43
+#define IRQ_PWA0 45
+#define IRQ_PWA1 46
+#define IRQ_SMI 48
+#define IRQ_GPIO0 49
+#define IRQ_GPIO1 50
+#define IRQ_GPIO2 51
+#define IRQ_GPIO3 52
+#define IRQ_I2C 53
+#define IRQ_SPI 54
+#define IRQ_PCM 55
+#define IRQ_UART 57
+
+#endif
diff --git a/bolthur/kernel/platform/raspi/mailbox/mailbox.c b/bolthur/kernel/platform/raspi/mailbox/mailbox.c
index e9e1c1d1b..ea82c8468 100644
--- a/bolthur/kernel/platform/raspi/mailbox/mailbox.c
+++ b/bolthur/kernel/platform/raspi/mailbox/mailbox.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/platform/raspi/mailbox/mailbox.h b/bolthur/kernel/platform/raspi/mailbox/mailbox.h
index 991db9126..8c4641e43 100644
--- a/bolthur/kernel/platform/raspi/mailbox/mailbox.h
+++ b/bolthur/kernel/platform/raspi/mailbox/mailbox.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/platform/raspi/mailbox/property.c b/bolthur/kernel/platform/raspi/mailbox/property.c
index bc47a6865..a6e72d98f 100644
--- a/bolthur/kernel/platform/raspi/mailbox/property.c
+++ b/bolthur/kernel/platform/raspi/mailbox/property.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -54,6 +54,7 @@ void mailbox_property_init( void ) {
if ( ! ptb_buffer ) {
ptb_buffer = aligned_alloc( PAGE_SIZE, PAGE_SIZE );
assert( ptb_buffer )
+ memset( ptb_buffer, 0, PAGE_SIZE );
ptb_buffer_phys = ( int32_t* )VIRT_2_PHYS( ptb_buffer );
}
// clear out buffer
diff --git a/bolthur/kernel/platform/raspi/mailbox/property.h b/bolthur/kernel/platform/raspi/mailbox/property.h
index 2c5c57f5e..50230f9a3 100644
--- a/bolthur/kernel/platform/raspi/mailbox/property.h
+++ b/bolthur/kernel/platform/raspi/mailbox/property.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/platform/raspi/mm/phys.c b/bolthur/kernel/platform/raspi/mm/phys.c
index 7b26051e0..22fb32c7e 100644
--- a/bolthur/kernel/platform/raspi/mm/phys.c
+++ b/bolthur/kernel/platform/raspi/mm/phys.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -106,12 +106,14 @@ bool phys_platform_init( void ) {
if ( ! phys_bitmap ) {
return false;
}
+ memset( phys_bitmap, 0, phys_bitmap_length * sizeof( uint32_t ) );
phys_bitmap_check = aligned_alloc(
sizeof( *phys_bitmap ),
phys_bitmap_length * sizeof( uint32_t ) );
if ( ! phys_bitmap_check ) {
return false;
}
+ memset( phys_bitmap_check, 0, phys_bitmap_length * sizeof( uint32_t ) );
// debug output
#if defined( PRINT_MM_PHYS )
DEBUG_OUTPUT( "total memory amount: %#"PRIx32"\r\n", memory_amount )
diff --git a/bolthur/kernel/platform/raspi/mm/virt.c b/bolthur/kernel/platform/raspi/mm/virt.c
index 72469cedf..ef8f7e734 100644
--- a/bolthur/kernel/platform/raspi/mm/virt.c
+++ b/bolthur/kernel/platform/raspi/mm/virt.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/platform/raspi/peripheral.c b/bolthur/kernel/platform/raspi/peripheral.c
index 0944a0b7b..d9e21739f 100644
--- a/bolthur/kernel/platform/raspi/peripheral.c
+++ b/bolthur/kernel/platform/raspi/peripheral.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/platform/raspi/peripheral.h b/bolthur/kernel/platform/raspi/peripheral.h
index 2782f5abe..1624c2a96 100644
--- a/bolthur/kernel/platform/raspi/peripheral.h
+++ b/bolthur/kernel/platform/raspi/peripheral.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/platform/raspi/serial.c b/bolthur/kernel/platform/raspi/serial.c
index f0fac2cb5..b4aa8e3d2 100644
--- a/bolthur/kernel/platform/raspi/serial.c
+++ b/bolthur/kernel/platform/raspi/serial.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -23,6 +23,7 @@
#include "peripheral.h"
#include "gpio.h"
#include "mailbox/property.h"
+#include "interrupt.h"
#include "../../io.h"
#include "../../serial.h"
@@ -211,11 +212,11 @@ bool serial_register_interrupt( void ) {
// get peripheral base
const uint32_t base = ( uint32_t )peripheral_base_get( PERIPHERAL_GPIO );
// register interrupt
- if ( ! interrupt_register_handler( 57, serial_clear, NULL, INTERRUPT_FAST, true, false ) ) {
+ if ( ! interrupt_register_handler( IRQ_UART, serial_clear, NULL, INTERRUPT_FAST, true, false ) ) {
return false;
}
// mask interrupt
- io_out32( base + INTERRUPT_FIQ_CONTROL, 57 | 0x80 );
+ io_out32( base + INTERRUPT_FIQ_CONTROL, IRQ_UART | 0x80 );
// flush it
serial_flush();
return true;
diff --git a/bolthur/kernel/platform/raspi/start.32.S b/bolthur/kernel/platform/raspi/start.32.S
index 2f63bd917..6883a369f 100644
--- a/bolthur/kernel/platform/raspi/start.32.S
+++ b/bolthur/kernel/platform/raspi/start.32.S
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/platform/raspi/start.64.S b/bolthur/kernel/platform/raspi/start.64.S
index fcf3deaf2..45d459b23 100644
--- a/bolthur/kernel/platform/raspi/start.64.S
+++ b/bolthur/kernel/platform/raspi/start.64.S
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/platform/raspi/timer.c b/bolthur/kernel/platform/raspi/timer.c
index 6dc92c106..b56734974 100644
--- a/bolthur/kernel/platform/raspi/timer.c
+++ b/bolthur/kernel/platform/raspi/timer.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -77,11 +77,8 @@ static void timer_clear( void* context ) {
#endif
io_out32( base + SYSTEM_TIMER_COMPARE_3, next_count );
- // get pending interrupt from memory clear timer and overwrite
- // should not be necessary but better safe than sorry
- uint32_t interrupt_line = io_in32( base + INTERRUPT_IRQ_PENDING_1 );
- interrupt_line &= ( uint32_t )( ~( SYSTEM_TIMER_3_INTERRUPT ) );
- io_out32( base + INTERRUPT_IRQ_PENDING_1, interrupt_line );
+ // clear handled interrupt
+ interrupt_clear( SYSTEM_TIMER_3_INTERRUPT );
// increment tick count by interval
timer_tick_count += timer_get_interval();
@@ -96,7 +93,7 @@ static void timer_clear( void* context ) {
* @brief Initialize timer
*/
void timer_platform_init( void ) {
- // initialise timer ticks
+ // initialize timer ticks
timer_tick_count = 0;
// get peripheral base
diff --git a/bolthur/kernel/platform/raspi/timer.h b/bolthur/kernel/platform/raspi/timer.h
index 5264de9b1..de08d02dc 100644
--- a/bolthur/kernel/platform/raspi/timer.h
+++ b/bolthur/kernel/platform/raspi/timer.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -33,9 +33,9 @@
#define SYSTEM_TIMER_MATCH_3 ( 1 << 3 )
// timer interrupts
-#define SYSTEM_TIMER_0_INTERRUPT ( 1 << 0 )
-#define SYSTEM_TIMER_1_INTERRUPT ( 1 << 1 )
-#define SYSTEM_TIMER_2_INTERRUPT ( 1 << 2 )
-#define SYSTEM_TIMER_3_INTERRUPT ( 1 << 3 )
+#define SYSTEM_TIMER_0_INTERRUPT 0 // ( 1 << 0 )
+#define SYSTEM_TIMER_1_INTERRUPT 1 // ( 1 << 1 )
+#define SYSTEM_TIMER_2_INTERRUPT 2 // ( 1 << 2 )
+#define SYSTEM_TIMER_3_INTERRUPT 3 // ( 1 << 3 )
#endif
diff --git a/bolthur/kernel/platform/raspi/tty.c b/bolthur/kernel/platform/raspi/tty.c
index 48618ba56..e6caddd16 100644
--- a/bolthur/kernel/platform/raspi/tty.c
+++ b/bolthur/kernel/platform/raspi/tty.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/rpc/backup.c b/bolthur/kernel/rpc/backup.c
index fa6f1c1d6..d6d169d42 100644
--- a/bolthur/kernel/rpc/backup.c
+++ b/bolthur/kernel/rpc/backup.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -69,7 +69,7 @@ rpc_backup_t* rpc_backup_get_active( task_thread_t* thread, size_t data_id ) {
DEBUG_OUTPUT( "thread->state = %d\r\n", thread->state )
#endif
// variables
- list_item_t* current = thread->process->rpc_queue->first;
+ const list_item_t* current = thread->process->rpc_queue->first;
rpc_backup_t* found = NULL;
// handle data id set
if ( data_id ) {
diff --git a/bolthur/kernel/rpc/backup.h b/bolthur/kernel/rpc/backup.h
index e77d670fa..9669ad244 100644
--- a/bolthur/kernel/rpc/backup.h
+++ b/bolthur/kernel/rpc/backup.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,32 +20,50 @@
#ifndef _RPC_BACKUP_H
#define _RPC_BACKUP_H
-#include
#include "../../library/collection/list/list.h"
#include "../task/process.h"
#include "../task/thread.h"
typedef struct {
+ /** cpu context */
void* context;
+ /** rpc data id */
size_t data_id;
+ /** rpc type */
size_t type;
+ /** thread used */
task_thread_t* thread;
+ /** thread state */
task_thread_state_t thread_state;
+ /** thread state data */
task_state_data_t thread_state_data;
+ /** source thread */
task_thread_t* source;
+ /** thread state to use */
+ task_thread_state_t state_to_use;
+ /** flag whether backup has been prepared */
bool prepared;
+ /** active flag */
bool active;
+ /** synchronous flag */
bool sync;
+ /** origin data id */
size_t origin_data_id;
+ /** rpc info */
void* rpc_info;
// necessary for nested rpc to return sync on end
+ /** synchronous return on end */
bool sync_return_on_end;
+ /** synchronous return blocked data id */
size_t sync_return_blocked_data_id;
+ /** synchronous return data id */
size_t sync_return_data_id;
+ /** interrupt flag */
+ bool is_interrupt;
} rpc_backup_t;
rpc_backup_t* rpc_backup_get_active( task_thread_t*, size_t );
-rpc_backup_t* rpc_backup_create( task_thread_t*, task_process_t*, size_t, void*, size_t, task_thread_t*, bool, size_t, bool );
+rpc_backup_t* rpc_backup_create( task_thread_t*, const task_process_t*, size_t, const void*, size_t, task_thread_t*, bool, size_t, bool, bool );
void rpc_backup_destroy( rpc_backup_t* );
#endif
diff --git a/bolthur/kernel/rpc/data.c b/bolthur/kernel/rpc/data.c
index ec5500b18..4745a5cf1 100644
--- a/bolthur/kernel/rpc/data.c
+++ b/bolthur/kernel/rpc/data.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -22,7 +22,6 @@
#include "../lib/string.h"
#include "../lib/stdlib.h"
#include "data.h"
-#include "../panic.h"
#include "../mm/phys.h"
#include "../mm/virt.h"
#if defined( PRINT_RPC )
@@ -63,7 +62,7 @@ bool rpc_data_queue_ready( task_process_t* proc ) {
int rpc_data_queue_add(
const pid_t target,
const char* data,
- size_t data_length,
+ const size_t data_length,
size_t* rpc_data_queue_id
) {
// get process by pid
@@ -107,7 +106,7 @@ int rpc_data_queue_add(
return EINVAL;
}
// map mailbox temporarily
- uintptr_t mailbox = virt_map_temporary( target_process->rpc_mailbox, PAGE_SIZE );
+ const uintptr_t mailbox = virt_map_temporary( target_process->rpc_mailbox, PAGE_SIZE );
if ( ! mailbox ) {
// debug output
#if defined( PRINT_RPC )
@@ -116,10 +115,12 @@ int rpc_data_queue_add(
return EINVAL;
}
// set pointer to beginning
- auto rpc_data_mailbox_entry_t* entry = ( rpc_data_mailbox_entry_t* )mailbox;
+ auto entry = ( rpc_data_mailbox_entry_t* )mailbox;
#if defined( PRINT_RPC )
+ DEBUG_OUTPUT( "===================================> %d <================================\r\n", target )
DEBUG_OUTPUT( "Mailbox temporarily mapped to 0x%"PRIxPTR", looking for free space \r\n", mailbox )
#endif
+ // cppcheck-suppress-begin duplicateCondition
// handle empty
if ( entry->id ) {
// debug output
@@ -141,7 +142,7 @@ int rpc_data_queue_add(
#if defined( PRINT_RPC )
DEBUG_OUTPUT(
"entry: %#"PRIxPTR", offset = %#"PRIxPTR", "
- "sizeof( rpc_data_mailbox_entry_t ) - offset = %#"PRIx32"\r\n",
+ "sizeof( rpc_data_mailbox_entry_t ) - offset = %#zx\r\n",
(uintptr_t)entry, offset, sizeof( rpc_data_mailbox_entry_t ) - offset )
#endif
entry = ( rpc_data_mailbox_entry_t* )( ( uintptr_t )entry + ( sizeof( rpc_data_mailbox_entry_t ) - offset ) );
@@ -161,7 +162,7 @@ int rpc_data_queue_add(
#if defined( PRINT_RPC )
DEBUG_OUTPUT(
"entry: %#"PRIxPTR", offset = %#"PRIxPTR", "
- "sizeof( rpc_data_mailbox_entry_t ) = %#"PRIx32"\r\n",
+ "sizeof( rpc_data_mailbox_entry_t ) = %#zx\r\n",
(uintptr_t)entry, offset, sizeof( rpc_data_mailbox_entry_t ) )
#endif
}
@@ -176,10 +177,11 @@ int rpc_data_queue_add(
virt_unmap_temporary( mailbox, PAGE_SIZE );
// debug output
#if defined( PRINT_RPC )
- DEBUG_OUTPUT( "Mailbox full!\r\n" )
+ DEBUG_OUTPUT( "Mailbox full of %d!\r\n", target )
#endif
return ENOMEM;
}
+ // cppcheck-suppress-end duplicateCondition
// debug output
#if defined( PRINT_RPC )
DEBUG_OUTPUT( "data_length = %#zx, max = %#zx!\r\n", data_length, PAGE_SIZE - ( ( uintptr_t )entry - mailbox - sizeof( rpc_data_mailbox_entry_t ) ) )
@@ -191,7 +193,7 @@ int rpc_data_queue_add(
virt_unmap_temporary( mailbox, PAGE_SIZE );
// debug output
#if defined( PRINT_RPC )
- DEBUG_OUTPUT( "Mailbox full!\r\n" )
+ DEBUG_OUTPUT( "Mailbox full of %d!\r\n", target )
#endif
return ENOMEM;
}
diff --git a/bolthur/kernel/rpc/data.h b/bolthur/kernel/rpc/data.h
index 12193e9dc..b1ff62bd7 100644
--- a/bolthur/kernel/rpc/data.h
+++ b/bolthur/kernel/rpc/data.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _RPC_DATA_H
#define _RPC_DATA_H
-#include
#include "../../library/collection/list/list.h"
#include "../task/process.h"
#include "../task/thread.h"
diff --git a/bolthur/kernel/rpc/generic.c b/bolthur/kernel/rpc/generic.c
index ce9af6628..eed08bedb 100644
--- a/bolthur/kernel/rpc/generic.c
+++ b/bolthur/kernel/rpc/generic.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -44,8 +44,8 @@ static avl_tree_t* origin_tree = NULL;
*/
static int32_t compare_callback( const avl_node_t* a, const avl_node_t* b ) {
// get blocks
- auto const rpc_origin_source_t* block_a = RPC_GET_ORIGIN_SOURCE( a );
- auto const rpc_origin_source_t* block_b = RPC_GET_ORIGIN_SOURCE( b );
+ auto const block_a = RPC_GET_ORIGIN_SOURCE( a );
+ auto const block_b = RPC_GET_ORIGIN_SOURCE( b );
// -1 if address of a->type is greater than address of b->type
if ( block_a->rpc_id > block_b->rpc_id ) {
return -1;
@@ -102,7 +102,7 @@ static int32_t lookup_callback(
*/
static void cleanup_callback( avl_node_t* a ) {
// get block from node
- auto rpc_origin_source_t* block = RPC_GET_ORIGIN_SOURCE( a );
+ auto block = RPC_GET_ORIGIN_SOURCE( a );
// debug output
#if defined( PRINT_RPC )
DEBUG_OUTPUT( "removing block %p!\r\n", block )
@@ -118,7 +118,7 @@ static void cleanup_callback( avl_node_t* a ) {
* @param id
* @return
*/
-rpc_origin_source_t* rpc_generic_source_info( size_t id ) {
+rpc_origin_source_t* rpc_generic_source_info( const size_t id ) {
// try to find node by data
avl_node_t* node = avl_find_by_data( origin_tree, ( void* )id );
if ( ! node ) {
@@ -150,7 +150,7 @@ void rpc_generic_destroy_source_info( rpc_origin_source_t* info ) {
}
// debug output
#if defined( PRINT_RPC )
- DEBUG_OUTPUT( "Trying to remove source info %d!\r\n", info->rpc_id )
+ DEBUG_OUTPUT( "Trying to remove source info %zu!\r\n", info->rpc_id )
avl_print( origin_tree, NULL );
#endif
// remove from tree
@@ -190,7 +190,7 @@ bool rpc_generic_setup_mailbox( task_process_t* proc ) {
return false;
}
// map page temporarily
- uintptr_t tmp_map = virt_map_temporary( proc->rpc_mailbox, PAGE_SIZE );
+ const uintptr_t tmp_map = virt_map_temporary( proc->rpc_mailbox, PAGE_SIZE );
if ( 0 == tmp_map ) {
// free mailbox again
phys_free_page( proc->rpc_mailbox );
@@ -208,7 +208,7 @@ bool rpc_generic_setup_mailbox( task_process_t* proc ) {
// unmap again
virt_unmap_temporary( tmp_map, PAGE_SIZE );
// set address
- uintptr_t tmp_addr = ROUND_UP_TO_FULL_PAGE( task_thread_current_thread->entry );
+ const uintptr_t tmp_addr = ROUND_UP_TO_FULL_PAGE( task_thread_current_thread->entry );
// find free space
proc->rpc_mailbox_virt = virt_find_free_page_range( proc->virtual_context, PAGE_SIZE, tmp_addr );
// handle no address found
@@ -230,7 +230,7 @@ bool rpc_generic_setup_mailbox( task_process_t* proc ) {
#if defined( PRINT_RPC )
DEBUG_OUTPUT(
"mapping %#"PRIx64" to address %#"PRIxPTR
- " with type %d, flag %"PRIu32" and len %zx for process %d\r\n",
+ " with type %d, flag %"PRIu32" and len %x for process %d\r\n",
proc->rpc_mailbox,
proc->rpc_mailbox_virt,
map_type,
@@ -288,7 +288,7 @@ void rpc_generic_destroy_mailbox( task_process_t* proc ) {
}
/**
- * @fn rpc_backup_t* rpc_generic_raise(task_thread_t*, task_process_t*, const size_t, void*, size_t, task_thread_t*, const bool, const size_t, const bool)
+ * @fn rpc_backup_t* rpc_generic_raise(task_thread_t*, task_process_t*, const size_t, void*, size_t, task_thread_t*, const bool, const size_t, const bool, const bool)
* @brief Raise a rpc in target from source
*
* @param source
@@ -300,6 +300,7 @@ void rpc_generic_destroy_mailbox( task_process_t* proc ) {
* @param sync
* @param origin_data_id
* @param disable_data
+ * @param is_interrupt
* @return
*/
rpc_backup_t* rpc_generic_raise(
@@ -307,11 +308,12 @@ rpc_backup_t* rpc_generic_raise(
task_process_t* target,
const size_t type,
void* data,
- size_t length,
+ const size_t length,
task_thread_t* target_thread,
const bool sync,
const size_t origin_data_id,
- const bool disable_data
+ const bool disable_data,
+ const bool is_interrupt
) {
// debug output
#if defined( PRINT_RPC )
@@ -330,7 +332,8 @@ rpc_backup_t* rpc_generic_raise(
target_thread,
sync,
origin_data_id,
- disable_data
+ disable_data,
+ is_interrupt
);
if ( ! backup ) {
// debug output
@@ -340,16 +343,6 @@ rpc_backup_t* rpc_generic_raise(
// skip if backup could not be created
return NULL;
}
- // prepare thread
- if ( ! rpc_generic_prepare_invoke( backup ) ) {
- // debug output
- #if defined( PRINT_RPC )
- DEBUG_OUTPUT( "Error while preparing target %d\r\n", target->id )
- #endif
- rpc_backup_destroy( backup );
- // skip if error occurred during rpc invoke
- return NULL;
- }
// allocate new structure for tree
if ( backup->data_id ) {
rpc_origin_source_t* rpc_info = malloc( sizeof( *rpc_info ) );
@@ -384,6 +377,16 @@ rpc_backup_t* rpc_generic_raise(
// cache rpc info structure
backup->rpc_info = rpc_info;
}
+ // prepare thread
+ if ( ! rpc_generic_prepare_invoke( backup ) ) {
+ // debug output
+ #if defined( PRINT_RPC )
+ DEBUG_OUTPUT( "Error while preparing target %d\r\n", target->id )
+ #endif
+ rpc_backup_destroy( backup );
+ // skip if error occurred during rpc invoke
+ return NULL;
+ }
// return created backup
return backup;
}
diff --git a/bolthur/kernel/rpc/generic.h b/bolthur/kernel/rpc/generic.h
index 72db9d541..d1643fe73 100644
--- a/bolthur/kernel/rpc/generic.h
+++ b/bolthur/kernel/rpc/generic.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _RPC_GENERIC_H
#define _RPC_GENERIC_H
-#include
#include "../../library/collection/avl/avl.h"
#include "../task/process.h"
#include "../task/thread.h"
@@ -52,7 +51,7 @@ void rpc_generic_destroy( task_process_t* );
bool rpc_generic_ready( task_process_t* );
bool rpc_generic_restore( task_thread_t* );
bool rpc_generic_prepare_invoke( rpc_backup_t* );
-rpc_backup_t* rpc_generic_raise( task_thread_t*, task_process_t*, size_t, void*, size_t, task_thread_t*, bool, size_t, bool );
+rpc_backup_t* rpc_generic_raise( task_thread_t*, task_process_t*, size_t, void*, size_t, task_thread_t*, bool, size_t, bool, bool );
bool rpc_generic_setup_mailbox( task_process_t* );
void rpc_generic_destroy_mailbox( task_process_t* );
diff --git a/bolthur/kernel/rpc/queue.c b/bolthur/kernel/rpc/queue.c
index ab6db0397..338d69cea 100644
--- a/bolthur/kernel/rpc/queue.c
+++ b/bolthur/kernel/rpc/queue.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/rpc/queue.h b/bolthur/kernel/rpc/queue.h
index 4b491caed..f191f33d0 100644
--- a/bolthur/kernel/rpc/queue.h
+++ b/bolthur/kernel/rpc/queue.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _RPC_QUEUE_H
#define _RPC_QUEUE_H
-#include
#include "../../library/collection/list/list.h"
#include "../task/process.h"
#include "../task/thread.h"
diff --git a/bolthur/kernel/serial.h b/bolthur/kernel/serial.h
index 9ca9bcc58..99c9df855 100644
--- a/bolthur/kernel/serial.h
+++ b/bolthur/kernel/serial.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _SERIAL_H
#define _SERIAL_H
-#include
#include
#define SERIAL_BAUD_RATE 115200
diff --git a/bolthur/kernel/stack.h b/bolthur/kernel/stack.h
index 706e06b25..a230e0513 100644
--- a/bolthur/kernel/stack.h
+++ b/bolthur/kernel/stack.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _STACK_H
#define _STACK_H
-#include
#include
bool stack_is_kernel( uintptr_t );
diff --git a/bolthur/kernel/syscall.h b/bolthur/kernel/syscall.h
index 8188b55e9..7ea3d18ba 100644
--- a/bolthur/kernel/syscall.h
+++ b/bolthur/kernel/syscall.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -22,7 +22,6 @@
#include
#include
-#include
#include "interrupt.h"
#define SYSCALL_BIND( id, handler ) interrupt_register_handler( id, handler, NULL, INTERRUPT_SOFTWARE, false, false )
@@ -59,6 +58,7 @@
#define SYSCALL_INTERRUPT_ACQUIRE 40
#define SYSCALL_INTERRUPT_RELEASE 41
+#define SYSCALL_INTERRUPT_HANDLED 42
#define SYSCALL_TIMER_TICK_COUNT 51
#define SYSCALL_TIMER_FREQUENCY 52
@@ -97,6 +97,7 @@ void syscall_memory_translate_bus( void* );
void syscall_interrupt_acquire( void* );
void syscall_interrupt_release( void* );
+void syscall_interrupt_handled( void* );
void syscall_rpc_set_handler( void* );
void syscall_rpc_raise( void* );
diff --git a/bolthur/kernel/syscall/init.c b/bolthur/kernel/syscall/init.c
index 597d29a43..34dab95f9 100644
--- a/bolthur/kernel/syscall/init.c
+++ b/bolthur/kernel/syscall/init.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -80,6 +80,7 @@ bool syscall_init( void ) {
if (
! SYSCALL_BIND( SYSCALL_INTERRUPT_ACQUIRE, syscall_interrupt_acquire )
|| ! SYSCALL_BIND( SYSCALL_INTERRUPT_RELEASE, syscall_interrupt_release )
+ || ! SYSCALL_BIND( SYSCALL_INTERRUPT_HANDLED, syscall_interrupt_handled )
) {
return false;
}
diff --git a/bolthur/kernel/syscall/interrupt.c b/bolthur/kernel/syscall/interrupt.c
index eee51d331..db2aa57dd 100644
--- a/bolthur/kernel/syscall/interrupt.c
+++ b/bolthur/kernel/syscall/interrupt.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -34,7 +34,7 @@
* @param context
*/
void syscall_interrupt_acquire( void* context ) {
- uint8_t num = ( uint8_t )syscall_get_parameter( context, 0 );
+ const uint8_t num = ( uint8_t )syscall_get_parameter( context, 0 );
// debug output
#if defined( PRINT_SYSCALL )
DEBUG_OUTPUT( "syscall_interrupt_acquire( %"PRIu8" )\r\n", num )
@@ -51,7 +51,7 @@ void syscall_interrupt_acquire( void* context ) {
return;
}
// validate interrupt number
- if ( ! interrupt_validate_number( num ) ) {
+ if ( ! interrupt_validate_number_rpc( num ) ) {
// debug output
#if defined( PRINT_SYSCALL )
DEBUG_OUTPUT( "Invalid interrupt passed!\r\n" )
@@ -60,6 +60,7 @@ void syscall_interrupt_acquire( void* context ) {
syscall_populate_error( context, ( size_t )-EINVAL );
return;
}
+ // register interrupt
if ( ! interrupt_register_handler(
num,
NULL,
@@ -71,6 +72,7 @@ void syscall_interrupt_acquire( void* context ) {
syscall_populate_error( context, ( size_t )-EAGAIN );
return;
}
+ // return success
syscall_populate_success( context, 0 );
}
@@ -81,7 +83,7 @@ void syscall_interrupt_acquire( void* context ) {
* @param context
*/
void syscall_interrupt_release( void* context ) {
- uint8_t num = ( uint8_t )syscall_get_parameter( context, 0 );
+ const uint8_t num = ( uint8_t )syscall_get_parameter( context, 0 );
// debug output
#if defined( PRINT_SYSCALL )
DEBUG_OUTPUT( "syscall_interrupt_release( %"PRIu8" )\r\n", num )
@@ -98,7 +100,7 @@ void syscall_interrupt_release( void* context ) {
return;
}
// validate interrupt number
- if ( ! interrupt_validate_number( num ) ) {
+ if ( ! interrupt_validate_number_rpc( num ) ) {
// debug output
#if defined( PRINT_SYSCALL )
DEBUG_OUTPUT( "Invalid interrupt passed!\r\n" )
@@ -107,6 +109,7 @@ void syscall_interrupt_release( void* context ) {
syscall_populate_error( context, ( size_t )-EINVAL );
return;
}
+ // remove registered interrupt handler
if ( ! interrupt_unregister_handler(
num,
NULL,
@@ -118,5 +121,40 @@ void syscall_interrupt_release( void* context ) {
syscall_populate_error( context, ( size_t )-EAGAIN );
return;
}
+ // return success
+ syscall_populate_success( context, 0 );
+}
+
+/**
+ * @fn void syscall_interrupt_handled(void*)
+ * @brief Interrupt handled syscall
+ * @param context
+ */
+void syscall_interrupt_handled( void* context ) {
+ // debug output
+ #if defined( PRINT_SYSCALL )
+ DEBUG_OUTPUT(
+ "syscall_interrupt_handled() from %d / %d\r\n",
+ task_thread_current_thread->process->id, task_thread_current_thread->id
+ )
+ #endif
+ // check for correct state for rpc end
+ if ( ! task_thread_current_thread->handling_interrupt ) {
+ // debug output
+ #if defined( PRINT_SYSCALL )
+ DEBUG_OUTPUT( "Not handling an interrupt\r\n" )
+ #endif
+ // populate success
+ syscall_populate_success( context, 0 );
+ // skip rest
+ return;
+ }
+ // debug output
+ #if defined( PRINT_SYSCALL )
+ DEBUG_OUTPUT( "Disabling handling interrupt flag\r\n" )
+ #endif
+ // reset flag
+ task_thread_current_thread->handling_interrupt = false;
+ // populate success
syscall_populate_success( context, 0 );
}
diff --git a/bolthur/kernel/syscall/memory.c b/bolthur/kernel/syscall/memory.c
index 2469ecbd0..f4da8a6a3 100644
--- a/bolthur/kernel/syscall/memory.c
+++ b/bolthur/kernel/syscall/memory.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -47,7 +47,7 @@
*/
void syscall_memory_acquire( void* context ) {
// get parameter
- auto void* addr = ( void* )syscall_get_parameter( context, 0 );
+ auto addr = ( void* )syscall_get_parameter( context, 0 );
size_t len = ( size_t )syscall_get_parameter( context, 1 );
int protection = ( int )syscall_get_parameter( context, 2 );
int flag = ( int )syscall_get_parameter( context, 3 );
@@ -433,6 +433,8 @@ void syscall_memory_shared_detach( void* context ) {
#if defined( PRINT_SYSCALL )
DEBUG_OUTPUT( "syscall_memory_shared_detach( %zu )\r\n", id )
#endif
+ // drain possible cached stuff by performing complete flush
+ virt_flush_complete();
// try to detach
if ( ! shared_memory_detach( task_thread_current_thread->process, id ) ) {
syscall_populate_error( context, ( size_t )-EIO );
@@ -456,7 +458,7 @@ void syscall_memory_shared_size( void* context ) {
DEBUG_OUTPUT( "syscall_memory_shared_size( %zu )\r\n", id )
#endif
// try to get size
- size_t len = shared_memory_size( task_thread_current_thread->process, id );
+ const size_t len = shared_memory_size( task_thread_current_thread->process, id );
if ( 0 == len ) {
syscall_populate_error( context, ( size_t )-EINVAL );
return;
@@ -486,8 +488,8 @@ void syscall_memory_translate_physical( void* context ) {
->process
->virtual_context;
// get min and max address of context
- uintptr_t min = virt_get_context_min_address( virtual_context );
- uintptr_t max = virt_get_context_max_address( virtual_context );
+ const uintptr_t min = virt_get_context_min_address( virtual_context );
+ const uintptr_t max = virt_get_context_max_address( virtual_context );
// ensure that address is in context
if (
min > address
@@ -502,7 +504,7 @@ void syscall_memory_translate_physical( void* context ) {
return;
}
// get mapped address
- uint64_t phys = virt_get_mapped_address_in_context( virtual_context, address );
+ const uint64_t phys = virt_get_mapped_address_in_context( virtual_context, address );
// populate success
syscall_populate_success( context, ( uintptr_t )phys + offset );
}
diff --git a/bolthur/kernel/syscall/print.c b/bolthur/kernel/syscall/print.c
index 29b67f031..164894a18 100644
--- a/bolthur/kernel/syscall/print.c
+++ b/bolthur/kernel/syscall/print.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -46,7 +46,7 @@ void syscall_kernel_putc( void* context ) {
*/
void syscall_kernel_puts( void* context ) {
// get parameter
- char* str = ( char* )syscall_get_parameter( context, 0 );
+ auto str = ( char* )syscall_get_parameter( context, 0 );
size_t len = ( size_t )syscall_get_parameter( context, 1 );
// debug output
#if defined( PRINT_SYSCALL )
@@ -66,7 +66,7 @@ void syscall_kernel_puts( void* context ) {
DEBUG_OUTPUT( "Allocate memory for unsafe copy!\r\n" )
#endif
// allocate space for duplicate and check for error
- char* data_dup = ( char* )malloc( sizeof( char ) * ( len + 1 ) );
+ auto const data_dup = ( char* )malloc( sizeof( char ) * ( len + 1 ) );
if ( ! data_dup ) {
// debug output
#if defined( PRINT_SYSCALL )
@@ -95,7 +95,7 @@ void syscall_kernel_puts( void* context ) {
return;
}
// print somewhere
- int written = printf( "%.*s", len, data_dup );
+ const int written = printf( "%.*s", len, data_dup );
// free data_dup and return written amount
free( data_dup );
// print until end of string or len
diff --git a/bolthur/kernel/syscall/rpc.c b/bolthur/kernel/syscall/rpc.c
index 206bd5423..06e22611d 100644
--- a/bolthur/kernel/syscall/rpc.c
+++ b/bolthur/kernel/syscall/rpc.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -39,7 +39,7 @@
* @param context
*/
void syscall_rpc_set_handler( void* context ) {
- uintptr_t handler = ( uintptr_t )syscall_get_parameter( context, 0 );
+ const uintptr_t handler = ( uintptr_t )syscall_get_parameter( context, 0 );
// debug output
#if defined( PRINT_SYSCALL )
DEBUG_OUTPUT( "syscall_rpc_set_handler( %#"PRIxPTR" )\r\n", handler )
@@ -62,18 +62,17 @@ void syscall_rpc_set_handler( void* context ) {
/**
* @fn void syscall_rpc_raise(void*)
* @brief Raise rpc system call
- *
* @param context
*/
void syscall_rpc_raise( void* context ) {
- size_t type = syscall_get_parameter( context, 0 );
- pid_t process = ( pid_t )syscall_get_parameter( context, 1 );
- void* data = ( void* )syscall_get_parameter( context, 2 );
- size_t length = syscall_get_parameter( context, 3 );
- size_t origin_rpc_data_id = syscall_get_parameter( context, 4 );
- bool synchronous = ( bool )syscall_get_parameter( context, 5 );
- bool no_return = ( bool )syscall_get_parameter( context, 6 );
- bool cleanup_current_id = ( bool )syscall_get_parameter( context, 7 );
+ const size_t type = syscall_get_parameter( context, 0 );
+ const pid_t process = ( pid_t )syscall_get_parameter( context, 1 );
+ auto const data = ( void* )syscall_get_parameter( context, 2 );
+ const size_t length = syscall_get_parameter( context, 3 );
+ const size_t origin_rpc_data_id = syscall_get_parameter( context, 4 );
+ const bool synchronous = syscall_get_parameter( context, 5 );
+ const bool no_return = syscall_get_parameter( context, 6 );
+ const bool cleanup_current_id = syscall_get_parameter( context, 7 );
// debug output
#if defined( PRINT_SYSCALL )
DEBUG_OUTPUT(
@@ -85,7 +84,7 @@ void syscall_rpc_raise( void* context ) {
origin_rpc_data_id,
synchronous ? 1 : 0,
no_return ? 1 : 0,
- cleanup ? 1 : 0,
+ no_return ? 1 : 0,
task_thread_current_thread->process->id
)
#endif
@@ -101,7 +100,7 @@ void syscall_rpc_raise( void* context ) {
return;
}
// handle invalid type
- if ( type <= UINT8_MAX ) {
+ if ( type <= UINT8_MAX ) {
// debug output
#if defined( PRINT_SYSCALL )
DEBUG_OUTPUT( "Interrupts are not allowed to be raised!\r\n" )
@@ -138,6 +137,7 @@ void syscall_rpc_raise( void* context ) {
// early exit
return;
}
+ // FIXME: handle possible kill
// validate addresses
if ( data && length && ! syscall_validate_address( ( uintptr_t )data, length ) ) {
// debug output
@@ -150,7 +150,7 @@ void syscall_rpc_raise( void* context ) {
return;
}
// create data duplicate
- char* dup_data = NULL;
+ char* dup_data = nullptr;
if ( data && length ) {
dup_data = malloc( sizeof( char ) * length );
if ( ! dup_data ) {
@@ -181,6 +181,12 @@ void syscall_rpc_raise( void* context ) {
return;
}
}
+ #if defined( PRINT_SYSCALL )
+ DEBUG_OUTPUT(
+ "calling process %d!\r\n",
+ target->id
+ )
+ #endif
// call rpc
rpc_backup_t* rpc = rpc_generic_raise(
task_thread_current_thread,
@@ -188,9 +194,10 @@ void syscall_rpc_raise( void* context ) {
type,
dup_data,
length,
- NULL,
+ nullptr,
synchronous,
origin_rpc_data_id,
+ false,
false
);
// free duplicate again
@@ -251,11 +258,16 @@ void syscall_rpc_raise( void* context ) {
#if defined( PRINT_SYSCALL )
DEBUG_OUTPUT( "rpc->data_id = %zu\r\n", rpc->data_id )
#endif
- // populate data id
- syscall_populate_success( context, rpc->data_id );
+ // populate data id in backup in case it's in current thread and already active
+ if ( rpc->thread == task_thread_current_thread && rpc->active ) {
+ syscall_populate_success( rpc->context, rpc->data_id );
+ // populate regular success via context
+ } else {
+ syscall_populate_success( context, rpc->data_id );
+ }
}
// switch it
- if ( task_thread_current_thread != rpc->thread ) {
+ if ( task_thread_current_thread != rpc->thread && synchronous ) {
// enqueue scheduler
task_thread_try_switch_to = rpc->thread;
// enqueue process event
@@ -266,14 +278,13 @@ void syscall_rpc_raise( void* context ) {
/**
* @fn void syscall_rpc_ret(void*)
* @brief Return rpc data
- *
* @param context
*/
void syscall_rpc_ret( void* context ) {
- size_t type = syscall_get_parameter( context, 0 );
- void* data = ( void* )syscall_get_parameter( context, 1 );
- size_t length = syscall_get_parameter( context, 2 );
- size_t original_rpc_id = syscall_get_parameter( context, 3 );
+ const size_t type = syscall_get_parameter( context, 0 );
+ auto const data = ( void* )syscall_get_parameter( context, 1 );
+ const size_t length = syscall_get_parameter( context, 2 );
+ const size_t original_rpc_id = syscall_get_parameter( context, 3 );
#if defined( PRINT_SYSCALL )
DEBUG_OUTPUT(
"syscall_rpc_ret( %zu, %p, %#zx, %zu ) from %d\r\n",
@@ -346,8 +357,13 @@ void syscall_rpc_ret( void* context ) {
rpc_origin_source_t* info = rpc_generic_source_info(
original_rpc_id ? original_rpc_id : active->data_id );
#if defined( PRINT_SYSCALL )
- DEBUG_OUTPUT( "active->sync = %d, info->sync = %d\r\n", active->sync ? 1 : 0,
- info->sync ? 1 : 0 )
+ DEBUG_OUTPUT( "active->sync = %d, info->sync = %d, rpc_id: %zu, source: %d, origin_rpc_id: %zu, type: %zu\r\n",
+ active->sync ? 1 : 0,
+ info->sync ? 1 : 0,
+ info->rpc_id,
+ info->source_process,
+ info->origin_rpc_id,
+ info->type )
#endif
if ( ! active->sync || original_rpc_id ) {
// overwrite blocked data id
@@ -356,6 +372,31 @@ void syscall_rpc_ret( void* context ) {
TASK_THREAD_STATE_RPC_WAIT_FOR_RETURN,
( task_state_data_t ){ .data_size = blocked_data_id }
);
+ // in case we have an original rpc id a valid target and a valid info object
+ // we need to overwrite sync and blocked_data_id similar to when no target
+ // was initially found
+ if ( original_rpc_id && target && info && active->type != type ) {
+ #if defined( PRINT_SYSCALL )
+ DEBUG_OUTPUT(
+ "rpc_id: %zu, source: %d, sync: %d, origin_rpc_id: %zu, type: %zu\r\n",
+ info->rpc_id,
+ info->source_process,
+ info->sync ? 1 : 0,
+ info->origin_rpc_id,
+ info->type
+ )
+ DEBUG_OUTPUT(
+ "sync = %d, data_id: %zu, original_data_id: %zu, type: %zu / %zu\r\n",
+ active->sync ? 1 : 0,
+ active->data_id,
+ active->origin_data_id,
+ active->type,
+ type
+ )
+ #endif
+ // reset sync to one from info
+ active->sync = info->sync;
+ }
// handle no target
if ( ! target ) {
if ( ! info ) {
@@ -373,9 +414,12 @@ void syscall_rpc_ret( void* context ) {
}
#if defined( PRINT_SYSCALL )
DEBUG_OUTPUT(
- "rpc_id: %zu, source: %d\r\n",
+ "rpc_id: %zu, source: %d, sync: %d, origin_rpc_id: %zu, type: %zu\r\n",
info->rpc_id,
- info->source_process
+ info->source_process,
+ info->sync ? 1 : 0,
+ info->origin_rpc_id,
+ info->type
)
#endif
// try to get pid
@@ -395,11 +439,11 @@ void syscall_rpc_ret( void* context ) {
// in case there is no target, use source and treat it as async
// use first possible process
avl_node_t* current = avl_iterate_first( proc->thread_manager );
- target = NULL;
+ target = nullptr;
// loop until usable thread has been found
while ( current && ! target ) {
// get thread
- task_thread_t* tmp = TASK_THREAD_GET_BLOCK( current );
+ auto const tmp = TASK_THREAD_GET_BLOCK( current );
// FIXME: CHECK IF ACTIVE
target = tmp;
// get next thread
@@ -423,7 +467,9 @@ void syscall_rpc_ret( void* context ) {
// destroy found info
rpc_generic_destroy_source_info( info );
// find and destroy possible info for current if original rpc id is set
- if ( original_rpc_id ) {
+ // in case it's an interrupt it is not possible to clean up active context
+ // since we might have multiple returns
+ if ( original_rpc_id && ! active->is_interrupt ) {
rpc_generic_destroy_source_info( rpc_generic_source_info( active->data_id ) );
}
#if defined( PRINT_SYSCALL )
@@ -472,7 +518,7 @@ void syscall_rpc_ret( void* context ) {
#endif
// get possible active target backup
- rpc_backup_t* target_active = NULL;
+ rpc_backup_t* target_active = nullptr;
if ( target != task_thread_current_thread ) {
// get current active rpc
target_active = rpc_backup_get_active( target, blocked_data_id );
@@ -503,6 +549,9 @@ void syscall_rpc_ret( void* context ) {
( task_state_data_t ){ .data_size = blocked_data_id }
);
} else {
+ #if defined( PRINT_SYSCALL )
+ DEBUG_OUTPUT( "sync return to %d on end!\r\n", target_active->thread->process->id )
+ #endif
target_active->sync_return_on_end = true;
target_active->sync_return_blocked_data_id = blocked_data_id;
target_active->sync_return_data_id = data_id;
@@ -519,9 +568,10 @@ void syscall_rpc_ret( void* context ) {
type,
dup_data,
length,
- NULL,
+ nullptr,
true,
blocked_data_id,
+ false,
false
);
#if defined( PRINT_SYSCALL )
@@ -560,7 +610,6 @@ void syscall_rpc_ret( void* context ) {
/**
* @fn void syscall_rpc_wait_for_call(void*)
* @brief Halt thread and wait for rpc call
- *
* @param context
*/
void syscall_rpc_wait_for_call( void* context ) {
@@ -584,7 +633,7 @@ void syscall_rpc_wait_for_call( void* context ) {
return;
}
// set state
- task_thread_current_thread->state = TASK_THREAD_STATE_RPC_WAIT_FOR_CALL;
+ task_thread_set_state( task_thread_current_thread, TASK_THREAD_STATE_RPC_WAIT_FOR_CALL );
// debug output
#if defined( PRINT_SYSCALL )
DEBUG_OUTPUT(
@@ -601,11 +650,10 @@ void syscall_rpc_wait_for_call( void* context ) {
/**
* @fn void syscall_process_rpc_ready(void*)
* @brief System call to set rpc ready flag
- *
* @param context
*/
void syscall_rpc_set_ready( void* context ) {
- const bool ready = ( bool )syscall_get_parameter( context, 0 );
+ const bool ready = syscall_get_parameter( context, 0 );
// cache process
task_process_t* process = task_thread_current_thread->process;
// set ready flag
@@ -636,7 +684,6 @@ void syscall_rpc_set_ready( void* context ) {
/**
* @fn void syscall_rpc_end(void*)
* @brief RPC ended, return to previous execution or next rpc if queued
- *
* @param context
*/
void syscall_rpc_end( void* context ) {
@@ -655,6 +702,9 @@ void syscall_rpc_end( void* context ) {
#endif
return;
}
+ #if defined( PRINT_SYSCALL )
+ DEBUG_OUTPUT( "restore %d\r\n", task_thread_current_thread->process->id )
+ #endif
// try to restore
if ( ! rpc_generic_restore( task_thread_current_thread ) ) {
// debug output
@@ -675,12 +725,11 @@ void syscall_rpc_end( void* context ) {
/**
* @fn void syscall_rpc_wait_for_ready(void*)
* @brief Wait for pid to be ready for rpc
- *
* @param context
*/
void syscall_rpc_wait_for_ready( void* context ) {
// get parameter
- pid_t process = ( pid_t )syscall_get_parameter( context, 0 );
+ const pid_t process = ( pid_t )syscall_get_parameter( context, 0 );
// debug output
#if defined( PRINT_SYSCALL )
DEBUG_OUTPUT(
@@ -749,7 +798,14 @@ void syscall_rpc_cleanup( void* context ) {
)
#endif
// get current active rpc
- const rpc_backup_t* active = rpc_backup_get_active( task_thread_current_thread, 0 );
+ auto const active = rpc_backup_get_active( task_thread_current_thread, 0 );
+ #if defined( PRINT_SYSCALL )
+ if ( active ) {
+ DEBUG_OUTPUT( "cleanup %zu of %d\r\n", active->data_id, task_thread_current_thread->process->id )
+ } else {
+ DEBUG_OUTPUT( "cleanup %d\r\n", task_thread_current_thread->process->id )
+ }
+ #endif
// cleanup if active
if ( active ) {
rpc_generic_destroy_source_info( rpc_generic_source_info( active->data_id ) );
diff --git a/bolthur/kernel/syscall/task.c b/bolthur/kernel/syscall/task.c
index e2f2c1f1c..fea82bba2 100644
--- a/bolthur/kernel/syscall/task.c
+++ b/bolthur/kernel/syscall/task.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/syscall/timer.c b/bolthur/kernel/syscall/timer.c
index 62c78c563..3cfdca706 100644
--- a/bolthur/kernel/syscall/timer.c
+++ b/bolthur/kernel/syscall/timer.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/target/raspi/Makefile.am b/bolthur/kernel/target/raspi/Makefile.am
index 75f198dee..96004e8dc 100644
--- a/bolthur/kernel/target/raspi/Makefile.am
+++ b/bolthur/kernel/target/raspi/Makefile.am
@@ -16,6 +16,12 @@ BUILT_SOURCES = \
libtarget.la \
kernel.elf \
kernel_qemu.elf
+# add kasan and ubsan to built sources when has sanitizer is set
+if HAS_SANITIZER
+ BUILT_SOURCES += \
+ ${abs_top_builddir}/lib/kasan/libkasan.la \
+ ${abs_top_builddir}/lib/libubsan.la
+endif
# no installable programs
noinst_PROGRAMS = kernel.elf kernel_qemu.elf ${output_img} ${output_img_qemu}
@@ -32,8 +38,7 @@ libtarget_la_DEPENDENCIES = \
${abs_top_builddir}/lib/libc/libc.la \
${abs_top_builddir}/lib/tar/libtar.la \
${abs_top_builddir}/lib/libduplicate.la \
- ${abs_top_builddir}/lib/libssp.la \
- ${abs_top_builddir}/lib/libubsan.la
+ ${abs_top_builddir}/lib/libssp.la
libtarget_la_SOURCES =
libtarget_la_LIBADD = \
${abs_top_builddir}/../library/collection/list/liblist.la \
@@ -46,9 +51,17 @@ libtarget_la_LIBADD = \
${abs_top_builddir}/lib/libc/libc.la \
${abs_top_builddir}/lib/tar/libtar.la \
${abs_top_builddir}/lib/libduplicate.la \
- ${abs_top_builddir}/lib/libssp.la \
- ${abs_top_builddir}/lib/libubsan.la
+ ${abs_top_builddir}/lib/libssp.la
libtarget_la_LDFLAGS = -all-static -Wl,-static
+# sanitizer additions
+if HAS_SANITIZER
+ libtarget_la_DEPENDENCIES += \
+ ${abs_top_builddir}/lib/kasan/libkasan.la \
+ ${abs_top_builddir}/lib/libubsan.la
+ libtarget_la_LIBADD += \
+ ${abs_top_builddir}/lib/kasan/libkasan.la \
+ ${abs_top_builddir}/lib/libubsan.la
+endif
# Normal kernel building for physical device
kernel_elf_SOURCES =
@@ -60,7 +73,6 @@ kernel_elf_LDFLAGS = \
-all-static -Wl,-static \
-Wl,--start-group,-ltarget,-lgcc,-lfdt,--end-group
kernel_elf_LDADD = -L./.libs
-
# Normal kernel building for physical device
kernel_qemu_elf_SOURCES =
diff --git a/bolthur/kernel/target/raspi/physical.v6.32.ld b/bolthur/kernel/target/raspi/physical.v6.32.ld
index 53e7563d9..7cde196c2 100644
--- a/bolthur/kernel/target/raspi/physical.v6.32.ld
+++ b/bolthur/kernel/target/raspi/physical.v6.32.ld
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/target/raspi/physical.v7.32.ld b/bolthur/kernel/target/raspi/physical.v7.32.ld
index 53e7563d9..7cde196c2 100644
--- a/bolthur/kernel/target/raspi/physical.v7.32.ld
+++ b/bolthur/kernel/target/raspi/physical.v7.32.ld
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/target/raspi/physical.v8.32.ld b/bolthur/kernel/target/raspi/physical.v8.32.ld
deleted file mode 100644
index 624ba7b25..000000000
--- a/bolthur/kernel/target/raspi/physical.v8.32.ld
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * Copyright (C) 2018 - 2025 bolthur project.
- *
- * This file is part of bolthur/kernel.
- *
- * bolthur/kernel is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * bolthur/kernel is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with bolthur/kernel. If not, see .
- */
-
-OUTPUT_FORMAT( elf32-littlearm )
-OUTPUT_ARCH( arm )
-
-ENTRY( startup )
-
-KERNEL_LMA = 0x80000;
-KERNEL_OFFSET = 0xC0000000;
-
-SECTIONS {
- . = KERNEL_LMA;
- __kernel_start = . + KERNEL_OFFSET;
-
- /* boot kernel sections */
- .text.boot : ALIGN( 4K ) {
- *( .text.boot )
- }
-
- .data.boot : ALIGN( 4K ) {
- *( .data.boot )
- }
-
- . += KERNEL_OFFSET;
-
- /* higher half kernel sections */
- .text ALIGN( 4K ) : AT( ADDR( .text ) - KERNEL_OFFSET ) {
- *( .text )
- }
-
- .rodata ALIGN( 4K ) : AT( ADDR( .rodata ) - KERNEL_OFFSET ) {
- *( .rodata )
- }
-
- .data ALIGN( 4K ) : AT( ADDR( .data ) - KERNEL_OFFSET ) {
- __data_start = .;
- *( .data )
- __data_end = .;
- }
-
- .bss ALIGN( 4K ) : AT( ADDR( .bss ) - KERNEL_OFFSET ) {
- __bss_start = .;
- *( COMMON )
- *( .bss )
-
- /* align to 4k */
- . = ALIGN( 4K );
- /* 1MB for initial heap */
- __initial_heap_start = .;
- . += 0x100000;
- __initial_heap_end = .;
-
- __bss_end = .;
- }
-
- __kernel_end = .;
-}
diff --git a/bolthur/kernel/target/raspi/physical.v8.64.ld b/bolthur/kernel/target/raspi/physical.v8.64.ld
index e3d779fda..35d4e0cb2 100644
--- a/bolthur/kernel/target/raspi/physical.v8.64.ld
+++ b/bolthur/kernel/target/raspi/physical.v8.64.ld
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/target/raspi/qemu.v6.32.ld b/bolthur/kernel/target/raspi/qemu.v6.32.ld
index 1cb7a53c9..f2d13e43d 100644
--- a/bolthur/kernel/target/raspi/qemu.v6.32.ld
+++ b/bolthur/kernel/target/raspi/qemu.v6.32.ld
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/target/raspi/qemu.v7.32.ld b/bolthur/kernel/target/raspi/qemu.v7.32.ld
index 1cb7a53c9..f2d13e43d 100644
--- a/bolthur/kernel/target/raspi/qemu.v7.32.ld
+++ b/bolthur/kernel/target/raspi/qemu.v7.32.ld
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/target/raspi/qemu.v8.32.ld b/bolthur/kernel/target/raspi/qemu.v8.32.ld
deleted file mode 100644
index 1cb7a53c9..000000000
--- a/bolthur/kernel/target/raspi/qemu.v8.32.ld
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * Copyright (C) 2018 - 2025 bolthur project.
- *
- * This file is part of bolthur/kernel.
- *
- * bolthur/kernel is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * bolthur/kernel is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with bolthur/kernel. If not, see .
- */
-
-OUTPUT_FORMAT( elf32-littlearm )
-OUTPUT_ARCH( arm )
-
-ENTRY( startup )
-
-KERNEL_LMA = 0x10000;
-KERNEL_OFFSET = 0xC0000000;
-
-SECTIONS {
- . = KERNEL_LMA;
- __kernel_start = . + KERNEL_OFFSET;
-
- /* boot kernel sections */
- .text.boot : ALIGN( 4K ) {
- *( .text.boot )
- }
-
- .data.boot : ALIGN( 4K ) {
- *( .data.boot )
- }
-
- . += KERNEL_OFFSET;
-
- /* higher half kernel sections */
- .text ALIGN( 4K ) : AT( ADDR( .text ) - KERNEL_OFFSET ) {
- *( .text )
- }
-
- .rodata ALIGN( 4K ) : AT( ADDR( .rodata ) - KERNEL_OFFSET ) {
- *( .rodata )
- }
-
- .data ALIGN( 4K ) : AT( ADDR( .data ) - KERNEL_OFFSET ) {
- __data_start = .;
- *( .data )
- __data_end = .;
- }
-
- .bss ALIGN( 4K ) : AT( ADDR( .bss ) - KERNEL_OFFSET ) {
- __bss_start = .;
- *( COMMON )
- *( .bss )
-
- /* align to 4k */
- . = ALIGN( 4K );
- /* 1MB for initial heap */
- __initial_heap_start = .;
- . += 0x100000;
- __initial_heap_end = .;
-
- __bss_end = .;
- }
-
- __kernel_end = .;
-}
diff --git a/bolthur/kernel/target/raspi/qemu.v8.64.ld b/bolthur/kernel/target/raspi/qemu.v8.64.ld
index ffb6b3b48..9f95d571b 100644
--- a/bolthur/kernel/target/raspi/qemu.v8.64.ld
+++ b/bolthur/kernel/target/raspi/qemu.v8.64.ld
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/task/lock.c b/bolthur/kernel/task/lock.c
index b3824205b..eb1ab58a5 100644
--- a/bolthur/kernel/task/lock.c
+++ b/bolthur/kernel/task/lock.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/task/lock.h b/bolthur/kernel/task/lock.h
index 9cfa64fa7..067041d4b 100644
--- a/bolthur/kernel/task/lock.h
+++ b/bolthur/kernel/task/lock.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/task/process.c b/bolthur/kernel/task/process.c
index 4c31f759e..619ae9a45 100644
--- a/bolthur/kernel/task/process.c
+++ b/bolthur/kernel/task/process.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -39,6 +39,7 @@
#include "process.h"
#include "thread.h"
#include "stack.h"
+#include "../entry.h"
#include "../rpc/data.h"
#include "../rpc/queue.h"
#include "../rpc/generic.h"
@@ -598,13 +599,13 @@ void task_process_cleanup(
// loop
while ( current ) {
// get process from item
- auto task_process_t* proc = ( task_process_t* )current->data;
+ auto const proc = ( task_process_t* )current->data;
// check for running thread
avl_node_t* current_thread = avl_iterate_first( proc->thread_manager );
bool skip = false;
while ( current_thread ) {
// get thread
- auto const task_thread_t* thread = TASK_THREAD_GET_BLOCK( current_thread );
+ auto const thread = TASK_THREAD_GET_BLOCK( current_thread );
// check for active
if ( thread->state != TASK_THREAD_STATE_KILL ) {
skip = true;
@@ -630,7 +631,7 @@ void task_process_cleanup(
// head over to next
current = current->next;
// remove list item
- list_remove_item( process_manager->process_to_cleanup, remove );
+ list_remove_item( process_manager->process_to_cleanup, remove, true );
}
}
@@ -789,7 +790,7 @@ void task_process_prepare_kill( void* context, task_process_t* proc ) {
// get thread
task_thread_t* thread = TASK_THREAD_GET_BLOCK( current );
// set process state
- thread->state = TASK_THREAD_STATE_KILL;
+ task_thread_set_state( thread, TASK_THREAD_STATE_KILL );
// get next thread
current = avl_iterate_next( proc->thread_manager, current );
}
@@ -801,6 +802,55 @@ void task_process_prepare_kill( void* context, task_process_t* proc ) {
event_enqueue( EVENT_PROCESS, EVENT_DETERMINE_ORIGIN( context ) );
}
+/**
+ * @fn void unmap_replace_random(size_t)
+ * @brief Unmap replace random area
+ * @param size
+ */
+static void unmap_replace_random( const size_t size ) {
+ // allocate space
+ const uintptr_t end = KERNEL_AREA_PROCESS_REPLACE_START + size;
+ for (
+ uintptr_t start = KERNEL_AREA_PROCESS_REPLACE_START;
+ start < end;
+ start += PAGE_SIZE
+ ) {
+ virt_unmap_address( virt_current_kernel_context, start, true );
+ }
+}
+
+/**
+ * @fn int map_replace_random(size_t)
+ * @brief Map replace random area
+ * @param size
+ * @return
+ */
+static int map_replace_random( const size_t size ) {
+ // allocate space
+ const uintptr_t end = KERNEL_AREA_PROCESS_REPLACE_START + size;
+ for (
+ uintptr_t start = KERNEL_AREA_PROCESS_REPLACE_START;
+ start < end;
+ start += PAGE_SIZE
+ ) {
+ // map address
+ const bool result = virt_map_address_random(
+ virt_current_kernel_context,
+ start,
+ VIRT_MEMORY_TYPE_NORMAL_NC,
+ VIRT_PAGE_TYPE_READ | VIRT_PAGE_TYPE_WRITE
+ );
+ // handle failure
+ if ( ! result ) {
+ // unmap random
+ unmap_replace_random( KERNEL_AREA_PROCESS_REPLACE_START - start );
+ // return nomem
+ return -ENOMEM;
+ }
+ }
+ return 0;
+}
+
/**
* @fn int task_process_replace(task_process_t*, uintptr_t, const char**, const char**, void*)
* @brief Replace current process with elf image
@@ -811,8 +861,6 @@ void task_process_prepare_kill( void* context, task_process_t* proc ) {
* @param env
* @param context
* @return
- *
- * @todo don't allocate kernel heap for elf application
*/
int task_process_replace(
task_process_t* proc,
@@ -821,7 +869,7 @@ int task_process_replace(
const char** env,
void* context
) {
- bool replace_current_thread = task_thread_current_thread->process == proc;
+ const bool replace_current_thread = task_thread_current_thread->process == proc;
#if defined( PRINT_PROCESS )
DEBUG_OUTPUT(
"task_thread_current_thread->process = %p, proc = %p\r\n",
@@ -850,17 +898,20 @@ int task_process_replace(
DEBUG_OUTPUT( "Preparing to load image\r\n" )
#endif
// save image temporary
- size_t image_size = elf_image_size( ( uintptr_t )elf );
+ const size_t image_size = elf_image_size( ( uintptr_t )elf );
#if defined( PRINT_PROCESS )
DEBUG_OUTPUT( "image_size = %#zx\r\n", image_size )
#endif
- void* image = malloc( sizeof( char ) * image_size );
- // handle error
- if ( ! image ) {
+ // map random place for image
+ const int result = map_replace_random( image_size );
+ if ( 0 != result ) {
free( tmp_argv );
free( tmp_env );
- return -ENOMEM;
+ return result;
}
+ // set image
+ auto const image = ( void* )KERNEL_AREA_PROCESS_REPLACE_START;
+ // copy over image
#if defined( PRINT_PROCESS )
DEBUG_OUTPUT( "image = %p\r\n", image )
#endif
@@ -870,7 +921,7 @@ int task_process_replace(
if ( ! shared_memory_cleanup_process( proc ) ) {
free( tmp_argv );
free( tmp_env );
- free( image );
+ unmap_replace_random( image_size );
task_process_prepare_kill( context, proc );
return -ENOMEM;
}
@@ -879,7 +930,7 @@ int task_process_replace(
if ( ! virt_destroy_context( proc->virtual_context, true ) ) {
free( tmp_argv );
free( tmp_env );
- free( image );
+ unmap_replace_random( image_size );
task_process_prepare_kill( context, proc );
return -ENOMEM;
}
@@ -908,7 +959,7 @@ int task_process_replace(
if ( ! proc->thread_manager ) {
free( tmp_argv );
free( tmp_env );
- free( image );
+ unmap_replace_random( image_size );
task_process_prepare_kill( context, proc );
return -ENOMEM;
}
@@ -916,7 +967,7 @@ int task_process_replace(
if ( ! proc->thread_stack_manager ) {
free( tmp_argv );
free( tmp_env );
- free( image );
+ unmap_replace_random( image_size );
task_process_prepare_kill( context, proc );
return -ENOMEM;
}
@@ -924,11 +975,11 @@ int task_process_replace(
proc->current_thread_id = 0;
// load elf image
- uintptr_t init_entry = elf_load( ( uintptr_t )image, proc );
+ const uintptr_t init_entry = elf_load( ( uintptr_t )image, proc );
if ( ! init_entry ) {
free( tmp_argv );
free( tmp_env );
- free( image );
+ unmap_replace_random( image_size );
task_process_prepare_kill( context, proc );
return -ENOMEM;
}
@@ -938,6 +989,7 @@ int task_process_replace(
if ( ! new_current ) {
free( tmp_argv );
free( tmp_env );
+ unmap_replace_random( image_size );
task_process_prepare_kill( context, proc );
return -ENOMEM;
}
@@ -952,12 +1004,13 @@ int task_process_replace(
if ( ! task_thread_push_arguments( new_current, tmp_argv, tmp_env ) ) {
free( tmp_argv );
free( tmp_env );
+ unmap_replace_random( image_size );
task_process_prepare_kill( context, proc );
return -ENOMEM;
}
// free temporary stuff
- free( image );
+ unmap_replace_random( image_size );
free( tmp_argv );
free( tmp_env );
@@ -970,7 +1023,7 @@ int task_process_replace(
// replace current thread pointer
task_thread_current_thread = new_current;
// switch thread state to active
- task_thread_current_thread->state = TASK_THREAD_STATE_ACTIVE;
+ task_thread_set_state( task_thread_current_thread, TASK_THREAD_STATE_ACTIVE );
}
return 0;
}
@@ -993,7 +1046,7 @@ void task_unblock_threads(
// loop until there is no more thread
while ( current_thread_node ) {
// get thread
- auto task_thread_t* possible_thread_to_unblock = TASK_THREAD_GET_BLOCK(
+ auto const possible_thread_to_unblock = TASK_THREAD_GET_BLOCK(
current_thread_node );
// try to unblock if blocked
task_thread_unblock(
diff --git a/bolthur/kernel/task/process.h b/bolthur/kernel/task/process.h
index 10af57035..195bcfc36 100644
--- a/bolthur/kernel/task/process.h
+++ b/bolthur/kernel/task/process.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/task/queue.c b/bolthur/kernel/task/queue.c
index 605bbbc12..0c7e113e7 100644
--- a/bolthur/kernel/task/queue.c
+++ b/bolthur/kernel/task/queue.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/task/queue.h b/bolthur/kernel/task/queue.h
index 8993aea70..97b156980 100644
--- a/bolthur/kernel/task/queue.h
+++ b/bolthur/kernel/task/queue.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/task/stack.c b/bolthur/kernel/task/stack.c
index 8653c960e..2118b1ede 100644
--- a/bolthur/kernel/task/stack.c
+++ b/bolthur/kernel/task/stack.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/task/stack.h b/bolthur/kernel/task/stack.h
index 1e502ae92..ef14dfa9d 100644
--- a/bolthur/kernel/task/stack.h
+++ b/bolthur/kernel/task/stack.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/task/state.h b/bolthur/kernel/task/state.h
index 822b85035..dae1b87ce 100644
--- a/bolthur/kernel/task/state.h
+++ b/bolthur/kernel/task/state.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/kernel/task/thread.c b/bolthur/kernel/task/thread.c
index 863318f4c..b96fcad9b 100644
--- a/bolthur/kernel/task/thread.c
+++ b/bolthur/kernel/task/thread.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -103,7 +103,7 @@ static void thread_destroy_callback( avl_node_t* node ) {
// get thread queue by priority
task_priority_queue_t* queue = task_queue_get_queue(
process_manager, proc->priority );
- while( queue && ! list_remove_data( queue->thread_list, thread ) ) {
+ while( queue && ! list_remove_data( queue->thread_list, thread, true ) ) {
// loop until successfully removed
}
// remove from stack address from manager
@@ -153,10 +153,12 @@ bool task_thread_set_current(
// update queue current
queue->current = thread;
// set state
- task_thread_current_thread->state =
+ task_thread_set_state(
+ task_thread_current_thread,
task_thread_current_thread->state == TASK_THREAD_STATE_RPC_QUEUED
? TASK_THREAD_STATE_RPC_ACTIVE
- : TASK_THREAD_STATE_ACTIVE;
+ : TASK_THREAD_STATE_ACTIVE
+ );
return true;
}
@@ -170,9 +172,9 @@ void task_thread_reset_current( void ) {
// set state
if ( task_thread_current_thread ) {
if ( TASK_THREAD_STATE_HALT_SWITCH == task_thread_current_thread->state ) {
- task_thread_current_thread->state = TASK_THREAD_STATE_READY;
+ task_thread_set_state( task_thread_current_thread, TASK_THREAD_STATE_READY );
} else if ( TASK_THREAD_STATE_RPC_HALT_SWITCH == task_thread_current_thread->state ) {
- task_thread_current_thread->state = TASK_THREAD_STATE_RPC_QUEUED;
+ task_thread_set_state( task_thread_current_thread, TASK_THREAD_STATE_RPC_QUEUED );
}
}
// unset current thread
@@ -397,8 +399,8 @@ void task_thread_kill( task_thread_t* thread, bool schedule, void* context ) {
)
#endif
// set thread state and push thread to clean up list
- thread->state = TASK_THREAD_STATE_KILL;
- list_push_back_data( process_manager->thread_to_cleanup, thread->process );
+ task_thread_set_state( thread, TASK_THREAD_STATE_KILL );
+ list_push_back_data( process_manager->thread_to_cleanup, thread->process );
// trigger schedule if necessary
if ( schedule ) {
event_enqueue( EVENT_PROCESS, EVENT_DETERMINE_ORIGIN( context ) );
@@ -454,7 +456,7 @@ void task_thread_cleanup(
}
}
// remove list item
- list_remove_item( process_manager->thread_to_cleanup, remove );
+ list_remove_item( process_manager->thread_to_cleanup, remove, true );
}
}
@@ -490,7 +492,7 @@ void task_thread_block(
thread->state_backup = TASK_THREAD_STATE_RPC_QUEUED;
}
// set state and data
- thread->state = state;
+ task_thread_set_state( thread, state );
thread->state_data = data;
#if defined( PRINT_PROCESS )
DEBUG_OUTPUT( "thread->state_backup = %d\r\n", thread->state_backup )
@@ -541,15 +543,27 @@ void task_thread_unblock(
#endif
return;
}
+ // validate data size
+ if ( thread->state_data.data_size != necessary_data.data_size ) {
+ // debug output
+ #if defined( PRINT_PROCESS )
+ DEBUG_OUTPUT(
+ "invalid data size attribute %zu / %zu\r\n",
+ thread->state_data.data_size,
+ necessary_data.data_size
+ )
+ #endif
+ return;
+ }
// debug output
#if defined( PRINT_PROCESS )
- DEBUG_OUTPUT( "thread->state = %d\r\n", thread->state )
+ DEBUG_OUTPUT( "%d: thread->state = %d\r\n", thread->process->id, thread->state )
#endif
// set back to back up again
- thread->state = thread->state_backup;
+ task_thread_set_state( thread, thread->state_backup );
// debug output
#if defined( PRINT_PROCESS )
- DEBUG_OUTPUT( "thread->state = %d\r\n", thread->state )
+ DEBUG_OUTPUT( "%d: thread->state = %d\r\n", thread->process->id, thread->state )
#endif
}
@@ -572,7 +586,7 @@ task_thread_t* task_thread_get_blocked(
avl_node_t* avl_proc = avl_iterate_first( process_manager->process_id );
while ( avl_proc ) {
// get process container
- task_process_t* proc = TASK_PROCESS_GET_BLOCK_ID( avl_proc );
+ auto const proc = TASK_PROCESS_GET_BLOCK_ID( avl_proc );
// debug output
#if defined( PRINT_PROCESS )
DEBUG_OUTPUT( "proc->id = %d\r\n", proc->id )
@@ -581,7 +595,7 @@ task_thread_t* task_thread_get_blocked(
avl_node_t* avl_thread = avl_iterate_first( proc->thread_manager );
while ( avl_thread ) {
// get thread
- task_thread_t* thread = TASK_THREAD_GET_BLOCK( avl_thread );
+ auto const thread = TASK_THREAD_GET_BLOCK( avl_thread );
// debug output
#if defined( PRINT_PROCESS )
DEBUG_OUTPUT(
@@ -599,6 +613,7 @@ task_thread_t* task_thread_get_blocked(
if (
thread->state == necessary_thread_state
&& thread->state_data.data_ptr == necessary_thread_data.data_ptr
+ && thread->state_data.data_size == necessary_thread_data.data_size
) {
return thread;
}
@@ -610,3 +625,22 @@ task_thread_t* task_thread_get_blocked(
}
return NULL;
}
+
+/**
+ * @fn void task_thread_set_state(task_thread_t*, task_thread_state_t)
+ * @brief Wrapper to set thread state
+ * @param thread
+ * @param state
+ */
+void task_thread_set_state( task_thread_t* thread, const task_thread_state_t state ) {
+ if ( ! thread ) {
+ return;
+ }
+ #if defined( PRINT_PROCESS )
+ void* returnAddress = __builtin_return_address(0);
+ DEBUG_OUTPUT( "change thread for pid %d from %d to %d. Return address is: %p\r\n",
+ thread->process ? thread->process->id : 0, thread->state, state,
+ returnAddress )
+ #endif
+ thread->state = state;
+}
diff --git a/bolthur/kernel/task/thread.h b/bolthur/kernel/task/thread.h
index 9a613b484..897363467 100644
--- a/bolthur/kernel/task/thread.h
+++ b/bolthur/kernel/task/thread.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -31,18 +31,32 @@ typedef struct task_process task_process_t;
typedef struct task_priority_queue task_priority_queue_t;
typedef struct task_thread {
+ /** current context */
void* current_context;
+ /** avl management node */
avl_node_t node_id;
+ /** thread id */
pid_t id;
+ /** thread priority */
size_t priority;
+ /** virtual stack address */
uintptr_t stack_virtual;
+ /** physical stack address */
uint64_t stack_physical;
+ /** stack size */
size_t stack_size;
+ /** root entry point */
uintptr_t entry;
+ /** current thread state */
task_thread_state_t state;
+ /** thread state backup */
task_thread_state_t state_backup;
+ /** thread state data */
task_state_data_t state_data;
+ /** pointer to process structure */
task_process_t* process;
+ /** flag indicating thread is handling an interrupt */
+ bool handling_interrupt;
} task_thread_t;
extern task_thread_t* task_thread_current_thread;
@@ -60,7 +74,7 @@ task_thread_t* task_thread_create( uintptr_t, task_process_t*, size_t );
task_thread_t* task_thread_fork( task_process_t*, task_thread_t* );
task_thread_t* task_thread_next( void );
[[noreturn]] void task_thread_switch_to( uintptr_t );
-bool task_thread_push_arguments( task_thread_t*, char**, char** );
+bool task_thread_push_arguments( const task_thread_t*, char**, char** );
void task_thread_cleanup( event_origin_t, void* );
void task_thread_block( task_thread_t*, task_thread_state_t, task_state_data_t );
void task_thread_unblock( task_thread_t*, task_thread_state_t, task_state_data_t );
@@ -68,5 +82,6 @@ task_thread_t* task_thread_get_blocked( task_thread_state_t, task_state_data_t )
void task_thread_kill( task_thread_t*, bool, void* );
bool task_thread_is_ready( task_thread_t* );
bool task_thread_is_active( task_thread_t* );
+void task_thread_set_state( task_thread_t*, task_thread_state_t );
#endif
diff --git a/bolthur/kernel/timer.c b/bolthur/kernel/timer.c
index add6ba456..8f544fe63 100644
--- a/bolthur/kernel/timer.c
+++ b/bolthur/kernel/timer.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -35,7 +35,6 @@ list_manager_t* timer_list;
/**
* @fn size_t timer_generate_id(void)
* @brief generate new callback id
- *
* @return
*/
size_t timer_generate_id( void ) {
@@ -48,7 +47,6 @@ size_t timer_generate_id( void ) {
/**
* @fn bool timer_insert(list_manager_t*, void*)
* @brief Timer insert callback
- *
* @param list
* @param data
* @return
@@ -62,11 +60,11 @@ static bool timer_insert(
return list_push_back_data( list, data );
}
// get entry to add
- timer_callback_entry_t* entry_to_add = ( timer_callback_entry_t* )data;
+ auto const entry_to_add = ( timer_callback_entry_t* )data;
list_item_t* item = list->first;
while ( item ) {
// get pointer to current entry
- timer_callback_entry_t* entry = ( timer_callback_entry_t* )item->data;
+ auto const entry = ( timer_callback_entry_t* )item->data;
// debug output
#if defined( PRINT_TIMER )
DEBUG_OUTPUT(
@@ -96,7 +94,6 @@ static bool timer_insert(
/**
* @fn void timer_cleanup(list_item_t*)
* @brief timer cleanup callback
- *
* @param item
*/
static void timer_cleanup( list_item_t* item ) {
@@ -110,8 +107,7 @@ static void timer_cleanup( list_item_t* item ) {
/**
* @fn int32_t timer_lookup(const list_item_t*, const void*)
- * @brief
- *
+ * @brief lookup a timer
* @param a
* @param data
* @return
@@ -120,7 +116,7 @@ static int32_t timer_lookup(
const list_item_t* a,
const void* data
) {
- timer_callback_entry_t* entry = a->data;
+ const timer_callback_entry_t* entry = a->data;
return entry->id == ( size_t )data ? 0 : 1;
}
@@ -139,7 +135,6 @@ void timer_init( void ) {
/**
* @fn timer_callback_entry_t* timer_register_callback(task_thread_t*, size_t, size_t)
* @brief Register timer callback
- *
* @param thread
* @param rpc_num
* @param timeout
@@ -147,13 +142,13 @@ void timer_init( void ) {
*/
timer_callback_entry_t* timer_register_callback(
task_thread_t* thread,
- size_t rpc_num,
- size_t timeout
+ const size_t rpc_num,
+ const size_t timeout
) {
// reserve new entry structure
timer_callback_entry_t* entry = malloc( sizeof( *entry ) );
if ( ! entry ) {
- return NULL;
+ return nullptr;
}
// clear out
memset( entry, 0, sizeof( *entry ) );
@@ -169,7 +164,7 @@ timer_callback_entry_t* timer_register_callback(
DEBUG_OUTPUT( "Timer insert failed!\r\n" )
#endif
free( entry );
- return NULL;
+ return nullptr;
}
// return structure
return entry;
@@ -178,18 +173,17 @@ timer_callback_entry_t* timer_register_callback(
/**
* @fn bool timer_unregister_callback(size_t)
* @brief Unregister timer callback by id
- *
* @param id
* @return
*/
-bool timer_unregister_callback( size_t id ) {
+bool timer_unregister_callback( const size_t id ) {
// try to find item
list_item_t* item = list_lookup_data( timer_list, ( void* ) id );
if ( ! item ) {
return true;
}
// remove item
- return list_remove_item( timer_list, item );
+ return list_remove_item( timer_list, item, true );
}
/**
@@ -202,12 +196,11 @@ void timer_handle_callback( void ) {
return;
}
// get current tick
- size_t tick = timer_get_tick();
+ const size_t tick = timer_get_tick();
list_item_t* current = timer_list->first;
// loop through handles
while( current ) {
- timer_callback_entry_t* entry =
- ( timer_callback_entry_t* )current->data;
+ auto const entry = ( timer_callback_entry_t* )current->data;
// debug output
#if defined( PRINT_TIMER )
DEBUG_OUTPUT( "tick = %zu, entry->expire = %zu\r\n", tick, entry->expire )
@@ -225,33 +218,37 @@ void timer_handle_callback( void ) {
entry->thread->process
)
#endif
- // raise rpc without data
- rpc_backup_t* rpc = rpc_generic_raise(
- entry->thread,
- entry->thread->process,
- entry->rpc,
- NULL,
- 0,
- entry->thread,
- false,
- entry->id,
- true
- );
- // handle error by skip
- if ( ! rpc ) {
- // debug output
- #if defined( PRINT_TIMER )
- DEBUG_OUTPUT( "Unable to raise rpc\r\n" )
- #endif
- current = current->next;
- continue;
+ // raise rpc without data if not handled
+ if ( ! entry->handled ) {
+ // raise rpc
+ rpc_backup_t* rpc = rpc_generic_raise(
+ entry->thread,
+ entry->thread->process,
+ entry->rpc,
+ nullptr,
+ 0,
+ entry->thread,
+ false,
+ 0, // pass 0 as origin data id to prevent possibly matching origin
+ true,
+ false
+ );
+ // handle error by skip
+ if ( ! rpc ) {
+ // debug output
+ #if defined( PRINT_TIMER )
+ DEBUG_OUTPUT( "Unable to raise rpc\r\n" )
+ #endif
+ current = current->next;
+ continue;
+ }
}
// cache current and set to next
list_item_t* to_remove = current;
// switch to next
current = current->next;
// remove from list
- if ( ! list_remove_item( timer_list, to_remove ) ) {
+ if ( ! list_remove_item( timer_list, to_remove, true ) ) {
// debug output
#if defined( PRINT_TIMER )
DEBUG_OUTPUT( "Error while removing timer from list\r\n" )
@@ -260,3 +257,30 @@ void timer_handle_callback( void ) {
}
}
}
+
+/**
+ * @fn timer_callback_entry_t* timer_get_by_process_id(pid_t)
+ * @brief Method to get possible timer by process id
+ * @param pid process id to lookup
+ * @return
+ */
+timer_callback_entry_t* timer_get_by_process_id( const pid_t pid ) {
+ // skip if list is empty
+ if ( list_empty( timer_list ) ) {
+ return nullptr;
+ }
+ // get current tick
+ auto current = timer_list->first;
+ // loop through handles
+ while( current ) {
+ // get entry
+ auto const entry = ( timer_callback_entry_t* )current->data;
+ // check for match
+ if ( entry->thread->process->id == pid ) {
+ return entry;
+ }
+ // switch to next
+ current = current->next;
+ }
+ return nullptr;
+}
diff --git a/bolthur/kernel/timer.h b/bolthur/kernel/timer.h
index ea0d346e7..c327fdc14 100644
--- a/bolthur/kernel/timer.h
+++ b/bolthur/kernel/timer.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -27,6 +27,7 @@ typedef struct {
size_t id;
size_t expire;
task_thread_t* thread;
+ bool handled;
size_t rpc;
} timer_callback_entry_t;
@@ -40,5 +41,6 @@ size_t timer_generate_id( void );
timer_callback_entry_t* timer_register_callback( task_thread_t*, size_t, size_t );
bool timer_unregister_callback( size_t );
void timer_handle_callback( void );
+timer_callback_entry_t* timer_get_by_process_id( pid_t );
#endif
diff --git a/bolthur/kernel/tty.h b/bolthur/kernel/tty.h
index 994a00083..5c37b0982 100644
--- a/bolthur/kernel/tty.h
+++ b/bolthur/kernel/tty.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _TTY_H
#define _TTY_H
-#include
#include
void tty_init( void );
diff --git a/bolthur/kernel/yield.h b/bolthur/kernel/yield.h
index 5cf708b29..f2c08d342 100644
--- a/bolthur/kernel/yield.h
+++ b/bolthur/kernel/yield.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/library/Makefile.am b/bolthur/library/Makefile.am
index 1b1f4faf6..34362d86a 100644
--- a/bolthur/library/Makefile.am
+++ b/bolthur/library/Makefile.am
@@ -1,4 +1,4 @@
ACLOCAL_AMFLAGS = -I ../../build-aux/m4
-SUBDIRS = collection framebuffer handle
+SUBDIRS = collection framebuffer handle hid platform usb util vfs
diff --git a/bolthur/library/collection/avl/avl.c b/bolthur/library/collection/avl/avl.c
index 7b2647e6d..6931aea3d 100644
--- a/bolthur/library/collection/avl/avl.c
+++ b/bolthur/library/collection/avl/avl.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/library/collection/avl/avl.h b/bolthur/library/collection/avl/avl.h
index b139ed06e..1a0a2a135 100644
--- a/bolthur/library/collection/avl/avl.h
+++ b/bolthur/library/collection/avl/avl.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -22,7 +22,6 @@
#include
#include
-#include
// forward declarations
typedef struct avl_node avl_node_t;
diff --git a/bolthur/library/collection/ht/ht.c b/bolthur/library/collection/ht/ht.c
index b209f773f..9d5a73a6d 100644
--- a/bolthur/library/collection/ht/ht.c
+++ b/bolthur/library/collection/ht/ht.c
@@ -1,5 +1,5 @@
/**
-* Copyright (C) 2018 - 2025 bolthur project.
+* Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -63,21 +63,21 @@ static const char* ht_set_entry(
// create hash from key
const uint64_t hash = hash_key( key );
// get base index
- size_t index = ( size_t )( hash & ( uint64_t )( capacity - 1 ) );
+ size_t ht_index = ( size_t )( hash & ( uint64_t )( capacity - 1 ) );
// loop while entries index key is valid
- while ( entries[index].key ) {
+ while ( entries[ht_index].key ) {
// handle match of entry with key
- if ( strcmp( key, entries[index].key ) == 0 ) {
+ if ( strcmp( key, entries[ht_index].key ) == 0 ) {
// overwrite value
- entries[index].value = value;
+ entries[ht_index].value = value;
// return current key
- return entries[index].key;
+ return entries[ht_index].key;
}
// increment index
- index++;
+ ht_index++;
// handle capacity reached by resetting index
- if ( index >= capacity ) {
- index = 0;
+ if ( ht_index >= capacity ) {
+ ht_index = 0;
}
}
// handle length set
@@ -92,8 +92,8 @@ static const char* ht_set_entry(
( *plength )++;
}
// populate key and value of found index
- entries[index].key = key;
- entries[index].value = value;
+ entries[ht_index].key = key;
+ entries[ht_index].value = value;
// return key
return key;
}
@@ -200,19 +200,19 @@ void* ht_get( const ht_t* table, const char* key ) {
// create hash from key
const uint64_t hash = hash_key( key );
// get base index
- size_t index = ( size_t )( hash & ( uint64_t )( table->capacity - 1 ) );
+ size_t ht_index = ( size_t )( hash & ( uint64_t )( table->capacity - 1 ) );
// loop while entries index key is valid
- while ( table->entries[ index ].key ) {
+ while ( table->entries[ ht_index ].key ) {
// handle match
- if ( strcmp( key, table->entries[ index ].key ) == 0 ) {
+ if ( strcmp( key, table->entries[ ht_index ].key ) == 0 ) {
// return set value
- return table->entries[ index ].value;
+ return table->entries[ ht_index ].value;
}
// increment index
- index++;
+ ht_index++;
// reset index if greater than capacity
- if ( index >= table->capacity ) {
- index = 0;
+ if ( ht_index >= table->capacity ) {
+ ht_index = 0;
}
}
// return null if not found
@@ -254,23 +254,23 @@ void ht_unset( ht_t* table, const char* key ) {
// create hash from key
const uint64_t hash = hash_key( key );
// get base index
- size_t index = ( size_t )( hash & ( uint64_t )( table->capacity - 1 ) );
+ size_t ht_index = ( size_t )( hash & ( uint64_t )( table->capacity - 1 ) );
// loop while entries index key is valid
- while ( table->entries[ index ].key ) {
+ while ( table->entries[ ht_index ].key ) {
// handle match
- if ( strcmp( key, table->entries[ index ].key ) == 0 ) {
+ if ( strcmp( key, table->entries[ ht_index ].key ) == 0 ) {
// free up key
- free( ( void* )table->entries[ index ].key );
- table->entries[ index ].key = NULL;
+ free( ( void* )table->entries[ ht_index ].key );
+ table->entries[ ht_index ].key = NULL;
table->length--;
// return early
return;
}
// increment index
- index++;
+ ht_index++;
// reset index if greater than capacity
- if ( index >= table->capacity ) {
- index = 0;
+ if ( ht_index >= table->capacity ) {
+ ht_index = 0;
}
}
}
diff --git a/bolthur/library/collection/ht/ht.h b/bolthur/library/collection/ht/ht.h
index eb12cc0e8..663ab9968 100644
--- a/bolthur/library/collection/ht/ht.h
+++ b/bolthur/library/collection/ht/ht.h
@@ -1,5 +1,5 @@
/**
-* Copyright (C) 2018 - 2025 bolthur project.
+* Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _HT_H
#define _HT_H
-#include
#include
#define INITIAL_CAPACITY 16
diff --git a/bolthur/library/collection/list/list.c b/bolthur/library/collection/list/list.c
index 55e382e95..7c5270c66 100644
--- a/bolthur/library/collection/list/list.c
+++ b/bolthur/library/collection/list/list.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -503,15 +503,51 @@ bool list_push_back_data( list_manager_t* list, void* data ) {
}
/**
- * @fn bool list_remove_item(list_manager_t*, list_item_t*)
+ * @fn bool list_push_after_data(struct list_manager*, void*, void*)
+ * @brief Function to insert data after data element if found
+ * @param list list to manipulate
+ * @param after data where new data shall be added as next
+ * @param data data to be added
+ * @return
+ */
+bool list_push_after_data( struct list_manager* list, void* after, void* data ) {
+ // handle invalid parameter
+ if ( ! list || ! data || ! after ) {
+ return false;
+ }
+ // get item where to insert
+ list_item_t* after_item = list_lookup_data( list, after );
+ // handle not found
+ if ( ! after_item ) {
+ return false;
+ }
+ // create new node
+ list_item_t* node = list_item_create( data );
+ // handle error
+ if ( !node ) {
+ return false;
+ }
+ // insert after found item
+ node->next = after_item->next;
+ if ( after_item->next ) {
+ after_item->next->previous = node;
+ }
+ node->previous = after_item;
+ after_item->next = node;
+ return true;
+}
+
+/**
+ * @fn bool list_remove_item(list_manager_t*, list_item_t*, bool)
* @brief Remove list item
*
* @param list
* @param item
+ * @param cleanup
* @return true
* @return false
*/
-bool list_remove_item( list_manager_t* list, list_item_t* item ) {
+bool list_remove_item( list_manager_t* list, list_item_t* item, const bool cleanup ) {
// handle invalid parameter
if ( !list || !item ) {
return false;
@@ -541,20 +577,25 @@ bool list_remove_item( list_manager_t* list, list_item_t* item ) {
}
// free list item
- list->cleanup( item );
+ if ( cleanup ) {
+ list->cleanup( item );
+ } else {
+ free( item );
+ }
return true;
}
/**
- * @fn bool list_remove_data(list_manager_t*, void*)
+ * @fn bool list_remove_data(list_manager_t*, void*, bool)
* @brief Remove list item
*
* @param list
* @param data
+ * @param cleanup
* @return true
* @return false
*/
-bool list_remove_data( list_manager_t* list, void* data ) {
+bool list_remove_data( list_manager_t* list, void* data, const bool cleanup ) {
// handle invalid parameter
if ( !list || !data ) {
return false;
@@ -586,7 +627,11 @@ bool list_remove_data( list_manager_t* list, void* data ) {
}
// free list item
- list->cleanup( item );
+ if ( cleanup ) {
+ list->cleanup( item );
+ } else {
+ free( item );
+ }
return true;
}
diff --git a/bolthur/library/collection/list/list.h b/bolthur/library/collection/list/list.h
index 20e705763..8a007f081 100644
--- a/bolthur/library/collection/list/list.h
+++ b/bolthur/library/collection/list/list.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _LIST_H
#define _LIST_H
-#include
#include
#include
@@ -60,14 +59,15 @@ list_item_t* list_lookup_data( list_manager_t*, void* );
list_item_t* list_lookup_item( list_manager_t*, const list_item_t* );
bool list_push_front_data( list_manager_t*, void* );
bool list_push_back_data( list_manager_t*, void* );
+bool list_push_after_data( struct list_manager*, void*, void* );
void* list_pop_front_data( list_manager_t* );
void* list_pop_back_data( list_manager_t* );
void* list_peek_front_data( list_manager_t* );
void* list_peek_back_data( list_manager_t* );
bool list_insert_data( list_manager_t*, void* );
bool list_insert_data_before( list_manager_t*, list_item_t*, void* );
-bool list_remove_item( list_manager_t*, list_item_t* );
-bool list_remove_data( list_manager_t*, void* );
+bool list_remove_item( list_manager_t*, list_item_t*, bool );
+bool list_remove_data( list_manager_t*, void*, bool );
size_t list_count_item( list_manager_t* );
list_item_t* list_get_item_at_pos( list_manager_t*, size_t );
diff --git a/bolthur/library/config.h b/bolthur/library/config.h
index b78d0331f..cdf790e42 100644
--- a/bolthur/library/config.h
+++ b/bolthur/library/config.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/library/configure.ac b/bolthur/library/configure.ac
index df73e08fc..c2a26287a 100644
--- a/bolthur/library/configure.ac
+++ b/bolthur/library/configure.ac
@@ -3,7 +3,7 @@ AC_PREREQ([2.71])
AC_INIT([bolthur-library], [0.1.0-dev], [https://github.com/bolthur/kernel/issues], [bolthur-library], [https://github.com/bolthur/kernel])
-AC_COPYRIGHT([Copyright (C) 2018 - 2025 bolthur project])
+AC_COPYRIGHT([Copyright (C) 2018 - 2026 bolthur project])
AC_CONFIG_AUX_DIR([_aux/config])
AC_CONFIG_MACRO_DIR([../../build-aux/m4])
@@ -51,6 +51,24 @@ AC_ARG_WITH(
[with_debug_debug_symbols=yes]
)
+AC_ARG_WITH(
+ [ubsan],
+ AS_HELP_STRING(
+ [--with-ubsan],
+ [compile with ubsan enabled]
+ ),
+ [with_ubsan_enabled=yes]
+)
+
+AC_ARG_WITH(
+ [asan],
+ AS_HELP_STRING(
+ [--with-asan],
+ [compile with asan enabled]
+ ),
+ [with_asan_enabled=yes]
+)
+
# enable output and enable remote debugging together is not allowed
AS_IF([test "x$enable_debug" == "xyes" && test "x$enable_release" == "xyes"], [
AC_MSG_ERROR([Enabled debug and release are not possible at the same time])
@@ -139,6 +157,13 @@ AC_CONFIG_FILES([
collection/list/Makefile
framebuffer/Makefile
handle/Makefile
+ hid/Makefile
+ platform/Makefile
+ platform/raspi/Makefile
+ platform/raspi/iomem/Makefile
+ usb/Makefile
+ util/Makefile
+ vfs/Makefile
])
# FIXME: REPLACE WITH SUBMODULE WHEN MOVING TO OWN REPO
diff --git a/bolthur/library/framebuffer/framebuffer.h b/bolthur/library/framebuffer/framebuffer.h
index 9d2503539..9703de778 100644
--- a/bolthur/library/framebuffer/framebuffer.h
+++ b/bolthur/library/framebuffer/framebuffer.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/library/handle/handle.c b/bolthur/library/handle/handle.c
index 8899fd06f..d913d4955 100644
--- a/bolthur/library/handle/handle.c
+++ b/bolthur/library/handle/handle.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/library/handle/handle.h b/bolthur/library/handle/handle.h
index 12476415a..e005fa474 100644
--- a/bolthur/library/handle/handle.h
+++ b/bolthur/library/handle/handle.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,6 +20,8 @@
#ifndef _HANDLE_H
#define _HANDLE_H
+#define __PERMIT_DEPRECATED_SYS_TREE_H 1
+
#include
#include
#include
diff --git a/bolthur/library/handle/process.c b/bolthur/library/handle/process.c
index e590691e1..3b0e43a2d 100644
--- a/bolthur/library/handle/process.c
+++ b/bolthur/library/handle/process.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/library/handle/process.h b/bolthur/library/handle/process.h
index d8d83f99b..89bd4373b 100644
--- a/bolthur/library/handle/process.h
+++ b/bolthur/library/handle/process.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,8 @@
#ifndef _PROCESS_H
#define _PROCESS_H
-#include
+#define __PERMIT_DEPRECATED_SYS_TREE_H 1
+
#include
#include
#include
diff --git a/bolthur/library/hid/Makefile.am b/bolthur/library/hid/Makefile.am
new file mode 100644
index 000000000..c76c88fe1
--- /dev/null
+++ b/bolthur/library/hid/Makefile.am
@@ -0,0 +1,6 @@
+
+AM_CFLAGS = -DPROGRAM_NAME=\"bolthur/libhid\"
+
+noinst_LTLIBRARIES = libhid.la
+libhid_la_SOURCES = \
+ hid.c
diff --git a/bolthur/library/hid/hid.c b/bolthur/library/hid/hid.c
new file mode 100644
index 000000000..6705c5a00
--- /dev/null
+++ b/bolthur/library/hid/hid.c
@@ -0,0 +1,638 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+// system includes
+#include
+#include
+#include
+#include
+// local includes
+#include "hid.h"
+// server includes
+#include "../../server/libusbd.h"
+
+static int fd_hid = -1;
+
+/**
+ * @fn int hid_init( void )
+ * @brief HID library init
+ * @return
+ */
+int hid_init( void ) {
+ // handle already initialized
+ if ( fd_hid != -1 ) {
+ return 0;
+ }
+ // debug output
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Opening %s\r\n", USBD_DEVICE_PATH )
+ #endif
+ // open handle
+ fd_hid = open( HID_DEVICE_PATH, O_RDWR );
+ // handle error
+ if ( fd_hid == -1 ) {
+ return errno;
+ }
+ // return success
+ return 0;
+}
+
+/**
+ * @fn int hid_register_handler(libusb_hid_usage_page_desktop_t)
+ * @brief Method to attach a new discovered device
+ * @param type
+ * @return
+ */
+int hid_register_handler( const libusb_hid_usage_page_desktop_t type ) {
+ const pid_t pid = getpid();
+ // debug message
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Registering pid %d for type %d\r\n", pid, type )
+ #endif
+ // allocate device
+ hid_register_device_handler_t* request = malloc( sizeof( *request ) );
+ // handle error
+ if ( ! request ) {
+ // debug output
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // return nomem
+ return ENOMEM;
+ }
+ // clear out
+ memset( request, 0, sizeof( *request ) );
+ // copy over necessary data
+ request->type = type;
+ request->handler = pid;
+ // perform request
+ const int result = ioctl(
+ fd_hid,
+ IOCTL_BUILD_REQUEST(
+ HID_REGISTER_HANDLER,
+ sizeof( *request ),
+ IOCTL_RDWR
+ ),
+ request
+ );
+ // handle ioctl error
+ if ( -1 == result ) {
+ // debug output
+ #if defined( LIBHID_ENABLE_ERROR )
+ const int e = errno;
+ STARTUP_PRINT( "e = %d, errno = %s\r\n", e, strerror( e ) );
+ #endif
+ // free request
+ free( request );
+ return EIO;
+ }
+ // free request
+ free( request );
+ // return success
+ return 0;
+}
+
+/**
+ * @fn int hid_get_driver(uint32_t, uint32_t*)
+ * @brief Hid get driver
+ * @param device_number
+ * @param device_driver
+ * @return
+ */
+int hid_get_driver( uint32_t device_number, uint32_t* device_driver ) {
+ // validate parameters
+ if ( ! device_driver ) {
+ return EINVAL;
+ }
+ // debug message
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Get driver for %"PRIu32"\r\n", device_number )
+ #endif
+ // allocate device
+ hid_get_driver_t* request = malloc( sizeof( *request ) );
+ // handle error
+ if ( ! request ) {
+ // debug output
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // return nomem
+ return ENOMEM;
+ }
+ // clear out
+ memset( request, 0, sizeof( *request ) );
+ // copy over necessary data
+ request->device_number = device_number;
+ // perform request
+ const int result = ioctl(
+ fd_hid,
+ IOCTL_BUILD_REQUEST(
+ HID_GET_DRIVER,
+ sizeof( *request ),
+ IOCTL_RDWR
+ ),
+ request
+ );
+ // handle ioctl error
+ if ( -1 == result ) {
+ // debug output
+ #if defined( LIBHID_ENABLE_ERROR )
+ const int e = errno;
+ STARTUP_PRINT( "e = %d, errno = %s\r\n", e, strerror( e ) );
+ #endif
+ // free request
+ free( request );
+ return EIO;
+ }
+ // return device driver
+ *device_driver = request->device_driver;
+ // free request
+ free( request );
+ // return success
+ return 0;
+}
+
+/**
+ * @fn int hid_get_application(uint32_t, libusb_hid_full_usage_t*)
+ * @brief Function to get hid application data
+ * @param device_number
+ * @param application
+ * @return
+ */
+int hid_get_application(
+ uint32_t device_number,
+ libusb_hid_full_usage_t* application
+) {
+ // validate parameters
+ if ( ! application ) {
+ return EINVAL;
+ }
+ // debug message
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Get application from %"PRIu32"\r\n", device_number )
+ #endif
+ // allocate device
+ hid_get_application_t* request = malloc( sizeof( *request ) );
+ // handle error
+ if ( ! request ) {
+ // debug output
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // return nomem
+ return ENOMEM;
+ }
+ // clear out
+ memset( request, 0, sizeof( *request ) );
+ // copy over necessary data
+ request->device_number = device_number;
+ // perform request
+ const int result = ioctl(
+ fd_hid,
+ IOCTL_BUILD_REQUEST(
+ HID_GET_APPLICATION,
+ sizeof( *request ),
+ IOCTL_RDWR
+ ),
+ request
+ );
+ // handle ioctl error
+ if ( -1 == result ) {
+ // debug output
+ #if defined( LIBHID_ENABLE_ERROR )
+ const int e = errno;
+ STARTUP_PRINT( "e = %d, errno = %s\r\n", e, strerror( e ) );
+ #endif
+ // free request
+ free( request );
+ return EIO;
+ }
+ // return device driver
+ memcpy( application, &request->application, sizeof( *application ) );
+ // free request
+ free( request );
+ // return success
+ return 0;
+}
+
+/**
+ * @fn int hid_get_report_count(uint32_t, uint8_t*)
+ * @brief Method to get report count of hid
+ * @param device_number
+ * @param report_count
+ * @return
+ */
+int hid_get_report_count( uint32_t device_number, uint8_t* report_count ) {
+ // validate parameters
+ if ( ! report_count ) {
+ return EINVAL;
+ }
+ // debug message
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Get report count from %"PRIu32"\r\n", device_number )
+ #endif
+ // allocate device
+ hid_get_report_count_t* request = malloc( sizeof( *request ) );
+ // handle error
+ if ( ! request ) {
+ // debug output
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // return nomem
+ return ENOMEM;
+ }
+ // clear out
+ memset( request, 0, sizeof( *request ) );
+ // copy over necessary data
+ request->device_number = device_number;
+ // perform request
+ const int result = ioctl(
+ fd_hid,
+ IOCTL_BUILD_REQUEST(
+ HID_GET_REPORT_COUNT,
+ sizeof( *request ),
+ IOCTL_RDWR
+ ),
+ request
+ );
+ // handle ioctl error
+ if ( -1 == result ) {
+ // debug output
+ #if defined( LIBHID_ENABLE_ERROR )
+ const int e = errno;
+ STARTUP_PRINT( "e = %d, errno = %s\r\n", e, strerror( e ) );
+ #endif
+ // free request
+ free( request );
+ return EIO;
+ }
+ // return device driver
+ *report_count = request->report_count;
+ // free request
+ free( request );
+ // return success
+ return 0;
+}
+
+/**
+ * @fn hid_destroy_report(libusb_hid_parser_report_t* report)
+ * @brief Wrapper to destroy a report object
+ * @param report
+ */
+void hid_destroy_report( libusb_hid_parser_report_t* report ) {
+ // handle no valid report
+ if ( ! report ) {
+ return;
+ }
+ // some debug output
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Freeing report\r\n" )
+ #endif
+ // free allocated resources
+ for ( size_t i = 0; i < report->fields_length; i++ ) {
+ // field for access
+ auto field = report->fields[ i ];
+ // skip variables or when no ptr is set
+ if (
+ field.attribute.variable
+ || ! field.value.ptr
+ ) {
+ continue;
+ }
+ // some debug output
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Freeing %p\r\n", field.value.ptr )
+ #endif
+ // free allocated pointer
+ free( field.value.ptr );
+ }
+ // free report itself
+ free( report );
+}
+
+/**
+ * @fn int hid_get_report(uint32_t, uint8_t, libusb_hid_parser_report_t**)
+ * @brief Function to get hid report
+ * @param device_number
+ * @param report
+ * @param result
+ * @return
+ */
+int hid_get_report(
+ const uint32_t device_number,
+ const uint8_t report,
+ libusb_hid_parser_report_t** result
+) {
+ // validate parameter
+ if ( ! result ) {
+ return EINVAL;
+ }
+ // allocate shared memory
+ const size_t shm_id = _syscall_memory_shared_create( 0x1000 );
+ // handle error
+ if ( errno ) {
+ const int e = errno;
+ // debug output
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to acquire shared memory!\r\n" )
+ #endif
+ // return error
+ return e;
+ }
+ // attach it
+ // attach shared memory
+ void* shm_addr = _syscall_memory_shared_attach( shm_id, ( uintptr_t )NULL );
+ // handle error
+ if ( errno ) {
+ const int e = errno;
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to attach shared memory!\r\n" )
+ #endif
+ // return error
+ return e;
+ }
+ // allocate request
+ hid_get_report_t* request = malloc( sizeof( *request ) );
+ if ( ! request ) {
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // return enomem
+ return ENOMEM;
+ }
+ // clear out request
+ memset( request, 0, sizeof( *request ) );
+ // populate request
+ request->device_number = device_number;
+ request->report = report;
+ request->shm_id = shm_id;
+ // perform request
+ const int ioctl_result = ioctl(
+ fd_hid,
+ IOCTL_BUILD_REQUEST(
+ HID_GET_REPORT,
+ sizeof( *request ),
+ IOCTL_RDWR
+ ),
+ request
+ );
+ // handle ioctl error
+ if ( -1 == ioctl_result ) {
+ // debug output
+ #if defined( LIBHID_ENABLE_ERROR )
+ const int e = errno;
+ STARTUP_PRINT( "e = %d, errno = %s\r\n", e, strerror( e ) );
+ #endif
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // free request
+ free( request );
+ return EIO;
+ }
+ // pointer to result
+ auto const parser = ( libusb_hid_parser_report_t* )shm_addr;
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Field length = %zu, field count = %zu\r\n", parser->fields_length, parser->field_count )
+ #endif
+ // calculate result size
+ const size_t result_size = sizeof( libusb_hid_parser_report_t ) + parser->fields_length * sizeof( libusb_hid_parser_fields_t );
+ // allocate space
+ *result = malloc( result_size );
+ if ( ! *result ) {
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate report fields\r\n" )
+ #endif
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // free request
+ free( request );
+ return ENOMEM;
+ }
+ // copy over content
+ memcpy( *result, parser, result_size );
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Field length = %zu, field count = %"PRIu8"\r\n", (*result)->fields_length, (*result)->field_count )
+ #endif
+ // copy over ptr stuff
+ for ( size_t i = 0; i < (*result)->fields_length; i++ ) {
+ // overwrite ptr
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "(*result)->fields[ %zu ].value.ptr = %"PRIxPTR"\r\n", i, ( uintptr_t )(*result)->fields[ i ].value.ptr )
+ STARTUP_PRINT( "parser->fields[ %zu ].value.ptr = %"PRIxPTR"\r\n", i, ( uintptr_t )parser->fields[ i ].value.ptr )
+ #endif
+ // skip variables or when no ptr is set
+ if (
+ (*result)->fields[ i ].attribute.variable
+ || ! (*result)->fields[ i ].value.ptr
+ ) {
+ continue;
+ }
+ // cache ptr
+ const uint8_t* ptr = (*result)->fields[ i ].value.ptr;
+ const size_t ptr_size = ( size_t )( (*result)->fields[ i ].size * (*result)->fields[ i ].count / 8 );
+ void* new_ptr = malloc( ptr_size );
+ // handle allocation error
+ if ( ! new_ptr ) {
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate report fields\r\n" )
+ #endif
+ // free up allocated stuff
+ for ( size_t inner = 0; inner < i; inner++ ) {
+ // skip variables or no ptr
+ if (
+ (*result)->fields[ inner ].attribute.variable
+ || ! (*result)->fields[ inner ].value.ptr
+ ) {
+ continue;
+ }
+ // free space
+ free( (*result)->fields[ inner ].value.ptr );
+ }
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // free request
+ free( request );
+ return ENOMEM;
+ }
+ // copy over stuff
+ memcpy( new_ptr, ( void* )( ( uintptr_t )ptr + ( uintptr_t )shm_addr), ptr_size );
+ // overwrite ptr
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "(*result)->fields[ %zu ].value.ptr = %"PRIxPTR", %zu\r\n", i, ( uintptr_t )(*result)->fields[ i ].value.ptr, ptr_size )
+ #endif
+ (*result)->fields[ i ].value.ptr = new_ptr;
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "(*result)->fields[ %zu ].value.ptr = %"PRIxPTR", %zu\r\n", i, ( uintptr_t )(*result)->fields[ i ].value.ptr, ptr_size )
+ #endif
+ }
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // free request
+ free( request );
+ // return success
+ return 0;
+}
+
+/**
+ * @fn int hid_set_report(uint32_t, uint8_t, uint8_t, uint8_t, void*, size_t)
+ * @brief Function to set hid report
+ * @param device_number device number
+ * @param report_type report type
+ * @param report_id report id
+ * @param buffer buffer to send
+ * @param buffer_size buffer size
+ * @return
+ */
+int hid_set_report( const uint32_t device_number, const uint8_t report_type, const uint8_t report_id, void* buffer, const size_t buffer_size) {
+ // validate parameter
+ if ( ! buffer || ! buffer_size ) {
+ return EINVAL;
+ }
+ // allocate shared memory
+ const size_t shm_id = _syscall_memory_shared_create( buffer_size );
+ // handle error
+ if ( errno ) {
+ const int e = errno;
+ // debug output
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to acquire shared memory!\r\n" )
+ #endif
+ // return error
+ return e;
+ }
+ // attach it
+ // attach shared memory
+ void* shm_addr = _syscall_memory_shared_attach( shm_id, ( uintptr_t )NULL );
+ // handle error
+ if ( errno ) {
+ const int e = errno;
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to attach shared memory!\r\n" )
+ #endif
+ // return error
+ return e;
+ }
+ // allocate request
+ hid_set_report_t* request = malloc( sizeof( *request ) );
+ if ( ! request ) {
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // return enomem
+ return ENOMEM;
+ }
+ // clear out request
+ memset( request, 0, sizeof( *request ) );
+ // populate request
+ request->device_number = device_number;
+ request->report_type = report_type;
+ request->report_id = report_id;
+ request->shm_id = shm_id;
+ request->buffer_size = buffer_size;
+ memcpy( shm_addr, buffer, buffer_size );
+ // perform request
+ const int ioctl_result = ioctl(
+ fd_hid,
+ IOCTL_BUILD_REQUEST(
+ HID_SET_REPORT,
+ sizeof( *request ),
+ IOCTL_RDWR
+ ),
+ request
+ );
+ // handle ioctl error
+ if ( -1 == ioctl_result ) {
+ // debug output
+ #if defined( LIBHID_ENABLE_ERROR )
+ const int e = errno;
+ STARTUP_PRINT( "e = %d, errno = %s\r\n", e, strerror( e ) );
+ #endif
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // free request
+ free( request );
+ return EIO;
+ }
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // free request
+ free( request );
+ // return success
+ return 0;
+}
+
+/**
+ * @fn int hid_set_idle(uint32_t, uint32_t, uint8_t, uint8_t, uint8_t, void*, size_t)
+ * @brief Function to set hid idle
+ * @param device_number device number
+ * @param interface_number interface number
+ * @param report_id report id
+ * @param duration duration
+ * @return
+ */
+int hid_set_idle( const uint32_t device_number, const uint32_t interface_number, const uint8_t report_id, const uint8_t duration) {
+ // allocate request
+ hid_set_idle_t* request = malloc( sizeof( *request ) );
+ if ( ! request ) {
+ #if defined( LIBHID_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // return enomem
+ return ENOMEM;
+ }
+ // clear out request
+ memset( request, 0, sizeof( *request ) );
+ // populate request
+ request->device_number = device_number;
+ request->interface_number = interface_number;
+ request->duration = duration;
+ request->report_id = report_id;
+ // perform request
+ const int ioctl_result = ioctl(
+ fd_hid,
+ IOCTL_BUILD_REQUEST(
+ HID_SET_IDLE,
+ sizeof( *request ),
+ IOCTL_RDWR
+ ),
+ request
+ );
+ // handle ioctl error
+ if ( -1 == ioctl_result ) {
+ // debug output
+ #if defined( LIBHID_ENABLE_ERROR )
+ const int e = errno;
+ STARTUP_PRINT( "e = %d, errno = %s\r\n", e, strerror( e ) );
+ #endif
+ // free request
+ free( request );
+ return EIO;
+ }
+ // free request
+ free( request );
+ // return success
+ return 0;
+}
diff --git a/bolthur/library/hid/hid.h b/bolthur/library/hid/hid.h
new file mode 100644
index 000000000..c4cf8b41d
--- /dev/null
+++ b/bolthur/library/hid/hid.h
@@ -0,0 +1,38 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#ifndef _HID_H
+#define _HID_H
+
+//#define LIBHID_ENABLE_DEBUG
+//#define LIBHID_ENABLE_ERROR
+
+#include "../../server/libusb.h"
+
+int hid_init( void );
+int hid_register_handler( libusb_hid_usage_page_desktop_t );
+int hid_get_driver( uint32_t, uint32_t* );
+int hid_get_application( uint32_t, libusb_hid_full_usage_t* );
+int hid_get_report_count( uint32_t, uint8_t* );
+void hid_destroy_report( libusb_hid_parser_report_t* );
+int hid_get_report( uint32_t, uint8_t, libusb_hid_parser_report_t** );
+int hid_set_report( uint32_t, uint8_t, uint8_t, void*, size_t );
+int hid_set_idle( uint32_t, uint32_t, uint8_t, uint8_t );
+
+#endif
diff --git a/bolthur/library/platform/Makefile.am b/bolthur/library/platform/Makefile.am
new file mode 100644
index 000000000..02a3060d0
--- /dev/null
+++ b/bolthur/library/platform/Makefile.am
@@ -0,0 +1,4 @@
+
+SUBDIRS = ${platform_subdir}
+
+DIST_SUBDIRS = raspi
diff --git a/bolthur/library/platform/raspi/Makefile.am b/bolthur/library/platform/raspi/Makefile.am
new file mode 100644
index 000000000..e0f3de2ed
--- /dev/null
+++ b/bolthur/library/platform/raspi/Makefile.am
@@ -0,0 +1,2 @@
+
+SUBDIRS = iomem
diff --git a/bolthur/library/platform/raspi/iomem/Makefile.am b/bolthur/library/platform/raspi/iomem/Makefile.am
new file mode 100644
index 000000000..cc570d58a
--- /dev/null
+++ b/bolthur/library/platform/raspi/iomem/Makefile.am
@@ -0,0 +1,7 @@
+
+AM_CFLAGS = -DPROGRAM_NAME=\"bolthur/libiomem\"
+
+noinst_LTLIBRARIES = libiomem.la
+libiomem_la_SOURCES = \
+ mailbox.c \
+ sequence.c
diff --git a/bolthur/server/platform/raspi/libdma.h b/bolthur/library/platform/raspi/iomem/libdma.h
similarity index 98%
rename from bolthur/server/platform/raspi/libdma.h
rename to bolthur/library/platform/raspi/iomem/libdma.h
index a287f10a9..52ff6533e 100644
--- a/bolthur/server/platform/raspi/libdma.h
+++ b/bolthur/library/platform/raspi/iomem/libdma.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/platform/raspi/libgpio.h b/bolthur/library/platform/raspi/iomem/libgpio.h
similarity index 97%
rename from bolthur/server/platform/raspi/libgpio.h
rename to bolthur/library/platform/raspi/iomem/libgpio.h
index 2f0487244..7b2aa38da 100644
--- a/bolthur/server/platform/raspi/libgpio.h
+++ b/bolthur/library/platform/raspi/iomem/libgpio.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/platform/raspi/libiomem.h b/bolthur/library/platform/raspi/iomem/libiomem.h
similarity index 97%
rename from bolthur/server/platform/raspi/libiomem.h
rename to bolthur/library/platform/raspi/iomem/libiomem.h
index 84e75a033..db36d4d81 100644
--- a/bolthur/server/platform/raspi/libiomem.h
+++ b/bolthur/library/platform/raspi/iomem/libiomem.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -21,9 +21,6 @@
#define _LIBIOMEM_H
#include
-#include
-#include
-#include
#include
#include "libgpio.h"
@@ -116,6 +113,11 @@ struct iomem_mmio_entry {
typedef struct iomem_mmio_entry iomem_mmio_entry_t;
typedef struct iomem_mmio_entry iomem_mmio_entry_array_t[];
+typedef struct {
+ size_t shm_id;
+ size_t length;
+} iomem_mmio_perform_t;
+
typedef struct {
iomem_gpio_enum_pin_t pin;
iomem_gpio_enum_function_t function;
diff --git a/bolthur/server/platform/raspi/libmailbox.h b/bolthur/library/platform/raspi/iomem/libmailbox.h
similarity index 95%
rename from bolthur/server/platform/raspi/libmailbox.h
rename to bolthur/library/platform/raspi/iomem/libmailbox.h
index 8f0732998..4b93b8ba1 100644
--- a/bolthur/server/platform/raspi/libmailbox.h
+++ b/bolthur/library/platform/raspi/iomem/libmailbox.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -17,8 +17,8 @@
* along with bolthur/kernel. If not, see .
*/
-#ifndef _LIBMAILBOX_H
-#define _LIBMAILBOX_H
+#ifndef _MAILBOX_H
+#define _MAILBOX_H
#define MAILBOX_REQUEST_SUCCESSFUL 0x80000000
diff --git a/bolthur/server/platform/raspi/libperipheral.h b/bolthur/library/platform/raspi/iomem/libperipheral.h
similarity index 78%
rename from bolthur/server/platform/raspi/libperipheral.h
rename to bolthur/library/platform/raspi/iomem/libperipheral.h
index 5df05d6f1..8bf15f9bf 100644
--- a/bolthur/server/platform/raspi/libperipheral.h
+++ b/bolthur/library/platform/raspi/iomem/libperipheral.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -276,5 +276,60 @@
#define PERIPHERAL_EMMC_SLOTISR_VER PERIPHERAL_EMMC_OFFSET + 0xFC // slot interrupt status and version
// usb
#define PERIPHERAL_USB_OFFSET 0x980000
+#define PERIPHERAL_USB_CORE_OFFSET PERIPHERAL_USB_OFFSET
+#define PERIPHERAL_USB_HOST_OFFSET PERIPHERAL_USB_OFFSET + 0x400
+#define PERIPHERAL_USB_POWER_OFFSET PERIPHERAL_USB_OFFSET + 0xE00
+// dwhci core
+#define PERIPHERAL_DWHCI_CORE_CTRL PERIPHERAL_USB_CORE_OFFSET + 0x000
+#define PERIPHERAL_DWHCI_CORE_OTG_INIT PERIPHERAL_USB_CORE_OFFSET + 0x004
+#define PERIPHERAL_DWHCI_CORE_AHB_CFG PERIPHERAL_USB_CORE_OFFSET + 0x008
+#define PERIPHERAL_DWHCI_CORE_USB_CFG PERIPHERAL_USB_CORE_OFFSET + 0x00C
+#define PERIPHERAL_DWHCI_CORE_RESET PERIPHERAL_USB_CORE_OFFSET + 0x010
+#define PERIPHERAL_DWHCI_CORE_INT_STAT PERIPHERAL_USB_CORE_OFFSET + 0x014
+#define PERIPHERAL_DWHCI_CORE_INT_MASK PERIPHERAL_USB_CORE_OFFSET + 0x018
+#define PERIPHERAL_DWHCI_CORE_RX_STAT_RD PERIPHERAL_USB_CORE_OFFSET + 0x01C
+#define PERIPHERAL_DWHCI_CORE_RX_STAT_POP PERIPHERAL_USB_CORE_OFFSET + 0x020
+#define PERIPHERAL_DWHCI_CORE_RX_FIFO_SIZ PERIPHERAL_USB_CORE_OFFSET + 0x024
+#define PERIPHERAL_DWHCI_CORE_NPER_FIFO_SIZ PERIPHERAL_USB_CORE_OFFSET + 0x028
+#define PERIPHERAL_DWHCI_CORE_NPER_TX_STAT PERIPHERAL_USB_CORE_OFFSET + 0x02C
+#define PERIPHERAL_DWHCI_CORE_I2C_CTRL PERIPHERAL_USB_CORE_OFFSET + 0x030
+#define PERIPHERAL_DWHCI_CORE_PHY_VENDOR_CTRL PERIPHERAL_USB_CORE_OFFSET + 0x034
+#define PERIPHERAL_DWHCI_CORE_GPIO PERIPHERAL_USB_CORE_OFFSET + 0x038
+#define PERIPHERAL_DWHCI_CORE_USER_ID PERIPHERAL_USB_CORE_OFFSET + 0x03C
+#define PERIPHERAL_DWHCI_CORE_VENDOR_ID PERIPHERAL_USB_CORE_OFFSET + 0x040
+#define PERIPHERAL_DWHCI_CORE_HW_CFG1 PERIPHERAL_USB_CORE_OFFSET + 0x044
+#define PERIPHERAL_DWHCI_CORE_HW_CFG2 PERIPHERAL_USB_CORE_OFFSET + 0x048
+#define PERIPHERAL_DWHCI_CORE_HW_CFG3 PERIPHERAL_USB_CORE_OFFSET + 0x04C
+#define PERIPHERAL_DWHCI_CORE_HW_CFG4 PERIPHERAL_USB_CORE_OFFSET + 0x050
+#define PERIPHERAL_DWHCI_CORE_LPM_CFG PERIPHERAL_USB_CORE_OFFSET + 0x054
+#define PERIPHERAL_DWHCI_CORE_POWER_DOWN PERIPHERAL_USB_CORE_OFFSET + 0x058
+#define PERIPHERAL_DWHCI_CORE_DFIFO_CFG PERIPHERAL_USB_CORE_OFFSET + 0x05C
+#define PERIPHERAL_DWHCI_CORE_ADP_CTRL PERIPHERAL_USB_CORE_OFFSET + 0x060
+#define PERIPHERAL_DWHCI_CORE_MDIO_CTRL PERIPHERAL_USB_CORE_OFFSET + 0x080
+#define PERIPHERAL_DWHCI_CORE_MDIO_DATA PERIPHERAL_USB_CORE_OFFSET + 0x084
+#define PERIPHERAL_DWHCI_CORE_VBUS_DRV_CTRL PERIPHERAL_USB_CORE_OFFSET + 0x088
+#define PERIPHERAL_DWHCI_CORE_HOST_PER_TX_FIFO_SZ PERIPHERAL_USB_CORE_OFFSET + 0x100
+#define PERIPHERAL_DWHCI_CORE_DEV_PER_TX_FIFO( fifo ) ( PERIPHERAL_USB_CORE_OFFSET + 0x104 + ( fifo ) * 4 )
+#define PERIPHERAL_DWHCI_CORE_DEV_TX_FIFO( fifo ) ( PERIPHERAL_USB_CORE_OFFSET + 0x108 + ( fifo ) * 4 )
+// dwhci host
+#define PERIPHERAL_DWHCI_HOST_CFG PERIPHERAL_USB_HOST_OFFSET + 0x000
+#define PERIPHERAL_DWHCI_HOST_FRM_INTERVAL PERIPHERAL_USB_HOST_OFFSET + 0x004
+#define PERIPHERAL_DWHCI_HOST_FRM_NUM PERIPHERAL_USB_HOST_OFFSET + 0x008
+#define PERIPHERAL_DWHCI_HOST_PER_TX_FIFO_STAT PERIPHERAL_USB_HOST_OFFSET + 0x010
+#define PERIPHERAL_DWHCI_HOST_ALLCHAN_INT PERIPHERAL_USB_HOST_OFFSET + 0x014
+#define PERIPHERAL_DWHCI_HOST_ALLCHAN_INT_MASK PERIPHERAL_USB_HOST_OFFSET + 0x018
+#define PERIPHERAL_DWHCI_HOST_FRMLST_BASE PERIPHERAL_USB_HOST_OFFSET + 0x01C
+#define PERIPHERAL_DWHCI_HOST_PORT PERIPHERAL_USB_HOST_OFFSET + 0x040
+#define PERIPHERAL_DWHCI_HOST_CHAN_CHARACTER( chan ) ( PERIPHERAL_USB_HOST_OFFSET + 0x100 + ( chan ) * 0x20 )
+#define PERIPHERAL_DWHCI_HOST_CHAN_SPLIT_CTRL( chan ) ( PERIPHERAL_USB_HOST_OFFSET + 0x104 + ( chan ) * 0x20 )
+#define PERIPHERAL_DWHCI_HOST_CHAN_INT( chan ) ( PERIPHERAL_USB_HOST_OFFSET + 0x108 + ( chan ) * 0x20 )
+#define PERIPHERAL_DWHCI_HOST_CHAN_INT_MASK( chan ) ( PERIPHERAL_USB_HOST_OFFSET + 0x10C + ( chan ) * 0x20 )
+#define PERIPHERAL_DWHCI_HOST_CHAN_XFER_SIZE( chan ) ( PERIPHERAL_USB_HOST_OFFSET + 0x110 + ( chan ) * 0x20 )
+#define PERIPHERAL_DWHCI_HOST_HOST_CHAN_DMA_ADDR( chan ) ( PERIPHERAL_USB_HOST_OFFSET + 0x114 + ( chan ) * 0x20 )
+#define PERIPHERAL_DWHCI_HOST_HOST_CHAN_DMA_BUF( chan ) ( PERIPHERAL_USB_HOST_OFFSET + 0x11C + ( chan ) * 0x20 )
+// dwhci data fifo ( non dma only )
+#define PERIPHERAL_DWHCI_DATA_FIFO_SIZE 0x1000
+#define PERIPHERAL_DWHCI_MAX_CHANNELS 16
+#define PERIPHERAL_DWHCI_DATA_FIFO( chan ) ( PERIPHERAL_USB_HOST_OFFSET + 0x1000 + ( chan ) * PERIPHERAL_DWHCI_DATA_FIFO_SIZE )
#endif
diff --git a/bolthur/library/platform/raspi/iomem/mailbox.c b/bolthur/library/platform/raspi/iomem/mailbox.c
new file mode 100644
index 000000000..79db58097
--- /dev/null
+++ b/bolthur/library/platform/raspi/iomem/mailbox.c
@@ -0,0 +1,90 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include
+#include
+#include
+#include "mailbox.h"
+#include "libiomem.h"
+
+/**
+ * @fn void* iomem_prepare_mailbox(size_t, size_t*)
+ * @brief Helper to allocate and clear mailbox property array
+ * @param count amount of entries
+ * @param total output variable for total size
+ */
+__attribute__((__malloc__(iomem_mailbox_release, 1))) void* iomem_prepare_mailbox( const size_t count, size_t* total ) {
+ if ( 0 == count ) {
+ return NULL;
+ }
+ // allocate
+ const size_t tmp_total = count * sizeof( uint32_t );
+ iomem_mmio_entry_t* tmp = malloc( tmp_total );
+ if ( ! tmp ) {
+ return NULL;
+ }
+ // erase
+ memset( tmp, 0, tmp_total );
+ // set total if not null
+ if ( total ) {
+ *total = tmp_total;
+ }
+ // return
+ return tmp;
+}
+
+/**
+ * @brief Execute a mailbox sequence
+ * @param fd file descriptor
+ * @param data data
+ * @param size data size
+ * @return
+ */
+int iomem_execute_mailbox( int fd, const void* data, size_t size ) {
+ // execute sequence
+ const int result = ioctl(
+ fd,
+ IOCTL_BUILD_REQUEST( IOMEM_RPC_MAILBOX, size, IOCTL_RDWR ),
+ data
+ );
+ // handle error
+ if ( result != 0 ) {
+ // error output
+ #if defined( MAILBOX_ERROR_OUTPUT )
+ const int e = errno;
+ EARLY_STARTUP_PRINT( "Unable to execute mmio sequence: %s\r\n",
+ strerror( e ) );
+ #endif
+ // return result
+ return result;
+ }
+ // return success
+ return 0;
+}
+
+/**
+ * @fn void iomem_mailbox_release(void*)
+ * @brief Function to free up mailbox stuff
+ * @param address
+ */
+void iomem_mailbox_release( void* address ) {
+ if ( address ) {
+ free( address );
+ }
+}
diff --git a/bolthur/library/platform/raspi/iomem/mailbox.h b/bolthur/library/platform/raspi/iomem/mailbox.h
new file mode 100644
index 000000000..274170a7e
--- /dev/null
+++ b/bolthur/library/platform/raspi/iomem/mailbox.h
@@ -0,0 +1,31 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#ifndef _PLATFORM_RASPI_IOMEM_MAILBOX_H
+#define _PLATFORM_RASPI_IOMEM_MAILBOX_H
+
+#include
+
+#define MAILBOX_ERROR_OUTPUT 1
+
+void iomem_mailbox_release( void* );
+__attribute__((__malloc__(iomem_mailbox_release, 1))) void* iomem_prepare_mailbox( size_t, size_t* );
+int iomem_execute_mailbox( int, const void*, size_t );
+
+#endif
diff --git a/bolthur/library/platform/raspi/iomem/sequence.c b/bolthur/library/platform/raspi/iomem/sequence.c
new file mode 100644
index 000000000..8ddd64f66
--- /dev/null
+++ b/bolthur/library/platform/raspi/iomem/sequence.c
@@ -0,0 +1,235 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include
+#include
+#include
+#include "sequence.h"
+#include "libiomem.h"
+
+/**
+ * @fn void* iomem_prepare_mmio_sequence(size_t, size_t*)
+ * @brief Prepare mmio sequence
+ * @param count amount of entries
+ * @param total output variable for total size
+ */
+__attribute__((__malloc__, __malloc__(iomem_release_mmio_sequence, 1))) void* iomem_prepare_mmio_sequence( const size_t count, size_t* total ) {
+ if ( 0 == count ) {
+ // error output
+ #if defined( SEQUENCE_ERROR_OUTPUT )
+ EARLY_STARTUP_PRINT( "Invalid sequence count given\r\n" )
+ #endif
+ // return null
+ return NULL;
+ }
+ // allocate
+ const size_t tmp_total = count * sizeof( iomem_mmio_entry_t );
+ iomem_mmio_entry_t* tmp = malloc( count * sizeof( iomem_mmio_entry_t ) );
+ if ( ! tmp ) {
+ // error output
+ #if defined( SEQUENCE_ERROR_OUTPUT )
+ EARLY_STARTUP_PRINT( "Unable to allocate sequence\r\n" )
+ #endif
+ // return null
+ return NULL;
+ }
+ // erase
+ memset( tmp, 0, tmp_total );
+ // preset with defaults
+ for ( uint32_t i = 0; i < count; i++ ) {
+ tmp[ i ].shift_type = IOMEM_MMIO_SHIFT_NONE;
+ tmp[ i ].sleep_type = IOMEM_MMIO_SLEEP_NONE;
+ tmp[ i ].failure_condition = IOMEM_MMIO_FAILURE_CONDITION_OFF;
+ }
+ // set total if not null
+ if ( total ) {
+ *total = tmp_total;
+ }
+ // return
+ return tmp;
+}
+
+/**
+ * @fn void iomem_release_mmio_sequence(void*)
+ * @brief Release iomem sequence
+ * @param sequence
+ */
+void iomem_release_mmio_sequence( void* sequence ) {
+ if ( sequence ) {
+ free( sequence );
+ }
+}
+
+/**
+ * @fn int iomem_execute_sequence(int, void*, size_t)
+ * @brief Function to execute a sequence
+ * @param fd file descriptor
+ * @param data data
+ * @param size data size
+ * @return
+ */
+int iomem_execute_sequence( const int fd, void* data, const size_t size ) {
+ // allocate wrapper
+ iomem_mmio_perform_t* perform = malloc( sizeof( *perform ) );
+ // handle error
+ if ( ! perform ) {
+ // error output
+ #if defined( SEQUENCE_ERROR_OUTPUT )
+ EARLY_STARTUP_PRINT( "Unable to allocate wrapper structure\r\n" )
+ #endif
+ // return result
+ return -1;
+ }
+ // clear out
+ memset( perform, 0, sizeof( *perform ) );
+ // allocate shared area
+ const size_t shm_id = _syscall_memory_shared_create( size );
+ if ( errno ) {
+ // error output
+ #if defined( SEQUENCE_ERROR_OUTPUT )
+ const int e = errno;
+ EARLY_STARTUP_PRINT( "Unable to allocate shared memory: %s\r\n",
+ strerror( e ) )
+ #endif
+ // free wrapper
+ free( perform );
+ // return error
+ return -1;
+ }
+ // attach shared area
+ void* shm_addr = _syscall_memory_shared_attach( shm_id, ( uintptr_t )NULL );
+ if ( errno ) {
+ // error output
+ #if defined( SEQUENCE_ERROR_OUTPUT )
+ const int e = errno;
+ EARLY_STARTUP_PRINT( "Unable to attach shared memory: %s\r\n",
+ strerror( e ) )
+ #endif
+ // free wrapper
+ free( perform );
+ // return error
+ return -1;
+ }
+ // copy over
+ memcpy( shm_addr, data, size );
+ // populate wrapper
+ perform->shm_id = shm_id;
+ perform->length = size;
+ // execute sequence
+ const int result = ioctl(
+ fd,
+ IOCTL_BUILD_REQUEST(
+ IOMEM_RPC_MMIO_PERFORM,
+ sizeof( *perform ),
+ IOCTL_RDWR
+ ),
+ perform
+ );
+ // handle error
+ if ( result != 0 ) {
+ // error output
+ #if defined( SEQUENCE_ERROR_OUTPUT )
+ const int e = errno;
+ EARLY_STARTUP_PRINT( "Unable to execute mmio sequence: %s\r\n",
+ strerror( e ) )
+ #endif
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // free wrapper
+ free( perform );
+ // return result
+ return result;
+ }
+ // copy back result
+ memcpy( data, shm_addr, size );
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // free wrapper
+ free( perform );
+ // return success
+ return 0;
+}
+
+/**
+ * @fn int iomem_execute_sequence_static(int, void*, size_t)
+ * @brief Function to execute a sequence
+ * @param fd file descriptor
+ * @param data data
+ * @param size data size
+ * @return
+ */
+int iomem_execute_sequence_static( const int fd, void* data, const size_t size ) {
+ // allocate shared area
+ const size_t shm_id = _syscall_memory_shared_create( size );
+ if ( errno ) {
+ // error output
+ #if defined( SEQUENCE_ERROR_OUTPUT )
+ const int e = errno;
+ EARLY_STARTUP_PRINT( "Unable to allocate shared memory: %s\r\n",
+ strerror( e ) )
+ #endif
+ // return error
+ return -1;
+ }
+ // attach shared area
+ void* shm_addr = _syscall_memory_shared_attach( shm_id, ( uintptr_t )NULL );
+ if ( errno ) {
+ // error output
+ #if defined( SEQUENCE_ERROR_OUTPUT )
+ const int e = errno;
+ EARLY_STARTUP_PRINT( "Unable to attach shared memory: %s\r\n",
+ strerror( e ) )
+ #endif
+ // return error
+ return -1;
+ }
+ // copy over
+ memcpy( shm_addr, data, size );
+ // populate wrapper
+ iomem_mmio_perform_t perform = { .length = size, .shm_id = shm_id };
+ // execute sequence
+ const int result = ioctl(
+ fd,
+ IOCTL_BUILD_REQUEST(
+ IOMEM_RPC_MMIO_PERFORM,
+ sizeof( perform ),
+ IOCTL_RDWR
+ ),
+ &perform
+ );
+ // handle error
+ if ( result != 0 ) {
+ // error output
+ #if defined( SEQUENCE_ERROR_OUTPUT )
+ const int e = errno;
+ EARLY_STARTUP_PRINT( "Unable to execute mmio sequence: %s\r\n",
+ strerror( e ) )
+ #endif
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // return result
+ return result;
+ }
+ // copy back result
+ memcpy( data, shm_addr, size );
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // return success
+ return 0;
+}
diff --git a/bolthur/library/platform/raspi/iomem/sequence.h b/bolthur/library/platform/raspi/iomem/sequence.h
new file mode 100644
index 000000000..81044305d
--- /dev/null
+++ b/bolthur/library/platform/raspi/iomem/sequence.h
@@ -0,0 +1,32 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#ifndef _PLATFORM_RASPI_IOMEM_SEQUENCE_H
+#define _PLATFORM_RASPI_IOMEM_SEQUENCE_H
+
+#include
+
+#define SEQUENCE_ERROR_OUTPUT 1
+
+void iomem_release_mmio_sequence( void* );
+__attribute__((__malloc__, __malloc__(iomem_release_mmio_sequence, 1))) void* iomem_prepare_mmio_sequence( size_t, size_t* );
+int iomem_execute_sequence( int, void*, size_t );
+int iomem_execute_sequence_static( int, void*, size_t );
+
+#endif
diff --git a/bolthur/library/usb/Makefile.am b/bolthur/library/usb/Makefile.am
new file mode 100644
index 000000000..4f49e39a1
--- /dev/null
+++ b/bolthur/library/usb/Makefile.am
@@ -0,0 +1,6 @@
+
+AM_CFLAGS = -DPROGRAM_NAME=\"bolthur/libusb\"
+
+noinst_LTLIBRARIES = libusb.la
+libusb_la_SOURCES = \
+ usb.c
diff --git a/bolthur/library/usb/usb.c b/bolthur/library/usb/usb.c
new file mode 100644
index 000000000..e40df0ab1
--- /dev/null
+++ b/bolthur/library/usb/usb.c
@@ -0,0 +1,1208 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+// system includes
+#include
+#include
+#include
+#include
+// local includes
+#include "usb.h"
+// server includes
+#include "../../server/libusbd.h"
+
+static int fd_usbd = -1;
+
+/**
+ * @fn int usb_init( void )
+ * @brief USB library init
+ * @return
+ */
+int usb_init( void ) {
+ // handle already initialized
+ if ( fd_usbd != -1 ) {
+ return 0;
+ }
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Opening %s\r\n", USBD_DEVICE_PATH )
+ #endif
+ // open handle
+ fd_usbd = open( USBD_DEVICE_PATH, O_RDWR );
+ // handle error
+ if ( fd_usbd == -1 ) {
+ return EIO;
+ }
+ // return success
+ return 0;
+}
+
+/**
+ * @fn const char* usb_get_description(uint32_t)
+ * @brief Wrapper to get description for device
+ * @param device_number
+ * @return
+ */
+const char* usb_get_description( const uint32_t device_number ) {
+ // local buffer for description
+ static char buffer[ 256 ];
+ // debug message
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Fetching usb description\r\n" )
+ #endif
+ // clear out buffer
+ memset( buffer, 0, sizeof( buffer ) );
+ // allocate device
+ usbd_get_description_t* request = malloc( sizeof( *request ) );
+ // handle error
+ if ( ! request ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // return nomem
+ return buffer;
+ }
+ // clear out
+ memset( request, 0, sizeof( *request ) );
+ // copy over necessary data
+ request->device_number = device_number;
+ // perform ioctl command
+ // perform request
+ const int result = ioctl(
+ fd_usbd,
+ IOCTL_BUILD_REQUEST(
+ USBD_GET_DESCRIPTION,
+ sizeof( *request ),
+ IOCTL_RDWR
+ ),
+ request
+ );
+ // handle ioctl error
+ if ( -1 == result ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ const int e = errno;
+ STARTUP_PRINT( "e = %d, errno = %s\r\n", e, strerror( e ) );
+ #endif
+ // free request
+ free( request );
+ // return eio
+ return buffer;
+ }
+ // copy over response
+ strcpy( buffer, ( const char* )request );
+ // free request
+ free( request );
+ // return copied buffer
+ return buffer;
+}
+
+/**
+ * @fn int usb_control_message(uint32_t, libusb_transfer_t, libusb_direction_t, void*, size_t, const libusb_device_request_t*, size_t, rpc_handler_t)
+ * @brief Wrapper to perform usb control message
+ * @param device_number
+ * @param transfer
+ * @param direction
+ * @param buffer
+ * @param buffer_length
+ * @param request
+ * @param timeout
+ * @param callback
+ * @return
+ */
+int usb_control_message_async(
+ const uint32_t device_number,
+ const libusb_transfer_t transfer,
+ const libusb_direction_t direction,
+ const void* buffer,
+ const size_t buffer_length,
+ const libusb_device_request_t* request,
+ const size_t timeout,
+ const rpc_handler_t callback
+) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "firing async usb control message\r\n" )
+ #endif
+ // allocate shared memory
+ const size_t data_size = sizeof ( usb_control_message_t ) + buffer_length + 1;
+ const size_t shm_id = _syscall_memory_shared_create( data_size );
+ // handle error
+ if ( errno ) {
+ const int e = errno;
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to acquire shared memory!\r\n" )
+ #endif
+ // return error
+ return e;
+ }
+ // attach shared memory
+ void* shm_addr = _syscall_memory_shared_attach( shm_id, 0 );
+ // handle error
+ if ( errno ) {
+ const int e = errno;
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to attach shared memory!\r\n" )
+ #endif
+ // return error
+ return e;
+ }
+ // clear out
+ memset( shm_addr, 0, data_size );
+ auto const message = ( usb_control_message_t* )shm_addr;
+ // populate real message in shared memory
+ message->device_number = device_number;
+ message->transfer = transfer;
+ message->direction = direction;
+ message->buffer_length = buffer_length;
+ message->timeout = timeout;
+ memcpy( &message->request, request, sizeof( *request ) );
+ if ( LIBUSB_DIRECTION_OUT == direction && buffer ) {
+ memcpy( &message->buffer, buffer, buffer_length );
+ }
+ // allocate request
+ usbd_control_message_t* control_request = malloc( sizeof( *control_request ) );
+ if ( ! control_request ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // return error
+ return ENOMEM;
+ }
+ // clear out everything
+ memset( control_request, 0, sizeof( *control_request ) );
+ // populate shm_id
+ control_request->shm_id = shm_id;
+ // calculate rpc request size
+ constexpr size_t rpc_request_size = sizeof( vfs_ioctl_perform_request_t )
+ + sizeof( *control_request );
+ // allocate rpc structures
+ vfs_ioctl_perform_request_t* rpc_request = malloc( rpc_request_size );
+ if ( ! rpc_request ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // free control request
+ free( control_request );
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // return error
+ return ENOMEM;
+ }
+ // clear rpc structures
+ memset( rpc_request, 0, rpc_request_size );
+ // populate structure
+ rpc_request->handle = fd_usbd;
+ rpc_request->command = USBD_CONTROL_MESSAGE;
+ rpc_request->type = IOCTL_RDWR;
+ // copy over data
+ memcpy( rpc_request->container, control_request, sizeof( *control_request ) );
+ // raise rpc and wait for return
+ const size_t response_id = bolthur_rpc_raise(
+ RPC_VFS_IOCTL,
+ VFS_DAEMON_ID,
+ rpc_request,
+ rpc_request_size,
+ callback,
+ RPC_VFS_IOCTL,
+ rpc_request,
+ rpc_request_size,
+ 0,
+ 0,
+ nullptr,
+ false
+ );
+ if ( ! response_id ) {
+ // free request data
+ free( rpc_request );
+ // free control request
+ free( control_request );
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // return io error
+ return EIO;
+ }
+ // free request data
+ free( rpc_request );
+ // free control request
+ free( control_request );
+ // return success
+ return 0;
+}
+
+/**
+ * @fn int usb_control_message(uint32_t, libusb_transfer_t, libusb_direction_t, void*, size_t, const libusb_device_request_t*, size_t, libusb_transfer_error_t*, uint32_t*)
+ * @brief Wrapper to perform usb control message
+ * @param device_number
+ * @param transfer
+ * @param direction
+ * @param buffer
+ * @param buffer_length
+ * @param request
+ * @param timeout
+ * @param error
+ * @param last_transfer
+ * @return
+ */
+int usb_control_message(
+ const uint32_t device_number,
+ const libusb_transfer_t transfer,
+ const libusb_direction_t direction,
+ void* buffer,
+ const size_t buffer_length,
+ const libusb_device_request_t* request,
+ const size_t timeout,
+ libusb_transfer_error_t* error,
+ uint32_t* last_transfer
+) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "firing usb control message\r\n" )
+ #endif
+ // allocate shared memory
+ const size_t data_size = sizeof ( usb_control_message_t ) + buffer_length + 1;
+ const size_t shm_id = _syscall_memory_shared_create( data_size );
+ // handle error
+ if ( errno ) {
+ const int e = errno;
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to acquire shared memory!\r\n" )
+ #endif
+ // return error
+ return e;
+ }
+ // attach shared memory
+ void* shm_addr = _syscall_memory_shared_attach( shm_id, 0 );
+ // handle error
+ if ( errno ) {
+ const int e = errno;
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to attach shared memory!\r\n" )
+ #endif
+ // return error
+ return e;
+ }
+ // clear out
+ memset( shm_addr, 0, data_size );
+ auto const message = ( usb_control_message_t* )shm_addr;
+ // populate real message in shared memory
+ message->device_number = device_number;
+ message->transfer = transfer;
+ message->direction = direction;
+ message->buffer_length = buffer_length;
+ message->timeout = timeout;
+ memcpy( &message->request, request, sizeof( *request ) );
+ if ( LIBUSB_DIRECTION_OUT == direction && buffer ) {
+ memcpy( &message->buffer, buffer, buffer_length );
+ }
+ // allocate request
+ usbd_control_message_t* control_request = malloc( sizeof( *control_request ) );
+ if ( ! control_request ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // return error
+ return ENOMEM;
+ }
+ // clear out everything
+ memset( control_request, 0, sizeof( *control_request ) );
+ // populate shm_id
+ control_request->shm_id = shm_id;
+ // perform request
+ const int result = ioctl(
+ fd_usbd,
+ IOCTL_BUILD_REQUEST(
+ USBD_CONTROL_MESSAGE,
+ sizeof( *control_request ),
+ IOCTL_RDWR
+ ),
+ control_request
+ );
+ // handle ioctl error
+ if ( -1 == result ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_ERROR )
+ const int e = errno;
+ STARTUP_PRINT( "e = %d, errno = %s\r\n", e, strerror( e ) );
+ #endif
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // free request
+ free( control_request );
+ // return eio
+ return EIO;
+ }
+ // populate error and last transfer
+ *error = message->error;
+ *last_transfer = message->last_transfer;
+ // response is equal to input
+ if ( *error & LIBUSB_TRANSFER_ERROR_PROCESSING ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_ERROR )
+ STARTUP_PRINT( "message->error: %#x\r\n", message->error );
+ #endif
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // free control_request
+ free( control_request );
+ // return timeout
+ return ETIMEDOUT;
+ }
+ // copy over data
+ if ( LIBUSB_DIRECTION_IN == direction && buffer ) {
+ memcpy( buffer, message->buffer, buffer_length );
+ }
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // free control message
+ free( control_request );
+ // return result
+ return result;
+}
+
+/**
+ * @fn libusb_device_t* usb_get_root_hub(void)
+ * @brief Wrapper to get root hub
+ * @return
+ */
+int usb_get_root_hub( uint32_t* device_number ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "firing usb get root hub\r\n" )
+ #endif
+ // handle invalid parameter
+ if ( ! device_number ) {
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Invalid parameter passed!\r\n" )
+ #endif
+ // return einval
+ return EINVAL;
+ }
+ // allocate request
+ usbd_get_roothub_t* request = malloc( sizeof( *request ) );
+ if ( ! request ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // return error
+ return ENOMEM;
+ }
+ // clear out everything
+ memset( request, 0, sizeof( *request ) );
+ // perform request
+ const int result = ioctl(
+ fd_usbd,
+ IOCTL_BUILD_REQUEST(
+ USBD_GET_ROOTHUB,
+ sizeof( *request ),
+ IOCTL_RDWR
+ ),
+ request
+ );
+ // handle ioctl error
+ if ( -1 == result ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_ERROR )
+ const int e = errno;
+ STARTUP_PRINT( "e = %d, errno = %s\r\n", e, strerror( e ) );
+ #endif
+ // free request
+ free( request );
+ // return eio
+ return EIO;
+ }
+ // copy over response
+ memcpy( device_number, request, sizeof ( uint32_t ) );
+ // free request
+ free( request );
+ // return device
+ return 0;
+}
+
+/**
+ * @fn int usb_get_descriptor(uint32_t, libusb_descriptor_type_t, uint8_t, uint16_t, void*, size_t, size_t, uint8_t)
+ * @brief Wrapper to get usb descriptor
+ * @param device_number
+ * @param type
+ * @param idx
+ * @param lang_id
+ * @param buffer
+ * @param buffer_length
+ * @param minimum_length
+ * @param recipient
+ * @return
+ */
+int usb_get_descriptor(
+ const uint32_t device_number,
+ const libusb_descriptor_type_t type,
+ const uint8_t idx,
+ const uint16_t lang_id,
+ void* buffer,
+ const size_t buffer_length,
+ const size_t minimum_length,
+ const uint8_t recipient
+) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "firing usb get descriptor\r\n" )
+ #endif
+ // allocate shared memory
+ const size_t data_size = sizeof ( usb_descriptor_message_t ) + buffer_length + 1;
+ const size_t shm_id = _syscall_memory_shared_create( data_size );
+ // handle error
+ if ( errno ) {
+ const int e = errno;
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to acquire shared memory!\r\n" )
+ #endif
+ // return error
+ return e;
+ }
+ // attach shared memory
+ void* shm_addr = _syscall_memory_shared_attach( shm_id, 0 );
+ // handle error
+ if ( errno ) {
+ const int e = errno;
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to attach shared memory!\r\n" )
+ #endif
+ // return error
+ return e;
+ }
+ // clear out
+ memset( shm_addr, 0, data_size );
+ usb_descriptor_message_t* message = ( usb_descriptor_message_t* )shm_addr;
+ // populate real message in shared memory
+ message->device_number = device_number;
+ message->type = type;
+ message->index = idx;
+ message->lang_id = lang_id;
+ message->buffer_length = buffer_length;
+ message->minimum_length = minimum_length;
+ message->recipient = recipient;
+ if ( buffer ) {
+ memcpy( &message->buffer, buffer, buffer_length );
+ }
+ // allocate request
+ usbd_get_descriptor_t* control_request = malloc( sizeof( *control_request ) );
+ if ( ! control_request ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // return error
+ return ENOMEM;
+ }
+ // clear out everything
+ memset( control_request, 0, sizeof( *control_request ) );
+ // populate shm_id
+ control_request->shm_id = shm_id;
+ // perform request
+ const int result = ioctl(
+ fd_usbd,
+ IOCTL_BUILD_REQUEST(
+ USBD_GET_DESCRIPTOR,
+ sizeof( *control_request ),
+ IOCTL_RDWR
+ ),
+ control_request
+ );
+ // handle ioctl error
+ if ( -1 == result ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_ERROR )
+ const int e = errno;
+ STARTUP_PRINT( "e = %d, errno = %s\r\n", e, strerror( e ) );
+ #endif
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // free request
+ free( control_request );
+ // return eio
+ return EIO;
+ }
+ // copy over data
+ if ( buffer ) {
+ memcpy( buffer, message->buffer, buffer_length );
+ }
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // free control message
+ free( control_request );
+ // return result
+ return result;
+}
+
+/**
+ * @fn int usb_attach_device(uint32_t, uint32_t, libusb_speed_t, rpc_handler_t, void*, origin, data_info)
+ * @brief Method to attach a new discovered device
+ * @param parent_number parent device number
+ * @param port_number port number
+ * @param speed detected speed
+ * @param callback callback to be invoked on finish
+ * @param context context ( use nullptr if not available
+ * @param origin origin process ( use 0 if not available )
+ * @param data_info data info ( use 0 if not available )
+ * @return
+ */
+int usb_attach_device(
+ const uint32_t parent_number,
+ const uint32_t port_number,
+ const libusb_speed_t speed,
+ const rpc_handler_t callback,
+ void* context,
+ const pid_t origin,
+ const size_t data_info
+) {
+ // debug message
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Attaching device %"PRIu32" to %"PRIu32"\r\n",
+ port_number, parent_number )
+ #endif
+ // allocate device
+ usbd_attach_device_t* request = malloc( sizeof( *request ) );
+ // handle error
+ if ( ! request ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // return nomem
+ return ENOMEM;
+ }
+ // clear out
+ memset( request, 0, sizeof( *request ) );
+ // copy over necessary data
+ request->parent_number = parent_number;
+ request->port_number = port_number;
+ request->speed = speed;
+ // calculate rpc request size
+ constexpr size_t rpc_request_size = sizeof( vfs_ioctl_perform_request_t )
+ + sizeof( *request );
+ // allocate rpc structures
+ vfs_ioctl_perform_request_t* rpc_request = malloc( rpc_request_size );
+ if ( ! rpc_request ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // free control request
+ free( request );
+ // return error
+ return ENOMEM;
+ }
+ // clear rpc structures
+ memset( rpc_request, 0, rpc_request_size );
+ // populate structure
+ rpc_request->handle = fd_usbd;
+ rpc_request->command = USBD_ATTACH_DEVICE;
+ rpc_request->type = IOCTL_RDWR;
+ // copy over data
+ memcpy( rpc_request->container, request, sizeof( *request ) );
+ EARLY_STARTUP_PRINT( "origin = %d, data_info = %zu\r\n", origin, data_info )
+ // raise rpc and wait for return
+ const size_t response_id = bolthur_rpc_raise(
+ RPC_VFS_IOCTL,
+ VFS_DAEMON_ID,
+ rpc_request,
+ rpc_request_size,
+ callback,
+ RPC_VFS_IOCTL,
+ rpc_request,
+ rpc_request_size,
+ origin,
+ data_info,
+ context,
+ false
+ );
+ if ( ! response_id ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_ERROR )
+ const int e = errno;
+ STARTUP_PRINT( "e = %d, errno = %s\r\n", e, strerror( e ) );
+ #endif
+ // free request data
+ free( rpc_request );
+ // free control request
+ free( request );
+ // return io error
+ return EIO;
+ }
+ // free request data
+ free( rpc_request );
+ // free control request
+ free( request );
+ // return success
+ return 0;
+}
+
+/**
+ * @fn int usb_register_handler(libusb_interface_class_t)
+ * @brief Method to attach a new discovered device
+ * @param type
+ * @return
+ */
+int usb_register_handler( const libusb_interface_class_t type ) {
+ const pid_t pid = getpid();
+ // debug message
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Registering pid %d for type %d\r\n", pid, type )
+ #endif
+ // allocate device
+ usbd_register_device_handler_t* request = malloc( sizeof( *request ) );
+ // handle error
+ if ( ! request ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // return nomem
+ return ENOMEM;
+ }
+ // clear out
+ memset( request, 0, sizeof( *request ) );
+ // copy over necessary data
+ request->type = type;
+ request->handler = pid;
+ // perform request
+ const int result = ioctl(
+ fd_usbd,
+ IOCTL_BUILD_REQUEST(
+ USBD_REGISTER_HANDLER,
+ sizeof( *request ),
+ IOCTL_RDWR
+ ),
+ request
+ );
+ // handle ioctl error
+ if ( -1 == result ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_ERROR )
+ const int e = errno;
+ STARTUP_PRINT( "e = %d, errno = %s\r\n", e, strerror( e ) );
+ #endif
+ // free request
+ free( request );
+ return EIO;
+ }
+ // free request
+ free( request );
+ // return success
+ return 0;
+}
+
+/**
+ * @fn int usb_get_endpoint(uint32_t, uint32_t, uint32_t, libusb_endpoint_descriptor_t*)
+ * @brief Helper to get usb endpoint data
+ * @param device_number
+ * @param interface_number
+ * @param endpoint_number
+ * @param descriptor
+ * @return
+ */
+int usb_get_endpoint(
+ const uint32_t device_number,
+ const uint32_t interface_number,
+ const uint32_t endpoint_number,
+ libusb_endpoint_descriptor_t* descriptor
+) {
+ // debug message
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Get endpoint information\r\n" )
+ #endif
+ // allocate device
+ usbd_get_endpoint_t* request = malloc( sizeof( *request ) );
+ // handle error
+ if ( ! request ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // return nomem
+ return ENOMEM;
+ }
+ // clear out
+ memset( request, 0, sizeof( *request ) );
+ // copy over necessary data
+ request->device_number = device_number;
+ request->interface_number = interface_number;
+ request->endpoint_number = endpoint_number;
+ // perform request
+ const int result = ioctl(
+ fd_usbd,
+ IOCTL_BUILD_REQUEST(
+ USBD_GET_ENDPOINT,
+ sizeof( *request ),
+ IOCTL_RDWR
+ ),
+ request
+ );
+ // handle ioctl error
+ if ( -1 == result ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_ERROR )
+ const int e = errno;
+ STARTUP_PRINT( "e = %d, errno = %s\r\n", e, strerror( e ) );
+ #endif
+ // free request
+ free( request );
+ return EIO;
+ }
+ // copy over endpoint data
+ memcpy( descriptor, request, sizeof( *descriptor ) );
+ // free request
+ free( request );
+ // return success
+ return 0;
+}
+
+/**
+ * @fn int usb_get_interface(uint32_t, uint32_t, libusb_interface_descriptor_t*)
+ * @brief Wrapper to get interface data
+ * @param device_number
+ * @param interface_number
+ * @param descriptor
+ * @return
+ */
+int usb_get_interface(
+ const uint32_t device_number,
+ const uint32_t interface_number,
+ libusb_interface_descriptor_t* descriptor
+) {
+ // debug message
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "fd_usbd = %d\r\n", fd_usbd );
+ STARTUP_PRINT( "Get interface\r\n" )
+ #endif
+ // allocate device
+ usbd_get_interface_t* request = malloc( sizeof( *request ) );
+ // handle error
+ if ( ! request ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // return nomem
+ return ENOMEM;
+ }
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "fd_usbd = %d\r\n", fd_usbd );
+ STARTUP_PRINT( "Get interface\r\n" )
+ #endif
+ // clear out
+ memset( request, 0, sizeof( *request ) );
+ // copy over necessary data
+ request->device_number = device_number;
+ request->interface_number = interface_number;
+ // perform request
+ const int result = ioctl(
+ fd_usbd,
+ IOCTL_BUILD_REQUEST(
+ USBD_GET_INTERFACE,
+ sizeof( *request ),
+ IOCTL_RDWR
+ ),
+ request
+ );
+ // handle ioctl error
+ if ( -1 == result ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_ERROR )
+ const int e = errno;
+ STARTUP_PRINT( "e = %d, errno = %s\r\n", e, strerror( e ) );
+ #endif
+ // free request
+ free( request );
+ return EIO;
+ }
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "fd_usbd = %d\r\n", fd_usbd );
+ STARTUP_PRINT( "Get interface\r\n" )
+ #endif
+ // copy over data
+ memcpy( descriptor, request, sizeof( *descriptor ) );
+ // free request
+ free( request );
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "fd_usbd = %d\r\n", fd_usbd );
+ STARTUP_PRINT( "Get interface\r\n" )
+ #endif
+ // return success
+ return 0;
+}
+
+/**
+ * @fn int usb_get_configuration(uint32_t, void**)
+ * @brief Method to get usb device configuration
+ * @param device_number
+ * @param target_buffer
+ * @return
+ */
+int usb_get_configuration( const uint32_t device_number, void** target_buffer ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "firing usb get configuration\r\n" )
+ #endif
+ // allocate shared memory
+ const size_t shm_id = _syscall_memory_shared_create( 0x1000 );
+ // handle error
+ if ( errno ) {
+ const int e = errno;
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to acquire shared memory!\r\n" )
+ #endif
+ // return error
+ return e;
+ }
+ // attach shared memory
+ void* shm_addr = _syscall_memory_shared_attach( shm_id, 0 );
+ // handle error
+ if ( errno ) {
+ const int e = errno;
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to attach shared memory!\r\n" )
+ #endif
+ // return error
+ return e;
+ }
+ // clear out
+ memset( shm_addr, 0, 0x1000 );
+ // allocate request
+ usbd_get_configuration_t* control_request = malloc( sizeof( *control_request ) );
+ if ( ! control_request ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // return error
+ return ENOMEM;
+ }
+ // clear out everything
+ memset( control_request, 0, sizeof( *control_request ) );
+ // populate shm_id
+ control_request->shm_id = shm_id;
+ control_request->device_number = device_number;
+ // perform request
+ const int result = ioctl(
+ fd_usbd,
+ IOCTL_BUILD_REQUEST(
+ USBD_GET_CONFIGURATION,
+ sizeof( *control_request ),
+ IOCTL_RDWR
+ ),
+ control_request
+ );
+ // handle ioctl error
+ if ( -1 == result ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_ERROR )
+ const int e = errno;
+ STARTUP_PRINT( "e = %d, errno = %s\r\n", e, strerror( e ) );
+ #endif
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // free request
+ free( control_request );
+ // return eio
+ return EIO;
+ }
+ // allocate space for buffer
+ *target_buffer = malloc( control_request->configuration_length );
+ if ( ! *target_buffer ) {
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to space for configuration\r\n" )
+ #endif
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // free request
+ free( control_request );
+ // return eio
+ return ENOMEM;
+ }
+ // clear space
+ memset( *target_buffer, 0, control_request->configuration_length );
+ // copy over from shared memory
+ memcpy( *target_buffer, shm_addr, control_request->configuration_length );
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // free control message
+ free( control_request );
+ // return result
+ return result;
+}
+
+/**
+ * @fn int usb_get_status(uint32_t, libusb_device_status_t*)
+ * @brief Method to get usb device status
+ * @param device_number
+ * @param status
+ * @return
+ */
+int usb_get_status( const uint32_t device_number, libusb_device_status_t* status ) {
+ // validate parameter
+ if ( ! status ) {
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Invalid status parameter passed\r\n" )
+ #endif
+ // return einval
+ return EINVAL;
+ }
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "firing usb get descriptor\r\n" )
+ #endif
+ // allocate request
+ usbd_get_status_t* request = malloc( sizeof( *request ) );
+ if ( ! request ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // return error
+ return ENOMEM;
+ }
+ // clear out everything
+ memset( request, 0, sizeof( *request ) );
+ // populate shm_id
+ request->device_number = device_number;
+ // perform request
+ const int result = ioctl(
+ fd_usbd,
+ IOCTL_BUILD_REQUEST(
+ USBD_GET_STATUS,
+ sizeof( *request ),
+ IOCTL_RDWR
+ ),
+ request
+ );
+ // handle ioctl error
+ if ( -1 == result ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_ERROR )
+ const int e = errno;
+ STARTUP_PRINT( "e = %d, errno = %s\r\n", e, strerror( e ) );
+ #endif
+ // free request
+ free( request );
+ // return eio
+ return EIO;
+ }
+ // set status
+ *status = request->status;
+ // free control message
+ free( request );
+ // return result
+ return result;
+}
+
+/**
+ * @fn int usb_interrupt_poll_async(uint32_t, libusb_transfer_t, uint32_t. libusb_direction_t, void*, size_t, size_t)
+ * @brief Wrapper to perform async interrupt poll
+ * @param device_number
+ * @param transfer
+ * @param endpoint_number
+ * @param direction
+ * @param buffer
+ * @param buffer_length
+ * @param timeout
+ * @return
+ *
+ * @todo detach shared memory on return
+ */
+int usb_interrupt_poll_async(
+ const uint32_t device_number,
+ const libusb_transfer_t transfer,
+ const uint32_t endpoint_number,
+ const libusb_direction_t direction,
+ const void* buffer,
+ const size_t buffer_length,
+ const size_t timeout
+) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "firing async usb poll interrupt message\r\n" )
+ #endif
+ // allocate shared memory
+ const size_t data_size = sizeof ( usb_interrupt_poll_t ) + buffer_length + 1;
+ const size_t shm_id = _syscall_memory_shared_create( data_size );
+ // handle error
+ if ( errno ) {
+ const int e = errno;
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to acquire shared memory!\r\n" )
+ #endif
+ // return error
+ return e;
+ }
+ // attach shared memory
+ void* shm_addr = _syscall_memory_shared_attach( shm_id, 0 );
+ // handle error
+ if ( errno ) {
+ const int e = errno;
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to attach shared memory!\r\n" )
+ #endif
+ // return error
+ return e;
+ }
+ // clear out
+ memset( shm_addr, 0, data_size );
+ auto const message = ( usb_interrupt_poll_t* )shm_addr;
+ // populate real message in shared memory
+ message->device_number = device_number;
+ message->endpoint = endpoint_number;
+ message->transfer = transfer;
+ message->direction = direction;
+ message->buffer_length = buffer_length;
+ message->timeout = timeout;
+ if ( LIBUSB_DIRECTION_OUT == direction && buffer ) {
+ memcpy( &message->buffer[ 0 ], buffer, buffer_length );
+ } else {
+ memset( &message->buffer[ 0 ], 0, buffer_length );
+ }
+ // allocate request
+ usbd_interrupt_message_t* control_request = malloc( sizeof( *control_request ) );
+ if ( ! control_request ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // return error
+ return ENOMEM;
+ }
+ // clear out everything
+ memset( control_request, 0, sizeof( *control_request ) );
+ // populate shm_id
+ control_request->shm_id = shm_id;
+ // perform request
+ const int result = ioctl(
+ fd_usbd,
+ IOCTL_BUILD_REQUEST(
+ USBD_POLL_INTERRUPT,
+ sizeof( *control_request ),
+ IOCTL_RDWR
+ ),
+ control_request
+ );
+ // handle ioctl error
+ if ( -1 == result ) {
+ const int e = errno;
+ // debug output
+ #if defined( LIBUSB_ENABLE_ERROR )
+ STARTUP_PRINT("e = %d, errno = %s\r\n", e, strerror( e ));
+ #endif
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
+ // free request
+ free( control_request );
+ // return eio
+ return e ? e : EIO;
+ }
+ // free control message
+ free( control_request );
+ // detach shared memory again
+ _syscall_memory_shared_detach( shm_id );
+ // return result
+ return result;
+}
+
+/**
+ * @brief Get enumerating status
+ * @param out output variable
+ * @return
+ */
+int usb_get_enumerating( bool* out ) {
+ // validate parameter
+ if ( ! out ) {
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Invalid status parameter passed\r\n" )
+ #endif
+ // return einval
+ return EINVAL;
+ }
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "firing usb get enumerating\r\n" )
+ #endif
+ // allocate request
+ usbd_get_enumerating_t* request = malloc( sizeof( *request ) );
+ if ( ! request ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_DEBUG )
+ STARTUP_PRINT( "Unable to allocate request\r\n" )
+ #endif
+ // return error
+ return ENOMEM;
+ }
+ // clear out everything
+ memset( request, 0, sizeof( *request ) );
+ // perform request
+ const int result = ioctl(
+ fd_usbd,
+ IOCTL_BUILD_REQUEST(
+ USBD_GET_ENUMERATING,
+ sizeof( *request ),
+ IOCTL_RDWR
+ ),
+ request
+ );
+ // handle ioctl error
+ if ( -1 == result ) {
+ // debug output
+ #if defined( LIBUSB_ENABLE_ERROR )
+ const int e = errno;
+ STARTUP_PRINT( "e = %d, errno = %s\r\n", e, strerror( e ) );
+ #endif
+ // free request
+ free( request );
+ // return eio
+ return EIO;
+ }
+ // copy over response
+ memcpy( out, request, sizeof ( bool ) );
+ // free control message
+ free( request );
+ // return result
+ return result;
+}
diff --git a/bolthur/library/usb/usb.h b/bolthur/library/usb/usb.h
new file mode 100644
index 000000000..07158fe31
--- /dev/null
+++ b/bolthur/library/usb/usb.h
@@ -0,0 +1,43 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#ifndef _USB_H
+#define _USB_H
+
+#include "../../server/libusb.h"
+
+//#define LIBUSB_ENABLE_DEBUG 1
+//#define LIBUSB_ENABLE_ERROR 1
+
+int usb_init( void );
+int usb_control_message( uint32_t, libusb_transfer_t, libusb_direction_t, void*, size_t, const libusb_device_request_t*, size_t, libusb_transfer_error_t*, uint32_t* );
+int usb_control_message_async( uint32_t, libusb_transfer_t, libusb_direction_t, const void*, size_t, const libusb_device_request_t*, size_t, rpc_handler_t );
+int usb_interrupt_poll_async( uint32_t, libusb_transfer_t, uint32_t, libusb_direction_t, const void*, size_t, size_t );
+const char* usb_get_description( uint32_t );
+int usb_get_descriptor( uint32_t, libusb_descriptor_type_t, uint8_t, uint16_t, void*, size_t, size_t, uint8_t );
+int usb_attach_device( uint32_t, uint32_t, libusb_speed_t, rpc_handler_t, void*, pid_t, size_t );
+int usb_register_handler( libusb_interface_class_t );
+int usb_get_endpoint( uint32_t, uint32_t, uint32_t, libusb_endpoint_descriptor_t* );
+int usb_get_interface( uint32_t, uint32_t, libusb_interface_descriptor_t* );
+int usb_get_root_hub( uint32_t* );
+int usb_get_configuration( uint32_t, void** );
+int usb_get_status( uint32_t, libusb_device_status_t* );
+int usb_get_enumerating( bool* );
+
+#endif
diff --git a/bolthur/library/util/Makefile.am b/bolthur/library/util/Makefile.am
new file mode 100644
index 000000000..74b6cfca4
--- /dev/null
+++ b/bolthur/library/util/Makefile.am
@@ -0,0 +1,7 @@
+
+AM_CFLAGS = -DPROGRAM_NAME=\"bolthur/libutil\"
+
+noinst_LTLIBRARIES = libutil.la
+libutil_la_SOURCES = \
+ max.c \
+ min.c
diff --git a/bolthur/library/util/max.c b/bolthur/library/util/max.c
new file mode 100644
index 000000000..96673e908
--- /dev/null
+++ b/bolthur/library/util/max.c
@@ -0,0 +1,34 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include "max.h"
+
+/**
+ * @fn uint32_t uint32_max( uint32_t, uint32_t )
+ * @brief uint32 max implementation
+ * @param a
+ * @param b
+ * @return
+ */
+uint32_t uint32_max( const uint32_t a, const uint32_t b ) {
+ if ( a < b ) {
+ return b;
+ }
+ return a;
+}
diff --git a/bolthur/library/util/max.h b/bolthur/library/util/max.h
new file mode 100644
index 000000000..fa94b0481
--- /dev/null
+++ b/bolthur/library/util/max.h
@@ -0,0 +1,28 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#ifndef _MAX_H
+#define _MAX_H
+
+#include
+#include
+
+uint32_t uint32_max( uint32_t, uint32_t );
+
+#endif
diff --git a/bolthur/library/util/min.c b/bolthur/library/util/min.c
new file mode 100644
index 000000000..4e7a5a53d
--- /dev/null
+++ b/bolthur/library/util/min.c
@@ -0,0 +1,48 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include "min.h"
+
+/**
+ * @fn uint32_t uint32_min( uint32_t, uint32_t )
+ * @brief uint32 min implementation
+ * @param a
+ * @param b
+ * @return
+ */
+uint32_t uint32_min( const uint32_t a, const uint32_t b ) {
+ if ( a < b ) {
+ return a;
+ }
+ return b;
+}
+
+/**
+ * @fn size_t size_min( size_t, size_t )
+ * @brief size min implementation
+ * @param a
+ * @param b
+ * @return
+ */
+size_t size_min( const size_t a, const size_t b ) {
+ if ( a < b ) {
+ return a;
+ }
+ return b;
+}
diff --git a/bolthur/library/util/min.h b/bolthur/library/util/min.h
new file mode 100644
index 000000000..9dfd6da7f
--- /dev/null
+++ b/bolthur/library/util/min.h
@@ -0,0 +1,29 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#ifndef _MIN_H
+#define _MIN_H
+
+#include
+#include
+
+uint32_t uint32_min( uint32_t, uint32_t );
+size_t size_min( size_t, size_t );
+
+#endif
diff --git a/bolthur/library/vfs/Makefile.am b/bolthur/library/vfs/Makefile.am
new file mode 100644
index 000000000..e08ecf152
--- /dev/null
+++ b/bolthur/library/vfs/Makefile.am
@@ -0,0 +1,10 @@
+
+AM_CFLAGS = -DPROGRAM_NAME=\"bolthur/libvfs\"
+
+noinst_LTLIBRARIES = libvfs.la
+libvfs_la_SOURCES = \
+ add.c \
+ dev.c \
+ handler.c \
+ remove.c \
+ wait.c
diff --git a/bolthur/library/vfs/add.c b/bolthur/library/vfs/add.c
new file mode 100644
index 000000000..4c93a6957
--- /dev/null
+++ b/bolthur/library/vfs/add.c
@@ -0,0 +1,86 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include
+#include
+#include "add.h"
+
+/**
+ * @fn void vfs_add(vfs_add_request_t*, size_t, uint32_t, rpc_handler_t)
+ * @brief Function to send a vfs add request
+ * @param msg message to send
+ * @param size message size
+ * @param wait sleep time in case it fails
+ * @param handler handler for async callback
+ */
+void vfs_add(
+ vfs_add_request_t* msg,
+ const size_t size,
+ const uint32_t wait,
+ const rpc_handler_t handler
+) {
+ if ( ! msg ) {
+ exit( -1 );
+ }
+ // push in current pid
+ msg->handler = getpid();
+ const size_t size_to_use = size ? size : sizeof( *msg );
+ // response id
+ size_t response_id = 0;
+ // try to send until it worked
+ while ( true ) {
+ // wait for response
+ response_id = bolthur_rpc_raise(
+ RPC_VFS_ADD,
+ VFS_DAEMON_ID,
+ msg,
+ size_to_use,
+ handler,
+ RPC_VFS_ADD,
+ msg,
+ size_to_use,
+ 0,
+ 0,
+ NULL,
+ false
+ );
+ if ( errno ) {
+ if ( wait ) {
+ sleep( wait );
+ }
+ continue;
+ }
+ break;
+ }
+ // fetch message only when no handler was passed
+ if ( ! handler ) {
+ // get message and data size
+ size_t data_size;
+ vfs_add_response_t* response = bolthur_rpc_fetch_from_mailbox( response_id, &data_size, true, NULL );
+ if ( ! response ) {
+ exit( -1 );
+ }
+ // stop on success
+ if ( VFS_ADD_SUCCESS != response->status ) {
+ exit( -1 );
+ }
+ // free up response
+ free( response );
+ }
+}
diff --git a/bolthur/library/vfs/add.h b/bolthur/library/vfs/add.h
new file mode 100644
index 000000000..81bee0778
--- /dev/null
+++ b/bolthur/library/vfs/add.h
@@ -0,0 +1,27 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#ifndef _LIBVFS_ADD_H
+#define _LIBVFS_ADD_H
+
+#include
+
+void vfs_add( vfs_add_request_t*, size_t, uint32_t, rpc_handler_t );
+
+#endif
diff --git a/bolthur/library/vfs/dev.c b/bolthur/library/vfs/dev.c
new file mode 100644
index 000000000..3b349e7b4
--- /dev/null
+++ b/bolthur/library/vfs/dev.c
@@ -0,0 +1,134 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include "dev.h"
+#include "add.h"
+
+/**
+ * @fn bool add_folder_file(const char*, const uint32_t*, const size_t, const mode_t, const rpc_handler_t)
+ * @brief Helper to add a subfolder or file
+ *
+ * @param path
+ * @param device_info
+ * @param count
+ * @param mode
+ * @param handler
+ * @return
+ */
+static bool add_folder_file(
+ const char* path,
+ const uint32_t* device_info,
+ const size_t count,
+ const mode_t mode,
+ const rpc_handler_t handler
+) {
+ // allocate memory for add request
+ const size_t msg_size = sizeof( vfs_add_request_t ) + count * sizeof( size_t );
+ vfs_add_request_t* msg = malloc( msg_size );
+ if ( ! msg ) {
+ return false;
+ }
+ // clear memory
+ memset( msg, 0, msg_size );
+ // debug output
+ EARLY_STARTUP_PRINT( "Sending \"%s\" to vfs\r\n", path )
+ // prepare message structure
+ msg->info.st_mode = mode;
+ strncpy( msg->file_path, path, PATH_MAX - 1 );
+ // copy over device info stuff
+ if ( device_info ) {
+ for ( size_t idx = 0; idx < count; idx++ ) {
+ msg->device_info[ idx ] = device_info[ idx ];
+ }
+ }
+ // perform add request
+ vfs_add( msg, msg_size, 0, handler );
+ // free stuff
+ free( msg );
+ // return success
+ return true;
+}
+
+/**
+ * @fn bool vfs_dev_add_folder_file_stat(const char*, const struct st*, const rpc_handler_t)
+ * @brief Helper to add a subfolder or file
+ *
+ * @param path
+ * @param st
+ * @param handler
+ * @return
+ */
+bool vfs_dev_add_folder_file_stat(
+ const char* path,
+ const struct stat* st,
+ const rpc_handler_t handler
+) {
+ // allocate memory for add request
+ constexpr size_t msg_size = sizeof( vfs_add_request_t ) + 0 * sizeof( size_t );
+ vfs_add_request_t* msg = malloc( msg_size );
+ if ( ! msg ) {
+ return false;
+ }
+ // clear memory
+ memset( msg, 0, msg_size );
+ // prepare message structure
+ memcpy( &msg->info, st, sizeof( struct stat ) );
+ strncpy( msg->file_path, path, PATH_MAX - 1 );
+ // perform add request
+ vfs_add( msg, msg_size, 0, handler );
+ // free stuff
+ free( msg );
+ return true;
+}
+
+/**
+ * @fn bool vfs_dev_add_file(const char*, const uint32_t*, size_t, rpc_handler_t)
+ * @brief Function to add a device file
+ * @param path path to device file
+ * @param device_info ioctl commands allowed by file
+ * @param count count of ioctl commands in device_info
+ * @param handler optional handler for async call flow
+ * @return
+ */
+bool vfs_dev_add_file(
+ const char* path,
+ const uint32_t* device_info,
+ const size_t count,
+ const rpc_handler_t handler
+) {
+ return add_folder_file( path, device_info, count, S_IFCHR, handler );
+}
+
+/**
+ * @fn bool vfs_dev_add_folder(const char*, const uint32_t*, size_t, rpc_handler_t)
+ * @brief Function to add a device file
+ * @param path path to device file
+ * @param device_info ioctl commands allowed by file
+ * @param count count of ioctl commands in device_info
+ * @param handler optional handler for async call flow
+ * @return
+ */
+bool vfs_dev_add_folder(
+ const char* path,
+ const uint32_t* device_info,
+ const size_t count,
+ const rpc_handler_t handler
+) {
+ return add_folder_file( path, device_info, count, S_IFCHR /*| S_IFDIR*/, handler );
+}
diff --git a/bolthur/library/vfs/dev.h b/bolthur/library/vfs/dev.h
new file mode 100644
index 000000000..028ddd519
--- /dev/null
+++ b/bolthur/library/vfs/dev.h
@@ -0,0 +1,31 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#ifndef _LIBVFS_DEV_H
+#define _LIBVFS_DEV_H
+
+#include
+#include
+#include
+
+bool vfs_dev_add_file( const char*, const uint32_t*, size_t, rpc_handler_t );
+bool vfs_dev_add_folder( const char*, const uint32_t*, size_t, rpc_handler_t );
+bool vfs_dev_add_folder_file_stat( const char*, const struct stat*, rpc_handler_t );
+
+#endif
diff --git a/bolthur/library/vfs/handler.c b/bolthur/library/vfs/handler.c
new file mode 100644
index 000000000..a59e67201
--- /dev/null
+++ b/bolthur/library/vfs/handler.c
@@ -0,0 +1,87 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include
+#include
+#include "handler.h"
+
+/**
+ * @fn int vfs_get_file_handler(const char*)
+ * @brief Function to get file handler
+ * @param path
+ * @return
+ */
+pid_t vfs_get_file_handler( const char* path ) {
+ // variables
+ vfs_stat_request_t* request = malloc( sizeof( vfs_stat_request_t ) );
+ if ( ! request ) {
+ errno = ENOMEM;
+ return -1;
+ }
+ // clear message structures
+ memset( request, 0, sizeof( vfs_stat_request_t ) );
+ // copy stuff to message
+ strncpy( request->file_path, path, PATH_MAX - 1 );
+ // raise rpc and wait for return
+ const size_t response_id = bolthur_rpc_raise(
+ RPC_VFS_STAT,
+ VFS_DAEMON_ID,
+ request,
+ sizeof( vfs_stat_request_t ),
+ NULL,
+ RPC_VFS_STAT,
+ request,
+ sizeof( vfs_stat_request_t ),
+ 0,
+ 0,
+ NULL,
+ false
+ );
+ // handle error
+ if ( 0 == response_id ) {
+ free( request );
+ return -1;
+ }
+ size_t data_size;
+ vfs_stat_response_t* response = bolthur_rpc_fetch_from_mailbox(
+ response_id,
+ &data_size,
+ true,
+ NULL
+ );
+ // handle error
+ if ( ! response ) {
+ free( request );
+ return -1;
+ }
+ // handle failure
+ if ( ! response->success ) {
+ free( request );
+ free( response );
+ errno = EIO;
+ return -1;
+ }
+ // cache handler
+ const pid_t handler = response->handler;
+ // free request and response
+ free( request );
+ free( response );
+ // return handler
+ return handler;
+}
diff --git a/bolthur/library/vfs/handler.h b/bolthur/library/vfs/handler.h
new file mode 100644
index 000000000..4eec05152
--- /dev/null
+++ b/bolthur/library/vfs/handler.h
@@ -0,0 +1,27 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#ifndef _LIBVFS_HANDLER_H
+#define _LIBVFS_HANDLER_H
+
+#include
+
+pid_t vfs_get_file_handler( const char* );
+
+#endif
diff --git a/bolthur/library/vfs/remove.c b/bolthur/library/vfs/remove.c
new file mode 100644
index 000000000..610be918a
--- /dev/null
+++ b/bolthur/library/vfs/remove.c
@@ -0,0 +1,81 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include
+#include
+#include "remove.h"
+
+/**
+ * @fn void vfs_remove(vfs_remove_request_t, uint32_t, rpc_handler_t)
+ * @brief Function to send a vfs remove request
+ * @param msg message to send
+ * @param wait sleep time in case it fails
+ * @param handler handler for async callback
+ */
+void vfs_remove(
+ vfs_remove_request_t* msg,
+ const uint32_t wait,
+ const rpc_handler_t handler
+) {
+ if ( ! msg ) {
+ exit( -1 );
+ }
+ // response id
+ size_t response_id = 0;
+ // try to send until it worked
+ while ( true ) {
+ // wait for response
+ response_id = bolthur_rpc_raise(
+ RPC_VFS_REMOVE,
+ VFS_DAEMON_ID,
+ msg,
+ sizeof( *msg ),
+ handler,
+ RPC_VFS_ADD,
+ msg,
+ sizeof( *msg ),
+ 0,
+ 0,
+ NULL,
+ false
+ );
+ if ( errno ) {
+ if ( wait ) {
+ sleep( wait );
+ }
+ continue;
+ }
+ break;
+ }
+ // fetch message only when no handler was passed
+ if ( ! handler ) {
+ // get message and data size
+ size_t data_size;
+ vfs_remove_response_t* response = bolthur_rpc_fetch_from_mailbox( response_id, &data_size, true, NULL );
+ if ( ! response ) {
+ exit( -1 );
+ }
+ // stop on success
+ if ( 0 != response->status ) {
+ exit( -1 );
+ }
+ // free up response
+ free( response );
+ }
+}
diff --git a/bolthur/library/vfs/remove.h b/bolthur/library/vfs/remove.h
new file mode 100644
index 000000000..799b8d2f4
--- /dev/null
+++ b/bolthur/library/vfs/remove.h
@@ -0,0 +1,27 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#ifndef _LIBVFS_REMOVE_H
+#define _LIBVFS_REMOVE_H
+
+#include
+
+void vfs_remove( vfs_remove_request_t*, uint32_t, rpc_handler_t );
+
+#endif
diff --git a/bolthur/library/vfs/wait.c b/bolthur/library/vfs/wait.c
new file mode 100644
index 000000000..ee13d1054
--- /dev/null
+++ b/bolthur/library/vfs/wait.c
@@ -0,0 +1,34 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include
+#include
+#include "wait.h"
+
+/**
+ * @fn void vfs_wait_for_path(const char*)
+ * @brief Function to wait for path to come up
+ * @param path path to check
+ */
+void vfs_wait_for_path( const char* path ) {
+ struct stat buffer;
+ while( 0 != stat( path, &buffer ) ) {
+ sleep( 1 );
+ }
+}
diff --git a/bolthur/library/vfs/wait.h b/bolthur/library/vfs/wait.h
new file mode 100644
index 000000000..0fcedd7b6
--- /dev/null
+++ b/bolthur/library/vfs/wait.h
@@ -0,0 +1,25 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#ifndef _LIBVFS_WAIT_H
+#define _LIBVFS_WAIT_H
+
+void vfs_wait_for_path( const char* );
+
+#endif
diff --git a/bolthur/server/authentication/Makefile.am b/bolthur/server/authentication/Makefile.am
index dbf45dcb7..536cdd161 100644
--- a/bolthur/server/authentication/Makefile.am
+++ b/bolthur/server/authentication/Makefile.am
@@ -2,6 +2,10 @@
AM_CFLAGS = -DPROGRAM_NAME=\"authentication\"
bin_PROGRAMS = authentication
+authentication_LDADD = -lcrypt \
+ ${abs_top_builddir}/../library/vfs/libvfs.la
+authentication_DEPENDENCIES = \
+ ${abs_top_builddir}/../library/vfs/libvfs.la
authentication_SOURCES = \
pid/node.c \
rpc/custom/fetch.c \
diff --git a/bolthur/server/authentication/config.ini b/bolthur/server/authentication/config.ini
index 869a90a52..7c41e2194 100644
--- a/bolthur/server/authentication/config.ini
+++ b/bolthur/server/authentication/config.ini
@@ -1,3 +1,3 @@
[general]
type=ramdisk_compressed
-path=ramdisk/server
\ No newline at end of file
+path=ramdisk/bin/server
diff --git a/bolthur/server/authentication/main.c b/bolthur/server/authentication/main.c
index 24c964809..2885c9088 100644
--- a/bolthur/server/authentication/main.c
+++ b/bolthur/server/authentication/main.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -22,8 +22,9 @@
#include
#include "rpc.h"
#include "pid/node.h"
-#include "../libhelper.h"
#include "../libauthentication.h"
+#include "../../library/vfs/wait.h"
+#include "../../library/vfs/dev.h"
/**
* @fn int main(int, char*[])
@@ -68,11 +69,13 @@ int main( int argc, char* argv[] ) {
_syscall_rpc_set_ready( true );
// wait for device
vfs_wait_for_path( "/dev/manager/device" );
+ // wait for ramdisk to prevent lockup
+ vfs_wait_for_path( "/dev/ramdisk" );
// add device file
- uint32_t device_info[] = { AUTHENTICATE_REQUEST, AUTHENTICATE_FETCH, };
- EARLY_STARTUP_PRINT( "AUTHENTICATE_REQUEST = %d, AUTHENTICATE_FETCH = %d\r\n",
- AUTHENTICATE_REQUEST, AUTHENTICATE_FETCH)
- if ( !dev_add_file( AUTHENTICATION_DEVICE, device_info, 2 ) ) {
+ constexpr uint32_t device_info[] = { AUTHENTICATE_REQUEST, AUTHENTICATE_FETCH, AUTHENTICATE_RELOAD, };
+ EARLY_STARTUP_PRINT( "AUTHENTICATE_REQUEST = %d, AUTHENTICATE_FETCH = %d, AUTHENTICATE_RELOAD = %d\r\n",
+ AUTHENTICATE_REQUEST, AUTHENTICATE_FETCH, AUTHENTICATE_RELOAD )
+ if ( ! vfs_dev_add_file( AUTHENTICATION_DEVICE, device_info, 3, nullptr ) ) {
EARLY_STARTUP_PRINT( "Unable to add dev authenticate\r\n" )
return -1;
}
diff --git a/bolthur/server/authentication/pid/node.c b/bolthur/server/authentication/pid/node.c
index 81999dc3d..f66da4542 100644
--- a/bolthur/server/authentication/pid/node.c
+++ b/bolthur/server/authentication/pid/node.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/authentication/pid/node.h b/bolthur/server/authentication/pid/node.h
index d8a63f722..8acc19424 100644
--- a/bolthur/server/authentication/pid/node.h
+++ b/bolthur/server/authentication/pid/node.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,8 +20,9 @@
#ifndef _PID_NODE_H
#define _PID_NODE_H
+#define __PERMIT_DEPRECATED_SYS_TREE_H 1
+
#include
-#include
#include
#include
#include
diff --git a/bolthur/server/authentication/rpc.h b/bolthur/server/authentication/rpc.h
index 94f043b54..770afa703 100644
--- a/bolthur/server/authentication/rpc.h
+++ b/bolthur/server/authentication/rpc.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _RPC_H
#define _RPC_H
-#include
#include
bool rpc_init( void );
diff --git a/bolthur/server/authentication/rpc/custom/fetch.c b/bolthur/server/authentication/rpc/custom/fetch.c
index 0ba3c6956..f47fe7cc3 100644
--- a/bolthur/server/authentication/rpc/custom/fetch.c
+++ b/bolthur/server/authentication/rpc/custom/fetch.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/authentication/rpc/custom/reload.c b/bolthur/server/authentication/rpc/custom/reload.c
index 2a4af6409..fa5254496 100644
--- a/bolthur/server/authentication/rpc/custom/reload.c
+++ b/bolthur/server/authentication/rpc/custom/reload.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/authentication/rpc/custom/request.c b/bolthur/server/authentication/rpc/custom/request.c
index cfd587fc5..265746ed5 100644
--- a/bolthur/server/authentication/rpc/custom/request.c
+++ b/bolthur/server/authentication/rpc/custom/request.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -19,8 +19,10 @@
#include
#include
+#include
#include "../../rpc.h"
#include "../../../libauthentication.h"
+#include "../../pid/node.h"
/**
* @fn void rpc_custom_handle_request(size_t, pid_t, size_t, size_t)
@@ -33,11 +35,10 @@
*/
void rpc_custom_handle_request(
[[maybe_unused]] size_t type,
- [[maybe_unused]] pid_t origin,
+ pid_t origin,
size_t data_info,
[[maybe_unused]] size_t response_info
) {
- EARLY_STARTUP_PRINT( "AUTHENTICATION REQUEST IOCTL\r\n" )
vfs_ioctl_perform_response_t error = { .status = -EINVAL };
// validate origin
if ( ! bolthur_rpc_validate_origin( origin, data_info ) ) {
@@ -50,15 +51,69 @@ void rpc_custom_handle_request(
bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
return;
}
- // get message and data size
+ // get data from mailbox
size_t data_size;
- authentication_request_request_t* request = bolthur_rpc_fetch_from_mailbox( data_info, &data_size, true, NULL );
+ vfs_ioctl_perform_request_t* request = bolthur_rpc_fetch_from_mailbox( data_info, &data_size, true, NULL );
if ( ! request ) {
+ error.status = -EIO;
+ bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
+ return;
+ }
+ // get authentication request from command
+ auto const authentication_request = ( authentication_request_request_t* )request->container;
+ // allocate shared memory
+ authentication_request_request_data_t* data = _syscall_memory_shared_attach(
+ authentication_request->shm_id, (uintptr_t)NULL );
+ if ( errno ) {
error.status = -errno;
bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
+ free( request );
+ return;
+ }
+ // get pwent entry
+ struct passwd* pw = getpwnam( data->user );
+ // handle error
+ if ( ! pw ) {
+ error.status = -EIO;
+ _syscall_memory_shared_detach( authentication_request->shm_id );
+ free( request );
+ bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
+ return;
+ }
+ // verify password
+ char* hash = crypt( data->password, pw->pw_passwd );
+ if ( ! hash ) {
+ error.status = -EIO;
+ _syscall_memory_shared_detach( authentication_request->shm_id );
+ free( request );
+ bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
+ return;
+ }
+ if ( 0 != strcmp( hash, pw->pw_passwd ) ) {
+ error.status = -EIO;
+ _syscall_memory_shared_detach( authentication_request->shm_id );
+ free( request );
+ bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
+ return;
+ }
+ // remove existing node
+ pid_node_remove( authentication_request->process );
+ // try to add it again with changed user id
+ if ( ! pid_node_add( authentication_request->process, pw->pw_uid ) ) {
+ error.status = -EIO;
+ _syscall_memory_shared_detach( authentication_request->shm_id );
+ free( request );
+ bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
return;
}
- error.status = -ENOSYS;
+ // populate data with user, home and shell
+ strcpy( data->pw_user, pw->pw_name );
+ strcpy( data->pw_home, pw->pw_dir );
+ strcpy( data->pw_shell, pw->pw_shell );
+ // return success
+ error.status = 0;
bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
+ // free allocated memory again
+ _syscall_memory_shared_detach( authentication_request->shm_id );
free( request );
}
diff --git a/bolthur/server/authentication/rpc/fork.c b/bolthur/server/authentication/rpc/fork.c
index eeaa5ff1d..844881eb2 100644
--- a/bolthur/server/authentication/rpc/fork.c
+++ b/bolthur/server/authentication/rpc/fork.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -50,7 +50,7 @@ void rpc_handle_fork(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/authentication/rpc/init.c b/bolthur/server/authentication/rpc/init.c
index 4308e4c62..b425285e3 100644
--- a/bolthur/server/authentication/rpc/init.c
+++ b/bolthur/server/authentication/rpc/init.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/boot/Makefile.am b/bolthur/server/boot/Makefile.am
index 397620b0a..10611dc88 100644
--- a/bolthur/server/boot/Makefile.am
+++ b/bolthur/server/boot/Makefile.am
@@ -8,7 +8,10 @@ boot_LDADD = \
$(CONFINI_LIBS) \
$(ZLIB_LIBS) \
-ltar \
- -lfdt
+ -lfdt \
+ ${abs_top_builddir}/../library/vfs/libvfs.la
+boot_DEPENDENCIES = \
+ ${abs_top_builddir}/../library/vfs/libvfs.la
boot_SOURCES = \
init/stage1.c \
init/stage2.c \
diff --git a/bolthur/server/boot/configuration.c b/bolthur/server/boot/configuration.c
index d7e33544d..275f59792 100644
--- a/bolthur/server/boot/configuration.c
+++ b/bolthur/server/boot/configuration.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -116,6 +116,7 @@ configuration_node_t* by_name( const char* name ) {
* @brief Parse and handle configuration
*
* @param path
+ * @param bootarg
* @return
*/
bool configuration_handle( const char* path, const char* bootarg ) {
diff --git a/bolthur/server/boot/configuration.h b/bolthur/server/boot/configuration.h
index 94e928596..e0da08dfe 100644
--- a/bolthur/server/boot/configuration.h
+++ b/bolthur/server/boot/configuration.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _CONFIGURATION_H
#define _CONFIGURATION_H
-#include
#include
#include
diff --git a/bolthur/server/boot/global.h b/bolthur/server/boot/global.h
index c3818f21f..7ee2741ae 100644
--- a/bolthur/server/boot/global.h
+++ b/bolthur/server/boot/global.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/boot/init.h b/bolthur/server/boot/init.h
index da34cfa95..834dc3c0b 100644
--- a/bolthur/server/boot/init.h
+++ b/bolthur/server/boot/init.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -24,7 +24,7 @@
#include
void init_stage1( void );
-[[noreturn]] void init_stage2( const char* );
+void init_stage2( const char* );
[[noreturn]] void init_stage3( void );
#endif
diff --git a/bolthur/server/boot/init/stage1.c b/bolthur/server/boot/init/stage1.c
index 037695875..b23b46b88 100644
--- a/bolthur/server/boot/init/stage1.c
+++ b/bolthur/server/boot/init/stage1.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -27,46 +27,19 @@
#include "../init.h"
#include "../util.h"
#include "../global.h"
-#include "../../libhelper.h"
+#include "../../../library/vfs/wait.h"
pid_t vfs_pid = 2;
pid_t dev_pid = 3;
pid_t ramdisk_pid = 4;
-/**
- * @fn void delay(size_t)
- * @brief delay method without necessity of rpc enabled
- *
- * @param sec
- */
-static void delay( size_t sec ) {
- // get clock frequency
- size_t frequency = _syscall_timer_frequency();
- // calculate second timeout
- size_t timeout = ( size_t )( sec * frequency );
- size_t tick;
- // add tick count to get an end time
- timeout += _syscall_timer_tick_count();
- // loop until timeout is reached
- while ( ( tick = _syscall_timer_tick_count() ) < timeout ) {
- __asm__ __volatile__( "nop" );
- }
-}
-
/**
* @fn void init_stage1(void)
* @brief Stage 1 init with start of necessary stuff ( VFS, DEV, and RAMDISK )
- *
- * @todo 1. start vfs and dev like it's done now
- * @todo 2. wait in non fork for vfs and dev
- * @todo 3. start mount server using dev
- * @todo 4. start authentication server using dev
- * @todo 5. start ramdisk server using dev
- * @todo 6. wait for ramdisk mount
*/
void init_stage1( void ) {
// transform number to string
- int len = snprintf( NULL, 0, "%zu", ramdisk_shared_id ) + 1;
+ int len = snprintf( nullptr, 0, "%zu", ramdisk_shared_id ) + 1;
char* shm_id_str = malloc( sizeof( char ) * ( size_t )len );
if ( ! shm_id_str ) {
EARLY_STARTUP_PRINT( "Unable to allocate space for parameter\r\n" )
@@ -77,7 +50,7 @@ void init_stage1( void ) {
// get vfs image
size_t vfs_size;
- void* vfs_image = ramdisk_lookup( disk, "ramdisk/server/fs/vfs", &vfs_size );
+ void* vfs_image = ramdisk_lookup( disk, "ramdisk/bin/server/fs/vfs", &vfs_size );
if ( ! vfs_image ) {
EARLY_STARTUP_PRINT( "VFS not found!\r\n" );
exit( -1 );
@@ -96,7 +69,7 @@ void init_stage1( void ) {
// start /dev
EARLY_STARTUP_PRINT( "Starting for dev server...\r\n" )
size_t dev_size;
- void* dev_image = ramdisk_lookup( disk, "ramdisk/server/fs/dev", &dev_size );
+ void* dev_image = ramdisk_lookup( disk, "ramdisk/bin/server/fs/dev", &dev_size );
if ( ! dev_image ) {
EARLY_STARTUP_PRINT( "dev server not found!\r\n" )
exit( -1 );
@@ -113,7 +86,7 @@ void init_stage1( void ) {
// call for vfs replace
if ( 0 != inner_forked_process ) {
EARLY_STARTUP_PRINT( "Replacing fork with vfs image %p!\r\n", vfs_image );
- _syscall_process_replace( vfs_image, NULL, NULL );
+ _syscall_process_replace( vfs_image, nullptr, nullptr );
if ( errno ) {
EARLY_STARTUP_PRINT( "Unable to replace process with image\r\n" )
EARLY_STARTUP_PRINT( "%s\r\n", strerror( errno ) )
@@ -129,7 +102,7 @@ void init_stage1( void ) {
EARLY_STARTUP_PRINT( "waiting for vfs and dev!\r\n" )
vfs_wait_for_path( ":/vfs" );
// start /dev/ramdisk
- void* ramdisk_image = ramdisk_lookup( disk, "ramdisk/server/fs/ramdisk", NULL );
+ void* ramdisk_image = ramdisk_lookup( disk, "ramdisk/bin/server/fs/ramdisk", nullptr );
if ( ! ramdisk_image ) {
EARLY_STARTUP_PRINT( "ramdisk server not found!\r\n" )
exit( -1 );
@@ -145,9 +118,9 @@ void init_stage1( void ) {
if ( 0 == inner_forked_process ) {
EARLY_STARTUP_PRINT( "Replacing fork with ramdisk image %p!\r\n", ramdisk_image )
// build command
- char* ramdisk_cmd[] = { "ramdisk", shm_id_str, NULL, };
+ char* ramdisk_cmd[] = { "ramdisk", shm_id_str, nullptr, };
// call for replace and handle error
- _syscall_process_replace( ramdisk_image, ramdisk_cmd, NULL );
+ _syscall_process_replace( ramdisk_image, ramdisk_cmd, nullptr );
if ( errno ) {
EARLY_STARTUP_PRINT( "Unable to replace process with image\r\n" )
EARLY_STARTUP_PRINT( "%s\r\n", strerror( errno ) )
@@ -158,8 +131,8 @@ void init_stage1( void ) {
// start /dev/authentication
void* authentication_image = ramdisk_lookup(
disk,
- "ramdisk/server/authentication",
- NULL
+ "ramdisk/bin/server/authentication",
+ nullptr
);
if ( ! authentication_image ) {
EARLY_STARTUP_PRINT( "authentication server not found!\r\n" )
@@ -176,9 +149,9 @@ void init_stage1( void ) {
if ( 0 == inner_forked_process ) {
EARLY_STARTUP_PRINT( "Replacing fork with authentication image %p!\r\n", authentication_image )
// build command
- char* authentication_cmd[] = { "authentication", "1", "2", "3", "4", "5", NULL, };
+ char* authentication_cmd[] = { "authentication", "1", "2", "3", "4", "5", nullptr, };
// call for replace and handle error
- _syscall_process_replace( authentication_image, authentication_cmd, NULL );
+ _syscall_process_replace( authentication_image, authentication_cmd, nullptr );
if ( errno ) {
EARLY_STARTUP_PRINT( "Unable to replace process with image\r\n" )
EARLY_STARTUP_PRINT( "%s\r\n", strerror( errno ) )
@@ -187,16 +160,14 @@ void init_stage1( void ) {
}
if ( 0 != inner_forked_process ) {
- // wait a few seconds
- delay( 2 );
EARLY_STARTUP_PRINT( "waiting for parent to be ready!\r\n" )
// wait for parent process to be ready
_syscall_rpc_wait_for_ready( forked_process );
EARLY_STARTUP_PRINT( "Replacing fork with dev image %p!\r\n", dev_image )
// build command
- char* dev_cmd[] = { "dev", NULL, };
+ char* dev_cmd[] = { "dev", nullptr, };
// call for replace and handle error
- _syscall_process_replace( dev_image, dev_cmd, NULL );
+ _syscall_process_replace( dev_image, dev_cmd, nullptr );
if ( errno ) {
EARLY_STARTUP_PRINT( "Unable to replace process with image\r\n" )
EARLY_STARTUP_PRINT( "%s\r\n", strerror( errno ) )
@@ -212,10 +183,10 @@ void init_stage1( void ) {
}
// enable rpc and wait for process to be ready
_syscall_rpc_set_ready( true );
- // delay necessary to not interrupt other startup
- delay( 20 );
// enough to wait here for ramdisk and authentication, since both need dev server
+ EARLY_STARTUP_PRINT( "Waiting for authentication device\r\n" )
vfs_wait_for_path( AUTHENTICATION_DEVICE );
+ EARLY_STARTUP_PRINT( "Waiting for ramdisk\r\n" )
vfs_wait_for_path( "/dev/ramdisk" );
// close ramdisk
EARLY_STARTUP_PRINT( "Closing early ramdisk\r\n" );
@@ -224,6 +195,6 @@ void init_stage1( void ) {
exit( -1 );
}
// unset disk
- disk = NULL;
+ disk = nullptr;
free( shm_id_str );
}
diff --git a/bolthur/server/boot/init/stage2.c b/bolthur/server/boot/init/stage2.c
index 801c50068..ea530ddd8 100644
--- a/bolthur/server/boot/init/stage2.c
+++ b/bolthur/server/boot/init/stage2.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -24,17 +24,15 @@
#include
#include
#include "../init.h"
-#include "../util.h"
-#include "../global.h"
#include "../configuration.h"
-#include "../../libhelper.h"
+#include "../../../library/vfs/wait.h"
/**
* @fn void init_stage2(const char*)
* @brief Stage 2 init starting necessary stuff so that stage 3 with stuff from disk can be started
* @param bootarg boot arguments
*/
-[[noreturn]] void init_stage2( const char* bootarg ) {
+void init_stage2( const char* bootarg ) {
// start servers by configuration
if ( ! configuration_handle( "/ramdisk/config/stage2.ini", bootarg ) ) {
EARLY_STARTUP_PRINT( "Something went wrong with stage2 startup!\r\n" )
@@ -163,7 +161,7 @@
STARTUP_PRINT( "unable to set seek end: %s\r\n", strerror( errno ) )
exit( 1 );
}
- size_t cmdline_size = ( size_t )position;
+ const size_t cmdline_size = ( size_t )position;
// reset back to beginning
if ( -1 == lseek( cmdline, 0, SEEK_SET ) ) {
STARTUP_PRINT( "unable to set seek start: %s\r\n", strerror( errno ) )
@@ -183,20 +181,6 @@
str[ cmdline_size ] = 0;
// print content
STARTUP_PRINT( "str: %s\r\n", str )
+ free( str );
STARTUP_PRINT( "continue with stage3!!!\r\n")
-
- // open dummy
- FILE* fp = fopen( "/boot/cmdline.txt", "r" );
- if ( ! fp ) {
- STARTUP_PRINT( "unable to open: %s\r\n", strerror( errno ) )
- exit( 1 );
- }
- // fork process
- pid_t boot_forked = fork();
- EARLY_STARTUP_PRINT( "error = %s\r\n", strerror( errno ) )
- EARLY_STARTUP_PRINT( "boot_forked = %d\r\n", boot_forked )
-
- for (;;) {
- __asm__ __volatile__ ( "nop" );
- }
}
diff --git a/bolthur/server/boot/init/stage3.c b/bolthur/server/boot/init/stage3.c
index 7bf118884..3c3b33907 100644
--- a/bolthur/server/boot/init/stage3.c
+++ b/bolthur/server/boot/init/stage3.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -21,11 +21,12 @@
#include
#include
#include
-#include
#include
-#include "../ramdisk.h"
+#include
+#include
+
+#include "../configuration.h"
#include "../init.h"
-#include "../util.h"
#include "../global.h"
/**
@@ -33,8 +34,35 @@
* @brief Final init stage starting servers from storage with finally starting shell
*/
[[noreturn]] void init_stage3( void ) {
+ // start servers by configuration
+ if ( ! configuration_handle( "/ramdisk/config/stage3.ini", nullptr ) ) {
+ EARLY_STARTUP_PRINT( "Something went wrong with stage3 startup!\r\n" )
+ exit( 1 );
+ }
+ EARLY_STARTUP_PRINT( "Starting login process\r\n" )
+/* // close device manager since everythig was fired up
+ close( fd_dev_manager );
+ // fork for starting the login shell
+ pid_t forked = fork();
+ if ( forked == 0 ) {
+ // build command
+ char* cmd[] = { "login", NULL, };
+ // exec to replace
+ if ( -1 == execv( "/bin/login", cmd ) ) {
+ EARLY_STARTUP_PRINT( "Error during exec, exiting: %s\r\n", strerror( errno ) )
+ exit( 1 );
+ }
+ }
+ if ( 0 > forked ) {
+ EARLY_STARTUP_PRINT( "Error while forking: %s\r\n", strerror( -forked ) )
+ }*/
+
+ EARLY_STARTUP_PRINT( "Looping till death\r\n" )
+ while ( true ) {
+ sleep( 10 );
+ __asm__ __volatile__( "nop" );
+ }
/// FIXME: Kill unnecessary ramdisk server again
- /// FIXME: Start authentication manager
/// FIXME: Start USB driver with all attached devices
/// FIXME: Start login console
diff --git a/bolthur/server/boot/main.c b/bolthur/server/boot/main.c
index 5cadcb671..69c96c75d 100644
--- a/bolthur/server/boot/main.c
+++ b/bolthur/server/boot/main.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -32,7 +32,6 @@
#include "ramdisk.h"
#include "util.h"
#include "init.h"
-#include "../libhelper.h"
#include "../libdev.h"
uintptr_t ramdisk_compressed;
diff --git a/bolthur/server/boot/ramdisk.h b/bolthur/server/boot/ramdisk.h
index 44f5049f7..6c3699066 100644
--- a/bolthur/server/boot/ramdisk.h
+++ b/bolthur/server/boot/ramdisk.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/boot/ramdisk/dump.c b/bolthur/server/boot/ramdisk/dump.c
index 7422be779..ec04990e5 100644
--- a/bolthur/server/boot/ramdisk/dump.c
+++ b/bolthur/server/boot/ramdisk/dump.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/boot/ramdisk/extract.c b/bolthur/server/boot/ramdisk/extract.c
index 38d976255..9978dfabc 100644
--- a/bolthur/server/boot/ramdisk/extract.c
+++ b/bolthur/server/boot/ramdisk/extract.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/boot/ramdisk/lookup.c b/bolthur/server/boot/ramdisk/lookup.c
index 580043913..e2f6054de 100644
--- a/bolthur/server/boot/ramdisk/lookup.c
+++ b/bolthur/server/boot/ramdisk/lookup.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/boot/ramdisk/size.c b/bolthur/server/boot/ramdisk/size.c
index c9730dd75..65e6e9d3d 100644
--- a/bolthur/server/boot/ramdisk/size.c
+++ b/bolthur/server/boot/ramdisk/size.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/boot/util.c b/bolthur/server/boot/util.c
index 0fafde2eb..7cb52a98b 100644
--- a/bolthur/server/boot/util.c
+++ b/bolthur/server/boot/util.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -22,8 +22,8 @@
#include
#include "util.h"
#include "global.h"
+#include "../../library/vfs/wait.h"
#include "../libdev.h"
-#include "../libhelper.h"
/**
* @fn pid_t util_execute_device_server(const char*, const char*, const char*)
@@ -41,37 +41,58 @@ pid_t util_execute_device_server(
) {
pid_t proc;
// calculate message size
- size_t msg_size = sizeof( dev_command_start_t );
+ size_t msg_size = sizeof( dev_command_start_data_t );
if ( args ) {
msg_size += sizeof( char ) * ( strlen( args ) + 1 );
} else {
msg_size += sizeof( char );
}
+ // allocate shared memory
+ const size_t shm_id = _syscall_memory_shared_create( msg_size );
+ // handle error
+ if ( errno ) {
+ // return error
+ return 0;
+ }
+ // attach shared memory
+ void* shm_addr = _syscall_memory_shared_attach( shm_id,
+ ( uintptr_t )NULL );
+ // handle error
+ if ( errno ) {
+ // return error
+ return 0;
+ }
+ // populate message data
+ auto const data = ( dev_command_start_data_t* )shm_addr;
+ strncpy( data->path, path, PATH_MAX - 1 );
+ if ( args ) {
+ strcpy( data->args, args );
+ }
// allocate message
- dev_command_start_t* start = malloc( msg_size );
+ dev_command_start_t* start = malloc( sizeof( *start ) );
// handle allocation failed
if ( ! start ) {
+ _syscall_memory_shared_detach( shm_id );
return 0;
}
// clear out
- memset( start, 0, msg_size );
- // prepare command content by copy path
- strncpy( start->path, path, PATH_MAX - 1 );
- // copy possible arguments
- if ( args ) {
- strcpy( start->args, args );
- }
+ memset( start, 0, sizeof( *start ) );
+ start->shm_id = shm_id;
+ start->data_size = msg_size;
// raise request
const int result = ioctl(
fd_dev_manager,
- IOCTL_BUILD_REQUEST( DEV_START, msg_size, IOCTL_RDWR ),
+ IOCTL_BUILD_REQUEST( DEV_START, sizeof( *start ), IOCTL_RDWR ),
start
);
// handle error
if ( -1 == result ) {
+ _syscall_memory_shared_detach( shm_id );
free( start );
return 0;
}
+ // detach shared memory
+ _syscall_memory_shared_detach( shm_id );
// extract process
memcpy( &proc, start, sizeof( proc ) );
// free ioctl start object
diff --git a/bolthur/server/boot/util.h b/bolthur/server/boot/util.h
index ae5b37980..4f200de84 100644
--- a/bolthur/server/boot/util.h
+++ b/bolthur/server/boot/util.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/config.h b/bolthur/server/config.h
index 6ce4c5466..1c00718c1 100644
--- a/bolthur/server/config.h
+++ b/bolthur/server/config.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/configure.ac b/bolthur/server/configure.ac
index 4da4fde8e..e4afc8841 100644
--- a/bolthur/server/configure.ac
+++ b/bolthur/server/configure.ac
@@ -3,7 +3,7 @@ AC_PREREQ([2.71])
AC_INIT([bolthur-server], [0.1.0-dev], [https://github.com/bolthur/kernel/issues], [bolthur-server], [https://github.com/bolthur/kernel])
-AC_COPYRIGHT([Copyright (C) 2018 - 2025 bolthur project])
+AC_COPYRIGHT([Copyright (C) 2018 - 2026 bolthur project])
AC_CONFIG_AUX_DIR([_aux/config])
AC_CONFIG_MACRO_DIR([../../build-aux/m4])
@@ -51,6 +51,24 @@ AC_ARG_WITH(
[with_debug_debug_symbols=yes]
)
+AC_ARG_WITH(
+ [ubsan],
+ AS_HELP_STRING(
+ [--with-ubsan],
+ [compile with ubsan enabled]
+ ),
+ [with_ubsan_enabled=yes]
+)
+
+AC_ARG_WITH(
+ [asan],
+ AS_HELP_STRING(
+ [--with-asan],
+ [compile with asan enabled]
+ ),
+ [with_asan_enabled=yes]
+)
+
# enable output and enable remote debugging together is not allowed
AS_IF([test "x$enable_debug" == "xyes" && test "x$enable_release" == "xyes"], [
AC_MSG_ERROR([Enabled debug and release are not possible at the same time])
@@ -162,6 +180,7 @@ AC_CONFIG_FILES([
usb/Makefile
usb/device/Makefile
usb/device/hid/Makefile
+ usb/device/hid/hid/Makefile
usb/device/hid/keyboard/Makefile
usb/device/hid/mouse/Makefile
usb/device/hub/Makefile
diff --git a/bolthur/server/console/Makefile.am b/bolthur/server/console/Makefile.am
index 7f0ff6850..d8adb921a 100644
--- a/bolthur/server/console/Makefile.am
+++ b/bolthur/server/console/Makefile.am
@@ -4,17 +4,26 @@ AM_CFLAGS = -DPROGRAM_NAME=\"console\"
bin_PROGRAMS = console
console_DEPENDENCIES = \
- ${abs_top_builddir}/../library/collection/list/liblist.la
+ ${abs_top_builddir}/../library/collection/list/liblist.la \
+ ${abs_top_builddir}/../library/vfs/libvfs.la
console_LDADD = \
- ${abs_top_builddir}/../library/collection/list/liblist.la
+ ${abs_top_builddir}/../library/collection/list/liblist.la \
+ ${abs_top_builddir}/../library/vfs/libvfs.la
console_SOURCES = \
rpc/custom/add.c \
+ rpc/custom/input.c \
rpc/custom/select.c \
+ rpc/close.c \
rpc/exec.c \
rpc/exit.c \
rpc/fork.c \
rpc/init.c \
+ rpc/open.c \
+ rpc/read.c \
rpc/write.c \
console.c \
- main.c
+ handler.c \
+ main.c \
+ queue.c \
+ terminal.c
console_LDFLAGS = -all-static --static
diff --git a/bolthur/server/console/config.ini b/bolthur/server/console/config.ini
index e39c4f0d6..7c41e2194 100644
--- a/bolthur/server/console/config.ini
+++ b/bolthur/server/console/config.ini
@@ -1,3 +1,3 @@
[general]
type=ramdisk_compressed
-path=ramdisk/server
+path=ramdisk/bin/server
diff --git a/bolthur/server/console/console.c b/bolthur/server/console/console.c
index f9d0e195d..3c8228790 100644
--- a/bolthur/server/console/console.c
+++ b/bolthur/server/console/console.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -19,7 +19,9 @@
#include
#include
+#include "queue.h"
#include "console.h"
+#include "handler.h"
/**
* @fn void console_destroy(console_t*)
@@ -31,9 +33,15 @@ void console_destroy( console_t* console ) {
if ( ! console ) {
return;
}
+ // cleanup possible listeners
+ queue_cleanup( console );
+ // free console path
if ( console->path ) {
free( console->path );
}
+ // remove from handler tree
+ handler_remove( console->handler );
+ // free console itself
free( console );
}
@@ -44,7 +52,7 @@ void console_destroy( console_t* console ) {
* @return
*/
console_t* console_get_active( void ) {
- list_item_t* current = console_list->first;
+ const list_item_t* current = console_list->first;
while ( current ) {
console_t* found = current->data;
if ( found->active ) {
@@ -52,7 +60,7 @@ console_t* console_get_active( void ) {
}
current = current->next;
}
- return NULL;
+ return nullptr;
}
/**
@@ -63,7 +71,7 @@ console_t* console_get_active( void ) {
* @return
*/
console_t* console_get_by_path( const char* path ) {
- list_item_t* current = console_list->first;
+ const list_item_t* current = console_list->first;
while ( current ) {
console_t* found = current->data;
if ( 0 == strcmp( found->path, path ) ) {
@@ -71,5 +79,5 @@ console_t* console_get_by_path( const char* path ) {
}
current = current->next;
}
- return NULL;
+ return nullptr;
}
diff --git a/bolthur/server/console/console.h b/bolthur/server/console/console.h
index 03e385e6a..e4b904883 100644
--- a/bolthur/server/console/console.h
+++ b/bolthur/server/console/console.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,8 +20,7 @@
#ifndef _CONSOLE_H
#define _CONSOLE_H
-#include
-#include
+#include
#include "../../library/collection/list/list.h"
typedef struct console {
diff --git a/bolthur/server/console/handler.c b/bolthur/server/console/handler.c
new file mode 100644
index 000000000..22b41733f
--- /dev/null
+++ b/bolthur/server/console/handler.c
@@ -0,0 +1,144 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include
+#include
+#include "handler.h"
+
+// define tree
+HANDLER_TREE_DEFINE(
+ handler_tree,
+ handler_node,
+ node,
+ handler_cmp,
+ [[maybe_unused]] static inline
+)
+
+/**
+ * @fn int handler_cmp(const struct handler_node*, const struct handler_node*)
+ * @brief Comparison function for tree
+ *
+ * @param a
+ * @param b
+ * @return
+ */
+int handler_cmp( const struct handler_node* a, const struct handler_node* b ) {
+ return a->process == b->process ? 0 : ( a->process > b->process ) ? 1 : -1;
+}
+
+// create static tree
+static struct handler_tree management_tree;
+
+/**
+ * @fn bool handler_setup(void)
+ * @brief mountpoint node setup
+ *
+ * @return
+ */
+bool handler_setup( void ) {
+ handler_node_tree_init( &management_tree );
+ return true;
+}
+
+/**
+ * @fn handler_node_t handler_extract*(const char*,bool)
+ * @brief Extract watch information by name
+ *
+ * @param process
+ * @param create
+ * @return
+ */
+handler_node_t* handler_extract( const pid_t process, const bool create ) {
+ // allocate node
+ handler_node_t* node = malloc( sizeof( *node ) );
+ // handle error
+ if ( ! node ) {
+ return NULL;
+ }
+ // clear out node
+ memset( node, 0, sizeof( *node ) );
+ // populate name
+ node->process = process;
+ // lookup for node
+ handler_node_t* found = handler_node_tree_find( &management_tree, node );
+ // insert if not existing
+ if ( ! found ) {
+ if ( ! create ) {
+ free( node );
+ return NULL;
+ }
+ if ( handler_node_tree_insert( &management_tree, node ) ) {
+ free( node );
+ return NULL;
+ }
+ return handler_node_tree_find( &management_tree, node );
+ }
+ // free up again
+ free( node );
+ // return found
+ return found;
+}
+
+/**
+ * @fn int handler_add(console_t*, pid_t)
+ * @brief Helper to add a watch node
+ *
+ * @param console
+ * @param process
+ * @return
+ */
+int handler_add( console_t* console, pid_t process ) {
+ // ensure that it doesn't exist
+ handler_node_t* node = handler_extract( process, false );
+ if ( node ) {
+ return -EEXIST;
+ }
+ // try to create it
+ node = handler_extract( process, true );
+ if ( ! node ) {
+ return -ENOMEM;
+ }
+ // allocate handler if not allocated
+ if ( ! node->console ) {
+ // duplicate string
+ node->console = console;
+ }
+ // return success
+ return 0;
+}
+
+/**
+ * @fn int handler_remove(pid_t)
+ * @brief Helper to remove a handler node
+ *
+ * @param process
+ * @return
+ */
+int handler_remove( const pid_t process ) {
+ handler_node_t* node = handler_extract( process, false );
+ if ( ! node ) {
+ return 0;
+ }
+ // remove node tree
+ handler_node_tree_remove( &management_tree, node );
+ // free node
+ free( node );
+ // return success
+ return 0;
+}
diff --git a/bolthur/server/console/handler.h b/bolthur/server/console/handler.h
new file mode 100644
index 000000000..984a53611
--- /dev/null
+++ b/bolthur/server/console/handler.h
@@ -0,0 +1,103 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#ifndef _HANDLER_H
+#define _HANDLER_H
+
+#define __PERMIT_DEPRECATED_SYS_TREE_H 1
+
+#include
+#include
+#include
+#include
+#include "console.h"
+
+#define HANDLER_TREE_DEFINE( name, type, field, cmp, attr ) \
+ SPLAY_HEAD( name, type ); \
+ SPLAY_PROTOTYPE( name, type, field, cmp ) \
+ SPLAY_GENERATE( name, type, field, cmp ) \
+ attr void type##_tree_init( struct name* t ) { \
+ SPLAY_INIT( t ); \
+ } \
+ attr int type##_tree_empty( struct name* t ) { \
+ return SPLAY_EMPTY( t ); \
+ } \
+ attr struct type* type##_tree_insert( struct name* t, struct type* e ) { \
+ return SPLAY_INSERT( name, t, e ); \
+ } \
+ attr struct type* type##_tree_remove( struct name* t, struct type* e ) { \
+ return SPLAY_REMOVE( name, t, e ); \
+ } \
+ attr struct type* type##_tree_find( struct name* t, struct type* e ) { \
+ return SPLAY_FIND( name, t, e ); \
+ } \
+ attr struct type* type##_tree_min( struct name* t ) { \
+ return SPLAY_MIN( name, t ); \
+ } \
+ attr struct type* type##_tree_max( struct name* t ) { \
+ return SPLAY_MAX( name, t ); \
+ } \
+ attr struct type* type##_tree_next( struct name* t, struct type* e ) { \
+ return SPLAY_NEXT( name, t, e ); \
+ } \
+ attr void type##_tree_apply( struct name* t, void( *cb )( struct type* ) ) { \
+ handler_tree_each( t, type, e, cb( e ) ); \
+ } \
+ attr void type##_tree_destroy( struct name* t, void( *free_cb )( struct type* ) ) { \
+ handler_tree_each_safe( t, type, e, free_cb( type##_tree_remove( t, e ) ) ); \
+ }
+
+#define handler_tree_each( t, type, e, block ) { \
+ struct type* e; \
+ for ( e = type##_tree_min( t ); e; e = type##_tree_next( t, e ) ) { \
+ block; \
+ }\
+ }
+
+#define handler_tree_each_safe( t, type, e, block ) { \
+ struct type* e; \
+ struct type* __tmp; \
+ for ( \
+ e = type##_tree_min( t ); \
+ e && ( __tmp = type##_tree_next( t, e ), e ); \
+ e = __tmp \
+ ) { \
+ block; \
+ }\
+ }
+
+typedef struct handler_node {
+ pid_t process;
+ console_t* console;
+ bool stdin_opened;
+ bool stdout_opened;
+ bool stderr_opened;
+ SPLAY_ENTRY( handler_node ) node;
+} handler_node_t;
+
+// comparison stuff for splay
+int handler_cmp( const struct handler_node*, const struct handler_node* );
+// generic stuff
+bool handler_setup( void );
+handler_node_t* handler_extract( pid_t, bool );
+int handler_add( console_t* console, pid_t );
+int handler_remove( pid_t );
+void handler_dump( void );
+
+#endif
diff --git a/bolthur/server/console/main.c b/bolthur/server/console/main.c
index 703110969..bff91754c 100644
--- a/bolthur/server/console/main.c
+++ b/bolthur/server/console/main.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -19,11 +19,13 @@
#include
#include "../libterminal.h"
-#include "../libhelper.h"
#include "../libconsole.h"
#include "../../library/collection/list/list.h"
+#include "../../library/vfs/dev.h"
#include "console.h"
+#include "handler.h"
#include "rpc.h"
+#include "queue.h"
list_manager_t* console_list = NULL;
@@ -70,6 +72,19 @@ int main( [[maybe_unused]] int argc, [[maybe_unused]] char* argv[] ) {
if ( ! console_list ) {
return -1;
}
+
+ // setup handler
+ EARLY_STARTUP_PRINT( "Setup handler tree\r\n" )
+ if ( ! handler_setup() ) {
+ return -1;
+ }
+
+ // setup queue
+ EARLY_STARTUP_PRINT( "Startup queue\r\n" )
+ if ( ! queue_setup() ) {
+ return -1;
+ }
+
// register rpc handler
EARLY_STARTUP_PRINT( "Setup rpc handler\r\n" )
if ( ! rpc_init() ) {
@@ -78,17 +93,17 @@ int main( [[maybe_unused]] int argc, [[maybe_unused]] char* argv[] ) {
}
// stdin device
- if ( !dev_add_file( "/dev/stdin", NULL, 0 ) ) {
+ if ( ! vfs_dev_add_file( "/dev/stdin", NULL, 0, nullptr ) ) {
EARLY_STARTUP_PRINT( "Unable to add dev fs\r\n" )
return -1;
}
// stdout device
- if ( !dev_add_file( "/dev/stdout", NULL, 0 ) ) {
+ if ( ! vfs_dev_add_file( "/dev/stdout", NULL, 0, nullptr ) ) {
EARLY_STARTUP_PRINT( "Unable to add dev fs\r\n" )
return -1;
}
// stderr device
- if ( !dev_add_file( "/dev/stderr", NULL, 0 ) ) {
+ if ( ! vfs_dev_add_file( "/dev/stderr", NULL, 0, nullptr ) ) {
EARLY_STARTUP_PRINT( "Unable to add dev fs\r\n" )
return -1;
}
@@ -98,8 +113,8 @@ int main( [[maybe_unused]] int argc, [[maybe_unused]] char* argv[] ) {
_syscall_rpc_set_ready( true );
// console device
- uint32_t device_info[] = { CONSOLE_ADD, CONSOLE_SELECT, };
- if ( !dev_add_file( "/dev/console", device_info, 2 ) ) {
+ constexpr uint32_t device_info[] = { CONSOLE_ADD, CONSOLE_SELECT, CONSOLE_INPUT, };
+ if ( ! vfs_dev_add_file( "/dev/console", device_info, 3, nullptr ) ) {
EARLY_STARTUP_PRINT( "Unable to add dev fs\r\n" )
return -1;
}
diff --git a/bolthur/server/console/queue.c b/bolthur/server/console/queue.c
new file mode 100644
index 000000000..ca3653258
--- /dev/null
+++ b/bolthur/server/console/queue.c
@@ -0,0 +1,148 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include
+#include "queue.h"
+
+static queue_head_t management_queue;
+
+/**
+ * @fn bool queue_setup(void)
+ * @brief queue setup
+ *
+ * @return
+ */
+bool queue_setup( void ) {
+ TAILQ_INIT( &management_queue );
+ return true;
+}
+
+/**
+ * @fn bool queue_push(size_t, size_t, vfs_read_request_t*, handler_node_t*)
+ * @brief
+ * @param type
+ * @param response_info
+ * @param request
+ * @param node
+ * @return
+ */
+bool queue_push( const size_t type, const size_t response_info, vfs_read_request_t* request, handler_node_t* node )
+{
+ // allocate node
+ queue_node_t* e = malloc( sizeof( queue_node_t ) );
+ if ( ! e ) {
+ return false;
+ }
+ // clear space
+ memset( e, 0, sizeof( queue_node_t ) );
+ // populate response and request
+ e->response_info = response_info;
+ e->request = request;
+ e->handler = node;
+ e->return_type = type;
+ TAILQ_INSERT_TAIL( &management_queue, e, node);
+ // return success
+ return true;
+}
+
+/**
+ * @fn bool queue_handle(const char*, const char*)
+ * @brief
+ * @param file file
+ * @param data data to process
+ * @return
+ */
+void queue_handle( const char* file, const char* data ) {
+ queue_node_t* e = NULL;
+ queue_node_t* next = NULL;
+ TAILQ_FOREACH_SAFE( e, &management_queue, node, next ) {
+ // handle path match and active console
+ if ( e->handler->console->active && 0 == strcmp( e->request->file_path, file ) ) {
+ char* area = _syscall_memory_shared_attach( e->request->shm_id, ( uintptr_t )NULL );
+ if ( area ) {
+ // get total len and evaluate to read
+ const size_t len = strlen( data );
+ size_t to_read = len;
+ if ( to_read > e->request->len - e->read_amount ) {
+ to_read = e->request->len - e->read_amount;
+ }
+ // check for newline
+ const char* newline = strstr( data, "\r\n" );
+ // subtract carriage return and newline
+ if ( newline ) {
+ to_read -= 2;
+ }
+ // copy over if there is something
+ if ( to_read ) {
+ memcpy( area + e->read_amount, data, to_read );
+ }
+ // increment read amount
+ e->read_amount += to_read;
+ // handle newline by set fulfilled
+ if ( newline ) {
+ ( area + e->read_amount )[ 0 ] = '\n';
+ ( area + e->read_amount )[ 1 ] = '\0';
+ e->read_amount += 2;
+ e->request->len = e->read_amount;
+ } else {
+ ( area + e->read_amount )[ 0 ] = '\0';
+ }
+ // detach again
+ _syscall_memory_shared_detach( e->request->shm_id );
+ // handle finished
+ if ( e->read_amount >= e->request->len ) {
+ // return to process
+ vfs_read_response_t response = { .len = ( ssize_t )e->read_amount };
+ bolthur_rpc_return(
+ e->return_type,
+ &response,
+ sizeof( response ),
+ NULL,
+ e->response_info
+ );
+ // remove from node
+ TAILQ_REMOVE(&management_queue, e, node);
+ // free up request and queue entry
+ free( e->request );
+ free( e );
+ }
+ }
+ }
+ }
+}
+
+/**
+ * @fn void queue_cleanup(const console_t*)
+ * @brief Cleanup queued input handlers for console
+ * @param console console to be cleaned up
+ */
+void queue_cleanup( const console_t* console ) {
+ queue_node_t* e = NULL;
+ queue_node_t* next = NULL;
+ TAILQ_FOREACH_SAFE( e, &management_queue, node, next ) {
+ // handle path match and active console
+ if ( e->handler->console == console ) {
+ // remove from node
+ TAILQ_REMOVE(&management_queue, e, node);
+ // free up request and queue entry
+ free( e->request );
+ free( e );
+ }
+ }
+}
diff --git a/bolthur/server/console/queue.h b/bolthur/server/console/queue.h
new file mode 100644
index 000000000..5fc475fee
--- /dev/null
+++ b/bolthur/server/console/queue.h
@@ -0,0 +1,44 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#ifndef _QUEUE_H
+#define _QUEUE_H
+
+#include
+#include
+#include "handler.h"
+
+typedef struct queue_node {
+ size_t return_type;
+ size_t response_info;
+ vfs_read_request_t* request;
+ size_t read_amount;
+ handler_node_t* handler;
+ TAILQ_ENTRY( queue_node ) node;
+} queue_node_t;
+
+typedef TAILQ_HEAD( queue_head, queue_node ) queue_head_t;
+
+// generic stuff
+bool queue_setup( void );
+bool queue_push( size_t, size_t, vfs_read_request_t*, handler_node_t* );
+void queue_handle( const char*, const char* );
+void queue_cleanup( const console_t* );
+
+#endif
diff --git a/bolthur/server/console/rpc.h b/bolthur/server/console/rpc.h
index cec69be0d..4b57cb625 100644
--- a/bolthur/server/console/rpc.h
+++ b/bolthur/server/console/rpc.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,17 +20,20 @@
#ifndef _RPC_H
#define _RPC_H
-#include
#include
#include "../../library/collection/list/list.h"
bool rpc_init( void );
-void rpc_handle_exec( size_t, pid_t,size_t, size_t );
-void rpc_handle_exit( size_t, pid_t,size_t, size_t );
+void rpc_handle_close( size_t, pid_t, size_t, size_t );
+void rpc_handle_exec( size_t, pid_t, size_t, size_t );
+void rpc_handle_exit( size_t, pid_t, size_t, size_t );
void rpc_handle_fork( size_t, pid_t, size_t, size_t );
+void rpc_handle_open( size_t, pid_t, size_t, size_t );
+void rpc_handle_read( size_t, pid_t, size_t, size_t );
void rpc_handle_write( size_t, pid_t, size_t, size_t );
void rpc_custom_handle_console_add( size_t, pid_t, size_t, size_t );
+void rpc_custom_handle_input( size_t, pid_t, size_t, size_t );
void rpc_custom_handle_console_select( size_t, pid_t, size_t, size_t );
#endif
diff --git a/bolthur/server/console/rpc/close.c b/bolthur/server/console/rpc/close.c
new file mode 100644
index 000000000..317e928dc
--- /dev/null
+++ b/bolthur/server/console/rpc/close.c
@@ -0,0 +1,76 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include
+#include
+#include "../rpc.h"
+#include "../handler.h"
+
+/**
+ * @fn void rpc_handle_fork(size_t, pid_t, size_t, size_t)
+ * @brief handle fork request
+ *
+ * @param type
+ * @param origin
+ * @param data_info
+ * @param response_info
+ */
+void rpc_handle_close(
+ size_t type,
+ pid_t origin,
+ size_t data_info,
+ [[maybe_unused]] size_t response_info
+) {
+ vfs_close_response_t response = { .status = -EINVAL };
+ // validate origin
+ if ( ! bolthur_rpc_validate_origin( origin, data_info ) ) {
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ return;
+ }
+ // handle no data
+ if ( ! data_info ) {
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ return;
+ }
+ size_t data_size;
+ vfs_close_request_t* request = bolthur_rpc_fetch_from_mailbox( data_info, &data_size, true, NULL );
+ if ( ! request ) {
+ response.status = -errno;
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ return;
+ }
+ // get handler
+ handler_node_t* handler = handler_extract( request->origin, true );
+ if ( ! handler ) {
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ free( request );
+ return;
+ }
+ // copy over stuff, return and free
+ if (request->handle == STDIN_FILENO) {
+ handler->stdin_opened = false;
+ } else if (request->handle == STDOUT_FILENO) {
+ handler->stdout_opened = false;
+ } else {
+ handler->stderr_opened = false;
+ }
+ response.status = 0;
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ free( request );
+}
diff --git a/bolthur/server/console/rpc/custom/add.c b/bolthur/server/console/rpc/custom/add.c
index 7b187bf2e..40a9175f7 100644
--- a/bolthur/server/console/rpc/custom/add.c
+++ b/bolthur/server/console/rpc/custom/add.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -47,7 +47,7 @@ void rpc_custom_handle_console_add(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
return;
}
@@ -60,9 +60,9 @@ void rpc_custom_handle_console_add(
return;
}
// allocate for data fetching
- console_command_add_t* command = ( console_command_add_t* )request->container;
+ auto const command = ( console_command_add_t* )request->container;
// try to lookup by name
- list_item_t* container_item = list_lookup_data(
+ const list_item_t* container_item = list_lookup_data(
console_list,
command->terminal
);
diff --git a/bolthur/server/console/rpc/custom/input.c b/bolthur/server/console/rpc/custom/input.c
new file mode 100644
index 000000000..422a7f785
--- /dev/null
+++ b/bolthur/server/console/rpc/custom/input.c
@@ -0,0 +1,82 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include
+#include
+#include
+#include "../../../libconsole.h"
+#include "../../rpc.h"
+#include "../../console.h"
+#include "../../queue.h"
+#include "../../../libterminal.h"
+
+/**
+ * @fn void rpc_custom_handle_input(size_t, pid_t, size_t, size_t)
+ * @brief Console handle input command handler
+ *
+ * @param type
+ * @param origin
+ * @param data_info
+ * @param response_info
+ */
+void rpc_custom_handle_input(
+ [[maybe_unused]] size_t type,
+ pid_t origin,
+ size_t data_info,
+ [[maybe_unused]] size_t response_info
+) {
+ vfs_ioctl_perform_response_t error = { .status = -EINVAL };
+ // validate origin
+ if ( ! bolthur_rpc_validate_origin( origin, data_info ) ) {
+ bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
+ return;
+ }
+ // handle no data
+ if ( ! data_info ) {
+ bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
+ return;
+ }
+ // get message and data size
+ size_t data_size;
+ vfs_ioctl_perform_request_t* request = bolthur_rpc_fetch_from_mailbox( data_info, &data_size, true, NULL );
+ if ( ! request ) {
+ error.status = -errno;
+ bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
+ return;
+ }
+ // allocate for data fetching
+ auto const command = ( console_command_input_t* )request->container;
+ // get active console and deactivate
+ console_t* console = console_get_active();
+ if ( ! console ) {
+ error.status = -errno;
+ bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
+ return;
+ }
+ // set success flag and return before handling anything else
+ error.status = 0;
+ bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
+ // debug print buffer
+ EARLY_STARTUP_PRINT( "%s\r\n", command->input );
+ // route to listening process
+ queue_handle( "/dev/stdin", command->input );
+ /// FIXME: ROUTE TO TERMINAL OUT
+ // free all used temporary structures
+ free( request );
+}
diff --git a/bolthur/server/console/rpc/custom/select.c b/bolthur/server/console/rpc/custom/select.c
index 695be34d9..ecaa68443 100644
--- a/bolthur/server/console/rpc/custom/select.c
+++ b/bolthur/server/console/rpc/custom/select.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -46,7 +46,7 @@ void rpc_custom_handle_console_select(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
return;
}
@@ -59,7 +59,7 @@ void rpc_custom_handle_console_select(
return;
}
// allocate for data fetching
- console_command_select_t* command = ( console_command_select_t* )request->container;
+ auto const command = ( console_command_select_t* )request->container;
// try to lookup by name
list_item_t* found = list_lookup_data( console_list, command->path );
// handle already existing
diff --git a/bolthur/server/console/rpc/exec.c b/bolthur/server/console/rpc/exec.c
index e4f43e2b8..1f10383ed 100644
--- a/bolthur/server/console/rpc/exec.c
+++ b/bolthur/server/console/rpc/exec.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -32,7 +32,7 @@
*/
void rpc_handle_exec(
size_t type,
- [[maybe_unused]] pid_t origin,
+ [[maybe_unused]] pid_t origin,
size_t data_info,
[[maybe_unused]] size_t response_info
) {
@@ -40,7 +40,7 @@ void rpc_handle_exec(
// dummy error response
vfs_exec_response_t response = { .result = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/console/rpc/exit.c b/bolthur/server/console/rpc/exit.c
index e21b3b421..1c766f6ad 100644
--- a/bolthur/server/console/rpc/exit.c
+++ b/bolthur/server/console/rpc/exit.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,6 +20,7 @@
#include
#include
#include "../rpc.h"
+#include "../handler.h"
/**
* @fn void rpc_handle_exit(size_t, pid_t, size_t, size_t)
@@ -32,14 +33,14 @@
*/
void rpc_handle_exit(
size_t type,
- [[maybe_unused]] pid_t origin,
+ [[maybe_unused]] pid_t origin,
size_t data_info,
[[maybe_unused]] size_t response_info
) {
// dummy error response
vfs_exit_response_t response = { .result = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
@@ -51,8 +52,8 @@ void rpc_handle_exit(
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
- // return success
- response.result = 0;
+ // remove possible console handling
+ response.result = handler_remove( request->origin );
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
// free request
free( request );
diff --git a/bolthur/server/console/rpc/fork.c b/bolthur/server/console/rpc/fork.c
index b60e3432a..e81a2c429 100644
--- a/bolthur/server/console/rpc/fork.c
+++ b/bolthur/server/console/rpc/fork.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,6 +20,7 @@
#include
#include
#include "../rpc.h"
+#include "../handler.h"
/**
* @fn void rpc_handle_fork(size_t, pid_t, size_t, size_t)
@@ -32,14 +33,14 @@
*/
void rpc_handle_fork(
size_t type,
- [[maybe_unused]] pid_t origin,
+ [[maybe_unused]] pid_t origin,
size_t data_info,
[[maybe_unused]] size_t response_info
) {
// dummy error response
vfs_fork_response_t response = { .status = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
@@ -51,6 +52,36 @@ void rpc_handle_fork(
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
+ // create new handler
+ handler_node_t* handler = handler_extract( request->process, true );
+ if ( ! handler ) {
+ response.status = -ENOMEM;
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ return;
+ }
+ // get parent
+ handler_node_t* parent = handler_extract( request->parent, true );
+ if ( ! parent ) {
+ handler_remove( request->process );
+ response.status = -EIO;
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ return;
+ }
+ // set console of parent
+ handler->console = parent->console;
+ // set current active one if nothing was set
+ if ( ! handler->console ) {
+ // get current active console
+ console_t* console = console_get_active();
+ if ( ! console ) {
+ response.status = -EIO;
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ free( request );
+ return;
+ }
+ // set both to current console
+ handler->console = parent->console = console;
+ }
// return success
response.status = 0;
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
diff --git a/bolthur/server/console/rpc/init.c b/bolthur/server/console/rpc/init.c
index 68aaa4958..ad4757dac 100644
--- a/bolthur/server/console/rpc/init.c
+++ b/bolthur/server/console/rpc/init.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -28,6 +28,11 @@
* @return
*/
bool rpc_init( void ) {
+ bolthur_rpc_bind( RPC_VFS_CLOSE, rpc_handle_close, true );
+ if ( errno ) {
+ EARLY_STARTUP_PRINT( "Unable to register handler close!\r\n" )
+ return false;
+ }
bolthur_rpc_bind( RPC_VFS_EXEC, rpc_handle_exec, true );
if ( errno ) {
EARLY_STARTUP_PRINT( "Unable to register handler exec!\r\n" )
@@ -43,6 +48,16 @@ bool rpc_init( void ) {
EARLY_STARTUP_PRINT( "Unable to register handler fork!\r\n" )
return false;
}
+ bolthur_rpc_bind( RPC_VFS_OPEN, rpc_handle_open, true );
+ if ( errno ) {
+ EARLY_STARTUP_PRINT( "Unable to register handler open!\r\n" )
+ return false;
+ }
+ bolthur_rpc_bind( RPC_VFS_READ, rpc_handle_read, true );
+ if ( errno ) {
+ EARLY_STARTUP_PRINT( "Unable to register handler read!\r\n" )
+ return false;
+ }
bolthur_rpc_bind( RPC_VFS_WRITE, rpc_handle_write, true );
if ( errno ) {
EARLY_STARTUP_PRINT( "Unable to register handler write!\r\n" )
@@ -53,6 +68,11 @@ bool rpc_init( void ) {
EARLY_STARTUP_PRINT( "Unable to register handler console add!\r\n" )
return false;
}
+ bolthur_rpc_bind( CONSOLE_INPUT, rpc_custom_handle_input, true );
+ if ( errno ) {
+ EARLY_STARTUP_PRINT( "Unable to register handler console input!\r\n" )
+ return false;
+ }
bolthur_rpc_bind( CONSOLE_SELECT, rpc_custom_handle_console_select, true );
if ( errno ) {
EARLY_STARTUP_PRINT( "Unable to register handler console select!\r\n" )
diff --git a/bolthur/server/console/rpc/open.c b/bolthur/server/console/rpc/open.c
new file mode 100644
index 000000000..c089cce42
--- /dev/null
+++ b/bolthur/server/console/rpc/open.c
@@ -0,0 +1,79 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include
+#include
+#include "../rpc.h"
+#include "../handler.h"
+
+/**
+ * @fn void rpc_handle_fork(size_t, pid_t, size_t, size_t)
+ * @brief handle fork request
+ *
+ * @param type
+ * @param origin
+ * @param data_info
+ * @param response_info
+ */
+void rpc_handle_open(
+ size_t type,
+ pid_t origin,
+ size_t data_info,
+ [[maybe_unused]] size_t response_info
+) {
+ vfs_open_response_t response = { .handle = -EINVAL };
+ // validate origin
+ if ( ! bolthur_rpc_validate_origin( origin, data_info ) ) {
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ return;
+ }
+ // handle no data
+ if ( ! data_info ) {
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ return;
+ }
+ size_t data_size;
+ vfs_open_request_t* request = bolthur_rpc_fetch_from_mailbox( data_info, &data_size, true, NULL );
+ if ( ! request ) {
+ response.handle = -errno;
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ return;
+ }
+ // get handler
+ handler_node_t* handler = handler_extract( request->origin, true );
+ if ( ! handler ) {
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ free( request );
+ return;
+ }
+ // copy over stuff, return and free
+ if ( 0 == strcmp( request->path, "/dev/stdin" ) ) {
+ response.handle = STDIN_FILENO;
+ handler->stdin_opened = true;
+ } else if ( 0 == strcmp( request->path, "/dev/stdout" ) ) {
+ response.handle = STDOUT_FILENO;
+ handler->stdout_opened = true;
+ } else {
+ response.handle = STDERR_FILENO;
+ handler->stderr_opened = true;
+ }
+ response.handler = getpid();
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ free( request );
+}
diff --git a/bolthur/server/console/rpc/read.c b/bolthur/server/console/rpc/read.c
new file mode 100644
index 000000000..a2a66dd77
--- /dev/null
+++ b/bolthur/server/console/rpc/read.c
@@ -0,0 +1,69 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include
+#include
+
+#include "../queue.h"
+#include "../rpc.h"
+#include "../handler.h"
+
+/**
+ * @fn void rpc_handle_read(size_t, pid_t, size_t, size_t)
+ * @brief Handle read request
+ *
+ * @param type
+ * @param origin
+ * @param data_info
+ * @param response_info
+ */
+void rpc_handle_read(
+ size_t type,
+ pid_t origin,
+ size_t data_info,
+ size_t response_info
+) {
+ vfs_read_response_t response = { .len = -EINVAL };
+ // validate origin
+ if ( ! bolthur_rpc_validate_origin( origin, data_info ) ) {
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ return;
+ }
+ // handle no data
+ if ( ! data_info ) {
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ return;
+ }
+ size_t data_size;
+ vfs_read_request_t* request = bolthur_rpc_fetch_from_mailbox( data_info, &data_size, true, NULL );
+ if ( ! request ) {
+ response.len = -errno;
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ return;
+ }
+ // get handler
+ handler_node_t* handler = handler_extract( request->origin, true );
+ if ( ! handler ) {
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ free( request );
+ return;
+ }
+ // push to queue
+ queue_push( type, response_info, request, handler );
+}
diff --git a/bolthur/server/console/rpc/write.c b/bolthur/server/console/rpc/write.c
index 8f48467d1..466b69aed 100644
--- a/bolthur/server/console/rpc/write.c
+++ b/bolthur/server/console/rpc/write.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -23,10 +23,59 @@
#include
#include
#include "../../libterminal.h"
-#include "../../libconsole.h"
#include "../rpc.h"
#include "../../../library/collection/list/list.h"
#include "../console.h"
+#include "../handler.h"
+
+/**
+ * @fn void rpc_handle_write_cleanup(size_t, pid_t, size_t, size_t)
+ * @brief Async write cleanup
+ * @param type
+ * @param origin
+ * @param data_info
+ * @param response_info
+ */
+static void rpc_handle_write_cleanup(
+ [[maybe_unused]] size_t type,
+ [[maybe_unused]] pid_t origin,
+ size_t data_info,
+ size_t response_info
+) {
+ // get matching async data
+ bolthur_async_data_t* async_data = bolthur_rpc_pop_async( RPC_VFS_WRITE, response_info );
+ // handle no async data
+ if ( ! async_data ) {
+ // cleanup
+ _syscall_rpc_cleanup();
+ // skip rest
+ return;
+ }
+ // handle no data
+ if ( ! data_info ) {
+ // cleanup
+ _syscall_rpc_cleanup();
+ bolthur_rpc_destroy_async( async_data );
+ // skip rest
+ return;
+ }
+ // get message and data size
+ size_t data_size;
+ vfs_ioctl_perform_request_t* response = bolthur_rpc_fetch_from_mailbox( data_info, &data_size, true, NULL );
+ if ( ! response ) {
+ // cleanup
+ bolthur_rpc_destroy_async( async_data );
+ _syscall_rpc_cleanup();
+ // skip rest
+ return;
+ }
+ // detach shared memory from original request
+ const vfs_write_request_t* original_request = async_data->original_data;
+ _syscall_memory_shared_detach( original_request->shm_id );
+ bolthur_rpc_destroy_async( async_data );
+ free( response );
+ _syscall_rpc_cleanup();
+}
/**
* @fn void rpc_handle_write(size_t, pid_t, size_t, size_t)
@@ -50,7 +99,7 @@ void rpc_handle_write(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
@@ -62,69 +111,125 @@ void rpc_handle_write(
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
- // get current active console
- console_t* console = console_get_active();
- if ( ! console ) {
- response.len = -EIO;
+ const pid_t root_origin = request->origin;
+ handler_node_t* handler = handler_extract( root_origin, true );
+ if ( ! handler ) {
+ response.len = -ENOMEM;
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ return;
+ }
+ // set console if not set
+ if ( ! handler->console ) {
+ // get current active console
+ console_t* console = console_get_active();
+ if ( ! console ) {
+ response.len = -EIO;
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ free( request );
+ return;
+ }
+ // set console
+ handler->console = console;
+ }
+ // get output stuff
+ const char* toWrite = _syscall_memory_shared_attach( request->shm_id, ( uintptr_t )NULL );
+ if ( errno ) {
+ response.len = -errno;
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
free( request );
return;
}
// get rpc to raise
const size_t rpc_num = 0 == strcmp( "/dev/stdout", request->file_path )
- ? console->out
- : console->err;
+ ? handler->console->out
+ : handler->console->err;
// build terminal command
- const size_t terminal_size = sizeof( terminal_write_request_t ) + request->len;
+ const size_t terminal_size = sizeof( terminal_write_request_t ) +
+ sizeof( char ) * ( strlen(handler->console->path) + 1 );
terminal_write_request_t* terminal = malloc( terminal_size );
if ( ! terminal ) {
- response.len = -EIO;
+ response.len = -ENOMEM;
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ _syscall_memory_shared_detach( request->shm_id );
free( request );
return;
}
-
+ // clear out memory
memset( terminal, 0, terminal_size );
+ // populate terminal
terminal->len = request->len;
terminal->shm_id = request->shm_id;
- strncpy( terminal->terminal, console->path, PATH_MAX - 1 );
-
- if ( 0 == console->fd ) {
+ strcpy( terminal->terminal, handler->console->path );
+ // handle not yet opened
+ if ( 0 == handler->console->fd ) {
// open path
- const int fd = open( console->path, O_RDWR );
+ const int fd = open( handler->console->path, O_RDWR );
// handle error
if ( -1 == fd ) {
- EARLY_STARTUP_PRINT( "Unable to open %s\r\n", console->path )
response.len = -EIO;
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ _syscall_memory_shared_detach( request->shm_id );
free( terminal );
free( request );
return;
}
// push back file handle
- console->fd = fd;
+ handler->console->fd = fd;
}
- // raise write request
- const int result = ioctl(
- console->fd,
- IOCTL_BUILD_REQUEST(
- rpc_num,
- terminal_size,
- IOCTL_RDWR
- ),
- terminal
+ // calculate rpc request size
+ size_t rpc_request_size = sizeof( vfs_ioctl_perform_request_t );
+ // add data to ioctl if existing
+ rpc_request_size += terminal_size * sizeof( char );
+ // allocate rpc structures
+ vfs_ioctl_perform_request_t* rpc_request = malloc( rpc_request_size );
+ if ( ! rpc_request ) {
+ response.len = -ENOMEM;
+ bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ _syscall_memory_shared_detach( request->shm_id );
+ free( request );
+ free( terminal );
+ return;
+ }
+ // clear rpc structures
+ memset( rpc_request, 0, rpc_request_size );
+ // populate structure
+ rpc_request->handle = handler->console->fd;
+ rpc_request->command = rpc_num;
+ rpc_request->type = IOCTL_RDWR;
+ // push data if set / passed
+ memcpy( rpc_request->container, terminal, terminal_size * sizeof( char ) );
+ // route request to mount point
+ bolthur_rpc_raise(
+ RPC_VFS_IOCTL,
+ handler->console->handler,
+ rpc_request,
+ rpc_request_size,
+ rpc_handle_write_cleanup,
+ RPC_VFS_WRITE,
+ request,
+ data_size,
+ 0,
+ 0,
+ NULL,
+ false
);
// handle error
- if ( -1 == result ) {
- response.len = -EIO;
+ if ( errno ) {
+ const int e = errno;
+ EARLY_STARTUP_PRINT( "Failed to invoke rpc: %s\r\n", strerror( e ) );
+ response.len = -e;
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
- free( terminal );
+ _syscall_memory_shared_detach( request->shm_id );
free( request );
+ free( terminal );
+ free( rpc_request );
return;
}
- // prepare return
- response.len = *( ( int* )terminal );
+ // return written amount
+ response.len = ( ssize_t )strlen( toWrite );
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
+ // free up stuff
free( terminal );
free( request );
+ free( rpc_request );
}
diff --git a/bolthur/server/console/terminal.c b/bolthur/server/console/terminal.c
new file mode 100644
index 000000000..2bfbbb888
--- /dev/null
+++ b/bolthur/server/console/terminal.c
@@ -0,0 +1,28 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#include "terminal.h"
+
+/**
+ * @fn void terminal_push_data(const char*)
+ * @brief Push to terminal with fire and forget
+ * @param data
+ */
+void terminal_push_data( [[maybe_unused]] const char* data ) {
+}
diff --git a/bolthur/server/console/terminal.h b/bolthur/server/console/terminal.h
new file mode 100644
index 000000000..edb2cb46b
--- /dev/null
+++ b/bolthur/server/console/terminal.h
@@ -0,0 +1,25 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#ifndef _TERMINAL_H
+#define _TERMINAL_H
+
+void terminal_push_data( const char* );
+
+#endif
diff --git a/bolthur/server/fs/dev/Makefile.am b/bolthur/server/fs/dev/Makefile.am
index fe4fbe80f..726696f8d 100644
--- a/bolthur/server/fs/dev/Makefile.am
+++ b/bolthur/server/fs/dev/Makefile.am
@@ -4,10 +4,12 @@ AM_CFLAGS = -DPROGRAM_NAME=\"fs/dev\"
bin_PROGRAMS = dev
dev_DEPENDENCIES = \
${abs_top_builddir}/../library/collection/list/liblist.la \
- ${abs_top_builddir}/../library/collection/avl/libavl.la
+ ${abs_top_builddir}/../library/collection/avl/libavl.la \
+ ${abs_top_builddir}/../library/vfs/libvfs.la
dev_LDADD = \
${abs_top_builddir}/../library/collection/list/liblist.la \
- ${abs_top_builddir}/../library/collection/avl/libavl.la
+ ${abs_top_builddir}/../library/collection/avl/libavl.la \
+ ${abs_top_builddir}/../library/vfs/libvfs.la
dev_SOURCES = \
ioctl/handler.c \
rpc/custom/kill.c \
diff --git a/bolthur/server/fs/dev/config.ini b/bolthur/server/fs/dev/config.ini
index a787604ef..9d819d98d 100644
--- a/bolthur/server/fs/dev/config.ini
+++ b/bolthur/server/fs/dev/config.ini
@@ -1,3 +1,3 @@
[general]
type=ramdisk_compressed
-path=ramdisk/server/fs
+path=ramdisk/bin/server/fs
diff --git a/bolthur/server/fs/dev/dev.h b/bolthur/server/fs/dev/dev.h
index 991b03b17..d2c4c7a9c 100644
--- a/bolthur/server/fs/dev/dev.h
+++ b/bolthur/server/fs/dev/dev.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _DEV_H
#define _DEV_H
-#include
#include
#define MOUNT_POINT_DESTINATION "/dev"
diff --git a/bolthur/server/fs/dev/handle.c b/bolthur/server/fs/dev/handle.c
index 81851917c..98a33d462 100644
--- a/bolthur/server/fs/dev/handle.c
+++ b/bolthur/server/fs/dev/handle.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/dev/handle.h b/bolthur/server/fs/dev/handle.h
index e73d78884..cad0f44cf 100644
--- a/bolthur/server/fs/dev/handle.h
+++ b/bolthur/server/fs/dev/handle.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/dev/ioctl/handler.c b/bolthur/server/fs/dev/ioctl/handler.c
index ba8b1de7b..1d81431ea 100644
--- a/bolthur/server/fs/dev/ioctl/handler.c
+++ b/bolthur/server/fs/dev/ioctl/handler.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -37,8 +37,8 @@ static int32_t compare_ioctl(
const avl_node_t* node_a,
const avl_node_t* node_b
) {
- ioctl_tree_entry_t* container_a = IOCTL_HANDLER_GET_ENTRY( node_a );
- ioctl_tree_entry_t* container_b = IOCTL_HANDLER_GET_ENTRY( node_b );
+ auto const container_a = IOCTL_HANDLER_GET_ENTRY( node_a );
+ auto const container_b = IOCTL_HANDLER_GET_ENTRY( node_b );
// return 0 if equal
if ( container_a->pid == container_b->pid ) {
return 0;
@@ -59,8 +59,8 @@ static int32_t lookup_ioctl(
const avl_node_t* node,
const void* value
) {
- pid_t pid = ( pid_t )value;
- ioctl_tree_entry_t* container = IOCTL_HANDLER_GET_ENTRY( node );
+ const pid_t pid = ( pid_t )value;
+ auto const container = IOCTL_HANDLER_GET_ENTRY( node );
// return 0 if equal
if ( container->pid == pid ) {
return 0;
@@ -76,7 +76,7 @@ static int32_t lookup_ioctl(
* @param node
*/
static void cleanup_ioctl( avl_node_t* node ) {
- ioctl_tree_entry_t* item = IOCTL_HANDLER_GET_ENTRY( node );
+ auto item = IOCTL_HANDLER_GET_ENTRY( node );
// destroy tree
avl_destroy_tree( item->tree );
// free item
@@ -95,8 +95,8 @@ static int32_t compare_container(
const avl_node_t* node_a,
const avl_node_t* node_b
) {
- ioctl_container_t* container_a = IOCTL_HANDLER_GET_CONTAINER( node_a );
- ioctl_container_t* container_b = IOCTL_HANDLER_GET_CONTAINER( node_b );
+ auto const container_a = IOCTL_HANDLER_GET_CONTAINER( node_a );
+ auto const container_b = IOCTL_HANDLER_GET_CONTAINER( node_b );
// return 0 if equal
if ( container_a->command == container_b->command ) {
return 0;
@@ -117,8 +117,8 @@ static int32_t lookup_container(
const avl_node_t* node,
const void* value
) {
- uint32_t command = ( uint32_t )value;
- ioctl_container_t* container = IOCTL_HANDLER_GET_CONTAINER( node );
+ const uint32_t command = ( uint32_t )value;
+ auto const container = IOCTL_HANDLER_GET_CONTAINER( node );
// return 0 if equal
if ( container->command == command ) {
return 0;
@@ -134,7 +134,7 @@ static int32_t lookup_container(
* @param node
*/
static void cleanup_container( avl_node_t* node ) {
- ioctl_container_t* item = IOCTL_HANDLER_GET_CONTAINER( node );
+ auto const item = IOCTL_HANDLER_GET_CONTAINER( node );
// free item
free( item );
}
@@ -160,12 +160,12 @@ bool ioctl_handler_init( void ) {
* @brief Helper for command lookup
*
* @param command
- * @param handle
+ * @param process
* @return
*/
ioctl_container_t* ioctl_lookup_command(
- uint32_t command,
- pid_t process
+ const uint32_t command,
+ const pid_t process
) {
// try to find command within tree before querying info
avl_node_t* found = avl_find_by_data(
@@ -177,7 +177,7 @@ ioctl_container_t* ioctl_lookup_command(
return NULL;
}
// get entry
- ioctl_tree_entry_t* entry = IOCTL_HANDLER_GET_ENTRY( found );
+ auto const entry = IOCTL_HANDLER_GET_ENTRY( found );
// lookup command
found = avl_find_by_data(
entry->tree,
@@ -196,12 +196,12 @@ ioctl_container_t* ioctl_lookup_command(
* @brief Push command for process
*
* @param command
- * @param handle
+ * @param process
* @return
*/
bool ioctl_push_command(
- uint32_t command,
- pid_t process
+ const uint32_t command,
+ const pid_t process
) {
// treat existing commands already pushed / success
if ( ioctl_lookup_command( command, process ) ) {
diff --git a/bolthur/server/fs/dev/ioctl/handler.h b/bolthur/server/fs/dev/ioctl/handler.h
index f11bcfd76..c641f9410 100644
--- a/bolthur/server/fs/dev/ioctl/handler.h
+++ b/bolthur/server/fs/dev/ioctl/handler.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/dev/main.c b/bolthur/server/fs/dev/main.c
index b7d78907c..694879309 100644
--- a/bolthur/server/fs/dev/main.c
+++ b/bolthur/server/fs/dev/main.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -26,12 +26,47 @@
#include "rpc.h"
#include "handle.h"
#include "ioctl/handler.h"
-#include "../../libhelper.h"
#include "../../libdev.h"
-#include "../../../library/collection/list/list.h"
+#include "../../../library/vfs/wait.h"
+#include "../../../library/vfs/dev.h"
#include "dev.h"
#include "watch.h"
+/**
+ * @fn void on_folder_file_added(size_t, pid_t, size_t, size_t)
+ * @brief On file or folder added callback
+ * @param type
+ * @param origin
+ * @param data_info
+ * @param response_info
+ */
+static void on_folder_file_added(
+ [[maybe_unused]] size_t type,
+ [[maybe_unused]] pid_t origin,
+ size_t data_info,
+ [[maybe_unused]] size_t response_info
+) {
+ // handle no data
+ if ( ! data_info ) {
+ EARLY_STARTUP_PRINT( "No data info found!\r\n" )
+ exit( -1 );
+ }
+ // get message and data size
+ size_t data_size;
+ vfs_add_response_t* response = bolthur_rpc_fetch_from_mailbox( data_info, &data_size, true, NULL );
+ if ( ! response ) {
+ const int e = errno;
+ EARLY_STARTUP_PRINT( "Unable to fetch response: %s\r\n", strerror( e ) )
+ exit( -1 );
+ }
+ // stop on success
+ if ( VFS_ADD_SUCCESS != response->status ) {
+ EARLY_STARTUP_PRINT( "Unable to add: %d\r\n", response->status )
+ exit( -1 );
+ }
+ free( response );
+}
+
/**
* @fn int main(int, char*[])
* @brief main entry point
@@ -93,25 +128,30 @@ int main( [[maybe_unused]] int argc, [[maybe_unused]] char* argv[] ) {
_syscall_rpc_set_ready( true );
// device info data
- uint32_t device_info[] = { DEV_START, DEV_KILL, };
+ constexpr uint32_t device_info[] = { DEV_START, DEV_KILL, };
- // add manager subfolder
- if ( !dev_add_folder( "/dev/manager", NULL, 0 ) ) {
+ // add manager subfolder with wait for path
+ if ( ! vfs_dev_add_folder( "/dev/manager", nullptr, 0, on_folder_file_added ) ) {
EARLY_STARTUP_PRINT( "Unable to add manager subfolder\r\n" )
return -1;
}
- // add storage subfolder
- if ( !dev_add_folder( "/dev/storage", NULL, 0 ) ) {
+ vfs_wait_for_path( "/dev/manager" );
+ // add storage subfolder with wait for path
+ if ( ! vfs_dev_add_folder( "/dev/storage", nullptr, 0, on_folder_file_added ) ) {
EARLY_STARTUP_PRINT( "Unable to add storage subfolder\r\n" )
return -1;
}
- // add usb subfolder
- if ( ! dev_add_folder( "/dev/usb", NULL, 0 ) ) {
+ vfs_wait_for_path( "/dev/storage" );
+ // add usb subfolder with wait for path
+ if ( ! vfs_dev_add_folder( "/dev/usb", nullptr, 0, on_folder_file_added ) ) {
EARLY_STARTUP_PRINT( "Unable to add USB subfolder\r\n" )
return -1;
}
- // add device file
- if ( !dev_add_file( "/dev/manager/device", device_info, 2 ) ) {
+ vfs_wait_for_path( "/dev/usb" );
+ // add device file without wait for file since everything else is blocked
+ // in early stage by /dev/manager/device and a wait for path would result
+ // in possible locked up dev daemon
+ if ( ! vfs_dev_add_file( "/dev/manager/device", device_info, 2, on_folder_file_added ) ) {
EARLY_STARTUP_PRINT( "Unable to add storage subfolder\r\n" )
return -1;
}
diff --git a/bolthur/server/fs/dev/rpc.h b/bolthur/server/fs/dev/rpc.h
index 99ccc7f37..03aa4640a 100644
--- a/bolthur/server/fs/dev/rpc.h
+++ b/bolthur/server/fs/dev/rpc.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _RPC_H
#define _RPC_H
-#include
#include
void rpc_handle_add( size_t, pid_t, size_t, size_t );
diff --git a/bolthur/server/fs/dev/rpc/add.c b/bolthur/server/fs/dev/rpc/add.c
index 8af829893..933d559e8 100644
--- a/bolthur/server/fs/dev/rpc/add.c
+++ b/bolthur/server/fs/dev/rpc/add.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -49,7 +49,7 @@ void rpc_handle_add(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/dev/rpc/boot.c b/bolthur/server/fs/dev/rpc/boot.c
index 54a0d595e..f9c64899f 100644
--- a/bolthur/server/fs/dev/rpc/boot.c
+++ b/bolthur/server/fs/dev/rpc/boot.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -49,7 +49,7 @@ void rpc_handle_boot_init(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
@@ -63,29 +63,23 @@ void rpc_handle_boot_init(
// ORDER NECESSARY HERE DUE TO THE DEFINES
// reroute stdin
EARLY_STARTUP_PRINT( "Rerouting stdin to %s\r\n", request->in )
- FILE* fpin = freopen( request->in, "r", stdin );
- if ( ! fpin ) {
+ if ( ! freopen( request->in, "r", stdin ) ) {
EARLY_STARTUP_PRINT( "errno = %s\r\n", strerror( errno ) )
EARLY_STARTUP_PRINT( "Unable to reroute stdin\r\n" )
exit( 1 );
}
// reroute stdout
- EARLY_STARTUP_PRINT( "stdin fileno = %d\r\n", fpin->_file )
EARLY_STARTUP_PRINT( "Rerouting stdout to %s\r\n", request->out )
- FILE* fpout = freopen( request->out, "w", stdout );
- if ( ! fpout ) {
+ if ( ! freopen( request->out, "w", stdout ) ) {
EARLY_STARTUP_PRINT( "Unable to reroute stdout\r\n" )
exit( 1 );
}
// reroute stderr
- EARLY_STARTUP_PRINT( "stdout fileno = %d\r\n", fpout->_file )
EARLY_STARTUP_PRINT( "Rerouting stderr to %s\r\n", request->err )
- FILE* fperr = freopen( request->err, "w", stderr );
- if ( ! fperr ) {
+ if ( ! freopen( request->err, "w", stderr ) ) {
EARLY_STARTUP_PRINT( "Unable to reroute stderr\r\n" )
exit( 1 );
}
- EARLY_STARTUP_PRINT( "stderr fileno = %d\r\n", fperr->_file )
// FIXME: ROUTE THROUGH TO CHILD PROCESSES
diff --git a/bolthur/server/fs/dev/rpc/close.c b/bolthur/server/fs/dev/rpc/close.c
index 3215e87bf..3b319e7bf 100644
--- a/bolthur/server/fs/dev/rpc/close.c
+++ b/bolthur/server/fs/dev/rpc/close.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/dev/rpc/custom/kill.c b/bolthur/server/fs/dev/rpc/custom/kill.c
index 1ad0810f5..af9cd0844 100644
--- a/bolthur/server/fs/dev/rpc/custom/kill.c
+++ b/bolthur/server/fs/dev/rpc/custom/kill.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/dev/rpc/custom/start.c b/bolthur/server/fs/dev/rpc/custom/start.c
index aade91d83..cc508dbff 100644
--- a/bolthur/server/fs/dev/rpc/custom/start.c
+++ b/bolthur/server/fs/dev/rpc/custom/start.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -48,7 +48,7 @@ void rpc_custom_handle_start(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
return;
}
@@ -60,17 +60,28 @@ void rpc_custom_handle_start(
bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
return;
}
- auto dev_command_start_t* command = ( dev_command_start_t* )request->container;
+ auto const command = ( dev_command_start_t* )request->container;
if ( ! command ) {
error.status = -ENOMEM;
bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
return;
}
+ void* shm_addr = _syscall_memory_shared_attach( command->shm_id, ( uintptr_t )NULL );
+ if ( errno ) {
+ const int e = errno;
+ free( request );
+ error.status = -e;
+ bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
+ return;
+ }
+ // get data
+ auto const data = ( dev_command_start_data_t* )shm_addr;
// allocate response
- size_t response_size = sizeof( vfs_ioctl_perform_response_t )
+ constexpr size_t response_size = sizeof( vfs_ioctl_perform_response_t )
+ sizeof( pid_t );
vfs_ioctl_perform_response_t* response = malloc( response_size );
if ( ! response ) {
+ _syscall_memory_shared_detach( command->shm_id );
free( request );
error.status = -ENOMEM;
bolthur_rpc_return( RPC_VFS_IOCTL, &error, sizeof( error ), NULL, 0 );
@@ -79,6 +90,7 @@ void rpc_custom_handle_start(
// allocate space for fork
pid_t* forked_process = malloc( sizeof( *forked_process ) );
if ( ! forked_process ) {
+ _syscall_memory_shared_detach( command->shm_id );
free( request );
free( response );
error.status = -ENOMEM;
@@ -88,6 +100,7 @@ void rpc_custom_handle_start(
// fork process
*forked_process = fork();
if ( 0 > *forked_process ) {
+ _syscall_memory_shared_detach( command->shm_id );
free( forked_process );
free( request );
free( response );
@@ -97,16 +110,26 @@ void rpc_custom_handle_start(
}
// fork only
if ( 0 == *forked_process ) {
- char* base = basename( command->path );
+ const size_t arg_size = command->data_size - sizeof( dev_command_start_data_t );
+ char* path = strdup( data->path );
+ if ( ! path ) {
+ exit( -1 );
+ }
+ char* args = strndup( data->args, arg_size );
+ if ( ! args ) {
+ exit( -1 );
+ }
+ _syscall_memory_shared_detach( command->shm_id );
+ char* base = basename( path );
if ( ! base ) {
exit( -1 );
}
// handle additional boot args
- if ( 0 < strlen( command->args ) ) {
+ if ( 0 < strlen( args ) ) {
// build command
- char* cmd[] = { base, command->args, NULL, };
+ char* cmd[] = { base, args, NULL, };
// exec to replace
- if ( -1 == execv( command->path, cmd ) ) {
+ if ( -1 == execv( path, cmd ) ) {
exit( 1 );
}
// handle no additional boot args
@@ -114,13 +137,14 @@ void rpc_custom_handle_start(
// build command
char* cmd[] = { base, NULL, };
// exec to replace
- if ( -1 == execv( command->path, cmd ) ) {
+ if ( -1 == execv( path, cmd ) ) {
exit( 1 );
}
}
// exit
exit( 1 );
}
+ _syscall_memory_shared_detach( command->shm_id );
// copy over pid
memcpy( response->container, forked_process, sizeof( pid_t ) );
// set success flag and return
diff --git a/bolthur/server/fs/dev/rpc/fork.c b/bolthur/server/fs/dev/rpc/fork.c
index 5a17713c9..691afdd9c 100644
--- a/bolthur/server/fs/dev/rpc/fork.c
+++ b/bolthur/server/fs/dev/rpc/fork.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -31,14 +31,14 @@
*/
void rpc_handle_fork(
size_t type,
- [[maybe_unused]] pid_t origin,
+ [[maybe_unused]] pid_t origin,
size_t data_info,
[[maybe_unused]] size_t response_info
) {
// dummy error response
vfs_fork_response_t response = { .status = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/dev/rpc/init.c b/bolthur/server/fs/dev/rpc/init.c
index 463193138..95ee5e05a 100644
--- a/bolthur/server/fs/dev/rpc/init.c
+++ b/bolthur/server/fs/dev/rpc/init.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/dev/rpc/ioctl.c b/bolthur/server/fs/dev/rpc/ioctl.c
index 6501c189a..7da2999cd 100644
--- a/bolthur/server/fs/dev/rpc/ioctl.c
+++ b/bolthur/server/fs/dev/rpc/ioctl.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -52,7 +52,7 @@ void rpc_handle_ioctl_async(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
return;
}
size_t data_size;
@@ -91,7 +91,7 @@ void rpc_handle_ioctl(
// dummy error response
vfs_ioctl_perform_response_t err_response = { .status = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &err_response, sizeof( err_response ), NULL, 0 );
return;
}
@@ -115,7 +115,7 @@ void rpc_handle_ioctl(
}
if ( getpid() == request->target_process ) {
// get local handler
- rpc_handler_t handler = bolthur_rpc_get( request->command );
+ const rpc_handler_t handler = bolthur_rpc_get( request->command );
if ( ! handler ) {
err_response.status = -EIO;
bolthur_rpc_return( type, &err_response, sizeof( err_response ), NULL, 0 );
diff --git a/bolthur/server/fs/dev/rpc/mount.c b/bolthur/server/fs/dev/rpc/mount.c
index 8e5540942..a4932798e 100644
--- a/bolthur/server/fs/dev/rpc/mount.c
+++ b/bolthur/server/fs/dev/rpc/mount.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -49,7 +49,7 @@ void rpc_handle_mount_async(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
return;
}
// fetch response
@@ -87,7 +87,7 @@ void rpc_handle_mount(
vfs_mount_response_t response = { .result = -ENOMEM };
response.result = -EINVAL;
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/dev/rpc/open.c b/bolthur/server/fs/dev/rpc/open.c
index 5b41bc9e4..efc58e146 100644
--- a/bolthur/server/fs/dev/rpc/open.c
+++ b/bolthur/server/fs/dev/rpc/open.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -47,7 +47,7 @@ void rpc_handle_open(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/dev/rpc/read.c b/bolthur/server/fs/dev/rpc/read.c
index b7e4e33b7..61e6ac8b1 100644
--- a/bolthur/server/fs/dev/rpc/read.c
+++ b/bolthur/server/fs/dev/rpc/read.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -51,7 +51,7 @@ void rpc_handle_read_async(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
return;
}
// original request
@@ -99,7 +99,7 @@ void rpc_handle_read(
memset( response, 0, sizeof( *response ) );
response->len = -EINVAL;
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, response, sizeof( *response ), NULL, 0 );
free( response );
return;
diff --git a/bolthur/server/fs/dev/rpc/stat.c b/bolthur/server/fs/dev/rpc/stat.c
index 49301918f..64cd95850 100644
--- a/bolthur/server/fs/dev/rpc/stat.c
+++ b/bolthur/server/fs/dev/rpc/stat.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -47,7 +47,7 @@ void rpc_handle_stat(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/dev/rpc/umount.c b/bolthur/server/fs/dev/rpc/umount.c
index 6d226d6fc..4f15313b7 100644
--- a/bolthur/server/fs/dev/rpc/umount.c
+++ b/bolthur/server/fs/dev/rpc/umount.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -49,7 +49,7 @@ void rpc_handle_umount_async(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
return;
}
// original request
@@ -91,7 +91,7 @@ void rpc_handle_umount(
vfs_umount_response_t response = { .result = -ENOMEM };
response.result = -EINVAL;
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/dev/rpc/watch/notify.c b/bolthur/server/fs/dev/rpc/watch/notify.c
index ecb658807..464ec0f16 100644
--- a/bolthur/server/fs/dev/rpc/watch/notify.c
+++ b/bolthur/server/fs/dev/rpc/watch/notify.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -45,7 +45,7 @@ void rpc_handle_watch_notify(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
return;
}
size_t data_size;
diff --git a/bolthur/server/fs/dev/rpc/watch/register.c b/bolthur/server/fs/dev/rpc/watch/register.c
index 86b361ac8..436a70da0 100644
--- a/bolthur/server/fs/dev/rpc/watch/register.c
+++ b/bolthur/server/fs/dev/rpc/watch/register.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -48,7 +48,7 @@ void rpc_handle_watch_register(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
response.result = -ENODATA;
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
diff --git a/bolthur/server/fs/dev/rpc/watch/release.c b/bolthur/server/fs/dev/rpc/watch/release.c
index d919ff1c0..0f56b4ac3 100644
--- a/bolthur/server/fs/dev/rpc/watch/release.c
+++ b/bolthur/server/fs/dev/rpc/watch/release.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -48,7 +48,7 @@ void rpc_handle_watch_release(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
response.result = -ENODATA;
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
diff --git a/bolthur/server/fs/dev/rpc/write.c b/bolthur/server/fs/dev/rpc/write.c
index 0785352b8..e7b62081a 100644
--- a/bolthur/server/fs/dev/rpc/write.c
+++ b/bolthur/server/fs/dev/rpc/write.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -51,7 +51,7 @@ void rpc_handle_write_async(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
return;
}
// original request
@@ -99,7 +99,7 @@ void rpc_handle_write(
memset( response, 0, sizeof( *response ) );
response->len = -EINVAL;
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, response, sizeof( *response ), NULL, 0 );
free( response );
return;
diff --git a/bolthur/server/fs/dev/watch.c b/bolthur/server/fs/dev/watch.c
index a11409486..203506e24 100644
--- a/bolthur/server/fs/dev/watch.c
+++ b/bolthur/server/fs/dev/watch.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/dev/watch.h b/bolthur/server/fs/dev/watch.h
index 80f966a1b..ee5a55aca 100644
--- a/bolthur/server/fs/dev/watch.h
+++ b/bolthur/server/fs/dev/watch.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,8 +20,9 @@
#ifndef _WATCH_H
#define _WATCH_H
+#define __PERMIT_DEPRECATED_SYS_TREE_H 1
+
#include
-#include
#include
#include
#include
diff --git a/bolthur/server/fs/ext/Makefile.am b/bolthur/server/fs/ext/Makefile.am
index 768145452..16c3d9740 100644
--- a/bolthur/server/fs/ext/Makefile.am
+++ b/bolthur/server/fs/ext/Makefile.am
@@ -2,9 +2,11 @@
bin_PROGRAMS = ext
ext_LDADD = \
$(BFS_LIBS) \
- ${abs_top_builddir}/../library/handle/libhandle.la
+ ${abs_top_builddir}/../library/handle/libhandle.la \
+ ${abs_top_builddir}/../library/vfs/libvfs.la
ext_DEPENDENCIES = \
- ${abs_top_builddir}/../library/handle/libhandle.la
+ ${abs_top_builddir}/../library/handle/libhandle.la \
+ ${abs_top_builddir}/../library/vfs/libvfs.la
ext_CFLAGS = \
-DPROGRAM_NAME=\"fs/ext\" \
$(BFS_CFLAGS)
diff --git a/bolthur/server/fs/ext/config.ini b/bolthur/server/fs/ext/config.ini
index 7296763ef..9d819d98d 100644
--- a/bolthur/server/fs/ext/config.ini
+++ b/bolthur/server/fs/ext/config.ini
@@ -1,3 +1,3 @@
[general]
type=ramdisk_compressed
-path=ramdisk/server/fs
\ No newline at end of file
+path=ramdisk/bin/server/fs
diff --git a/bolthur/server/fs/ext/main.c b/bolthur/server/fs/ext/main.c
index be5df5bcc..2d7588395 100644
--- a/bolthur/server/fs/ext/main.c
+++ b/bolthur/server/fs/ext/main.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -24,9 +24,9 @@
#include
#include "rpc.h"
#include "stat.h"
-#include "../../libhelper.h"
#include "../../libpartition.h"
#include "../../../library/handle/process.h"
+#include "../../../library/vfs/dev.h"
/**
* @fn int main(int, char*[])
@@ -113,7 +113,7 @@ int main( [[maybe_unused]] int argc, [[maybe_unused]] char* argv[] ) {
}
// add device file
- if ( !dev_add_file( "/dev/ext", NULL, 0 ) ) {
+ if ( ! vfs_dev_add_file( "/dev/ext", NULL, 0, nullptr ) ) {
STARTUP_PRINT( "Unable to add dev fs\r\n" )
free( reg );
close( fd );
diff --git a/bolthur/server/fs/ext/rpc.h b/bolthur/server/fs/ext/rpc.h
index 83ad40fc6..ac6a1d662 100644
--- a/bolthur/server/fs/ext/rpc.h
+++ b/bolthur/server/fs/ext/rpc.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _RPC_H
#define _RPC_H
-#include
#include
bool rpc_init( void );
diff --git a/bolthur/server/fs/ext/rpc/close.c b/bolthur/server/fs/ext/rpc/close.c
index 77c8bb887..933c5a4fc 100644
--- a/bolthur/server/fs/ext/rpc/close.c
+++ b/bolthur/server/fs/ext/rpc/close.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -59,7 +59,7 @@ void rpc_handle_close(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/ext/rpc/exec.c b/bolthur/server/fs/ext/rpc/exec.c
index aa216fced..95fad57ce 100644
--- a/bolthur/server/fs/ext/rpc/exec.c
+++ b/bolthur/server/fs/ext/rpc/exec.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -32,7 +32,7 @@
*/
void rpc_handle_exec(
size_t type,
- [[maybe_unused]] pid_t origin,
+ [[maybe_unused]] pid_t origin,
size_t data_info,
[[maybe_unused]] size_t response_info
) {
diff --git a/bolthur/server/fs/ext/rpc/exit.c b/bolthur/server/fs/ext/rpc/exit.c
index 51c8bf981..40c2b701a 100644
--- a/bolthur/server/fs/ext/rpc/exit.c
+++ b/bolthur/server/fs/ext/rpc/exit.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -32,7 +32,7 @@
*/
void rpc_handle_exit(
size_t type,
- [[maybe_unused]] pid_t origin,
+ [[maybe_unused]] pid_t origin,
size_t data_info,
[[maybe_unused]] size_t response_info
) {
diff --git a/bolthur/server/fs/ext/rpc/fork.c b/bolthur/server/fs/ext/rpc/fork.c
index 31e8a59a0..a6e928cee 100644
--- a/bolthur/server/fs/ext/rpc/fork.c
+++ b/bolthur/server/fs/ext/rpc/fork.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -32,14 +32,14 @@
*/
void rpc_handle_fork(
size_t type,
- [[maybe_unused]] pid_t origin,
+ [[maybe_unused]] pid_t origin,
size_t data_info,
[[maybe_unused]] size_t response_info
) {
// dummy error response
vfs_fork_response_t response = { .status = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
// return from rpc
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
// return
diff --git a/bolthur/server/fs/ext/rpc/getdents.c b/bolthur/server/fs/ext/rpc/getdents.c
index be5932528..5eedf3af0 100644
--- a/bolthur/server/fs/ext/rpc/getdents.c
+++ b/bolthur/server/fs/ext/rpc/getdents.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -62,7 +62,7 @@ void rpc_handle_getdents(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &dummy_response, sizeof( dummy_response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/ext/rpc/init.c b/bolthur/server/fs/ext/rpc/init.c
index dfc503cf2..7771616c6 100644
--- a/bolthur/server/fs/ext/rpc/init.c
+++ b/bolthur/server/fs/ext/rpc/init.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/ext/rpc/mount.c b/bolthur/server/fs/ext/rpc/mount.c
index 6beb99d12..a27e82bde 100644
--- a/bolthur/server/fs/ext/rpc/mount.c
+++ b/bolthur/server/fs/ext/rpc/mount.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -217,7 +217,7 @@ void rpc_handle_mount(
STARTUP_PRINT( "request->source = %s\r\n", request->source )
STARTUP_PRINT( "request->target = %s\r\n", request->target )
STARTUP_PRINT( "request->type = %s\r\n", request->type )
- STARTUP_PRINT( "request->flags = %"PRIx32"\r\n", request->flags )
+ STARTUP_PRINT( "request->flags = %lx\r\n", request->flags )
STARTUP_PRINT( "device = %s\r\n", device )
STARTUP_PRINT( "partition_index = %"PRIu32"\r\n", partition_index )
diff --git a/bolthur/server/fs/ext/rpc/open.c b/bolthur/server/fs/ext/rpc/open.c
index ba336ac41..440200741 100644
--- a/bolthur/server/fs/ext/rpc/open.c
+++ b/bolthur/server/fs/ext/rpc/open.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -65,7 +65,7 @@ void rpc_handle_open(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
@@ -87,7 +87,7 @@ void rpc_handle_open(
return;
}
// cache fs
- auto const ext_fs_t* fs = ( ext_fs_t* )mp->fs;
+ auto const fs = ( ext_fs_t* )mp->fs;
// start transaction
int result = common_transaction_begin( fs->bdev );
if ( EOK != result ) {
diff --git a/bolthur/server/fs/ext/rpc/read.c b/bolthur/server/fs/ext/rpc/read.c
index b62378b33..4000d1d16 100644
--- a/bolthur/server/fs/ext/rpc/read.c
+++ b/bolthur/server/fs/ext/rpc/read.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -64,7 +64,7 @@ void rpc_handle_read(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, response, sizeof( *response ), NULL, 0 );
free( response );
return;
diff --git a/bolthur/server/fs/ext/rpc/stat.c b/bolthur/server/fs/ext/rpc/stat.c
index e5323dff3..4417a3c9d 100644
--- a/bolthur/server/fs/ext/rpc/stat.c
+++ b/bolthur/server/fs/ext/rpc/stat.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -52,7 +52,7 @@ void rpc_handle_stat(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/ext/rpc/umount.c b/bolthur/server/fs/ext/rpc/umount.c
index 34ee9948b..23cee4ff3 100644
--- a/bolthur/server/fs/ext/rpc/umount.c
+++ b/bolthur/server/fs/ext/rpc/umount.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/ext/rpc/write.c b/bolthur/server/fs/ext/rpc/write.c
index 8e99d3c62..681d64478 100644
--- a/bolthur/server/fs/ext/rpc/write.c
+++ b/bolthur/server/fs/ext/rpc/write.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -65,7 +65,7 @@ void rpc_handle_write(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, response, sizeof( *response ), NULL, 0 );
free( response );
return;
diff --git a/bolthur/server/fs/ext/stat.c b/bolthur/server/fs/ext/stat.c
index ef13a0632..aac68e3fe 100644
--- a/bolthur/server/fs/ext/stat.c
+++ b/bolthur/server/fs/ext/stat.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/ext/stat.h b/bolthur/server/fs/ext/stat.h
index 759c1f998..1e74740d7 100644
--- a/bolthur/server/fs/ext/stat.h
+++ b/bolthur/server/fs/ext/stat.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,8 +20,9 @@
#ifndef _STAT_H
#define _STAT_H
+#define __PERMIT_DEPRECATED_SYS_TREE_H 1
+
#include
-#include
#include
#include
#include
diff --git a/bolthur/server/fs/ext/types.h b/bolthur/server/fs/ext/types.h
index c5c4f08a9..634c4980b 100644
--- a/bolthur/server/fs/ext/types.h
+++ b/bolthur/server/fs/ext/types.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/fat/Makefile.am b/bolthur/server/fs/fat/Makefile.am
index 1cc16da24..9411406f4 100644
--- a/bolthur/server/fs/fat/Makefile.am
+++ b/bolthur/server/fs/fat/Makefile.am
@@ -2,9 +2,11 @@
bin_PROGRAMS = fat
fat_LDADD = \
$(BFS_LIBS) \
- ${abs_top_builddir}/../library/handle/libhandle.la
+ ${abs_top_builddir}/../library/handle/libhandle.la \
+ ${abs_top_builddir}/../library/vfs/libvfs.la
fat_DEPENDENCIES = \
- ${abs_top_builddir}/../library/handle/libhandle.la
+ ${abs_top_builddir}/../library/handle/libhandle.la \
+ ${abs_top_builddir}/../library/vfs/libvfs.la
fat_CFLAGS = \
-DPROGRAM_NAME=\"fs/fat\" \
$(BFS_CFLAGS)
diff --git a/bolthur/server/fs/fat/config.ini b/bolthur/server/fs/fat/config.ini
index 7296763ef..9d819d98d 100644
--- a/bolthur/server/fs/fat/config.ini
+++ b/bolthur/server/fs/fat/config.ini
@@ -1,3 +1,3 @@
[general]
type=ramdisk_compressed
-path=ramdisk/server/fs
\ No newline at end of file
+path=ramdisk/bin/server/fs
diff --git a/bolthur/server/fs/fat/main.c b/bolthur/server/fs/fat/main.c
index fe40b8e58..fb013b564 100644
--- a/bolthur/server/fs/fat/main.c
+++ b/bolthur/server/fs/fat/main.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -24,8 +24,8 @@
#include
#include "rpc.h"
#include "stat.h"
-#include "../../libhelper.h"
#include "../../libpartition.h"
+#include "../../../library/vfs/dev.h"
/**
* @fn int main(int, char*[])
@@ -97,7 +97,7 @@ int main( [[maybe_unused]] int argc, [[maybe_unused]] char* argv[] ) {
STARTUP_PRINT( "register result: %d\r\n", result )
// add device file
- if ( !dev_add_file( "/dev/fat", NULL, 0 ) ) {
+ if ( ! vfs_dev_add_file( "/dev/fat", NULL, 0, nullptr ) ) {
STARTUP_PRINT( "Unable to add dev fs\r\n" )
free( reg );
close( fd );
diff --git a/bolthur/server/fs/fat/rpc.h b/bolthur/server/fs/fat/rpc.h
index 83ad40fc6..ac6a1d662 100644
--- a/bolthur/server/fs/fat/rpc.h
+++ b/bolthur/server/fs/fat/rpc.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _RPC_H
#define _RPC_H
-#include
#include
bool rpc_init( void );
diff --git a/bolthur/server/fs/fat/rpc/close.c b/bolthur/server/fs/fat/rpc/close.c
index e6ac293b5..243ad9359 100644
--- a/bolthur/server/fs/fat/rpc/close.c
+++ b/bolthur/server/fs/fat/rpc/close.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -59,7 +59,7 @@ void rpc_handle_close(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/fat/rpc/exec.c b/bolthur/server/fs/fat/rpc/exec.c
index aa216fced..95fad57ce 100644
--- a/bolthur/server/fs/fat/rpc/exec.c
+++ b/bolthur/server/fs/fat/rpc/exec.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -32,7 +32,7 @@
*/
void rpc_handle_exec(
size_t type,
- [[maybe_unused]] pid_t origin,
+ [[maybe_unused]] pid_t origin,
size_t data_info,
[[maybe_unused]] size_t response_info
) {
diff --git a/bolthur/server/fs/fat/rpc/exit.c b/bolthur/server/fs/fat/rpc/exit.c
index 51c8bf981..40c2b701a 100644
--- a/bolthur/server/fs/fat/rpc/exit.c
+++ b/bolthur/server/fs/fat/rpc/exit.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -32,7 +32,7 @@
*/
void rpc_handle_exit(
size_t type,
- [[maybe_unused]] pid_t origin,
+ [[maybe_unused]] pid_t origin,
size_t data_info,
[[maybe_unused]] size_t response_info
) {
diff --git a/bolthur/server/fs/fat/rpc/fork.c b/bolthur/server/fs/fat/rpc/fork.c
index ee59ee3b0..be1c62f8b 100644
--- a/bolthur/server/fs/fat/rpc/fork.c
+++ b/bolthur/server/fs/fat/rpc/fork.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -32,14 +32,14 @@
*/
void rpc_handle_fork(
size_t type,
- [[maybe_unused]] pid_t origin,
+ [[maybe_unused]] pid_t origin,
size_t data_info,
[[maybe_unused]] size_t response_info
) {
// dummy error response
vfs_fork_response_t response = { .status = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/fat/rpc/getdents.c b/bolthur/server/fs/fat/rpc/getdents.c
index 1bb71749b..00a2390d0 100644
--- a/bolthur/server/fs/fat/rpc/getdents.c
+++ b/bolthur/server/fs/fat/rpc/getdents.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -62,7 +62,7 @@ void rpc_handle_getdents(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &dummy_response, sizeof( dummy_response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/fat/rpc/init.c b/bolthur/server/fs/fat/rpc/init.c
index dfc503cf2..7771616c6 100644
--- a/bolthur/server/fs/fat/rpc/init.c
+++ b/bolthur/server/fs/fat/rpc/init.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/fat/rpc/mount.c b/bolthur/server/fs/fat/rpc/mount.c
index f487f70ed..f9b1cc221 100644
--- a/bolthur/server/fs/fat/rpc/mount.c
+++ b/bolthur/server/fs/fat/rpc/mount.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -161,7 +161,7 @@ void rpc_handle_mount(
vfs_mount_response_t response = { .result = -ENOMEM };
response.result = -EINVAL;
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
@@ -216,7 +216,7 @@ void rpc_handle_mount(
STARTUP_PRINT( "request->source = %s\r\n", request->source )
STARTUP_PRINT( "request->target = %s\r\n", request->target )
STARTUP_PRINT( "request->type = %s\r\n", request->type )
- STARTUP_PRINT( "request->flags = %"PRIx32"\r\n", request->flags )
+ STARTUP_PRINT( "request->flags = %lx\r\n", request->flags )
STARTUP_PRINT( "device = %s\r\n", device )
STARTUP_PRINT( "partition_index = %"PRIu32"\r\n", partition_index )
diff --git a/bolthur/server/fs/fat/rpc/open.c b/bolthur/server/fs/fat/rpc/open.c
index c1927687a..e7d8b9240 100644
--- a/bolthur/server/fs/fat/rpc/open.c
+++ b/bolthur/server/fs/fat/rpc/open.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -64,7 +64,7 @@ void rpc_handle_open(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
@@ -86,7 +86,7 @@ void rpc_handle_open(
return;
}
// cache fs
- auto const fat_fs_t* fs = ( fat_fs_t* )mp->fs;
+ auto const fs = ( fat_fs_t* )mp->fs;
// start transaction
int result = common_transaction_begin( fs->bdev );
if ( EOK != result ) {
diff --git a/bolthur/server/fs/fat/rpc/read.c b/bolthur/server/fs/fat/rpc/read.c
index b8d6f4104..c970d0cb4 100644
--- a/bolthur/server/fs/fat/rpc/read.c
+++ b/bolthur/server/fs/fat/rpc/read.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -64,7 +64,7 @@ void rpc_handle_read(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, response, sizeof( *response ), NULL, 0 );
free( response );
return;
diff --git a/bolthur/server/fs/fat/rpc/stat.c b/bolthur/server/fs/fat/rpc/stat.c
index 84dfef7e5..9f33860d0 100644
--- a/bolthur/server/fs/fat/rpc/stat.c
+++ b/bolthur/server/fs/fat/rpc/stat.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -52,7 +52,7 @@ void rpc_handle_stat(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/fat/rpc/umount.c b/bolthur/server/fs/fat/rpc/umount.c
index 6bf16cb60..985501194 100644
--- a/bolthur/server/fs/fat/rpc/umount.c
+++ b/bolthur/server/fs/fat/rpc/umount.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/fat/rpc/write.c b/bolthur/server/fs/fat/rpc/write.c
index 60633baf2..08d458aee 100644
--- a/bolthur/server/fs/fat/rpc/write.c
+++ b/bolthur/server/fs/fat/rpc/write.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -65,7 +65,7 @@ void rpc_handle_write(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, response, sizeof( *response ), NULL, 0 );
free( response );
return;
diff --git a/bolthur/server/fs/fat/stat.c b/bolthur/server/fs/fat/stat.c
index ef13a0632..aac68e3fe 100644
--- a/bolthur/server/fs/fat/stat.c
+++ b/bolthur/server/fs/fat/stat.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/fat/stat.h b/bolthur/server/fs/fat/stat.h
index 759c1f998..1e74740d7 100644
--- a/bolthur/server/fs/fat/stat.h
+++ b/bolthur/server/fs/fat/stat.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,8 +20,9 @@
#ifndef _STAT_H
#define _STAT_H
+#define __PERMIT_DEPRECATED_SYS_TREE_H 1
+
#include
-#include
#include
#include
#include
diff --git a/bolthur/server/fs/fat/types.h b/bolthur/server/fs/fat/types.h
index c5c4f08a9..634c4980b 100644
--- a/bolthur/server/fs/fat/types.h
+++ b/bolthur/server/fs/fat/types.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/ramdisk/Makefile.am b/bolthur/server/fs/ramdisk/Makefile.am
index 4e2640f0d..f3dcbeaba 100644
--- a/bolthur/server/fs/ramdisk/Makefile.am
+++ b/bolthur/server/fs/ramdisk/Makefile.am
@@ -2,7 +2,10 @@
AM_CFLAGS = -DPROGRAM_NAME=\"fs/ramdisk\"
bin_PROGRAMS = ramdisk
-ramdisk_LDADD = -ltar
+ramdisk_LDADD = -ltar \
+ ${abs_top_builddir}/../library/vfs/libvfs.la
+ramdisk_DEPENDENCIES = \
+ ${abs_top_builddir}/../library/vfs/libvfs.la
ramdisk_SOURCES = \
rpc/add.c \
rpc/close.c \
diff --git a/bolthur/server/fs/ramdisk/config.ini b/bolthur/server/fs/ramdisk/config.ini
index a787604ef..9d819d98d 100644
--- a/bolthur/server/fs/ramdisk/config.ini
+++ b/bolthur/server/fs/ramdisk/config.ini
@@ -1,3 +1,3 @@
[general]
type=ramdisk_compressed
-path=ramdisk/server/fs
+path=ramdisk/bin/server/fs
diff --git a/bolthur/server/fs/ramdisk/main.c b/bolthur/server/fs/ramdisk/main.c
index 33e9fc4a8..a76ec716d 100644
--- a/bolthur/server/fs/ramdisk/main.c
+++ b/bolthur/server/fs/ramdisk/main.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -22,11 +22,13 @@
#include
#include
#include
+#include
#include
#include
#include "ramdisk.h"
#include "rpc.h"
-#include "../../libhelper.h"
+#include "../../../library/vfs/wait.h"
+#include "../../../library/vfs/dev.h"
extern TAR* disk;
@@ -68,7 +70,7 @@ int main( int argc, char* argv[] ) {
vfs_wait_for_path( "/dev/manager/device" );
// add device file
- if ( !dev_add_file( "/dev/ramdisk", NULL, 0 ) ) {
+ if ( ! vfs_dev_add_file( "/dev/ramdisk", NULL, 0, nullptr ) ) {
EARLY_STARTUP_PRINT( "Unable to add dev fs\r\n" )
return -1;
}
diff --git a/bolthur/server/fs/ramdisk/ramdisk.c b/bolthur/server/fs/ramdisk/ramdisk.c
index b6ee83109..1db081edc 100644
--- a/bolthur/server/fs/ramdisk/ramdisk.c
+++ b/bolthur/server/fs/ramdisk/ramdisk.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/ramdisk/ramdisk.h b/bolthur/server/fs/ramdisk/ramdisk.h
index 55fed5442..3e5558728 100644
--- a/bolthur/server/fs/ramdisk/ramdisk.h
+++ b/bolthur/server/fs/ramdisk/ramdisk.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/ramdisk/rpc.h b/bolthur/server/fs/ramdisk/rpc.h
index cb313d30b..f3eefd018 100644
--- a/bolthur/server/fs/ramdisk/rpc.h
+++ b/bolthur/server/fs/ramdisk/rpc.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _RPC_H
#define _RPC_H
-#include
#include
bool rpc_init( void );
diff --git a/bolthur/server/fs/ramdisk/rpc/add.c b/bolthur/server/fs/ramdisk/rpc/add.c
index f33973811..4e15e08a5 100644
--- a/bolthur/server/fs/ramdisk/rpc/add.c
+++ b/bolthur/server/fs/ramdisk/rpc/add.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -39,7 +39,7 @@ void rpc_handle_add(
) {
vfs_add_response_t response = { .status = -EINVAL, .handler = 0 };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/ramdisk/rpc/close.c b/bolthur/server/fs/ramdisk/rpc/close.c
index 0e05faf40..4b7a9257b 100644
--- a/bolthur/server/fs/ramdisk/rpc/close.c
+++ b/bolthur/server/fs/ramdisk/rpc/close.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -41,7 +41,7 @@ void rpc_handle_close(
// dummy error response
vfs_close_response_t response = { .status = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/ramdisk/rpc/exec.c b/bolthur/server/fs/ramdisk/rpc/exec.c
index 70d56aaee..0dc015b9d 100644
--- a/bolthur/server/fs/ramdisk/rpc/exec.c
+++ b/bolthur/server/fs/ramdisk/rpc/exec.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -39,7 +39,7 @@ void rpc_handle_exec(
) {
vfs_exec_response_t response = { .result = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/ramdisk/rpc/exit.c b/bolthur/server/fs/ramdisk/rpc/exit.c
index 3128e799e..06b2d1c63 100644
--- a/bolthur/server/fs/ramdisk/rpc/exit.c
+++ b/bolthur/server/fs/ramdisk/rpc/exit.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -39,7 +39,7 @@ void rpc_handle_exit(
) {
vfs_exit_response_t response = { .result = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/ramdisk/rpc/fork.c b/bolthur/server/fs/ramdisk/rpc/fork.c
index 9b518cc85..3c9972bab 100644
--- a/bolthur/server/fs/ramdisk/rpc/fork.c
+++ b/bolthur/server/fs/ramdisk/rpc/fork.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -41,7 +41,7 @@ void rpc_handle_fork(
// dummy error response
vfs_fork_response_t response = { .status = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/ramdisk/rpc/init.c b/bolthur/server/fs/ramdisk/rpc/init.c
index 3369dafcd..123c8db56 100644
--- a/bolthur/server/fs/ramdisk/rpc/init.c
+++ b/bolthur/server/fs/ramdisk/rpc/init.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/ramdisk/rpc/ioctl.c b/bolthur/server/fs/ramdisk/rpc/ioctl.c
index 5146011e0..b9a5df4ac 100644
--- a/bolthur/server/fs/ramdisk/rpc/ioctl.c
+++ b/bolthur/server/fs/ramdisk/rpc/ioctl.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -42,7 +42,7 @@ void rpc_handle_ioctl(
) {
vfs_ioctl_perform_response_t err_response = { .status = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &err_response, sizeof( err_response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/ramdisk/rpc/open.c b/bolthur/server/fs/ramdisk/rpc/open.c
index 70ce50bc8..7efdd2dfc 100644
--- a/bolthur/server/fs/ramdisk/rpc/open.c
+++ b/bolthur/server/fs/ramdisk/rpc/open.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/ramdisk/rpc/read.c b/bolthur/server/fs/ramdisk/rpc/read.c
index 8637a2cef..fdcb1cfde 100644
--- a/bolthur/server/fs/ramdisk/rpc/read.c
+++ b/bolthur/server/fs/ramdisk/rpc/read.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -76,7 +76,7 @@ void rpc_handle_read(
}
memset( response, 0, sizeof( vfs_read_response_t ) );
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
response->len = -EINVAL;
bolthur_rpc_return( type, response, sizeof( vfs_read_response_t ), NULL, 0 );
free( response );
diff --git a/bolthur/server/fs/ramdisk/rpc/remove.c b/bolthur/server/fs/ramdisk/rpc/remove.c
index f04823341..18234fd4d 100644
--- a/bolthur/server/fs/ramdisk/rpc/remove.c
+++ b/bolthur/server/fs/ramdisk/rpc/remove.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -39,7 +39,7 @@ void rpc_handle_remove(
) {
vfs_remove_response_t response = { .status = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/ramdisk/rpc/seek.c b/bolthur/server/fs/ramdisk/rpc/seek.c
index f4460fc6e..8818288d4 100644
--- a/bolthur/server/fs/ramdisk/rpc/seek.c
+++ b/bolthur/server/fs/ramdisk/rpc/seek.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -39,7 +39,7 @@ void rpc_handle_seek(
) {
vfs_seek_response_t response = { .position = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/ramdisk/rpc/stat.c b/bolthur/server/fs/ramdisk/rpc/stat.c
index 2a7a93cb0..c38603777 100644
--- a/bolthur/server/fs/ramdisk/rpc/stat.c
+++ b/bolthur/server/fs/ramdisk/rpc/stat.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/ramdisk/rpc/write.c b/bolthur/server/fs/ramdisk/rpc/write.c
index b777ca1e7..448104d88 100644
--- a/bolthur/server/fs/ramdisk/rpc/write.c
+++ b/bolthur/server/fs/ramdisk/rpc/write.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -39,7 +39,7 @@ void rpc_handle_write(
) {
vfs_write_response_t response = { .len = -ENOMEM };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/vfs/config.ini b/bolthur/server/fs/vfs/config.ini
index a787604ef..9d819d98d 100644
--- a/bolthur/server/fs/vfs/config.ini
+++ b/bolthur/server/fs/vfs/config.ini
@@ -1,3 +1,3 @@
[general]
type=ramdisk_compressed
-path=ramdisk/server/fs
+path=ramdisk/bin/server/fs
diff --git a/bolthur/server/fs/vfs/handler/node.c b/bolthur/server/fs/vfs/handler/node.c
index 45d773448..6ab2a4025 100644
--- a/bolthur/server/fs/vfs/handler/node.c
+++ b/bolthur/server/fs/vfs/handler/node.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/vfs/handler/node.h b/bolthur/server/fs/vfs/handler/node.h
index 086cb83e5..ee0e4d414 100644
--- a/bolthur/server/fs/vfs/handler/node.h
+++ b/bolthur/server/fs/vfs/handler/node.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,8 +20,9 @@
#ifndef _HANDLER_NODE_H
#define _HANDLER_NODE_H
+#define __PERMIT_DEPRECATED_SYS_TREE_H 1
+
#include
-#include
#include
#include
#include
diff --git a/bolthur/server/fs/vfs/ioctl/handler.c b/bolthur/server/fs/vfs/ioctl/handler.c
index 143db1e1e..230375313 100644
--- a/bolthur/server/fs/vfs/ioctl/handler.c
+++ b/bolthur/server/fs/vfs/ioctl/handler.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/vfs/ioctl/handler.h b/bolthur/server/fs/vfs/ioctl/handler.h
index f11bcfd76..c641f9410 100644
--- a/bolthur/server/fs/vfs/ioctl/handler.h
+++ b/bolthur/server/fs/vfs/ioctl/handler.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/vfs/main.c b/bolthur/server/fs/vfs/main.c
index 48e87f114..535e690cf 100644
--- a/bolthur/server/fs/vfs/main.c
+++ b/bolthur/server/fs/vfs/main.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/vfs/mountpoint/node.c b/bolthur/server/fs/vfs/mountpoint/node.c
index d2e2aace6..0ec235b86 100644
--- a/bolthur/server/fs/vfs/mountpoint/node.c
+++ b/bolthur/server/fs/vfs/mountpoint/node.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/vfs/mountpoint/node.h b/bolthur/server/fs/vfs/mountpoint/node.h
index 458f2c299..89956e4af 100644
--- a/bolthur/server/fs/vfs/mountpoint/node.h
+++ b/bolthur/server/fs/vfs/mountpoint/node.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,8 +20,9 @@
#ifndef _MOUNTPOINT_NODE_H
#define _MOUNTPOINT_NODE_H
+#define __PERMIT_DEPRECATED_SYS_TREE_H 1
+
#include
-#include
#include
#include
#include
diff --git a/bolthur/server/fs/vfs/rpc.h b/bolthur/server/fs/vfs/rpc.h
index c5f20fbfd..e5db5979e 100644
--- a/bolthur/server/fs/vfs/rpc.h
+++ b/bolthur/server/fs/vfs/rpc.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,7 +20,6 @@
#ifndef _RPC_H
#define _RPC_H
-#include
#include
extern pid_t vfs_pid;
diff --git a/bolthur/server/fs/vfs/rpc/add.c b/bolthur/server/fs/vfs/rpc/add.c
index 864042b69..182538fef 100644
--- a/bolthur/server/fs/vfs/rpc/add.c
+++ b/bolthur/server/fs/vfs/rpc/add.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -49,7 +49,7 @@ void rpc_handle_add_async(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), async_data, 0 );
return;
}
@@ -75,13 +75,13 @@ void rpc_handle_add_async(
return;
}
// get original request
- vfs_add_request_t* request = async_data->original_data;
+ const vfs_add_request_t* request = async_data->original_data;
// handle device info stuff if is device
if (
sizeof( vfs_add_request_t ) < async_data->length
&& S_ISCHR( request->info.st_mode )
) {
- size_t idx_max =
+ const size_t idx_max =
( async_data->length - sizeof( vfs_add_request_t ) ) / sizeof( size_t );
for ( size_t idx = 0; idx < idx_max; idx++ ) {
while ( true ) {
@@ -126,7 +126,7 @@ void rpc_handle_add(
}
vfs_add_response_t response = { .status = -EINVAL, .handler = 0 };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
@@ -165,7 +165,9 @@ void rpc_handle_add(
request,
data_size,
origin,
- data_info,
+ // don't push back data info when handler and origin are the same to prevent
+ // async callback in target process to kick in
+ mount_point->pid == origin ? 0 : data_info,
NULL,
false
);
diff --git a/bolthur/server/fs/vfs/rpc/boot.c b/bolthur/server/fs/vfs/rpc/boot.c
index b59c2ca72..c9c004fe5 100644
--- a/bolthur/server/fs/vfs/rpc/boot.c
+++ b/bolthur/server/fs/vfs/rpc/boot.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -56,7 +56,7 @@ void rpc_handle_boot_init_async(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), async_data, 0 );
return;
}
@@ -86,7 +86,7 @@ void rpc_handle_boot_init_async(
return;
}
// transform original origin to string
- snprintf( str, sizeof( *str ) * 256, "%zu", async_data->original_origin );
+ snprintf( str, sizeof( *str ) * 256, "%d", async_data->original_origin );
// get table
ht_t* table = ht_get( boot_hash_table, str );
if ( ! table ) {
@@ -101,7 +101,7 @@ void rpc_handle_boot_init_async(
return;
}
// transform current origin to string
- snprintf( str, sizeof( *str ) * 256, "%zu", origin );
+ snprintf( str, sizeof( *str ) * 256, "%d", origin );
// unset entry
ht_unset( table, str );
// destroyed flag
@@ -109,7 +109,7 @@ void rpc_handle_boot_init_async(
// handle length 0
if ( ! table->length ) {
// get original origin
- snprintf( str, sizeof( *str ) * 256, "%zu", async_data->original_origin );
+ snprintf( str, sizeof( *str ) * 256, "%d", async_data->original_origin );
// unset table
ht_unset( boot_hash_table, str );
// destroy hash table
@@ -118,7 +118,7 @@ void rpc_handle_boot_init_async(
finished = true;
}
// get finished table
- snprintf( str, sizeof( *str ) * 256, "%zu", async_data->original_origin );
+ snprintf( str, sizeof( *str ) * 256, "%d", async_data->original_origin );
int* data = ht_get( finished_table, str );
if ( ! data ) {
// free string
@@ -152,7 +152,7 @@ void rpc_handle_boot_init_async(
// handle finished
if ( finished ) {
// transform origin
- snprintf( str, sizeof( *str ) * 256, "%zu", async_data->original_origin );
+ snprintf( str, sizeof( *str ) * 256, "%d", async_data->original_origin );
// unset finished table entry
ht_unset( finished_table, str );
// populate result
@@ -187,7 +187,7 @@ void rpc_handle_boot_init(
// default response
vfs_boot_init_response_t response = { .result = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
@@ -246,13 +246,14 @@ void rpc_handle_boot_init(
return;
}
// transform origin into string
- snprintf( str, sizeof( *str ) * 256, "%zu", origin );
+ snprintf( str, sizeof( *str ) * 256, "%d", origin );
int* data = malloc( sizeof( int ) );
if ( ! data ) {
// set result
response.result = -ENOMEM;
// free request
free( request );
+ free( str );
// return error
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
// return execution
@@ -266,6 +267,7 @@ void rpc_handle_boot_init(
response.result = -EIO;
// free request
free( request );
+ free( str );
free( data );
// return error
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
@@ -281,6 +283,7 @@ void rpc_handle_boot_init(
free( request );
// remove entry from finished table
ht_unset( finished_table, str );
+ free( str );
free( data );
// return error
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
diff --git a/bolthur/server/fs/vfs/rpc/close.c b/bolthur/server/fs/vfs/rpc/close.c
index 94eba9471..6fa2294e5 100644
--- a/bolthur/server/fs/vfs/rpc/close.c
+++ b/bolthur/server/fs/vfs/rpc/close.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/vfs/rpc/exec.c b/bolthur/server/fs/vfs/rpc/exec.c
index 2adfa92f0..8b08af250 100644
--- a/bolthur/server/fs/vfs/rpc/exec.c
+++ b/bolthur/server/fs/vfs/rpc/exec.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -39,7 +39,7 @@ static void rpc_handle_exec_table(
[[maybe_unused]] size_t type,
pid_t origin,
size_t data_info,
- [[maybe_unused]] size_t response_info
+ size_t response_info
) {
// response object
vfs_exec_response_t response = { .result = -EINVAL };
diff --git a/bolthur/server/fs/vfs/rpc/exit.c b/bolthur/server/fs/vfs/rpc/exit.c
index 631c26379..d0a20a995 100644
--- a/bolthur/server/fs/vfs/rpc/exit.c
+++ b/bolthur/server/fs/vfs/rpc/exit.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/vfs/rpc/fork.c b/bolthur/server/fs/vfs/rpc/fork.c
index f87416341..04da1e4dd 100644
--- a/bolthur/server/fs/vfs/rpc/fork.c
+++ b/bolthur/server/fs/vfs/rpc/fork.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -313,7 +313,7 @@ static void rpc_handle_fork_stat(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( RPC_VFS_FORK, &response, sizeof( response ), async_data, 0 );
return;
}
@@ -376,7 +376,7 @@ void rpc_handle_fork(
// dummy error response
vfs_fork_response_t response = { .status = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/vfs/rpc/getdents.c b/bolthur/server/fs/vfs/rpc/getdents.c
index 2a0fc7082..c51296092 100644
--- a/bolthur/server/fs/vfs/rpc/getdents.c
+++ b/bolthur/server/fs/vfs/rpc/getdents.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -53,7 +53,7 @@ void rpc_handle_getdents_async(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
return;
}
// get message and data size
@@ -118,7 +118,7 @@ void rpc_handle_getdents(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
response->result = -EINVAL;
bolthur_rpc_return( type, response, sizeof( *response ), NULL, 0 );
free( response );
diff --git a/bolthur/server/fs/vfs/rpc/handler/register.c b/bolthur/server/fs/vfs/rpc/handler/register.c
index ae202cfc8..b4b25798f 100644
--- a/bolthur/server/fs/vfs/rpc/handler/register.c
+++ b/bolthur/server/fs/vfs/rpc/handler/register.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -42,7 +42,7 @@ void rpc_handle_handler_register(
) {
vfs_register_handler_response_t response = { .result = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
response.result = -ENODATA;
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
diff --git a/bolthur/server/fs/vfs/rpc/handler/release.c b/bolthur/server/fs/vfs/rpc/handler/release.c
index 98e173f68..beab4047d 100644
--- a/bolthur/server/fs/vfs/rpc/handler/release.c
+++ b/bolthur/server/fs/vfs/rpc/handler/release.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -42,7 +42,7 @@ void rpc_handle_handler_release(
) {
vfs_release_handler_response_t response = { .result = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
response.result = -ENODATA;
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
diff --git a/bolthur/server/fs/vfs/rpc/init.c b/bolthur/server/fs/vfs/rpc/init.c
index e665fd29e..96c1f8d86 100644
--- a/bolthur/server/fs/vfs/rpc/init.c
+++ b/bolthur/server/fs/vfs/rpc/init.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/vfs/rpc/ioctl.c b/bolthur/server/fs/vfs/rpc/ioctl.c
index a0281e79c..d74f54292 100644
--- a/bolthur/server/fs/vfs/rpc/ioctl.c
+++ b/bolthur/server/fs/vfs/rpc/ioctl.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -54,7 +54,7 @@ void rpc_handle_ioctl_async(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
return;
}
// get message and data size
@@ -94,7 +94,7 @@ void rpc_handle_ioctl(
// dummy error response
vfs_ioctl_perform_response_t err_response = { .status = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &err_response, sizeof( err_response ), NULL, 0 );
return;
}
@@ -109,7 +109,7 @@ void rpc_handle_ioctl(
// get handle
handle_node_t* handle_container;
// try to get handle information
- int result = handle_get( &handle_container, origin, request->handle );
+ const int result = handle_get( &handle_container, origin, request->handle );
// handle error
if ( 0 > result ) {
err_response.status = result;
@@ -117,7 +117,10 @@ void rpc_handle_ioctl(
free( request );
return;
}
- mountpoint_node_t* node = handle_container->data;
+ // populate origin
+ request->origin = origin;
+ // route depending on pid
+ const mountpoint_node_t* node = handle_container->data;
if ( vfs_pid != node->pid ) {
// set handler and redirect request
request->target_process = handle_container->handler;
diff --git a/bolthur/server/fs/vfs/rpc/mount.c b/bolthur/server/fs/vfs/rpc/mount.c
index 0cdac06d9..d3122e2d9 100644
--- a/bolthur/server/fs/vfs/rpc/mount.c
+++ b/bolthur/server/fs/vfs/rpc/mount.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -52,7 +52,7 @@ void rpc_handle_mount_async(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), async_data, 0 );
return;
}
@@ -135,7 +135,7 @@ void rpc_handle_mount(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/vfs/rpc/open.c b/bolthur/server/fs/vfs/rpc/open.c
index b671cce26..97c98d434 100644
--- a/bolthur/server/fs/vfs/rpc/open.c
+++ b/bolthur/server/fs/vfs/rpc/open.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -157,7 +157,7 @@ void rpc_handle_open_async(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( RPC_VFS_OPEN, &response, sizeof( response ), async_data, 0 );
return;
}
@@ -227,7 +227,7 @@ void rpc_handle_open(
// variables
vfs_open_response_t response = { .handle = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/vfs/rpc/read.c b/bolthur/server/fs/vfs/rpc/read.c
index d37bc0d4c..c6db4c49f 100644
--- a/bolthur/server/fs/vfs/rpc/read.c
+++ b/bolthur/server/fs/vfs/rpc/read.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -53,7 +53,7 @@ void rpc_handle_read_async(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
return;
}
// original request
@@ -69,7 +69,7 @@ void rpc_handle_read_async(
}
handle_node_t* container;
// try to get handle information
- int result = handle_get(
+ const int result = handle_get(
&container,
async_data->original_origin,
request->handle
@@ -81,8 +81,8 @@ void rpc_handle_read_async(
free( response );
return;
}
- // update offsets and return
- if ( 0 < response->len ) {
+ // update offsets if not stdin and return
+ if ( 0 < response->len && container->handle != STDIN_FILENO ) {
container->pos += ( off_t )response->len;
}
bolthur_rpc_return( type, response, sizeof( *response ), async_data, 0 );
@@ -119,7 +119,7 @@ void rpc_handle_read(
handle_node_t* container;
response->len = -EINVAL;
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, response, sizeof( *response ), NULL, 0 );
free( response );
return;
@@ -128,7 +128,7 @@ void rpc_handle_read(
size_t data_size;
vfs_read_request_t* request = bolthur_rpc_fetch_from_mailbox( data_info, &data_size, true, NULL );
if ( ! request ) {
- response->len= -errno;
+ response->len = -errno;
bolthur_rpc_return( type, response, sizeof( *response ), NULL, 0 );
free( response );
return;
diff --git a/bolthur/server/fs/vfs/rpc/remove.c b/bolthur/server/fs/vfs/rpc/remove.c
index 40b92b8d9..107571fbf 100644
--- a/bolthur/server/fs/vfs/rpc/remove.c
+++ b/bolthur/server/fs/vfs/rpc/remove.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -43,7 +43,7 @@ void rpc_handle_remove(
) {
vfs_remove_response_t response = { .status = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/vfs/rpc/seek.c b/bolthur/server/fs/vfs/rpc/seek.c
index 879392c2a..9d5771cc7 100644
--- a/bolthur/server/fs/vfs/rpc/seek.c
+++ b/bolthur/server/fs/vfs/rpc/seek.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -44,7 +44,7 @@ void rpc_handle_seek(
vfs_seek_response_t response = { .position = -EINVAL };
handle_node_t* container;
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/vfs/rpc/stat.c b/bolthur/server/fs/vfs/rpc/stat.c
index db83930e1..cf9d63a8f 100644
--- a/bolthur/server/fs/vfs/rpc/stat.c
+++ b/bolthur/server/fs/vfs/rpc/stat.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -50,7 +50,7 @@ void rpc_handle_stat_async(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), async_data, 0 );
return;
}
@@ -94,7 +94,7 @@ void rpc_handle_stat(
vfs_stat_response_t response = { .success = false };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/vfs/rpc/umount.c b/bolthur/server/fs/vfs/rpc/umount.c
index 97d1b51bd..96384c1df 100644
--- a/bolthur/server/fs/vfs/rpc/umount.c
+++ b/bolthur/server/fs/vfs/rpc/umount.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -26,7 +26,7 @@
#include "../rpc.h"
#include "../mountpoint/node.h"
#include "../../../../library/handle/process.h"
-#include "handler/node.h"
+#include "../handler/node.h"
/**
* @fn void rpc_handle_umount_async(size_t, pid_t, size_t, size_t)
@@ -51,7 +51,7 @@ void rpc_handle_umount_async(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), async_data, 0 );
return;
}
@@ -108,7 +108,7 @@ void rpc_handle_umount(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/vfs/rpc/watch/notify.c b/bolthur/server/fs/vfs/rpc/watch/notify.c
index 3114b5846..72a804697 100644
--- a/bolthur/server/fs/vfs/rpc/watch/notify.c
+++ b/bolthur/server/fs/vfs/rpc/watch/notify.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -41,7 +41,7 @@ void rpc_handle_watch_notify(
[[maybe_unused]] size_t response_info
) {
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
return;
}
// get message and data size
diff --git a/bolthur/server/fs/vfs/rpc/watch/register.c b/bolthur/server/fs/vfs/rpc/watch/register.c
index 1cb4447ab..9e118b5d5 100644
--- a/bolthur/server/fs/vfs/rpc/watch/register.c
+++ b/bolthur/server/fs/vfs/rpc/watch/register.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -46,7 +46,7 @@ void rpc_handle_watch_register_async(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
return;
}
// get message and data size
@@ -79,7 +79,7 @@ void rpc_handle_watch_register(
// variables
vfs_watch_register_response_t response = { .result = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
response.result = -ENODATA;
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
diff --git a/bolthur/server/fs/vfs/rpc/watch/release.c b/bolthur/server/fs/vfs/rpc/watch/release.c
index 473223052..3c0231520 100644
--- a/bolthur/server/fs/vfs/rpc/watch/release.c
+++ b/bolthur/server/fs/vfs/rpc/watch/release.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -46,7 +46,7 @@ void rpc_handle_watch_release_async(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
return;
}
// get message and data size
@@ -79,7 +79,7 @@ void rpc_handle_watch_release(
// variables
vfs_watch_release_response_t response = { .result = -EINVAL };
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
response.result = -ENODATA;
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
diff --git a/bolthur/server/fs/vfs/rpc/write.c b/bolthur/server/fs/vfs/rpc/write.c
index 3c11be86d..d47ad9a55 100644
--- a/bolthur/server/fs/vfs/rpc/write.c
+++ b/bolthur/server/fs/vfs/rpc/write.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -54,7 +54,7 @@ void rpc_handle_write_async(
return;
}
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
return;
}
response.len = -ENOMEM;
@@ -125,7 +125,7 @@ void rpc_handle_write(
// switch error return
response.len = -EINVAL;
// handle no data
- if( ! data_info ) {
+ if ( ! data_info ) {
bolthur_rpc_return( type, &response, sizeof( response ), NULL, 0 );
return;
}
diff --git a/bolthur/server/fs/vfs/util.c b/bolthur/server/fs/vfs/util.c
index 0cea0a81f..15148b2c2 100644
--- a/bolthur/server/fs/vfs/util.c
+++ b/bolthur/server/fs/vfs/util.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/fs/vfs/util.h b/bolthur/server/fs/vfs/util.h
index 67d6a9904..99ed462ae 100644
--- a/bolthur/server/fs/vfs/util.h
+++ b/bolthur/server/fs/vfs/util.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/libauthentication.h b/bolthur/server/libauthentication.h
index c327e790d..2edaf1234 100644
--- a/bolthur/server/libauthentication.h
+++ b/bolthur/server/libauthentication.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -22,7 +22,6 @@
#include
#include
-#include
#include
#include
@@ -31,14 +30,18 @@
#define AUTHENTICATE_RELOAD AUTHENTICATE_FETCH + 1
typedef struct {
- char user[ PATH_MAX ];
- char password[ PATH_MAX ];
+ size_t shm_id;
pid_t process;
} authentication_request_request_t;
typedef struct {
- int result;
-} authentication_request_response_t;
+ char user[ PATH_MAX ];
+ char password[ PATH_MAX ];
+ // used for return
+ char pw_user[ PATH_MAX ];
+ char pw_home[ PATH_MAX ];
+ char pw_shell[ PATH_MAX ];
+} authentication_request_request_data_t;
typedef struct {
pid_t process;
diff --git a/bolthur/server/libconsole.h b/bolthur/server/libconsole.h
index 9ca28bcdc..dca4d3d27 100644
--- a/bolthur/server/libconsole.h
+++ b/bolthur/server/libconsole.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -20,14 +20,13 @@
#ifndef _LIBCONSOLE_H
#define _LIBCONSOLE_H
-#include
-#include
-#include
-#include
#include
#define CONSOLE_ADD RPC_CUSTOM_START
#define CONSOLE_SELECT CONSOLE_ADD + 1
+#define CONSOLE_INPUT CONSOLE_SELECT + 1
+
+#define CONSOLE_MAX_INPUT_SEQUENCE 25
typedef struct console_command_add {
char terminal[ PATH_MAX ];
@@ -37,17 +36,12 @@ typedef struct console_command_add {
pid_t origin;
} console_command_add_t;
-typedef struct {
- char path[ PATH_MAX ];
-} console_command_remove_t;
-
typedef struct {
char path[ PATH_MAX ];
} console_command_select_t;
typedef struct {
- char terminal_path[ PATH_MAX ];
- char destination_path[ PATH_MAX ];
-} console_command_change_t;
+ char input[ CONSOLE_MAX_INPUT_SEQUENCE ];
+} console_command_input_t;
#endif
diff --git a/bolthur/server/libdev.h b/bolthur/server/libdev.h
index 8d479319f..c352cfc7b 100644
--- a/bolthur/server/libdev.h
+++ b/bolthur/server/libdev.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -22,7 +22,6 @@
#include
#include
-#include
#include
#include
@@ -30,12 +29,22 @@
#define DEV_KILL DEV_START + 1
typedef struct {
- char path[ PATH_MAX ];
- char args[];
+ size_t shm_id;
+ size_t data_size;
} dev_command_start_t;
typedef struct {
char path[ PATH_MAX ];
+ char args[];
+} dev_command_start_data_t;
+
+typedef struct {
+ size_t shm_id;
+ size_t data_size;
} dev_command_kill_t;
+typedef struct {
+ char path[ PATH_MAX ];
+} dev_command_kill_data_t;
+
#endif
diff --git a/bolthur/server/libframebuffer.h b/bolthur/server/libframebuffer.h
index a56a9140c..54ce90306 100644
--- a/bolthur/server/libframebuffer.h
+++ b/bolthur/server/libframebuffer.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -22,7 +22,6 @@
#include
#include
-#include
#include
#include
diff --git a/bolthur/server/libhcd.h b/bolthur/server/libhcd.h
new file mode 100644
index 000000000..f0e0f1e9a
--- /dev/null
+++ b/bolthur/server/libhcd.h
@@ -0,0 +1,28 @@
+/**
+ * Copyright (C) 2018 - 2026 bolthur project.
+ *
+ * This file is part of bolthur/kernel.
+ *
+ * bolthur/kernel is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bolthur/kernel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with bolthur/kernel. If not, see .
+ */
+
+#ifndef _LIBHCD_H
+#define _LIBHCD_H
+
+#define HCD_DEVICE_PATH "/dev/usb/hcd"
+
+#define HCD_SUBMIT_CONTROL_MESSAGE RPC_CUSTOM_START
+#define HCD_POLL_INTERRUPT HCD_SUBMIT_CONTROL_MESSAGE + 1
+
+#endif
diff --git a/bolthur/server/libhelper.h b/bolthur/server/libhelper.h
deleted file mode 100644
index 6b4ccf555..000000000
--- a/bolthur/server/libhelper.h
+++ /dev/null
@@ -1,274 +0,0 @@
-/**
- * Copyright (C) 2018 - 2025 bolthur project.
- *
- * This file is part of bolthur/kernel.
- *
- * bolthur/kernel is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * bolthur/kernel is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with bolthur/kernel. If not, see .
- */
-
-#ifndef _LIBHELPER_H
-#define _LIBHELPER_H
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-/**
- * @fn void send_vfs_add_request(vfs_add_request_t*, size_t, unsigned int)
- * @brief Helper to send add request with wait for response
- *
- * @param msg message to send
- * @param size message size or 0
- * @param wait amount of seconds to sleep on rpc raise error
- */
-[[maybe_unused]] static void send_vfs_add_request(
- vfs_add_request_t* msg,
- size_t size,
- unsigned int wait
-) {
- if ( ! msg ) {
- exit( -1 );
- }
- // push in current pid
- msg->handler = getpid();
- size_t size_to_use = size ? size : sizeof( *msg );
- // response id
- size_t response_id = 0;
- // try to send until it worked
- while ( true ) {
- // wait for response
- response_id = bolthur_rpc_raise(
- RPC_VFS_ADD,
- VFS_DAEMON_ID,
- msg,
- size_to_use,
- NULL,
- RPC_VFS_ADD,
- msg,
- size_to_use,
- 0,
- 0,
- NULL,
- false
- );
- if ( errno ) {
- if ( wait ) {
- sleep( wait );
- }
- continue;
- }
- break;
- }
- // get message and data size
- size_t data_size;
- vfs_add_response_t* response = bolthur_rpc_fetch_from_mailbox( response_id, &data_size, true, NULL );
- if ( ! response ) {
- EARLY_STARTUP_PRINT( "%s\r\n", strerror(errno) )
- exit( -1 );
- }
- // stop on success
- if ( VFS_ADD_SUCCESS != response->status ) {
- EARLY_STARTUP_PRINT( "Unable to add: %d\r\n", response->status )
- exit( -1 );
- }
- // free up response
- free( response );
-}
-
-/**
- * @fn void send_vfs_add_request(vfs_add_request_t*, size_t, unsigned int)
- * @brief Helper to send add request with wait for response
- *
- * @param msg message to send
- * @param size message size or 0
- * @param wait amount of seconds to sleep on rpc raise error
- */
-[[maybe_unused]] static void send_vfs_remove_request(
- vfs_remove_request_t* msg,
- unsigned int wait
-) {
- if ( ! msg ) {
- exit( -1 );
- }
- // response id
- size_t response_id = 0;
- // try to send until it worked
- while ( true ) {
- // wait for response
- response_id = bolthur_rpc_raise(
- RPC_VFS_REMOVE,
- VFS_DAEMON_ID,
- msg,
- sizeof( *msg ),
- NULL,
- RPC_VFS_ADD,
- msg,
- sizeof( *msg ),
- 0,
- 0,
- NULL,
- false
- );
- if ( errno ) {
- if ( wait ) {
- sleep( wait );
- }
- continue;
- }
- break;
- }
- // get message and data size
- size_t data_size;
- vfs_remove_response_t* response = bolthur_rpc_fetch_from_mailbox( response_id, &data_size, true, NULL );
- if ( ! response ) {
- EARLY_STARTUP_PRINT( "%s\r\n", strerror(errno) )
- exit( -1 );
- }
- // stop on success
- if ( 0 != response->status ) {
- exit( -1 );
- }
- // free up response
- free( response );
-}
-
-/**
- * @fn void wait_for_path(const char*)
- * @brief Wait for vfs path is existing
- *
- * @param path
- */
-[[maybe_unused]] static void vfs_wait_for_path( const char* path ) {
- struct stat buffer;
- do {
- sleep( 1 );
- } while( 0 != stat( path, &buffer ) );
-}
-
-/**
- * @fn bool dev_add_folder_file_stat(const char*, struct stat* )
- * @brief Helper to add a subfolder or file
- *
- * @param path
- * @param device_info
- * @param count
- * @param mode
- * @return
- */
-[[maybe_unused]] static bool dev_add_folder_file_stat(
- const char* path,
- struct stat* stat
-) {
- // allocate memory for add request
- size_t msg_size = sizeof( vfs_add_request_t ) + 0 * sizeof( size_t );
- vfs_add_request_t* msg = malloc( msg_size );
- if ( ! msg ) {
- return false;
- }
- // clear memory
- memset( msg, 0, msg_size );
- // debug output
- EARLY_STARTUP_PRINT( "Sending \"%s\" to vfs\r\n", path )
- // prepare message structure
- memcpy( &msg->info, stat, sizeof( struct stat ) );
- strncpy( msg->file_path, path, PATH_MAX - 1 );
- // perform add request
- send_vfs_add_request( msg, msg_size, 0 );
- // free stuff
- free( msg );
- return true;
-}
-
-/**
- * @fn bool dev_add_folder_file(const char*, uint32_t*, size_t, mode_t)
- * @brief Helper to add a subfolder or file
- *
- * @param path
- * @param device_info
- * @param count
- * @param mode
- * @return
- */
-[[maybe_unused]] static bool dev_add_folder_file(
- const char* path,
- uint32_t* device_info,
- size_t count,
- mode_t mode
-) {
- // allocate memory for add request
- size_t msg_size = sizeof( vfs_add_request_t ) + count * sizeof( size_t );
- vfs_add_request_t* msg = malloc( msg_size );
- if ( ! msg ) {
- return false;
- }
- // clear memory
- memset( msg, 0, msg_size );
- // debug output
- EARLY_STARTUP_PRINT( "Sending \"%s\" to vfs\r\n", path )
- // prepare message structure
- msg->info.st_mode = mode;
- strncpy( msg->file_path, path, PATH_MAX - 1 );
- // copy over device info stuff
- if ( device_info ) {
- for ( size_t idx = 0; idx < count; idx++ ) {
- msg->device_info[ idx ] = device_info[ idx ];
- }
- }
- // perform add request
- send_vfs_add_request( msg, msg_size, 0 );
- // free stuff
- free( msg );
- return true;
-}
-
-/**
- * @fn bool dev_add_file(const char*, uint32_t*, size_t)
- * @brief Wrapper to add a file
- *
- * @param path
- * @param device_info
- * @param count
- * @return
- */
-[[maybe_unused]] static bool dev_add_file(
- const char* path,
- uint32_t* device_info,
- size_t count
-) {
- return dev_add_folder_file( path, device_info, count, S_IFCHR );
-}
-
-/**
- * @fn bool dev_add_folder(const char*, uint32_t*, size_t)
- * @brief Wrapper to add a folder
- *
- * @param path
- * @param device_info
- * @param count
- * @return
- */
-[[maybe_unused]] static bool dev_add_folder(
- const char* path,
- uint32_t* device_info,
- size_t count
-) {
- return dev_add_folder_file( path, device_info, count, S_IFCHR /*| S_IFDIR*/ );
-}
-
-#endif
diff --git a/bolthur/server/libmbr.h b/bolthur/server/libmbr.h
index 2ba15f1f7..1f154db90 100644
--- a/bolthur/server/libmbr.h
+++ b/bolthur/server/libmbr.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
diff --git a/bolthur/server/libpartition.h b/bolthur/server/libpartition.h
index 63028678c..aacca8945 100644
--- a/bolthur/server/libpartition.h
+++ b/bolthur/server/libpartition.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 - 2025 bolthur project.
+ * Copyright (C) 2018 - 2026 bolthur project.
*
* This file is part of bolthur/kernel.
*
@@ -22,7 +22,6 @@
#include
#include
-#include