diff --git a/brewos.iso b/brewos.iso index cc2891e..2e5f78d 100644 Binary files a/brewos.iso and b/brewos.iso differ diff --git a/build/brewos.elf b/build/brewos.elf index de32de5..fc2a39a 100755 Binary files a/build/brewos.elf and b/build/brewos.elf differ diff --git a/build/cli_apps/fs_commands.o b/build/cli_apps/fs_commands.o index 30ab72b..23216d2 100644 Binary files a/build/cli_apps/fs_commands.o and b/build/cli_apps/fs_commands.o differ diff --git a/build/cmd.o b/build/cmd.o index 49a7504..8f738e8 100644 Binary files a/build/cmd.o and b/build/cmd.o differ diff --git a/build/fat32.o b/build/fat32.o index 061ad77..3903abd 100644 Binary files a/build/fat32.o and b/build/fat32.o differ diff --git a/build/memory_manager.o b/build/memory_manager.o index b9ae500..efb2b26 100644 Binary files a/build/memory_manager.o and b/build/memory_manager.o differ diff --git a/iso_root/brewos.elf b/iso_root/brewos.elf index de32de5..fc2a39a 100755 Binary files a/iso_root/brewos.elf and b/iso_root/brewos.elf differ diff --git a/src/kernel/cli_apps/cli_apps.h b/src/kernel/cli_apps/cli_apps.h index ecbceb0..b8d5f10 100644 --- a/src/kernel/cli_apps/cli_apps.h +++ b/src/kernel/cli_apps/cli_apps.h @@ -28,6 +28,8 @@ void cli_cmd_rm(char *args); void cli_cmd_echo(char *args); void cli_cmd_cat(char *args); void cli_cmd_touch(char *args); +void cli_cmd_cp(char *args); +void cli_cmd_mv(char *args); // Memory management commands void cli_cmd_meminfo(char *args); diff --git a/src/kernel/cli_apps/fs_commands.c b/src/kernel/cli_apps/fs_commands.c index 20b655a..f983235 100644 --- a/src/kernel/cli_apps/fs_commands.c +++ b/src/kernel/cli_apps/fs_commands.c @@ -275,3 +275,116 @@ void cli_cmd_touch(char *args) { cli_write(filename); cli_write("\n"); } + +void cli_cmd_cp(char *args) { + char *src = args; + while (*src == ' ') src++; + + char *dest = src; + while (*dest && *dest != ' ') dest++; + + if (*dest) { + *dest = 0; + dest++; + while (*dest == ' ') dest++; + } + + if (!*src || !*dest) { + cli_write("Usage: cp \n"); + return; + } + + // Check if dest is a directory + char final_dest[256]; + cli_strcpy(final_dest, dest); + + if (fat32_is_directory(dest)) { + // Append filename from src to dest + int len = cli_strlen(final_dest); + if (len > 0 && final_dest[len-1] != '/') { + final_dest[len++] = '/'; + final_dest[len] = 0; + } + + // Extract filename from src + const char *fname = src; + const char *p = src; + while (*p) { + if (*p == '/') fname = p + 1; + p++; + } + + // Append + int j = 0; + while (fname[j]) { + final_dest[len++] = fname[j++]; + } + final_dest[len] = 0; + } + + FAT32_FileHandle *fh_in = fat32_open(src, "r"); + if (!fh_in) { + cli_write("Error: Cannot open source file: "); + cli_write(src); + cli_write("\n"); + return; + } + + FAT32_FileHandle *fh_out = fat32_open(final_dest, "w"); + if (!fh_out) { + cli_write("Error: Cannot create destination file: "); + cli_write(final_dest); + cli_write("\n"); + fat32_close(fh_in); + return; + } + + char buffer[4096]; + int bytes; + while ((bytes = fat32_read(fh_in, buffer, sizeof(buffer))) > 0) { + fat32_write(fh_out, buffer, bytes); + } + + fat32_close(fh_in); + fat32_close(fh_out); + + cli_write("Copied "); + cli_write(src); + cli_write(" to "); + cli_write(final_dest); + cli_write("\n"); +} + +void cli_cmd_mv(char *args) { + // Parse args similar to cp + char *src = args; + while (*src == ' ') src++; + + char *dest = src; + while (*dest && *dest != ' ') dest++; + + if (*dest) { + *dest = 0; + dest++; + while (*dest == ' ') dest++; + } + + if (!*src || !*dest) { + cli_write("Usage: mv \n"); + return; + } + + + char cp_args[512]; + int i = 0; + const char *s = src; + while (*s) cp_args[i++] = *s++; + cp_args[i++] = ' '; + const char *d = dest; + while (*d) cp_args[i++] = *d++; + cp_args[i] = 0; + + cli_cmd_cp(cp_args); + + fat32_delete(src); +} diff --git a/src/kernel/cmd.c b/src/kernel/cmd.c index f89d67b..d51d144 100644 --- a/src/kernel/cmd.c +++ b/src/kernel/cmd.c @@ -451,6 +451,10 @@ static const CommandEntry commands[] = { {"cat", cli_cmd_cat}, {"TOUCH", cli_cmd_touch}, {"touch", cli_cmd_touch}, + {"CP", cli_cmd_cp}, + {"cp", cli_cmd_cp}, + {"MV", cli_cmd_mv}, + {"mv", cli_cmd_mv}, // Memory Management Commands {"MEMINFO", cli_cmd_meminfo}, {"meminfo", cli_cmd_meminfo}, @@ -479,6 +483,8 @@ static const CommandEntry commands[] = { {"pcilist", cli_cmd_pcilist}, {"COMPC", cli_cmd_cc}, {"compc", cli_cmd_cc}, + {"CC", cli_cmd_cc}, + {"cc", cli_cmd_cc}, {NULL, NULL} }; @@ -541,6 +547,38 @@ static void cmd_exec_single(char *cmd) { } } + // Check for executable in /Apps/ + char app_path[256]; + char *p = app_path; + const char *prefix = "/Apps/"; + while (*prefix) *p++ = *prefix++; + char *c = cmd; + while (*c) *p++ = *c++; + *p = 0; + + FAT32_FileHandle *app_fh = fat32_open(app_path, "r"); + if (app_fh) { + uint8_t *app_buffer = (uint8_t*)kmalloc(VM_MEMORY_SIZE); + if (app_buffer) { + int size = fat32_read(app_fh, app_buffer, VM_MEMORY_SIZE); + fat32_close(app_fh); + + if (size > 0) { + int res = vm_exec(app_buffer, size); + if (res != 0) { + cmd_write("Execution failed (invalid format or runtime error).\n"); + } + } else { + cmd_write("Error: Empty file.\n"); + } + kfree(app_buffer); + } else { + fat32_close(app_fh); + cmd_write("Error: Out of memory.\n"); + } + return; + } + cmd_write("Unknown command: "); cmd_write(cmd); cmd_write("\n"); diff --git a/src/kernel/fat32.c b/src/kernel/fat32.c index f5b158a..f21099a 100644 --- a/src/kernel/fat32.c +++ b/src/kernel/fat32.c @@ -108,28 +108,63 @@ static void extract_parent_path(const char *path, char *parent) { // Normalize path (remove .., ., etc) void fat32_normalize_path(const char *path, char *normalized) { + char temp[FAT32_MAX_PATH]; + int temp_len = 0; + + // Initialize with current directory or root if (path[0] == '/') { - // Absolute path - fs_strcpy(normalized, path); + temp[0] = '/'; + temp[1] = 0; + temp_len = 1; } else { - // Relative path - prepend current directory - if (fs_strcmp(current_dir, "/") == 0) { - normalized[0] = '/'; - fs_strcpy(normalized + 1, path); - } else { - fs_strcpy(normalized, current_dir); - if (normalized[fs_strlen(normalized) - 1] != '/') { - fs_strcat(normalized, "/"); + fs_strcpy(temp, current_dir); + temp_len = fs_strlen(temp); + } + + int i = 0; + while (path[i]) { + // Skip separators + while (path[i] == '/') i++; + if (!path[i]) break; + + // Extract component + char component[256]; + int j = 0; + while (path[i] && path[i] != '/' && j < 255) { + component[j++] = path[i++]; + } + component[j] = 0; + + if (fs_strcmp(component, ".") == 0) { + continue; + } else if (fs_strcmp(component, "..") == 0) { + // Go up one level + if (temp_len > 1) { // Not root + while (temp_len > 0 && temp[temp_len - 1] != '/') { + temp_len--; + } + if (temp_len > 1) { // Remove trailing slash if not root + temp_len--; + } + temp[temp_len] = 0; } - fs_strcat(normalized, path); + } else { + // Append component + if (temp[temp_len - 1] != '/') { + temp[temp_len++] = '/'; + temp[temp_len] = 0; + } + fs_strcat(temp, component); + temp_len = fs_strlen(temp); } } // Remove trailing slashes (except for root) - int len = fs_strlen(normalized); - while (len > 1 && normalized[len - 1] == '/') { - normalized[--len] = 0; + if (temp_len > 1 && temp[temp_len - 1] == '/') { + temp[--temp_len] = 0; } + + fs_strcpy(normalized, temp); } // Find file entry by path diff --git a/src/kernel/memory_manager.c b/src/kernel/memory_manager.c index 3ecc514..998be70 100644 --- a/src/kernel/memory_manager.c +++ b/src/kernel/memory_manager.c @@ -3,8 +3,10 @@ #include // --- Internal State --- -static uint8_t *memory_pool = NULL; // Dynamically allocated -static size_t memory_pool_size = DEFAULT_POOL_SIZE; // Track actual pool size +#define KERNEL_HEAP_SIZE (32 * 1024 * 1024) // 32MB Static Heap +static uint8_t memory_pool_buffer[KERNEL_HEAP_SIZE]; +static uint8_t *memory_pool = memory_pool_buffer; +static size_t memory_pool_size = KERNEL_HEAP_SIZE; static MemBlock block_list[MAX_ALLOCATIONS]; static int block_count = 0; static size_t total_allocated = 0; @@ -119,14 +121,6 @@ static size_t calculate_fragmentation(void) { void memory_manager_init_with_size(size_t pool_size) { if (initialized) return; - memory_pool_size = pool_size; - - // Initialize memory pool - in a real kernel, this would be passed a physical address - // For now, we use a simple tracking mechanism where allocations are tracked virtually - // The caller is responsible for ensuring the pool_size is valid - if (memory_pool == NULL) { - memory_pool = (uint8_t *)0x100000000; // Start from 4GB boundary as virtual tracking - } // Clear metadata mem_memset(block_list, 0, sizeof(block_list));