Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
f85145e
[SERVICES] added services
Aug 2, 2026
3f345a5
Merge branch 'threading' into services
Aug 2, 2026
fd35887
Merge branch 'threading' into services
Aug 2, 2026
12be274
Merge branch 'threading' into services
Aug 3, 2026
ad3e6ba
Merge branch 'threading' into services
Aug 3, 2026
1947884
Merge branch 'threading' into services
Aug 2, 2026
7195633
Merge branch 'threading' into services
Aug 3, 2026
bed3a6f
Merge branch 'threading' into services
Aug 3, 2026
607ae12
Merge branch 'threading' into services
Aug 3, 2026
707d927
[JOB] always interrupt kernel
Aug 2, 2026
bd268c2
[JOB] proper reuse of kstack
Aug 6, 2026
aa3e1ee
[PACKAGEMAN] tools dir
Aug 7, 2026
543dd0d
[FAT32] stat fix
Aug 8, 2026
605df03
[APP_BUNDLE] added package identifiers (not yet parsed)
Aug 8, 2026
3de0af4
[FS] added transform operations
Aug 8, 2026
8248550
[KBD] differentiate between key press and key continue
Aug 10, 2026
ed8ecdd
[SHARED] sign fix
Aug 10, 2026
9cb5b03
[JOB] replace the stack using virtual mapping
Aug 11, 2026
f7049b1
[MMU] restored flushes to header
Aug 12, 2026
de08b95
[F32] using new allocator
Aug 18, 2026
f0337d6
[JOB] fat32/stack fix
Aug 18, 2026
c09a186
[JOB, CORR] nvm
Aug 18, 2026
688eaad
[TERM] brought back c term
Aug 18, 2026
bfb4687
[JOB] per-page buffer copying on fulfill
Aug 18, 2026
4220fe4
[PROJ] moved shared back to main
Aug 18, 2026
dd82b73
[JOB] simplify stack creation and fix fat32 crash
Aug 18, 2026
ee3ed74
[SHARED] using diylib-compatible branch
Aug 18, 2026
0e12de3
[SHARED] compatibility with new rendering and draw lib refactoring
Aug 29, 2026
6fb93d8
[PROJ] proper-multifile simplemake
Aug 31, 2026
ab9006d
[MMU] barrier before swap
Aug 31, 2026
e3fd85b
Merge branch 'services' of mm.local:dfs/redactedos into services
Aug 31, 2026
13321d0
[JOB] don't map reused buffers twice
Aug 31, 2026
cd46545
[MMU] memory barrier fix for userspace
Aug 31, 2026
4dd8531
Merge branch 'services' of mm.local:dfs/redactedos into services
Aug 31, 2026
a1b4b6e
[REGEX] integrated into redlib
Sep 5, 2026
88d44a1
[DEBUG] watchpoints (real hw only)
Sep 5, 2026
c23da14
[MANUAL] regex syntax fix
Sep 5, 2026
85eeacf
[LIB] shared bump
Sep 5, 2026
ef40bab
[DOS] allowing overlapping clicks again
Sep 5, 2026
eb5cc97
[MMU] avoid unnecessary swaps
Sep 5, 2026
ee5615e
[SYSCALLS] disable kernel sleep until it is stable
Sep 5, 2026
120ec0f
[IFS] cleaner module loading
Sep 5, 2026
7ee8493
[LAUNCHER] restore non-package-manager launcher
Sep 5, 2026
4750340
[SCHEDULER] code cleanup
Sep 12, 2026
7968cdd
[FEATURE_FLAGS] added feature flags file
Sep 12, 2026
de5e4eb
[GIT] gitignore feature flag file
Sep 12, 2026
55b07d4
[FEATURE_FLAGS] added feature flag toggles for current crashes
Sep 12, 2026
fa3f2b6
[WIN] window offset correction for menu
Sep 12, 2026
df2e3d3
[MENU] restored menus behind a feature flag
Sep 14, 2026
427aaa2
[FS] moved module loader to shared
Sep 14, 2026
28084d0
[CURSOR] always render cursor on top
Sep 18, 2026
435d5a9
[MENU] layout fixes
Sep 18, 2026
8df1ec6
[MENU] added clicking on menus
Sep 18, 2026
93119f9
[CURSOR] offset
Sep 18, 2026
2eaf6f8
[FEATURES] moved module strict to features
Sep 18, 2026
9abc535
[MOUSE] complete blank if mouse outside of process
Sep 18, 2026
165c34e
[TRES] allow opening windows with other processes
Sep 18, 2026
0ffd35d
[DEBUGGER] basic ui and trace skeleton call
Sep 18, 2026
7256f71
[DEBUG] thread inspector skeleton call
Sep 18, 2026
2c5ddba
[PROJ] compile libs for user
Sep 18, 2026
c591d35
[THEME] added theme_palette type
Sep 18, 2026
463754a
[SYSCALLS] put panicking js detection behind feature flag
Sep 26, 2026
662e2d5
[SYSCALLS] put panicking js detection behind feature flag
Sep 26, 2026
834f02f
Merge branch 'services' of mm.local:dfs/redactedos into services
Sep 26, 2026
3ad3907
[DOS] properly calculate window locations
Sep 26, 2026
63d73ab
[WINDOWLESS] run launcher in windowless non-headless mode
Sep 26, 2026
00364c4
[CONSOLE] fail silently if not initialized
Sep 26, 2026
6161ae3
[UART] print input back out
Sep 26, 2026
4ee479f
[PROCFS] rewrite using folderfs with permissions
Sep 26, 2026
6153091
[FILES] removed deprecated methods
Sep 26, 2026
bdb7520
[AUTH] added entitlements as a wildcard for any resource
Oct 3, 2026
5a73cd9
[DEBUG, WIP] watchpoint improvements, still not hit on qemu
Oct 3, 2026
c7d97ee
[DEMO] pipe demo
Oct 3, 2026
007b40a
[LFSP] moved to service and new skeleton
Oct 3, 2026
60ccbcd
[LFSP] moved into beyond toolchain
Oct 3, 2026
f0d360f
[LFSP] removed leftover file
Oct 11, 2026
3a37aa4
[AUX_WIN] proper null checking of aux window so it can be reopened
Oct 11, 2026
fd99c27
[ACCESS] moved auth to access
Oct 11, 2026
2cc5e02
[MUTEX] irq restore on failure to lock
Oct 11, 2026
13d0390
[FS] added proper fd synchronization
Oct 11, 2026
8f59e1c
[DEMO] concurrent writing with two procs
Oct 11, 2026
ae4b8d8
[DEMO] codes for demos for more consistent selection
Oct 11, 2026
072b5e2
[PROC_FS] removed old implementation entirely
Oct 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ compile_commands.json
*.red
trace
screenlog.0
feature_flags.mk
6 changes: 3 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[submodule "shared"]
path = shared
url = https://github.com/differrari/redlib.git
[submodule "libs/regex"]
path = libs/regex
url = git@github.com:differrari/regex.git
[submodule "libs/uno"]
path = libs/uno
url = git@github.com:differrari/uno.git
10 changes: 8 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
include common.mk
include feature_flags.mk

