diff --git a/Makefile b/Makefile index 4fa170fe..d0440aa8 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ include common.mk OS := $(shell uname) -FS_DIRS := fs/redos/user +FS_DIRS := fs/redos/system ifeq ($(OS),Darwin) BOOTFS := /Volumes/bootfs @@ -11,7 +11,7 @@ endif .PHONY: all shared user kernel clean raspi virt run debug dump prepare-fs help install -all: kshared modules kernel shared user utils bins +all: kshared modules kernel shared user tools @echo "Build complete." ./createfs @@ -30,11 +30,8 @@ user: shared prepare-fs kernel: kshared modules $(MAKE) -C kernel LOAD_ADDR=$(LOAD_ADDR) XHCI_CTX_SIZE=$(XHCI_CTX_SIZE) QEMU=$(QEMU) TEST=$(TEST) -utils: shared prepare-fs - $(MAKE) -C utils - -bins: shared prepare-fs - $(MAKE) -C bin +tools: shared prepare-fs + $(MAKE) -C tools test: $(MAKE) $(MODE) QEMU=true TEST=true all @@ -44,8 +41,7 @@ clean: $(MAKE) -C shared $@ $(MAKE) -C user $@ $(MAKE) -C kernel $@ - $(MAKE) -C utils $@ - $(MAKE) -C bin $@ + $(MAKE) -C tools $@ $(MAKE) -C modules $@ @echo "removing images" $(RM) kernel.img kernel.elf dump @@ -68,7 +64,6 @@ debug: dump: $(ARCH)objdump -D kernel.elf > dump $(MAKE) -C user $@ - $(MAKE) -C utils $@ install: $(MAKE) clean diff --git a/bin/Makefile b/bin/Makefile deleted file mode 100644 index 8b55fdc7..00000000 --- a/bin/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -include ../common.mk - -SUBDIRS := $(wildcard */.) -SUBCLEAN = $(addsuffix .clean,$(SUBDIRS)) -MAKEFILE := $(shell pwd)/BinMakefile - -all: $(SUBDIRS) - -$(SUBDIRS): - $(MAKE) -f $(MAKEFILE) -C $@ - -clean: $(SUBCLEAN) - -$(SUBCLEAN): %.clean: - $(MAKE) -f $(MAKEFILE) -C $* clean - -clean: $(SUBCLEAN) - -.PHONY: all $(SUBDIRS) diff --git a/kernel/bin/bin_mod.c b/kernel/bin/bin_mod.c index f953bed2..5f094b1f 100644 --- a/kernel/bin/bin_mod.c +++ b/kernel/bin/bin_mod.c @@ -61,7 +61,7 @@ process_t* execute(const char* prog_name, int argc, const char* argv[], uint32_t char *full_name = (strend_case(prog_name, ".elf", true) == 0) ? string_from_literal(prog_name).data : strcat_new(prog_name, ".elf"); if (full_name) { char pathbuf[1024] = {}; - size_t pathlen = string_format_buf(pathbuf, sizeof(pathbuf), "/boot/redos/bin/%s",full_name); + size_t pathlen = string_format_buf(pathbuf, sizeof(pathbuf), "/boot/redos/tools/%s",full_name); process_t *proc = 0; if (pathlen < sizeof(pathbuf) - 1) proc = load_elf_process_path(prog_name, 0, pathbuf, argc, argv); release(full_name); diff --git a/kernel/dev/module_loader.c b/kernel/dev/module_loader.c index 4371d280..787d313e 100644 --- a/kernel/dev/module_loader.c +++ b/kernel/dev/module_loader.c @@ -5,11 +5,14 @@ #include "memory/page_allocator.h" #include "syscalls/syscalls.h" #include "files/dir_list.h" +#include "exceptions/exception_handler.h" //TODO: use hashmaps linked_list_t* modules; void *mod_page = 0; +#define MODULE_STRICT + void* mod_alloc(size_t size){ if (!mod_page) mod_page = page_alloc(PAGE_SIZE); return allocate(mod_page, size, page_alloc); @@ -23,6 +26,17 @@ bool load_module(system_module *module){ if (strcmp(module->mount,"/console")) kprintf("[MODULE] module not initialized due to missing initializer");//TODO: can we make printf silently fail so logging becomes easier? return false; } + if (!module->version){ + string format = string_format("Version number cannot be null for module /%s",module->mount); + if (strcmp(module->mount,"/console")) + #ifdef MODULE_STRICT + panic(format.data,0); + #else + kprintf(format.data); + #endif + string_free(format); + return false; + } if (!module->init()){ if (strcmp(module->mount,"/console")) kprintf("[MODULE] failed to load module %s. Init failed",module->name); return false; diff --git a/kernel/exceptions/irq.c b/kernel/exceptions/irq.c index 01249f19..89e04021 100644 --- a/kernel/exceptions/irq.c +++ b/kernel/exceptions/irq.c @@ -95,7 +95,6 @@ void irq_restore(irq_flags_t flags){ void irq_el1_handler() { save_return_address_interrupt(); - mmu_ttbr0_disable_user(); syscall_depth++; uint32_t irq; if (RPI_BOARD == 3){ diff --git a/kernel/input/input_dispatch.cpp b/kernel/input/input_dispatch.cpp index 9eb2247b..f5243997 100644 --- a/kernel/input/input_dispatch.cpp +++ b/kernel/input/input_dispatch.cpp @@ -192,6 +192,10 @@ void sys_unset_focus(bool close){ } } +u16 sys_get_focused_pid(){ + return focused_proc ? focused_proc->id : 0; +} + void sys_set_secure(bool secure){ secure_mode = secure; } diff --git a/kernel/input/input_dispatch.h b/kernel/input/input_dispatch.h index 4b7df15b..a06a94b3 100644 --- a/kernel/input/input_dispatch.h +++ b/kernel/input/input_dispatch.h @@ -24,6 +24,7 @@ uint16_t sys_subscribe_shortcut_current(keypress kp); void sys_set_focus(int pid); void sys_focus_current(); void sys_unset_focus(bool close); +u16 sys_get_focused_pid(); ///A process can request for shortcuts and others to be disabled void sys_set_secure(bool secure); diff --git a/kernel/kernel.c b/kernel/kernel.c index 2c8c46cd..c4aee85b 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -27,6 +27,7 @@ #include "dtb.h" #include "filesystem/tmp/tmp_fs.h" #include "std/memory.h" +#include "utils/utils.h" extern char __bss_start[]; extern char __bss_end[]; @@ -110,6 +111,8 @@ void kernel_main(uint64_t board_type, uint64_t dtb_pa) { load_module(&scheduler_module); + load_util_mods(); + start_scheduler(); panic("Kernel did not activate any process", 0); diff --git a/kernel/kernel_processes/windows/dos.c b/kernel/kernel_processes/windows/dos.c index d7c6f4ef..e091a8eb 100644 --- a/kernel/kernel_processes/windows/dos.c +++ b/kernel/kernel_processes/windows/dos.c @@ -25,6 +25,8 @@ u16 mode_shortcuts[mode_count]; u16 sid_g = 0; u16 sid_f = 0; u16 newwin_s = 0; +u16 copy_s = 0; +u16 paste_s = 0; static dos_mode mode; static draw_ctx *dos_ctx; @@ -154,6 +156,16 @@ void setup_shortcuts(){ .keys = { KEY_ENTER, 0, 0, 0, 0, 0} }); + // copy_s = sys_subscribe_shortcut_current((keypress){ + // .modifier = KEY_MOD_LMETA, + // .keys = { KEY_C, 0, 0, 0, 0, 0} + // }); + + // paste_s = sys_subscribe_shortcut_current((keypress){ + // .modifier = KEY_MOD_LMETA, + // .keys = { KEY_V, 0, 0, 0, 0, 0} + // }); + for (int i = 0; i < 4; i++) move_shortcuts[i] = sys_subscribe_shortcut_current((keypress){ .modifier = KEY_MOD_LMETA, @@ -178,6 +190,14 @@ void check_shortcuts(){ } if (sys_shortcut_triggered_current(newwin_s)) new_managed_window(); + // if (sys_shortcut_triggered_current(copy_s)){ + // print("Copy"); + // //TODO: How do normal applications know they're supposed to copy/paste? + // } + // if (sys_shortcut_triggered_current(paste_s)){ + // print("Paste"); + // //TODO: How do normal applications know they're supposed to copy/paste? + // } for (int i = 0; i < 4; i++) if (sys_shortcut_triggered_current(move_shortcuts[i])){ int sign = i % 2 == 0 ? -1 : 1; diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index ca117c78..27f06933 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -36,7 +36,6 @@ extern char __kstack_top[]; static uintptr_t *kernel_ttbr0; static uintptr_t *kernel_ttbr1; static uint64_t kernel_ttbr0_hw; -static bool ttbr0_user_on; static bool mmu_verbose; static inline void mmu_flush_icache(); @@ -792,9 +791,9 @@ void debug_mmu_address(uint64_t va){ } void mmu_ttbr0_disable_user() { - asm volatile("msr ttbr0_el1, %0" :: "r"((uint64_t)kernel_ttbr0_hw)); - asm volatile("dsb ish\n\tisb" ::: "memory"); - ttbr0_user_on = false; + // asm volatile("msr ttbr0_el1, %0" :: "r"((uint64_t)kernel_ttbr0_hw)); + // asm volatile("dsb ish\n\tisb" ::: "memory"); + // ttbr0_user_on = false; } void mmu_ttbr0_enable_user() { @@ -802,11 +801,6 @@ void mmu_ttbr0_enable_user() { if (pttbr && pttbr != (uintptr_t*)kernel_ttbr0) hw = pttbr_hw; asm volatile("msr ttbr0_el1, %0" :: "r"(hw)); asm volatile("dsb ish\n\tisb" ::: "memory"); - ttbr0_user_on = pttbr && pttbr != (uintptr_t*)kernel_ttbr0; -} - -bool mmu_ttbr0_user_enabled() { - return ttbr0_user_on; } void mmu_swap_ttbr(mm_struct *mm){ diff --git a/kernel/memory/mmu.h b/kernel/memory/mmu.h index fa7befe9..80d150a1 100644 --- a/kernel/memory/mmu.h +++ b/kernel/memory/mmu.h @@ -48,7 +48,6 @@ void mmu_enable_verbose(); void mmu_swap_ttbr(mm_struct *mm); void mmu_ttbr0_disable_user(); void mmu_ttbr0_enable_user(); -bool mmu_ttbr0_user_enabled(); void mmu_flush_asid(uint16_t asid); void mmu_asid_ensure(mm_struct *mm); void mmu_asid_release(mm_struct *mm); diff --git a/kernel/process/scheduler.c b/kernel/process/scheduler.c index 6c9069df..a772210d 100644 --- a/kernel/process/scheduler.c +++ b/kernel/process/scheduler.c @@ -118,10 +118,9 @@ void update_sleep_timer() { } void switch_proc(ProcSwitchReason reason) { - if (mmu_ttbr0_user_enabled()) panic("switch_proc with user ttbr0 active", current_proc ? current_proc->id : 0); if (proc_count == 0) panic("No processes active", 0); - process_t*prev = current_proc, *next_proc = 0; + process_t *prev = current_proc, *next_proc = 0; if (prev && prev->state == RUNNING) { if (prev == idle_proc) prev->state = BLOCKED; else ready_process(prev); @@ -765,6 +764,7 @@ size_t readdir_proc(const char *path, void *buf, size_t size, file_offset *offse irq_restore(irq); return res; } + irq_restore(irq); return false; } diff --git a/kernel/process/syscall.c b/kernel/process/syscall.c index 2d3f8c81..0460340e 100644 --- a/kernel/process/syscall.c +++ b/kernel/process/syscall.c @@ -35,6 +35,21 @@ int syscall_depth = 0; uintptr_t cpec; +#define SYSCALL_STR(name, arg, write)\ + if (!ctx->arg) return 0;\ + char *name = (char*)ctx->arg;\ + if (!validate_address(ctx, ctx->arg, sizeof(name), write)) return 0; + +#define SYSCALL_ARG(type, name, arg, write) \ + if (!ctx->arg) return 0;\ + type *name = (type*)ctx->arg;\ + if (!validate_address(ctx, (uptr)name, sizeof(type), write)) return 0;\ + +#define SYSCALL_ARG_SIZE(type, name, size, arg, write) \ + if (!ctx->arg) return 0;\ + type *name = (type*)ctx->arg;\ + if (!validate_address(ctx, (uptr)name, size, write)) return 0;\ + //TEST: What happens if we pass another process' data in here? typedef uint64_t (*syscall_entry)(process_t *ctx); @@ -67,7 +82,6 @@ uptr syscall_palloc(process_t *ctx){ if (ctx->mm.ttbr0){ if (ctx->mm.rss_anon_pages + pages > ctx->mm.cap_anon_pages) return 0; - //TODO zalloc likely needs a dedicated syscall to request zeroed on fault explicitly uptr va = mm_alloc_mmap(&ctx->mm, alloc_size, MEM_RW, VMA_KIND_ANON, VMA_FLAG_DEMAND | VMA_FLAG_USERALLOC | VMA_FLAG_ZERO); if (!va) return 0; mmu_flush_asid(ctx->mm.asid); @@ -132,43 +146,19 @@ u64 syscall_free(process_t *ctx){ } u64 syscall_printl(process_t *ctx){ - uintptr_t u = (uintptr_t)ctx->PROC_X0; - if (!u) return 0; - - char buf[256] = {}; - - for (;;) { - size_t copied = 0; - bool term = false; - uaccess_result_t ur = copy_str_from_user(ctx, buf, sizeof(buf), u, &copied, &term); - if (ur != UACCESS_OK && ur != UACCESS_ENAMETOOLONG) return 0; - kprint(buf); - if (term) break; - if (!copied) break; - u += copied; - } - + SYSCALL_STR(str, PROC_X0, false); + kprint((char*)str); return 0; } u64 syscall_read_key(process_t *ctx){ - uintptr_t up = (uintptr_t)ctx->PROC_X0; - keypress tmp = {}; - u64 r = sys_read_input_current(&tmp); - if (!r) return 0; - uaccess_result_t ur = copy_to_user(ctx, up, &tmp, sizeof(tmp)); - if (ur != UACCESS_OK) return 0; - return r; + SYSCALL_ARG(keypress, key, PROC_X0, true); + return sys_read_input_current(key); } u64 syscall_read_event(process_t *ctx){ - uintptr_t up = (uintptr_t)ctx->PROC_X0; - kbd_event tmp = {}; - u64 r = sys_read_event_current(&tmp); - if (!r) return 0; - uaccess_result_t ur = copy_to_user(ctx, up, &tmp, sizeof(tmp)); - if (ur != UACCESS_OK) return 0; - return r; + SYSCALL_ARG(kbd_event, ev, PROC_X0, true); + return sys_read_event_current(ev); } u64 syscall_read_shortcut(process_t *ctx){ @@ -178,60 +168,33 @@ u64 syscall_read_shortcut(process_t *ctx){ u64 syscall_get_mouse(process_t *ctx){ //TODO: we're not fully preventing the mouse from being read outside of proc's window (raw & buttons) - if (get_current_proc_pid() != ctx->id) return 0; - uintptr_t up = (uintptr_t)ctx->PROC_X0; - mouse_data tmp = {}; - tmp.raw = get_raw_mouse_in(); - tmp.raw.scroll = sys_read_scroll_current(); - tmp.position = convert_mouse_position(get_mouse_pos()); - uaccess_result_t ur = copy_to_user(ctx, up, &tmp, sizeof(tmp)); - if (ur != UACCESS_OK) return 0; + if (sys_get_focused_pid() != ctx->id) return 0; + SYSCALL_ARG(mouse_data, inp, PROC_X0, true); + inp->raw = get_raw_mouse_in(); + inp->raw.scroll = sys_read_scroll_current(); + inp->position = convert_mouse_position(get_mouse_pos()); return 0; } uptr syscall_gpu_request_ctx(process_t *ctx){ - uintptr_t up = (uintptr_t)ctx->PROC_X0; - draw_ctx tmp = {}; - get_window_ctx(&tmp); - uaccess_result_t ur = copy_to_user(ctx, up, &tmp, sizeof(tmp)); - if (ur != UACCESS_OK) return 0; + SYSCALL_ARG(draw_ctx, win, PROC_X0, true); + get_window_ctx(win); return 0; } u64 syscall_gpu_flush(process_t *ctx){ - uintptr_t up = (uintptr_t)ctx->PROC_X0; - draw_ctx tmp = {}; - uaccess_result_t ur = copy_from_user(ctx, &tmp, up, sizeof(tmp)); - if (ur != UACCESS_OK) return 0; - - draw_ctx win = {}; - get_window_ctx(&win); - if (!tmp.full_redraw) { - if (tmp.dirty_count > MAX_DIRTY_RECTS) return 0; - if (!win.width || !win.height) return 0; - for (uint32_t i = 0; i < tmp.dirty_count; i++) { - gpu_rect r = tmp.dirty_rects[i]; - if (r.point.x < 0 || r.point.y < 0) return 0; - if ((uint32_t)r.point.x >= win.width || (uint32_t)r.point.y >= win.height) return 0; - if (r.size.width > win.width - (uint32_t)r.point.x) return 0; - if (r.size.height > win.height - (uint32_t)r.point.y) return 0; - } - } - - commit_frame(&tmp, 0); + SYSCALL_ARG(draw_ctx, win, PROC_X0, true); + commit_frame(win, 0); gpu_flush(); return 0; } u64 syscall_gpu_resize_ctx(process_t *ctx){ - uintptr_t up = (uintptr_t)ctx->PROC_X0; uint32_t width = (uint32_t)ctx->PROC_X1; uint32_t height = (uint32_t)ctx->PROC_X2; resize_window(width, height); - draw_ctx tmp = {}; - get_window_ctx(&tmp); - uaccess_result_t ur = copy_to_user(ctx, up, &tmp, sizeof(tmp)); - if (ur != UACCESS_OK) return 0; + SYSCALL_ARG(draw_ctx, win, PROC_X0, true); + get_window_ctx(win); gpu_flush(); return 0; } @@ -261,31 +224,20 @@ u64 syscall_halt(process_t *ctx){ //https://man7.org/linux/man-pages/man7/credentials.7.html ///https://en.wikipedia.org/wiki/Job_control_(Unix) u64 syscall_exec(process_t *ctx){ - uintptr_t upath = (uintptr_t)ctx->PROC_X0; + SYSCALL_STR(prog_name, PROC_X0, false); int argc = (int)ctx->PROC_X1; uintptr_t uargv = (uintptr_t)ctx->PROC_X2; uint32_t mode = (uint32_t)ctx->PROC_X3; - if (argc < 0) return 0; - - char prog_name[256] = {}; - size_t copied = 0; - bool term = false; - uaccess_result_t ur = copy_str_from_user(ctx, prog_name, sizeof(prog_name), upath, &copied, &term); - if (ur != UACCESS_OK) return 0; - if (!term) return 0; - - const int max_args = 64; - if (argc > max_args) return 0; - + if (argc < 0 || argc > 64) return 0; + user_argv_t user_argv = {}; - ur = copy_argv_from_user(ctx, argc, uargv, &user_argv); + uaccess_result_t ur = copy_argv_from_user(ctx, argc, uargv, &user_argv); if (ur != UACCESS_OK) return 0; process_t *p = execute(prog_name, argc, user_argv.argv, mode); - free_argv_from_user(&user_argv); return p ? p->id : 0; } @@ -310,433 +262,162 @@ u64 syscall_get_time(process_t *ctx){ u64 syscall_socket_create(process_t *ctx){ Socket_Role role = (Socket_Role)ctx->PROC_X0; protocol_t protocol = (protocol_t)ctx->PROC_X1; - uintptr_t uextra = (uintptr_t)ctx->PROC_X2; - uintptr_t uout = (uintptr_t)ctx->PROC_X3; - SocketExtraOptions extra = {}; - SocketExtraOptions *pe = 0; - if (uextra) { - uaccess_result_t ur = copy_from_user(ctx, &extra, uextra, sizeof(extra)); - if (ur != UACCESS_OK) return 0; - pe = &extra; - } - - SocketHandle out = {}; - i64 r = create_socket(role, protocol, pe, ctx->id, &out); - if (r < 0) return r; + SYSCALL_ARG(const SocketExtraOptions, extra, PROC_X2, false); + SYSCALL_ARG(SocketHandle, out, PROC_X3, true); - uaccess_result_t ur = copy_to_user(ctx, uout, &out, sizeof(out)); - if (ur != UACCESS_OK) return 0; - return r; + return create_socket(role, protocol, extra, ctx->id, out); } u64 syscall_socket_bind(process_t *ctx){ - uintptr_t uhandle = (uintptr_t)ctx->PROC_X0; + SYSCALL_ARG(SocketHandle,handle,PROC_X0, true); ip_version_t ip_version = (ip_version_t)ctx->PROC_X1; uint16_t port = (uint16_t)ctx->PROC_X2; - SocketHandle handle = {}; - uaccess_result_t ur = copy_from_user(ctx, &handle, uhandle, sizeof(handle)); - if (ur != UACCESS_OK) return 0; - return bind_socket(&handle, port, ip_version, ctx->id); + return bind_socket(handle, port, ip_version, ctx->id); } u64 syscall_socket_connect(process_t *ctx){ - uintptr_t uhandle = (uintptr_t)ctx->PROC_X0; uint8_t dst_kind = (uint8_t)ctx->PROC_X1; - uintptr_t udst = (uintptr_t)ctx->PROC_X2; uint16_t port = (uint16_t)ctx->PROC_X3; - SocketHandle handle = {}; - uaccess_result_t ur = copy_from_user(ctx, &handle, uhandle, sizeof(handle)); - if (ur != UACCESS_OK) return 0; + SYSCALL_ARG(SocketHandle,handle,PROC_X0,true); - net_l4_endpoint ep = {}; - char domain[256] = {}; const void *dst = 0; if (dst_kind == DST_ENDPOINT) { - ur = copy_from_user(ctx, &ep, udst, sizeof(ep)); - if (ur != UACCESS_OK) return 0; - dst = &ep; + SYSCALL_ARG(net_l4_endpoint, ep, PROC_X2, true); + dst = ep; } else if (dst_kind == DST_DOMAIN) { - size_t copied = 0; - bool term = false; - ur = copy_str_from_user(ctx, domain, sizeof(domain), udst, &copied, &term); - if (ur != UACCESS_OK) return 0; - if (!term) return 0; + SYSCALL_STR(domain, PROC_X2, true); dst = domain; } else { return 0; } - return connect_socket(&handle, dst_kind, dst, port, ctx->id); + return connect_socket(handle, dst_kind, dst, port, ctx->id); } u64 syscall_socket_listen(process_t *ctx){ - uintptr_t uhandle = (uintptr_t)ctx->PROC_X0; + SYSCALL_ARG(SocketHandle,handle, PROC_X0, true); int32_t backlog = (int32_t)ctx->PROC_X1; - SocketHandle handle = {}; - uaccess_result_t ur = copy_from_user(ctx, &handle, uhandle, sizeof(handle)); - if (ur != UACCESS_OK) return 0; - return listen_on(&handle, backlog, ctx->id); + return listen_on(handle, backlog, ctx->id); } u64 syscall_socket_accept(process_t *ctx){ - uintptr_t uhandle = (uintptr_t)ctx->PROC_X0; - SocketHandle handle = {}; - uaccess_result_t ur = copy_from_user(ctx, &handle, uhandle, sizeof(handle)); - if (ur != UACCESS_OK) return 0; - accept_on_socket(&handle, ctx->id); + SYSCALL_ARG(SocketHandle,handle, PROC_X0, true); + accept_on_socket(handle, ctx->id); return 1; } u64 syscall_socket_send(process_t *ctx){ - uintptr_t uhandle = (uintptr_t)ctx->PROC_X0; uint8_t dst_kind = (uint8_t)ctx->PROC_X1; - uintptr_t udst = (uintptr_t)ctx->PROC_X2; uint16_t port = (uint16_t)ctx->PROC_X3; - uintptr_t ubuf = (uintptr_t)ctx->PROC_X4; size_t size = (size_t)ctx->regs[5]; - SocketHandle handle = {}; - uaccess_result_t ur = copy_from_user(ctx, &handle, uhandle, sizeof(handle)); - if (ur != UACCESS_OK) return 0; + SYSCALL_ARG(SocketHandle,handle, PROC_X0, true); - net_l4_endpoint ep = {}; - char domain[256] = {}; const void *dst = 0; if (dst_kind == DST_ENDPOINT){ - ur = copy_from_user(ctx, &ep, udst, sizeof(ep)); - if (ur != UACCESS_OK) return 0; - dst = &ep; + SYSCALL_ARG(net_l4_endpoint, ep, PROC_X2, true); + dst = ep; } else if (dst_kind == DST_DOMAIN){ - size_t copied = 0; - bool term = false; - ur = copy_str_from_user(ctx, domain, sizeof(domain), udst, &copied, &term); - if (ur != UACCESS_OK) return 0; - if (!term) return 0; + SYSCALL_STR(domain, PROC_X2, true); dst = domain; } else { return 0; } if (!size) return 0; - + uint64_t alloc_size = (size + 0xFFF) & ~0xFFFULL; - void *kbuf = zalloc(alloc_size); - if (!kbuf) return 0; - ur = copy_from_user(ctx, kbuf, ubuf, size); - if (ur != UACCESS_OK){ - release(kbuf); - return 0; - } + SYSCALL_ARG_SIZE(void, kbuf, alloc_size, PROC_X4, true); + if (!kbuf) return 0; - u64 r = send_on_socket(&handle, dst_kind, dst, port, kbuf, size, ctx->id); - release(kbuf); - return r; + return send_on_socket(handle, dst_kind, dst, port, kbuf, size, ctx->id); } u64 syscall_socket_receive(process_t *ctx){ - uintptr_t uhandle = (uintptr_t)ctx->PROC_X0; - uintptr_t ubuf = (uintptr_t)ctx->PROC_X1; size_t size = (size_t)ctx->PROC_X2; - uintptr_t uout_src = (uintptr_t)ctx->PROC_X3; - - SocketHandle handle = {}; - uaccess_result_t ur = copy_from_user(ctx, &handle, uhandle, sizeof(handle)); - if (ur != UACCESS_OK) return 0; if (!size) return 0; - uint64_t alloc_size = (size + 0xFFF) & ~0xFFFULL; - void *kbuf = zalloc(alloc_size); - if (!kbuf) return 0; + + SYSCALL_ARG(SocketHandle, handle, PROC_X0, true); + SYSCALL_ARG_SIZE(void, buf, alloc_size, PROC_X1, true); - net_l4_endpoint src = {}; - i64 r = receive_from_socket(&handle, kbuf, size, &src, ctx->id); - if (r > 0) { - ur = copy_to_user(ctx, ubuf, kbuf, (size_t)r); - if (ur != UACCESS_OK) r = ur; - } - if (r >= 0) { - ur = copy_to_user(ctx, uout_src, &src, sizeof(src)); - if (ur != UACCESS_OK) r = ur; - } - - release(kbuf); - return r; + SYSCALL_ARG(net_l4_endpoint, src, PROC_X3, true); + return receive_from_socket(handle, buf, size, src, ctx->id); } u64 syscall_socket_close(process_t *ctx){ - uintptr_t uhandle = (uintptr_t)ctx->PROC_X0; - SocketHandle handle = {}; - uaccess_result_t ur = copy_from_user(ctx, &handle, uhandle, sizeof(handle)); - if (ur != UACCESS_OK) return 0; - return close_socket(&handle, ctx->id); + SYSCALL_ARG(SocketHandle,handle, PROC_X0, true); + return close_socket(handle, ctx->id); } u64 syscall_openf(process_t *ctx){ - uintptr_t upath = (uintptr_t)ctx->PROC_X0; - uintptr_t udesc = (uintptr_t)ctx->PROC_X1; - - char req_path[255] = {}; - size_t copied = 0; - bool term = false; - uaccess_result_t ur = copy_str_from_user(ctx, req_path, sizeof(req_path), upath, &copied, &term); - if (ur != UACCESS_OK) return 0; - if (!term) return 0; - + SYSCALL_STR(req_path, PROC_X0, false); char path[255] = {}; - if (!(ctx->PROC_PRIV) && req_path[0] != '/' && ctx->bundle && *ctx->bundle) { - string_format_buf(path, sizeof(path), "%s/%s", ctx->bundle, req_path); - } else if (!(ctx->PROC_PRIV) && strstart_case("/resources/", req_path, true) == 11 && ctx->bundle && *ctx->bundle) { - string_format_buf(path, sizeof(path), "%s%s", ctx->bundle, req_path); - } else { - memcpy(path, req_path, strlen(req_path) + 1); - } - file descriptor = {}; - FS_RESULT r = open_file(path, &descriptor); - if (r != FS_RESULT_SUCCESS) return r; - ur = copy_to_user(ctx, udesc, &descriptor, sizeof(descriptor)); - if (ur != UACCESS_OK) return 0; - return r; + if (!(ctx->PROC_PRIV) && strstart_case("/resources/", req_path,true) == 11){ + string_format_buf(path, sizeof(path),"%s%s", ctx->bundle, req_path); + } else memcpy(path, req_path, strlen(req_path) + 1); + //TODO: Restrict access to own bundle, own fs and require privilege escalation for full-ish filesystem access + SYSCALL_ARG(file,descriptor,PROC_X1, true); + return open_file(path, descriptor); } u64 syscall_readf(process_t *ctx){ - uintptr_t udesc = (uintptr_t)ctx->PROC_X0; - uintptr_t ubuf = (uintptr_t)ctx->PROC_X1; + SYSCALL_ARG(file, descriptor, PROC_X0, true); size_t size = (size_t)ctx->PROC_X2; - file descriptor = {}; - uaccess_result_t ur = copy_from_user(ctx, &descriptor, udesc, sizeof(descriptor)); - if (ur != UACCESS_OK) return 0; - - uint8_t tmp[4096]; - size_t done = 0; - - while (done < size){ - size_t chunk = size - done; - if (chunk > sizeof(tmp)) chunk = sizeof(tmp); - - size_t r = read_file(&descriptor, (char*)tmp, chunk); - if (!r) break; - - ur = copy_to_user(ctx, ubuf + (uintptr_t)done, tmp, r); - if (ur != UACCESS_OK) { - if (!done) done = ur; - break; - } - - done += r; - if (r < chunk) break; - } - - ur = copy_to_user(ctx, udesc, &descriptor, sizeof(descriptor)); - if (ur != UACCESS_OK) return 0; - return done; + SYSCALL_ARG_SIZE(void, buf, size, PROC_X1, true); + return read_file(descriptor, buf, size); } u64 syscall_writef(process_t *ctx){ - uintptr_t udesc = (uintptr_t)ctx->PROC_X0; - uintptr_t ubuf = (uintptr_t)ctx->PROC_X1; + SYSCALL_ARG(file, descriptor, PROC_X0, true); size_t size = (size_t)ctx->PROC_X2; - - file descriptor = {}; - uaccess_result_t ur = copy_from_user(ctx, &descriptor, udesc, sizeof(descriptor)); - if (ur != UACCESS_OK) return 0; - - uint8_t tmp[4096]; - size_t done = 0; - - while (done < size) { - size_t chunk = size - done; - if (chunk > sizeof(tmp)) chunk = sizeof(tmp); - - ur = copy_from_user(ctx, tmp, ubuf + (uintptr_t)done, chunk); - if (ur != UACCESS_OK) { - if (!done) done = ur; - break; - } - - size_t w = write_file(&descriptor, (const char*)tmp, chunk); - if (!w) break; - - done += w; - if (w < chunk) break; - } - - ur = copy_to_user(ctx, udesc, &descriptor, sizeof(descriptor)); - if (ur != UACCESS_OK) return 0; - return done; + SYSCALL_ARG_SIZE(void, buf, size, PROC_X1, false); + return write_file(descriptor, buf, size); } u64 syscall_sreadf(process_t *ctx){ - uintptr_t upath = (uintptr_t)ctx->PROC_X0; - uintptr_t ubuf = (uintptr_t)ctx->PROC_X1; + SYSCALL_STR(path, PROC_X0, false); size_t size = (size_t)ctx->PROC_X2; - - char req_path[255] = {}; - size_t copied = 0; - bool term = false; - uaccess_result_t ur = copy_str_from_user(ctx, req_path, sizeof(req_path), upath, &copied, &term); - if (ur != UACCESS_OK) return 0; - if (!term) return 0; - - char path[255] = {}; - if (!(ctx->PROC_PRIV) && req_path[0] != '/' && ctx->bundle && *ctx->bundle) { - string_format_buf(path, sizeof(path), "%s/%s", ctx->bundle, req_path); - } else if (!(ctx->PROC_PRIV) && strstart_case("/resources/", req_path, true) == 11 && ctx->bundle && *ctx->bundle) { - string_format_buf(path, sizeof(path), "%s%s", ctx->bundle, req_path); - } else { - memcpy(path, req_path, strlen(req_path) + 1); - } - - uint64_t alloc_size = (size + 0xFFF) & ~0xFFFULL; - void *kbuf = zalloc(alloc_size); - if (!kbuf) return 0; - - size_t r = simple_read(path, kbuf, size); - if (r) { - ur = copy_to_user(ctx, ubuf, kbuf, r); - if (ur != UACCESS_OK) { - release(kbuf); - return 0; - } - } - - release(kbuf); - return r; + SYSCALL_ARG_SIZE(void, buf, size, PROC_X1, false); + return simple_read(path, buf, size); } u64 syscall_swritef(process_t *ctx){ - uintptr_t upath = (uintptr_t)ctx->PROC_X0; - uintptr_t ubuf = (uintptr_t)ctx->PROC_X1; + SYSCALL_STR(path, PROC_X0, false); size_t size = (size_t)ctx->PROC_X2; - - char req_path[255] = {}; - size_t copied = 0; - bool term = false; - uaccess_result_t ur = copy_str_from_user(ctx, req_path, sizeof(req_path), upath, &copied, &term); - if (ur != UACCESS_OK) return 0; - if (!term) return 0; - - char path[255] = {}; - if (!(ctx->PROC_PRIV) && req_path[0] != '/' && ctx->bundle && *ctx->bundle) { - string_format_buf(path, sizeof(path), "%s/%s", ctx->bundle, req_path); - } else if (!(ctx->PROC_PRIV) && strstart_case("/resources/", req_path, true) == 11 && ctx->bundle && *ctx->bundle) { - string_format_buf(path, sizeof(path), "%s%s", ctx->bundle, req_path); - } else { - memcpy(path, req_path, strlen(req_path) + 1); - } - - uint64_t alloc_size = (size + 0xFFF) & ~0xFFFULL; - void *kbuf = zalloc(alloc_size); - if (!kbuf) return 0; - - ur = copy_from_user(ctx, kbuf, ubuf, size); - if (ur != UACCESS_OK){ - release(kbuf); - return 0; - } - - size_t r = simple_write(path, kbuf, size); - release(kbuf); - return r; + SYSCALL_ARG_SIZE(void, buf, size, PROC_X1, false); + return simple_write(path, buf, size); } u64 syscall_closef(process_t *ctx){ - uintptr_t udesc = (uintptr_t)ctx->PROC_X0; - file descriptor = {}; - uaccess_result_t ur = copy_from_user(ctx, &descriptor, udesc, sizeof(descriptor)); - if (ur != UACCESS_OK) return 0; - close_file(&descriptor); + SYSCALL_ARG(file,descriptor, PROC_X0, true); + close_file(descriptor); return 0; } u64 syscall_dir_list(process_t *ctx){ - uintptr_t upath = (uintptr_t)ctx->PROC_X0; - uintptr_t ubuf = (uintptr_t)ctx->PROC_X1; + SYSCALL_STR(path,PROC_X0, false); size_t size = (size_t)ctx->PROC_X2; - uintptr_t uoffset = (uintptr_t)ctx->PROC_X3; - - char req_path[255] = {}; - size_t copied = 0; - bool term = false; - uaccess_result_t ur = copy_str_from_user(ctx, req_path, sizeof(req_path), upath, &copied, &term); - if (ur != UACCESS_OK) return 0; - if (!term) return 0; - - char path[255] = {}; - if (!(ctx->PROC_PRIV) && req_path[0] != '/' && ctx->bundle && *ctx->bundle) { - string_format_buf(path, sizeof(path), "%s/%s", ctx->bundle, req_path); - } else if (!(ctx->PROC_PRIV) && strstart_case("/resources/", req_path, true) == 11 && ctx->bundle && *ctx->bundle) { - string_format_buf(path, sizeof(path), "%s%s", ctx->bundle, req_path); - } else { - memcpy(path, req_path, strlen(req_path) + 1); - } - - uint64_t off = 0; - ur = copy_from_user(ctx, &off, uoffset, sizeof(off)); - if (ur != UACCESS_OK) return 0; - - uint64_t alloc_size = (size + 0xFFF) & ~0xFFFULL; - void *kbuf = zalloc(alloc_size); - if (!kbuf) return 0; - - size_t r = list_directory_contents(path, kbuf, size, &off); - if (r) { - ur = copy_to_user(ctx, ubuf, kbuf, r); - if (ur != UACCESS_OK) { - release(kbuf); - return 0; - } - } - ur = copy_to_user(ctx, uoffset, &off, sizeof(off)); - release(kbuf); - if (ur != UACCESS_OK) return 0; - return r; + SYSCALL_ARG_SIZE(void, buf, size, PROC_X1, true); + SYSCALL_ARG(u64,offset,PROC_X3, true); + return list_directory_contents(path, buf, size, offset); } u64 syscall_stat(process_t *ctx){ - uintptr_t upath = (uintptr_t)ctx->PROC_X0; - uintptr_t uout = (uintptr_t)ctx->PROC_X1; - - char req_path[255] = {}; - size_t copied = 0; - bool term = false; - uaccess_result_t ur = copy_str_from_user(ctx, req_path, sizeof(req_path), upath, &copied, &term); - if (ur != UACCESS_OK) return 0; - if (!term) return 0; - - char path[255] = {}; - if (!(ctx->PROC_PRIV) && req_path[0] != '/' && ctx->bundle && *ctx->bundle) { - string_format_buf(path, sizeof(path), "%s/%s", ctx->bundle, req_path); - } else if (!(ctx->PROC_PRIV) && strstart_case("/resources/", req_path, true) == 11 && ctx->bundle && *ctx->bundle) { - string_format_buf(path, sizeof(path), "%s%s", ctx->bundle, req_path); - } else { - memcpy(path, req_path, strlen(req_path) + 1); - } - - fs_stat st = {}; - FS_RESULT res = get_stat(path, &st); - if (res != FS_RESULT_SUCCESS) return res; - - ur = copy_to_user(ctx, uout, &st, sizeof(st)); - if (ur != UACCESS_OK) return 0; - return FS_RESULT_SUCCESS; + SYSCALL_STR(path,PROC_X0, false); + SYSCALL_ARG(fs_stat,out_stat,PROC_X1, true); + return get_stat(path, out_stat); } u64 syscall_trunc(process_t* ctx){ - uintptr_t udesc = (uintptr_t)ctx->PROC_X0; - size_t size = (size_t)ctx->PROC_X1; - file descriptor = {}; - uaccess_result_t ur = copy_from_user(ctx, &descriptor, udesc, sizeof(descriptor)); - if (ur != UACCESS_OK) return 0; - bool ok = truncate(&descriptor, size); - if (!ok) return 0; - ur = copy_to_user(ctx, udesc, &descriptor, sizeof(descriptor)); - if (ur != UACCESS_OK) return 0; - return ok; + SYSCALL_ARG(file,descriptor,PROC_X0, true); + size_t size = ctx->PROC_X1; + return truncate(descriptor, size); } // uint64_t syscall_load_fsmod(process_t *ctx){ @@ -933,18 +614,16 @@ void sync_el0_handler_c(){ } else { if (currentEL == 1){ if (syscall_depth < 3){ - if (syscall_depth < 1) kprintf("System has crashed. ESR: %llx. ELR: %llx. FAR: %llx", esr, elr, far); - if (syscall_depth < 2) { - uint64_t ksp = 0; - asm volatile ("mov %0, sp" : "=r"(ksp)); - coredump(esr, elr, far, ksp); - } - handle_exception("UNEXPECTED EXCEPTION",ec); + kprintf("System has crashed. ESR: %llx. ELR: %llx. FAR: %llx", esr, elr, far); + uint64_t ksp = 0; + asm volatile ("mov %0, sp" : "=r"(ksp)); + coredump(esr, elr, far, ksp); } + handle_exception("UNEXPECTED EXCEPTION", ec); while (true); } else { kprintf("Process has crashed. ESR: %llx. ELR: %llx. FAR: %llx. SP: %llx", esr, elr, far, proc->sp); - if (syscall_depth < 2) coredump(esr, elr, far, proc->sp); + if (syscall_depth <= 2) coredump(esr, elr, far, proc->sp); syscall_depth--; stop_current_process(ec); } diff --git a/kernel/process/uaccess.c b/kernel/process/uaccess.c index fff347ae..6705f0e9 100644 --- a/kernel/process/uaccess.c +++ b/kernel/process/uaccess.c @@ -61,6 +61,33 @@ uaccess_result_t copy_from_user(process_t *proc, void *dst, uintptr_t src, size_ return UACCESS_OK; } +bool validate_address(process_t *proc, uintptr_t addr, size_t size, bool want_write) { + if (!addr && size) return false; + if (!size) return true; + if (!access_ok_range(proc, addr, size, want_write)) return false; + + while (size) { + size_t off = addr & (PAGE_SIZE - 1); + size_t chunk = PAGE_SIZE - off; + if (chunk > size) chunk = size; + + int st = 0; + mmu_translate((uint64_t*)proc->mm.ttbr0, addr, &st); + if (st) { + uint64_t esr = (0x24ULL << 26) | 0x7ULL | (want_write << 6); + if (!mm_try_handle_page_fault(proc, addr, esr)) return false; + + mmu_translate((uint64_t*)proc->mm.ttbr0, addr, &st); + if (st) return false; + } + + addr += chunk; + size -= chunk; + } + + return true; +} + uaccess_result_t copy_to_user(process_t *proc, uintptr_t dst, const void *src, size_t size) { if (!src && size) return UACCESS_EINVAL; if (!size) return UACCESS_OK; diff --git a/kernel/process/uaccess.h b/kernel/process/uaccess.h index 387195d4..598d6a8e 100644 --- a/kernel/process/uaccess.h +++ b/kernel/process/uaccess.h @@ -22,6 +22,7 @@ typedef struct user_argv { } user_argv_t; bool access_ok_range(process_t *proc, uintptr_t addr, size_t size, bool want_write); +bool validate_address(process_t *proc, uintptr_t addr, size_t size, bool want_write); uaccess_result_t copy_from_user(process_t *proc, void *dst, uintptr_t src, size_t size); uaccess_result_t copy_to_user(process_t *proc, uintptr_t dst, const void *src, size_t size); uaccess_result_t copy_str_from_user(process_t *proc, char *dst, size_t dst_size, uintptr_t src, size_t *out_copied, bool *out_terminated); diff --git a/kernel/sysregs.h b/kernel/sysregs.h index 94f883d3..5754ba31 100644 --- a/kernel/sysregs.h +++ b/kernel/sysregs.h @@ -4,6 +4,7 @@ // *************************************** #define SCTLR_RESERVED (3 << 28) | (3 << 22) | (1 << 20) | (1 << 11) +#define SCTRL_NOT_ALIGN_ACCESS_DISABLED (1 << 6) #define SCTLR_EE_LITTLE_ENDIAN (0 << 25) #define SCTLR_EOE_LITTLE_ENDIAN (0 << 24) #define SCTLR_I_CACHE_DISABLED (0 << 12) @@ -13,7 +14,7 @@ #define SCTLR_MMU_DISABLED (0 << 0) #define SCTLR_MMU_ENABLED (1 << 0) -#define SCTLR_VALUE_MMU_DISABLED (SCTLR_RESERVED | SCTLR_EE_LITTLE_ENDIAN | SCTLR_I_CACHE_ENABLED | SCTLR_D_CACHE_ENABLED | SCTLR_MMU_DISABLED) +#define SCTLR_VALUE_MMU_DISABLED (SCTLR_RESERVED | SCTRL_NOT_ALIGN_ACCESS_DISABLED | SCTLR_EE_LITTLE_ENDIAN | SCTLR_I_CACHE_ENABLED | SCTLR_D_CACHE_ENABLED | SCTLR_MMU_DISABLED) // *************************************** // HCR_EL2, Hypervisor Configuration Register (EL2), Page 2487 of AArch64-Reference-Manual. diff --git a/kernel/theme/theme.c b/kernel/theme/theme.c index 11130e8c..85069a77 100644 --- a/kernel/theme/theme.c +++ b/kernel/theme/theme.c @@ -149,6 +149,7 @@ u64 reload(void *ctx, size_t len){ system_module theme_mod = (system_module){ .name = "theme", .mount = "theme", + .version = VERSION_NUM(0, 1, 0, 0), .init = load_theme, .open = vfs_open, .write = vfs_write, diff --git a/kernel/utils/clipboard/clipboard.c b/kernel/utils/clipboard/clipboard.c new file mode 100644 index 00000000..f4d067e6 --- /dev/null +++ b/kernel/utils/clipboard/clipboard.c @@ -0,0 +1,18 @@ +#include "clipboard.h" +#include "data/struct/ring_buffer.h" +#include "files/buffer.h" +#include "syscalls/syscalls.h" +#include "files/stack_fs.h" +#include "console/kio.h" + +system_module clipboard_mod = { + .name = "clipboard", + .mount = "clipboard", + .version = VERSION_NUM(0, 1, 0, 0), + .init = stackfs_init, + .open = stackfs_open, + .read = stackfs_read, + .write = stackfs_write, + .readdir = stackfs_readdir, + .getstat = stackfs_stat +}; \ No newline at end of file diff --git a/kernel/utils/clipboard/clipboard.h b/kernel/utils/clipboard/clipboard.h new file mode 100644 index 00000000..1a5b8a15 --- /dev/null +++ b/kernel/utils/clipboard/clipboard.h @@ -0,0 +1,5 @@ +#pragma once + +#include "files/system_module.h" + +extern system_module clipboard_mod; \ No newline at end of file diff --git a/kernel/utils/utils.h b/kernel/utils/utils.h new file mode 100644 index 00000000..e721ce63 --- /dev/null +++ b/kernel/utils/utils.h @@ -0,0 +1,11 @@ +#pragma once + +#include "dev/module_loader.h" + +#include "clipboard/clipboard.h" + +static inline bool load_util_mods(){ + return + load_module(&clipboard_mod) && + true; +} \ No newline at end of file diff --git a/shared b/shared index 7c696e29..15b0d66d 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit 7c696e29dbac2315d5f614355456fbf8414262ce +Subproject commit 15b0d66d0d6f4fb7f6613ea835984b7da0b731bf diff --git a/utils/Makefile b/tools/Makefile similarity index 67% rename from utils/Makefile rename to tools/Makefile index 783a96f8..e4e94b1d 100644 --- a/utils/Makefile +++ b/tools/Makefile @@ -3,21 +3,22 @@ include ../common.mk SUBDIRS := $(wildcard */.) SUBCLEAN = $(addsuffix .clean,$(SUBDIRS)) SUBDUMP = $(addsuffix .dump,$(SUBDIRS)) +MAKEFILE := $(shell pwd)/ToolMakefile all: $(SUBDIRS) +dump: $(SUBDUMP) + $(SUBDIRS): - $(MAKE) -C $@ + $(MAKE) -f $(MAKEFILE) -C $@ clean: $(SUBCLEAN) - -dump: $(SUBDUMP) $(SUBCLEAN): %.clean: - $(MAKE) -C $* clean - + $(MAKE) -f $(MAKEFILE) -C $* clean + $(SUBDUMP): %.dump: - $(MAKE) -C $* dump + $(MAKE) -f $(MAKEFILE) -C $* dump clean: $(SUBCLEAN) diff --git a/bin/BinMakefile b/tools/ToolMakefile similarity index 97% rename from bin/BinMakefile rename to tools/ToolMakefile index 3ac66ce2..be652fba 100644 --- a/bin/BinMakefile +++ b/tools/ToolMakefile @@ -15,7 +15,7 @@ DEP := $(C_SRC:%.c=$(BUILD_DIR)/%.d) $(CPP_SRC:%.cpp=$(BUILD_DIR)/%.d) NAME := $(notdir $(CURDIR)) ELF := $(NAME).elf TARGET := $(NAME).bin -LOCATION := ../../fs/redos/bin/ +LOCATION := ../../fs/redos/tools/ .PHONY: prepare all clean diff --git a/bin/read/read.c b/tools/read/read.c similarity index 100% rename from bin/read/read.c rename to tools/read/read.c diff --git a/bin/test/test.c b/tools/test/test.c similarity index 100% rename from bin/test/test.c rename to tools/test/test.c diff --git a/user/Makefile b/user/Makefile index f10cb34c..7de89320 100644 --- a/user/Makefile +++ b/user/Makefile @@ -1,59 +1,25 @@ -#user - include ../common.mk -CPPFLAGS := -I. -I../shared -CFLAGS := $(CFLAGS_BASE) -g $(CPPFLAGS) -CXXFLAGS := $(CXXFLAGS_BASE) $(CPPFLAGS) -LDFLAGS := -T $(shell ls *.ld) - -CLEAN_OBJS := $(shell find . -name '*.o') -CLEAN_DEPS := $(shell find . -name '*.d') -C_SRC := $(shell find . -name '*.c') -CPP_SRC := $(shell find . -name '*.cpp') -OBJ := $(C_SRC:%.c=$(BUILD_DIR)/%.o) $(CPP_SRC:%.cpp=.$(BUILD_DIR)/%.o) -DEP := $(C_SRC:%.c=$(BUILD_DIR)/%.d) $(CPP_SRC:%.cpp=.$(BUILD_DIR)/%.d) - -NAME := $(notdir $(CURDIR)) -ELF := $(NAME).elf -TARGET := $(NAME).bin -PACKAGE := $(NAME).red -LOCATION := ../fs/redos/user/ - - -.PHONY: prepare all clean - -all: prepare $(PACKAGE)/$(TARGET) - -prepare: - mkdir -p $(BUILD_DIR) - mkdir -p $(PACKAGE) - cp -r resources $(PACKAGE) - cp package.info $(PACKAGE) - -$(PACKAGE)/$(TARGET): ../shared/libshared.a $(OBJ) - $(VLD) $(LDFLAGS) -o $(PACKAGE)/$(ELF) -g $(addprefix $(BUILD_DIR)/,$(notdir $(OBJ))) ../shared/libshared.a - $(OBJCOPY) -O binary $(PACKAGE)/$(ELF) $@ - cp -r $(PACKAGE) $(LOCATION) - -$(BUILD_DIR)/%.o: %.S - @mkdir -p $(dir $@) - $(VAS) $(CFLAGS) -c $< -o $@ +SUBDIRS := $(wildcard */.) +SUBCLEAN = $(addsuffix .clean,$(SUBDIRS)) +SUBDUMP = $(addsuffix .dump,$(SUBDIRS)) +MAKEFILE := $(shell pwd)/UserMakefile -$(BUILD_DIR)/%.o: %.c - @mkdir -p $(dir $@) - $(VCC) $(CFLAGS) -c -MMD -MP $< -o $@ +all: $(SUBDIRS) -$(BUILD_DIR)/%.o: %.cpp - @mkdir -p $(dir $@) - $(VCXX) $(CXXFLAGS) -c -MMD -MP $< -o $@ +$(SUBDIRS): + $(MAKE) -f $(MAKEFILE) -C $@ -clean: - $(RM) $(CLEAN_OBJS) $(CLEAN_DEPS) $(TARGET) - $(RM) -r $(PACKAGE) $(BUILD_DIR) +clean: $(SUBCLEAN) + +dump: $(SUBDUMP) -dump: all - $(ARCH)objdump -S $(NAME).red/$(NAME).elf > dump +$(SUBCLEAN): %.clean: + $(MAKE) -f $(MAKEFILE) -C $* clean + +$(SUBDUMP): %.dump: + $(MAKE) -f $(MAKEFILE) -C $* dump +clean: $(SUBCLEAN) --include $(DEP) +.PHONY: all $(SUBDIRS) \ No newline at end of file diff --git a/utils/theme/Makefile b/user/UserMakefile similarity index 97% rename from utils/theme/Makefile rename to user/UserMakefile index e387d78f..d18b4a53 100644 --- a/utils/theme/Makefile +++ b/user/UserMakefile @@ -16,8 +16,7 @@ NAME := $(notdir $(CURDIR)) ELF := $(NAME).elf TARGET := $(NAME).bin PACKAGE := $(NAME).red -LOCATION := ../../fs/redos/user/ - +LOCATION := ../../fs/redos/system/ .PHONY: prepare all clean diff --git a/user/default_process.c b/user/demo/default_process.c similarity index 91% rename from user/default_process.c rename to user/demo/default_process.c index 23946e49..5bf829f1 100644 --- a/user/default_process.c +++ b/user/demo/default_process.c @@ -154,9 +154,26 @@ void write_large_file(){ } +void copypaste(){ + char *copythis = "hello"; + swritef("/clipboard", copythis, strlen(copythis)); + + char buf[10]; + sreadf("/clipboard", buf, 10); + + char *copythis2 = "hello1"; + swritef("/clipboard", copythis2, strlen(copythis2)); + + char *copythis3 = "hello2"; + swritef("/clipboard", copythis3, strlen(copythis3)); + + print("Pasted text %s",buf); + +} + int main(int argc, char* argv[]){ - write_large_file(); + copypaste(); return 0; } diff --git a/user/default_process.h b/user/demo/default_process.h similarity index 100% rename from user/default_process.h rename to user/demo/default_process.h diff --git a/user/package.info b/user/demo/package.info similarity index 100% rename from user/package.info rename to user/demo/package.info diff --git a/user/resources/jest.bmp b/user/demo/resources/jest.bmp similarity index 100% rename from user/resources/jest.bmp rename to user/demo/resources/jest.bmp diff --git a/user/resources/scale.wav b/user/demo/resources/scale.wav similarity index 100% rename from user/resources/scale.wav rename to user/demo/resources/scale.wav diff --git a/user/resources/test.png b/user/demo/resources/test.png similarity index 100% rename from user/resources/test.png rename to user/demo/resources/test.png diff --git a/user/resources/test_unc.png b/user/demo/resources/test_unc.png similarity index 100% rename from user/resources/test_unc.png rename to user/demo/resources/test_unc.png diff --git a/utils/filebrowser/Makefile b/user/filebrowser/Makefile similarity index 100% rename from utils/filebrowser/Makefile rename to user/filebrowser/Makefile diff --git a/utils/filebrowser/main.c b/user/filebrowser/main.c similarity index 96% rename from utils/filebrowser/main.c rename to user/filebrowser/main.c index ff5ab555..454db633 100644 --- a/utils/filebrowser/main.c +++ b/user/filebrowser/main.c @@ -121,6 +121,13 @@ void enter(const char *name){ string_free(full_path); halt(0); } + + if (strend(name, ".c") == 0){ + const char* argv[1] = { full_path.data }; + exec("/shared/applications/braincode.red/braincode.elf", 1, argv, EXEC_MODE_DEFAULT); + string_free(full_path); + halt(0); + } fs_stat st = {}; if (!statf(full_path.data, &st)){ diff --git a/utils/launcher/Makefile b/user/launcher/Makefile similarity index 100% rename from utils/launcher/Makefile rename to user/launcher/Makefile diff --git a/utils/launcher/main.c b/user/launcher/main.c similarity index 98% rename from utils/launcher/main.c rename to user/launcher/main.c index 123da848..312f6d6e 100644 --- a/utils/launcher/main.c +++ b/user/launcher/main.c @@ -69,6 +69,7 @@ package_info get_pkg_info(char* info_path){ } void handle_entry(const char *directory, const char *file) { + if (!strcmp_case("launcher.red",file,true)) return; string fullpath = string_format("%s/%s",directory, (uintptr_t)file); uint16_t ext_loc = find_extension((char*)file); string_slice name = make_string_slice(fullpath.data, fullpath.length - strlen(file), ext_loc); @@ -94,7 +95,7 @@ void load_entries(){ } chunk_array_reset(entries); traverse_directory("/shared/applications", false, handle_entry); - traverse_directory("/boot/redos/user", false, handle_entry); + traverse_directory("/boot/redos/system", false, handle_entry); } void draw_desktop(){ diff --git a/utils/launcher/package_info.c b/user/launcher/package_info.c similarity index 100% rename from utils/launcher/package_info.c rename to user/launcher/package_info.c diff --git a/utils/launcher/package_info.h b/user/launcher/package_info.h similarity index 100% rename from utils/launcher/package_info.h rename to user/launcher/package_info.h diff --git a/user/linker.ld b/user/linker.ld deleted file mode 100644 index 3060b9cd..00000000 --- a/user/linker.ld +++ /dev/null @@ -1,32 +0,0 @@ -ENTRY(main) -PHDRS { - text PT_LOAD FLAGS(5); - data PT_LOAD FLAGS(6); -} - -SECTIONS { - . = 0x1000; - - .text : { - *(.text .text.*) - }:text - - .rodata : { - *(.rodata .rodata.*) - } :text - . = ALIGN(0x1000); - - .data : { - *(.data .data.*) - } :data - - .bss (NOLOAD) : { - __bss_start = .; - *(.bss .bss.* COMMON) - __bss_end = .; - } :data - - /DISCARD/ : { - *(.comment .note .eh_frame) - } -} \ No newline at end of file diff --git a/utils/terminal/Makefile b/user/terminal/Makefile similarity index 100% rename from utils/terminal/Makefile rename to user/terminal/Makefile diff --git a/utils/terminal/main.cpp b/user/terminal/main.cpp similarity index 100% rename from utils/terminal/main.cpp rename to user/terminal/main.cpp diff --git a/utils/terminal/terminal.cpp b/user/terminal/terminal.cpp similarity index 100% rename from utils/terminal/terminal.cpp rename to user/terminal/terminal.cpp diff --git a/utils/terminal/terminal.hpp b/user/terminal/terminal.hpp similarity index 100% rename from utils/terminal/terminal.hpp rename to user/terminal/terminal.hpp diff --git a/utils/theme/main.c b/user/theme/main.c similarity index 100% rename from utils/theme/main.c rename to user/theme/main.c