diff --git a/.gitignore b/.gitignore index 60dc212..bc4be83 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ BrewKernel/.DS_Store BrewKernel/build/.DS_Store BrewKernel/build/x86_64/.DS_Store .DS_Store +.vscode/ diff --git a/BrewKernel/build/kernel/main.o b/BrewKernel/build/kernel/main.o index 7d5ce4d..58eb614 100644 Binary files a/BrewKernel/build/kernel/main.o and b/BrewKernel/build/kernel/main.o differ diff --git a/BrewKernel/core b/BrewKernel/core index baaf8fb..72544e9 100644 Binary files a/BrewKernel/core and b/BrewKernel/core differ diff --git a/BrewKernel/dist/x86_64/kernel.bin b/BrewKernel/dist/x86_64/kernel.bin index ac3e246..bd9af80 100755 Binary files a/BrewKernel/dist/x86_64/kernel.bin and b/BrewKernel/dist/x86_64/kernel.bin differ diff --git a/BrewKernel/dist/x86_64/kernel.iso b/BrewKernel/dist/x86_64/kernel.iso index 562097e..7115e5d 100644 Binary files a/BrewKernel/dist/x86_64/kernel.iso and b/BrewKernel/dist/x86_64/kernel.iso differ diff --git a/BrewKernel/src/impl/kernel/main.c b/BrewKernel/src/impl/kernel/main.c index 53e0c28..b064414 100644 --- a/BrewKernel/src/impl/kernel/main.c +++ b/BrewKernel/src/impl/kernel/main.c @@ -54,10 +54,9 @@ #include "shell_cli.h" #include "APPS/calc.h" -// External assembly function to initialize IDT extern void init_idt(void); -// Enable to automatically enter the CLI on boot. Set to 0 to disable this, probably no reason to do this might be handy though. +// Enable to automatically enter the CLI on boot. Set to 0 to disable this (probably no reason to do this) but it *might* be handy for some dumb reason. #ifndef AUTO_START_CLI #define AUTO_START_CLI 1 #endif @@ -70,16 +69,16 @@ static int strcmp_kernel(const char *s1, const char *s2) { return *(const unsigned char*)s1 - *(const unsigned char*)s2; } -// CLI state and buffer +// DONT TOUCH this static char command_buffer[256]; int buffer_pos = 0; -// Command history +// same here, shit likes to break if you do #define HISTORY_SIZE 10 static char command_history[HISTORY_SIZE][256]; -static int history_count = 0; // Number of commands in history -static int history_current = -1; // Current position in history while navigating -static int history_newest = -1; // Index of the most recent command +static int history_count = 0; +static int history_current = -1; +static int history_newest = -1; static int in_cli_mode = 0; static int timezone_offset_h = 0; static int timezone_offset_m = 0; @@ -178,7 +177,6 @@ static int split_command(char *cmd, char *args[], int max_args) { return arg_count; } -// Find pipe operator in command string static const char* find_pipe(const char* cmd) { while (*cmd) { if (*cmd == '|') { @@ -203,14 +201,11 @@ static void process_command(void) { } cmd_upper[i] = '\0'; - // Check for pipe operator const char* pipe_pos = find_pipe(command_buffer); if (pipe_pos) { - // Handle piped commands char left_cmd[256] = {0}; char right_cmd[256] = {0}; - // Extract left command (before pipe) size_t left_len = pipe_pos - command_buffer; if (left_len >= sizeof(left_cmd)) left_len = sizeof(left_cmd) - 1; for (size_t j = 0; j < left_len; j++) { @@ -218,12 +213,10 @@ static void process_command(void) { } left_cmd[left_len] = '\0'; - // Trim trailing spaces from left command while (left_len > 0 && left_cmd[left_len - 1] == ' ') { left_cmd[--left_len] = '\0'; } - // Extract right command (after pipe) const char* right_start = pipe_pos + 1; while (*right_start == ' ') right_start++; @@ -234,14 +227,10 @@ static void process_command(void) { } right_cmd[right_len] = '\0'; - // Trim trailing spaces from right command while (right_len > 0 && right_cmd[right_len - 1] == ' ') { right_cmd[--right_len] = '\0'; } - // Handle pipe: extract content from left command and pass to right command - // Currently support: CAT | UDPSEND - char left_upper[256] = {0}; for (i = 0; left_cmd[i]; i++) { left_upper[i] = left_cmd[i] >= 'a' && left_cmd[i] <= 'z' @@ -258,7 +247,6 @@ static void process_command(void) { } right_upper[i] = '\0'; - // Handle CAT command piped if (strncmp_kernel(left_upper, "CAT ", 4) == 0) { const char* file_path = left_cmd + 4; while (*file_path == ' ') file_path++; @@ -267,11 +255,9 @@ static void process_command(void) { const char* file_content = fs_read_file_at_path(file_path, &file_size); if (file_content && file_size > 0) { - // Limit file size to prevent overflow if (file_size > 4096) { - brew_str("\nFile too large (max 4KB for UDP pipe)\n"); + brew_str("\nFile too large (max 4KB for UDP pipe)\n"); // dont touch this youll get a stack overflow and break the system <3 } else if (strncmp_kernel(right_upper, "UDPSEND ", 8) == 0) { - // Parse UDPSEND arguments from right_cmd const char* args = right_cmd + 8; while (*args == ' ') args++; @@ -279,7 +265,6 @@ static void process_command(void) { if (!network_is_initialized()) { brew_str("Network not initialized. Use NETINIT first.\n"); } else { - // Parse IP address ipv4_address_t dest_ip; int ip_bytes[4] = {0}; int ip_idx = 0; @@ -304,7 +289,6 @@ static void process_command(void) { dest_ip.bytes[k] = (uint8_t)ip_bytes[k]; } - // Parse port while (*p == ' ') p++; int port = 0; while (*p >= '0' && *p <= '9') { @@ -312,7 +296,6 @@ static void process_command(void) { p++; } - // Send UDP packet(s) with file content (chunked if necessary) const size_t chunk_size = 512; size_t offset = 0; int chunk_count = 0; @@ -324,7 +307,6 @@ static void process_command(void) { to_send = chunk_size; } - // Send directly from file content pointer int result = udp_send_packet(&dest_ip, (uint16_t)port, 54321, (const void*)(file_content + offset), to_send); if (result == 0) { @@ -359,7 +341,9 @@ static void process_command(void) { } bool return_to_prompt = true; - + // command handlind here, it isn't the best solution but it works + // You basically just add a new .h file for your app, include whatever modules you need in that file + // and then call the function here in the if-else chain. (super efficient 100%) if (strcmp_kernel(cmd_upper, "HELP") == 0) { display_help(); } @@ -484,19 +468,17 @@ static void process_command(void) { const char* args = command_buffer + 5; while (*args == ' ') args++; - // Look for redirection operator > char redirect_path[256] = {0}; const char* redirect_pos = args; bool found_redirect = false; int redirect_idx = 0; - // Find the > character while (*redirect_pos) { if (*redirect_pos == '>') { found_redirect = true; - redirect_pos++; // skip the > - while (*redirect_pos == ' ') redirect_pos++; // skip spaces - // Copy redirect path + redirect_pos++; + while (*redirect_pos == ' ') redirect_pos++; + redirect_idx = 0; while (*redirect_pos && redirect_idx < 255) { redirect_path[redirect_idx++] = *redirect_pos; @@ -509,8 +491,6 @@ static void process_command(void) { } if (found_redirect && redirect_path[0] != '\0') { - // Write to file - // Get the text to echo (everything before >) char echo_text[256] = {0}; int text_idx = 0; const char* text_ptr = args; @@ -520,7 +500,6 @@ static void process_command(void) { } echo_text[text_idx] = '\0'; - // Trim trailing spaces from echo text while (text_idx > 0 && echo_text[text_idx - 1] == ' ') { echo_text[--text_idx] = '\0'; } @@ -531,7 +510,6 @@ static void process_command(void) { brew_str("'\n"); } } else { - // Just print to console brew_str("\n"); brew_str(args); brew_str("\n"); @@ -755,17 +733,15 @@ void kernel_main(void* multiboot_info) { #endif while (1) { - // Process network frames continuously for (int i = 0; i < 10; i++) { network_process_frames(); } - net_check_udp_received(); // Check for and print UDP receive notifications + net_check_udp_received(); if (check_keyboard()) { unsigned char scan_code = read_scan_code(); - // special keys - if (scan_code == 0x0E) { // Backspace + if (scan_code == 0x0E) { if (buffer_pos > 0) { buffer_pos--; print_backspace(); @@ -775,10 +751,8 @@ void kernel_main(void* multiboot_info) { } else if (scan_code == SCAN_CODE_DOWN_ARROW && in_cli_mode) { navigate_history(1); // Navigate forwards in history } else { - // Convert scan code to ASCII and print if it's a printable character char ascii_char = scan_code_to_ascii(scan_code); if (ascii_char != 0) { - // Handle special characters if (ascii_char == '\n' || ascii_char == '\r') { if (!in_cli_mode) { command_buffer[buffer_pos] = '\0'; @@ -804,8 +778,7 @@ void kernel_main(void* multiboot_info) { } else { process_command(); } - - // Process network frames after command execution + for (int i = 0; i < 10; i++) { network_process_frames(); } diff --git a/BrewKernel/src/impl/kernel/memory.c b/BrewKernel/src/impl/kernel/memory.c index 684f579..d6e9220 100644 --- a/BrewKernel/src/impl/kernel/memory.c +++ b/BrewKernel/src/impl/kernel/memory.c @@ -20,7 +20,7 @@ // Memory management for file content using a free list allocator -#define MEMORY_SIZE 67108864 // 64MB - sufficient for DOOM WAD files and zone memory +#define MEMORY_SIZE 67108864 #define ALIGNMENT 8 // Align blocks to 8 bytes #define MIN_BLOCK_SIZE (sizeof(BlockHeader) + ALIGNMENT) @@ -53,44 +53,37 @@ static void init_memory(void) { memory_initialized = 1; } -// Split a free block if it's large enough static void split_block(BlockHeader* block, size_t size) { size_t remaining = block->size - size; if (remaining >= MIN_BLOCK_SIZE) { - // Create new free block from remaining space BlockHeader* new_block = (BlockHeader*)((char*)block + sizeof(BlockHeader) + size); new_block->size = remaining - sizeof(BlockHeader); new_block->is_free = 1; - new_block->next = free_list; // Add to free list + new_block->next = free_list; block->size = size; - free_list = new_block; // Add new block to free list + free_list = new_block; } } -// Coalesce adjacent free blocks static void coalesce_blocks(void) { BlockHeader* current = (BlockHeader*)memory_pool; BlockHeader* end = (BlockHeader*)(memory_pool + MEMORY_SIZE); - int max_iterations = MEMORY_SIZE / sizeof(BlockHeader); // Safety limit + int max_iterations = MEMORY_SIZE / sizeof(BlockHeader); int iterations = 0; while ((char*)current < (char*)end && iterations < max_iterations) { iterations++; - // Safety check: block size must be reasonable if (current->size == 0 || current->size > MEMORY_SIZE) { - break; // Corrupted allocator state, stop + break; } if (current->is_free) { - // Check if next block is adjacent and free BlockHeader* next = (BlockHeader*)((char*)current + sizeof(BlockHeader) + current->size); if ((char*)next < (char*)end && next->is_free) { - // Merge blocks current->size += sizeof(BlockHeader) + next->size; - // Update free list BlockHeader* prev = NULL; BlockHeader* walk = free_list; while (walk) { @@ -105,11 +98,9 @@ static void coalesce_blocks(void) { prev = walk; walk = walk->next; } - // Continue checking from current position continue; } } - // Move to next block current = (BlockHeader*)((char*)current + sizeof(BlockHeader) + current->size); } } @@ -119,18 +110,15 @@ void* fs_allocate(size_t size) { init_memory(); - // Align size size = align_size(size); if (size < MIN_BLOCK_SIZE - sizeof(BlockHeader)) { size = MIN_BLOCK_SIZE - sizeof(BlockHeader); } - // Prevent requesting more than available if (size > MEMORY_SIZE - sizeof(BlockHeader)) { return NULL; } - // Find a suitable free block (limit iterations to prevent infinite loops) BlockHeader* prev = NULL; BlockHeader* current = free_list; int max_iterations = MEMORY_SIZE / sizeof(BlockHeader); @@ -239,44 +227,36 @@ size_t fs_get_used_memory(void) { } size_t fs_get_free_memory(void) { - init_memory(); // Ensure memory is initialized + init_memory(); return MEMORY_SIZE - fs_get_used_memory(); } -// System memory detection using Multiboot info static size_t system_total_ram = 0; static int system_memory_initialized = 0; -// Multiboot info structure (simplified - we only need memory fields) struct multiboot_info { uint32_t flags; uint32_t mem_lower; uint32_t mem_upper; - // ... other fields we don't need + }; void sys_memory_init(void* multiboot_info_ptr) { if (system_memory_initialized) return; if (!multiboot_info_ptr) { - // No multiboot info, assume default (e.g., 512MB) - system_total_ram = 512 * 1024 * 1024; // 512MB default + system_total_ram = 512 * 1024 * 1024; system_memory_initialized = 1; return; } struct multiboot_info* mb_info = (struct multiboot_info*)multiboot_info_ptr; - // Check if memory info is available (bit 0 of flags) if (mb_info->flags & 0x01) { - // mem_lower is in KB (typically 0-640KB) - // mem_upper is in KB (typically 1MB+) - // Total RAM = (mem_lower + mem_upper) * 1024 bytes uint32_t total_kb = mb_info->mem_lower + mb_info->mem_upper; system_total_ram = (size_t)total_kb * 1024; } else { - // Memory info not available, use default - system_total_ram = 512 * 1024 * 1024; // 512MB default + system_total_ram = 512 * 1024 * 1024; } system_memory_initialized = 1; @@ -284,25 +264,16 @@ void sys_memory_init(void* multiboot_info_ptr) { size_t sys_get_total_ram(void) { if (!system_memory_initialized) { - // Not initialized yet, return default - return 512 * 1024 * 1024; // 512MB default + return 512 * 1024 * 1024; } return system_total_ram; } size_t sys_get_used_ram(void) { - // Estimate kernel memory usage: - // - File content pool: fs_get_used_memory() - // - Kernel code/data/stack: rough estimate - // - Static arrays and structures - + size_t file_pool_used = fs_get_used_memory(); - // Rough estimate of kernel overhead: - // - Kernel code: ~100KB (rough estimate) - // - Stack: 16KB (from boot code) - // - Static data: ~50KB (rough estimate) - // - Page tables: ~12KB (3 * 4KB) + size_t kernel_overhead = 100 * 1024 + 16 * 1024 + 50 * 1024 + 12 * 1024; // ~178KB return file_pool_used + kernel_overhead; @@ -312,6 +283,6 @@ size_t sys_get_free_ram(void) { size_t total = sys_get_total_ram(); size_t used = sys_get_used_ram(); - if (used > total) return 0; // Safety check + if (used > total) return 0; return total - used; } \ No newline at end of file diff --git a/BrewKernel/src/impl/kernel/network_cli.c b/BrewKernel/src/impl/kernel/network_cli.c index 8f6783b..47c3ce8 100644 --- a/BrewKernel/src/impl/kernel/network_cli.c +++ b/BrewKernel/src/impl/kernel/network_cli.c @@ -45,15 +45,14 @@ static int brew_strlen_cli(const char* s) { return n; } -// UDP test state and echo callback moved from main.c static int udp_test_active = 0; static int udp_received_flag = 0; static ipv4_address_t udp_received_src_ip; static uint16_t udp_received_src_port; static uint16_t udp_received_length; -static uint16_t udp_message_length; // Actual length of stored message +static uint16_t udp_message_length; #define UDP_MESSAGE_BUFFER_SIZE 256 -static char udp_received_message[UDP_MESSAGE_BUFFER_SIZE] = {0}; // Initialize to zeros +static char udp_received_message[UDP_MESSAGE_BUFFER_SIZE] = {0}; static void udp_echo_callback(const ipv4_address_t* src_ip, uint16_t src_port, const mac_address_t* src_mac, const void* data, size_t length) { @@ -62,19 +61,16 @@ static void udp_echo_callback(const ipv4_address_t* src_ip, uint16_t src_port, udp_received_src_port = src_port; udp_received_length = (uint16_t)length; - // Store message data (with size limit) size_t copy_len = length; if (copy_len > UDP_MESSAGE_BUFFER_SIZE) { copy_len = UDP_MESSAGE_BUFFER_SIZE; } udp_message_length = (uint16_t)copy_len; - // Clear buffer first for (int i = 0; i < UDP_MESSAGE_BUFFER_SIZE; i++) { udp_received_message[i] = 0; } - // Copy message data - copy raw bytes directly if (data && copy_len > 0) { const uint8_t* src = (const uint8_t*)data; for (size_t i = 0; i < copy_len; i++) { @@ -82,7 +78,6 @@ static void udp_echo_callback(const ipv4_address_t* src_ip, uint16_t src_port, } } - // Echo back the data as-is udp_send_packet_to_mac(src_ip, src_mac, src_port, 12345, data, length); } @@ -144,14 +139,11 @@ void net_check_udp_received(void) { num[pos] = '\0'; brew_str(num); - // Only print message if we have data if (udp_message_length > 0) { brew_str(" - Message: \""); - // Print the received message for (uint16_t i = 0; i < udp_message_length; i++) { char ch = udp_received_message[i]; - // Print all bytes as-is, including non-printable if (ch == '\n') { brew_str("\\n"); } else if (ch == '\r') { @@ -393,7 +385,6 @@ static void handle_udptest(int* return_to_prompt) { return; } - // Print current network info ipv4_address_t ip; if (network_get_ipv4_address(&ip) == 0) { brew_str("Current IP: "); @@ -442,7 +433,7 @@ static void handle_ipset(const char* command_buffer) { return; } - const char* args = &command_buffer[5]; // Skip "IPSET" + const char* args = &command_buffer[5]; while (*args == ' ') args++; if (*args == '\0') { diff --git a/BrewKernel/src/impl/kernel/shell_cli.c b/BrewKernel/src/impl/kernel/shell_cli.c index ee6dbaf..fd035c4 100644 --- a/BrewKernel/src/impl/kernel/shell_cli.c +++ b/BrewKernel/src/impl/kernel/shell_cli.c @@ -18,12 +18,10 @@ #include "shell_cli.h" -// Returns 1 if handled, 0 otherwise. May modify *return_to_prompt (1/0). int shell_handle_command(const char* cmd_upper, char* command_buffer, int* return_to_prompt) { (void)cmd_upper; (void)command_buffer; (void)return_to_prompt; - // No shell-specific commands handled yet return 0; } diff --git a/BrewKernel/src/intf/APPS/help.h b/BrewKernel/src/intf/APPS/help.h index 8ff6b7a..fce2b1c 100644 --- a/BrewKernel/src/intf/APPS/help.h +++ b/BrewKernel/src/intf/APPS/help.h @@ -45,7 +45,7 @@ static void display_help() { brew_str(" ECHO - Print text (can redirect to file with >)\n"); brew_str(" NETINIT - Initialize network card\n"); brew_str(" NETINFO - Show network status (MAC, IP)\n"); - brew_str(" UDPTEST - Start UDP echo server on port 12345 (broken)\n"); + brew_str(" UDPTEST - Start UDP echo server on port 12345\n"); brew_str(" UDPSEND - Send UDP packet (UDPSEND )\n"); brew_str("\nPipe support:\n"); brew_str(" CAT | UDPSEND - Send file contents via UDP\n"); diff --git a/BrewKernel/targets/x86_64/iso/boot/kernel.bin b/BrewKernel/targets/x86_64/iso/boot/kernel.bin index ac3e246..bd9af80 100644 Binary files a/BrewKernel/targets/x86_64/iso/boot/kernel.bin and b/BrewKernel/targets/x86_64/iso/boot/kernel.bin differ