OS := $(shell uname)
FS_DIRS := fs/redos/system
Expand All @@ -11,7 +12,7 @@ endif

.PHONY: all shared user kernel clean raspi virt run debug dump prepare-fs help install

all: kshared modules kernel shared user tools libs docs
all: kshared modules kernel shared user tools libs services docs
@echo "Build complete."
./createfs

Expand All @@ -24,7 +25,7 @@ modules: kshared
shared:
$(MAKE) -C shared BUILD_DIR=./build

user: shared prepare-fs
user: shared libs prepare-fs
$(MAKE) -C user

kernel: kshared modules
Expand All @@ -33,6 +34,9 @@ kernel: kshared modules
tools: shared libs prepare-fs
$(MAKE) -C tools

services: shared libs prepare-fs
$(MAKE) -C services

libs: shared
$(MAKE) -C libs

Expand All @@ -50,6 +54,7 @@ clean:
$(MAKE) -C tools $@
$(MAKE) -C modules $@
$(MAKE) -C libs $@
$(MAKE) -C services $@
@echo "removing images"
$(RM) kernel.img kernel.elf dump

Expand All @@ -72,6 +77,7 @@ dump:
$(ARCH)objdump -S -D kernel.elf > dump
$(MAKE) -C user $@
$(MAKE) -C tools $@
$(MAKE) -C services $@

install:
$(MAKE) clean
Expand Down
2 changes: 1 addition & 1 deletion common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ ifeq ($(ARCH), aarch64-none-elf-)
COMMON_FLAGS += -mcpu=cortex-a72 -Wno-error=sized-deallocation
endif

CFLAGS_BASE ?= $(COMMON_FLAGS) -std=c99
CFLAGS_BASE += $(COMMON_FLAGS) -std=c99
CXXFLAGS_BASE ?= $(COMMON_FLAGS) -fno-rtti
LDFLAGS_BASE ?=

Expand Down
10 changes: 10 additions & 0 deletions feature_flags.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Add extra compilation flags meant to enable or disable features at compile time.
# For runtime create a system.config inside ./fs/redos/system.config

# CFLAGS_BASE += -DBUG_CRASH_FSUS # disable or enable a sometimes crashing launcher functionality using the package manager
# CFLAGS_BASE += -DBUG_RESET_TTBR0 # disable or enable a crashing cleanup function in virtual memory
CFLAGS_BASE += -DFEATURE_MENU # disable or enable the menubar
# CFLAGS_BASE += -DMODULE_STRICT # disable or enable strict checking for modules. May panic unnecessarily
CFLAGS_BASE += -DFEATURE_DEBUGGING # enable window button to attach debugger to currently running program
CFLAGS_BASE += -DFEATURE_NEW_PROCFS # enable cleaner /proc filesystem
# CFLAGS_BASE += -DFEATURE_JS_PROTECTION
1 change: 1 addition & 0 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# toolchain (inherited from top-level)

include ../common.mk
include ../feature_flags.mk

CPPFLAGS := -I. -I../shared -I../user -DXHCI_CTX_SIZE=$(XHCI_CTX_SIZE)

Expand Down
112 changes: 112 additions & 0 deletions kernel/access/authorize.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#include "authorize.h"
#include "process/process.h"
#include "alloc/alloc.h"

#define auth_fail { print("[AUTH error] Token %i is not in the %i'd files for resource %i. This incident will be reported.",owner,type,resource_id.id); return false; }

#define AUTH_DEBUG
#ifdef AUTH_DEBUG
#define auth_print(...) print(__VA_ARGS__)
#else
#define auth_print(...)
#endif

hash_map_t *auth_entries;
hash_map_t *auth_entitlements;

static u32 auth_id_counter = 1;

auth_token auth_new_token(){
return auth_id_counter++;
}

auth_token auth_get_proc_token(process_t *t){
if (!t) return (auth_token){};
if (!t->permissions.auth_id){
t->permissions.auth_id = auth_new_token();
auth_print("[AUTH] token %i assigned to process %i",t->permissions.auth_id,t->id);
}
return t->permissions.auth_id;
}

bool auth_valid_proc(auth_token owner, auth_process_actions type, resource resource_id){
hash_map_t *entitlement_entries = hash_map_get(auth_entitlements, &owner, sizeof(auth_token));
if (entitlement_entries){
const resource_types t = resource_process;
auth_entitlement_t *entry = hash_map_get(entitlement_entries, &t, sizeof(resource_types));
if (entry){
if ((entry->action_type & type) == type) return true;
}
}

hash_map_t *resource_entries = hash_map_get(auth_entries, &resource_id, sizeof(resource));
if (!resource_entries) auth_fail;
auth_entry *entry = hash_map_get(resource_entries, &owner, sizeof(auth_token));
if (!entry) auth_fail;
return (entry->actions & type) == type;
}

bool auth_valid(auth_token owner, u32 type, resource resource_id){
if (resource_id.type == resource_process)
return auth_valid_proc(owner, type, resource_id);
auth_print("[AUTH error] Only process resource ids are allowed");
return true;
}

bool request_auth_proc(auth_token owner, auth_process_actions type, resource resource_id){
auth_print("[AUTH debug] Token %i requesting resource %i for action %i",owner,resource_id.id, type);
if (type >= auth_process_count) return false;
hash_map_t *resource_entries = hash_map_get(auth_entries, &resource_id, sizeof(resource));
if (!resource_entries) {
resource_entries = hash_map_create_alloc(64, alloc, release);
hash_map_put(auth_entries, &resource_id, sizeof(resource), resource_entries);
}
if (!resource_entries) return false;
auth_entry *entry = hash_map_get(resource_entries, &owner, sizeof(auth_token));
if (!entry){
entry = new(auth_entry);
hash_map_put(resource_entries, &owner, sizeof(auth_token), entry);
}
if (!entry) return false;
entry->auth_token = owner;
entry->actions |= type;
auth_print("[AUTH debug] Token %i authorized for item %i on resource %i",owner, type, resource_id.id);
return true;
}

bool auth_request(auth_token owner, u32 type, resource resource_id){
if (!auth_entries) auth_entries = hash_map_create_alloc(64,alloc,release);
if (resource_id.type == resource_process)
return request_auth_proc(owner, type, resource_id);
return false;
}


bool auth_entitlement_proc(auth_token owner, auth_process_actions type){
auth_print("[AUTH debug] Token %i entitled to process action %i",owner,type);
if (type >= auth_process_count) return false;
hash_map_t *resource_entries = hash_map_get(auth_entitlements, &owner, sizeof(auth_token));
if (!resource_entries) {
resource_entries = hash_map_create_alloc(64, alloc, release);
hash_map_put(auth_entitlements, &owner, sizeof(auth_token), resource_entries);
}
if (!resource_entries) return false;
const resource_types t = resource_process;
auth_entitlement_t *entry = hash_map_get(resource_entries, &t, sizeof(resource_types));
if (!entry){
entry = new(auth_entitlement_t);
hash_map_put(resource_entries, &t, sizeof(resource_types), entry);
}
if (!entry) return false;
entry->action_type |= type;
entry->auth_type = t;
auth_print("[AUTH debug] Token %i authorized for item %i with entitlement",owner, type);
return true;
}

bool auth_entitlement(auth_token owner, u32 type, resource_types resource_type){
if (!auth_entitlements) auth_entitlements = hash_map_create_alloc(64, alloc, release);
if (resource_type == resource_process)
return auth_entitlement_proc(owner, type);
return false;
}
40 changes: 40 additions & 0 deletions kernel/access/authorize.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#pragma once

#include "types.h"
#include "resources.h"

typedef u32 auth_token;

typedef struct {
u32 auth_token;
u32 actions;
} auth_entry;

typedef enum {
auth_process_send_signals = 1 << 0,
auth_process_intercept_exceptions = 1 << 1,
auth_process_input = 1 << 2, // /proc/<id>/in
auth_process_output = 1 << 3, // /proc/<id>/out

auth_process_state = 1 << 4, // /proc/<id>/state
auth_process_info = 1 << 5, // /proc/<id>/info

auth_process_count = 1 << 6
} auth_process_actions;

typedef union {
struct {
u64 auth_type: 8;
u64 rsvd: 24;
u64 action_type: 32;
};
u64 entitlement;
} auth_entitlement_t;

auth_token auth_get_proc_token(process_t *t);

bool auth_valid(auth_token owner, u32 type, resource resource_id);

bool auth_request(auth_token owner, u32 type, resource resource_id);

bool auth_entitlement(auth_token owner, u32 type, resource_types resource_type);
46 changes: 46 additions & 0 deletions kernel/access/entitlements.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "entitlements.h"
#include "utils/package_info.h"
#include "files/helpers.h"
#include "authorize.h"

#define PROC_ENT_PREF "com.redos.process"

#define ENTITLEMENT_DEBUG
#ifdef ENTITLEMENT_DEBUG
#define ent_print(...) print(__VA_ARGS__)
#else
#define ent_print(...)
#endif

void process_grant_entitlements(process_t *proc){
if (!proc->bundle) return;//TODO: CLI tools don't have access to entitlements

string path = string_format("%s/package.info",proc->bundle);
string_slice package = read_file_slice(path.data);

package_info info = parse_package_info(package.data);

if (!info.entitlements) return;

size_t ents = chunk_array_count(info.entitlements);
auth_token tok = auth_get_proc_token(proc);

for (u64 i = 0; i < ents; i++){
string_slice ent = slice_from_string(CHUNK_ARRAY_GET(string, info.entitlements, i));
if (slice_starts_with(ent, SLICE(PROC_ENT_PREF))){
ent.data += sizeof(PROC_ENT_PREF)-1;
ent.length -= sizeof(PROC_ENT_PREF)-1;
if (ent.length && ent.data[0] == '.'){
ent.data++;
ent.length--;
}
ent_print("[ENTITLEMENT debug] found process entitlement %v",ent);
if (slice_lit_match(ent, "signal", true)) auth_entitlement(tok, auth_process_send_signals, resource_process);
if (slice_lit_match(ent, "exceptions", true)) auth_entitlement(tok, auth_process_intercept_exceptions, resource_process);
if (slice_lit_match(ent, "input", true)) auth_entitlement(tok, auth_process_input, resource_process);
if (slice_lit_match(ent, "output", true)) auth_entitlement(tok, auth_process_output, resource_process);
if (slice_lit_match(ent, "info", true)) auth_entitlement(tok, auth_process_info, resource_process);
if (slice_lit_match(ent, "state", true)) auth_entitlement(tok, auth_process_state, resource_process);
} else print("[ENTITLEMENT error] Unknown entitlement %v",ent);
}
}
5 changes: 5 additions & 0 deletions kernel/access/entitlements.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include "process/process.h"

void process_grant_entitlements(process_t *proc);
39 changes: 39 additions & 0 deletions kernel/access/mutex.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include "mutex.h"
#include "exceptions/irq.h"
#define MOG_MODULE "mutex"
#define MOG_LEVEL MOG_VERBOSE
#include "utils/mog.h"

hash_map_t *mutexed_resources;

u32 mutex_owner_id = 1;

mutex_owner new_mutex_owner(){
return mutex_owner_id++;
}

bool lock_mutex(mutex_owner owner, resource r){
irq_flags_t irq = irq_save_disable();
if (!mutexed_resources) mutexed_resources = hash_map_create(256);
mutex_owner locker = ((u64)hash_map_get(mutexed_resources, &r, sizeof(resource)) & UINT32_MAX);
if (locker) {
irq_restore(irq);
return false;
}
hash_map_put(mutexed_resources, &r, sizeof(resource), (void*)(u64)owner);
locker = ((u64)hash_map_get(mutexed_resources, &r, sizeof(resource)) & UINT32_MAX);
bool res = locker == owner;
irq_restore(irq);
return res;
}

bool unlock_mutex(mutex_owner owner, resource r){
if (!mutexed_resources) return false;
mutex_owner mutexer = ((u64)hash_map_get(mutexed_resources, &r, sizeof(resource)) & UINT32_MAX);
if (owner != mutexer){
mog(ERROR,"mutex owner %i does not own resource %llx",owner,r.resource);
return false;
}
hash_map_remove(mutexed_resources, &r, sizeof(resource), 0);
return true;
}
10 changes: 10 additions & 0 deletions kernel/access/mutex.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#include "resources.h"

typedef u32 mutex_owner;

mutex_owner new_mutex_owner();

bool lock_mutex(mutex_owner owner, resource r);
bool unlock_mutex(mutex_owner owner, resource r);
Loading
Loading