diff --git a/Makefile b/Makefile index 8401064..9302bf7 100644 --- a/Makefile +++ b/Makefile @@ -2,22 +2,18 @@ # Target Architecture: x86_64 # Host: macOS -# Toolchain Definitions CC = x86_64-elf-gcc LD = x86_64-elf-ld NASM = nasm XORRISO = xorriso -# Directories SRC_DIR = src/kernel BUILD_DIR = build ISO_DIR = iso_root -# Output KERNEL_ELF = $(BUILD_DIR)/brewos.elf ISO_IMAGE = brewos.iso -# Source Files C_SOURCES = $(wildcard $(SRC_DIR)/*.c) CLI_APP_SOURCES = $(wildcard $(SRC_DIR)/cli_apps/*.c) ASM_SOURCES = $(wildcard $(SRC_DIR)/*.asm) @@ -25,7 +21,6 @@ OBJ_FILES = $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o, $(C_SOURCES)) \ $(patsubst $(SRC_DIR)/cli_apps/%.c, $(BUILD_DIR)/cli_apps/%.o, $(CLI_APP_SOURCES)) \ $(patsubst $(SRC_DIR)/%.asm, $(BUILD_DIR)/%.o, $(ASM_SOURCES)) -# Flags CFLAGS = -g -O2 -pipe -Wall -Wextra -std=gnu11 -ffreestanding \ -fno-stack-protector -fno-stack-check -fno-lto -fPIE \ -m64 -march=x86-64 -mno-80387 -mno-mmx -mno-sse -mno-sse2 -mno-red-zone \ @@ -123,4 +118,4 @@ clean: run: $(ISO_IMAGE) qemu-system-x86_64 -m 2G -serial stdio -cdrom $(ISO_IMAGE) -boot d \ -audiodev coreaudio,id=audio0 -machine pcspk-audiodev=audio0 \ - -netdev user,id=net0 -device e1000,netdev=net0 + -netdev user,id=net0,hostfwd=udp::12345-:12345 -device e1000,netdev=net0 diff --git a/brewos.iso b/brewos.iso index 2e5f78d..d33e468 100644 Binary files a/brewos.iso and b/brewos.iso differ diff --git a/build/brewos.elf b/build/brewos.elf index fc2a39a..baac746 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 23216d2..9c32906 100644 Binary files a/build/cli_apps/fs_commands.o and b/build/cli_apps/fs_commands.o differ diff --git a/build/cli_apps/net.o b/build/cli_apps/net.o index 73c2798..c49162d 100644 Binary files a/build/cli_apps/net.o and b/build/cli_apps/net.o differ diff --git a/build/cmd.o b/build/cmd.o index 8f738e8..13fc27c 100644 Binary files a/build/cmd.o and b/build/cmd.o differ diff --git a/build/editor.o b/build/editor.o index 122dcde..b2b2b1f 100644 Binary files a/build/editor.o and b/build/editor.o differ diff --git a/build/network.o b/build/network.o index dbc2f6a..b02c1b3 100644 Binary files a/build/network.o and b/build/network.o differ diff --git a/build/wm.o b/build/wm.o index 6f0cdd1..f35305e 100644 Binary files a/build/wm.o and b/build/wm.o differ diff --git a/iso_root/brewos.elf b/iso_root/brewos.elf index fc2a39a..baac746 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 b8d5f10..25cae41 100644 --- a/src/kernel/cli_apps/cli_apps.h +++ b/src/kernel/cli_apps/cli_apps.h @@ -45,6 +45,7 @@ void cli_cmd_netinfo(char *args); void cli_cmd_ipset(char *args); void cli_cmd_udpsend(char *args); void cli_cmd_udptest(char *args); +void cli_cmd_msgrc(char *args); // PCI commands void cli_cmd_pcilist(char *args); diff --git a/src/kernel/cli_apps/fs_commands.c b/src/kernel/cli_apps/fs_commands.c index f983235..f8bc464 100644 --- a/src/kernel/cli_apps/fs_commands.c +++ b/src/kernel/cli_apps/fs_commands.c @@ -1,5 +1,6 @@ #include "cli_utils.h" #include "fat32.h" +#include "cmd.h" void cli_cmd_cd(char *args) { if (!args || args[0] == 0) { @@ -221,6 +222,10 @@ void cli_cmd_cat(char *args) { i++; } filename[i] = 0; + + if (cli_strcmp(filename, "messages") == 0) { + cmd_reset_msg_count(); + } FAT32_FileHandle *fh = fat32_open(filename, "r"); if (!fh) { diff --git a/src/kernel/cli_apps/net.c b/src/kernel/cli_apps/net.c index cba41f2..20fcdcd 100644 --- a/src/kernel/cli_apps/net.c +++ b/src/kernel/cli_apps/net.c @@ -1,5 +1,8 @@ #include "cli_utils.h" #include "network.h" +#include "fat32.h" +#include "cmd.h" +#include "memory_manager.h" static void print_mac(const mac_address_t* mac){ char buf[64]; @@ -97,11 +100,35 @@ void cli_cmd_udpsend(char *args){ static void udp_print_callback(const ipv4_address_t* src_ip,uint16_t src_port,const mac_address_t* src_mac,const void* data,size_t length){ (void)src_mac; - cli_write("UDP from "); - for(int i=0;i<4;i++){ cli_write_int(src_ip->bytes[i]); if(i<3) cli_write("."); } - cli_write(":"); cli_write_int(src_port); cli_write(" "); - for(size_t i=0;ibytes[i], buf); + fat32_write(fh, buf, cli_strlen(buf)); + if(i<3) fat32_write(fh, ".", 1); + } + + fat32_write(fh, ":", 1); + + // Write Port + cli_itoa(src_port, buf); + fat32_write(fh, buf, cli_strlen(buf)); + + fat32_write(fh, " ", 1); + + // Write Message + fat32_write(fh, data, length); + fat32_write(fh, "\n", 1); + + fat32_close(fh); + + cmd_increment_msg_count(); + } } void cli_cmd_udptest(char *args){ @@ -110,3 +137,54 @@ void cli_cmd_udptest(char *args){ if(port<=0||port>65535){ cli_write("Invalid port\n"); return; } if(udp_register_callback((uint16_t)port,udp_print_callback)==0) cli_write("UDP callback registered\n"); else cli_write("Register failed\n"); } + +void cli_cmd_msgrc(char *args) { + (void)args; + // Reset message count since we are viewing them + cmd_reset_msg_count(); + + FAT32_FileHandle *fh = fat32_open("messages", "r"); + if (!fh) { + cli_write("No messages.\n"); + return; + } + + uint32_t size = fh->size; + if (size == 0) { + fat32_close(fh); + cli_write("No messages.\n"); + return; + } + + char *buffer = (char*)kmalloc(size + 1); + if (!buffer) { + fat32_close(fh); + cli_write("Error: Out of memory\n"); + return; + } + + fat32_read(fh, buffer, size); + buffer[size] = 0; + fat32_close(fh); + + int count = 0; + int pos = size - 1; + + while (count < 10 && pos >= 0) { + // Skip trailing newlines/whitespace + while (pos >= 0 && (buffer[pos] == '\n' || buffer[pos] == '\r')) { + buffer[pos] = 0; + pos--; + } + if (pos < 0) break; + + // Find start of line + while (pos >= 0 && buffer[pos] != '\n' && buffer[pos] != '\r') pos--; + + cli_write(&buffer[pos + 1]); + cli_write("\n"); + count++; + } + + kfree(buffer); +} diff --git a/src/kernel/cmd.c b/src/kernel/cmd.c index d51d144..c284e87 100644 --- a/src/kernel/cmd.c +++ b/src/kernel/cmd.c @@ -119,6 +119,17 @@ static char pipe_buffer[8192]; static int pipe_buffer_pos = 0; int boot_year, boot_month, boot_day, boot_hour, boot_min, boot_sec; +// Message notification state +static int msg_count = 0; + +void cmd_increment_msg_count(void) { + msg_count++; +} + +void cmd_reset_msg_count(void) { + msg_count = 0; +} + // --- Helpers --- static void cmd_memset(void *dest, int val, size_t len) { unsigned char *ptr = dest; @@ -481,6 +492,8 @@ static const CommandEntry commands[] = { {"udptest", cli_cmd_udptest}, {"PCILIST", cli_cmd_pcilist}, {"pcilist", cli_cmd_pcilist}, + {"MSGRC", cli_cmd_msgrc}, + {"msgrc", cli_cmd_msgrc}, {"COMPC", cli_cmd_cc}, {"compc", cli_cmd_cc}, {"CC", cli_cmd_cc}, @@ -941,6 +954,11 @@ void cmd_reset(void) { // Reset terminal to fresh state cmd_screen_clear(); cmd_write("BrewOS Command Prompt\n"); + if (msg_count > 0) { + cmd_write("You have "); + cmd_write_int(msg_count); + cmd_write(" new message(s) run \"msgrc\" to see your new message(s).\n"); + } cmd_write(PROMPT); } @@ -1046,6 +1064,15 @@ static void create_test_files(void) { fat32_close(fh); } + fh = fat32_open("Apps/README.md", "w"); + if (fh) { + const char *content = + "# All compiled C files in this directory are openable from any other directory by typing in the name of the compiled file by typing in the name of the compiled file.\n\n" + "The c file 'wordofgod.c' contains a C program similar to one in TempleOS, which Terry A. Davis (RIP) saw as 'words from god' telling him what to do with his kernel.\n" + "I made this file as a tribute to him, as he also inspired me to create this project in '24. If you want to run it you simply do cc (or compc) wordofgod.c and then run ./wordofgod \n"; + fat32_write(fh, (void *)content, cmd_strlen(content)); + fat32_close(fh); + } write_license_file(); fh = fat32_open("Documents/notes.txt", "w"); @@ -1061,6 +1088,7 @@ static void create_test_files(void) { fat32_write(fh, (void *)content, 32); fat32_close(fh); } + fh = fat32_open("Apps/wordofgod.c", "w"); if (fh) { diff --git a/src/kernel/cmd.h b/src/kernel/cmd.h index ddd8684..f742a51 100644 --- a/src/kernel/cmd.h +++ b/src/kernel/cmd.h @@ -14,4 +14,7 @@ void cmd_putchar(char c); void cmd_write_int(int n); void cmd_screen_clear(void); +void cmd_increment_msg_count(void); +void cmd_reset_msg_count(void); + #endif \ No newline at end of file diff --git a/src/kernel/editor.c b/src/kernel/editor.c index 52fc8f7..aa4f5e0 100644 --- a/src/kernel/editor.c +++ b/src/kernel/editor.c @@ -312,8 +312,10 @@ static void editor_paint(Window *win) { int text_len = lines[line_idx].length; int char_idx = 0; int local_display_line = 0; + bool first_pass = true; - while (char_idx < text_len && display_line < max_display_lines) { + while ((char_idx < text_len || (text_len == 0 && first_pass)) && display_line < max_display_lines) { + first_pass = false; int current_display_y = offset_y + 35 + display_line * EDITOR_LINE_HEIGHT; // Extract segment (up to max_chars_per_line) @@ -353,9 +355,18 @@ static void editor_paint(Window *win) { } // Draw cursor if on this line and wrapped segment - if (line_idx == cursor_line && cursor_col >= segment_start && cursor_col < segment_start + segment_len) { - int cursor_x = text_start_x + ((cursor_col - segment_start) * EDITOR_CHAR_WIDTH); - draw_rect(cursor_x, current_display_y, 2, 10, COLOR_BLACK); + if (line_idx == cursor_line) { + int segment_end = segment_start + segment_len; + bool draw_cursor = false; + if (cursor_col >= segment_start && cursor_col < segment_end) { + draw_cursor = true; + } else if (cursor_col == text_len && segment_end == text_len) { + draw_cursor = true; + } + if (draw_cursor) { + int cursor_x = text_start_x + ((cursor_col - segment_start) * EDITOR_CHAR_WIDTH); + draw_rect(cursor_x, current_display_y, 2, 10, COLOR_BLACK); + } } display_line++; diff --git a/src/kernel/network.c b/src/kernel/network.c index abacd03..b2d5d81 100644 --- a/src/kernel/network.c +++ b/src/kernel/network.c @@ -106,6 +106,11 @@ void network_process_frames(void){ if(for_our_ip || ip->dest_ip[0]==255){ mac_address_t src_mac; kmemcpy(src_mac.bytes,eth->src_mac,6); + + ipv4_address_t src_ip_struct; + kmemcpy(src_ip_struct.bytes, ip->src_ip, 4); + arp_cache_add(&src_ip_struct, &src_mac); + ipv4_process_packet(ip,&src_mac,payload_length); } } diff --git a/src/kernel/wm.c b/src/kernel/wm.c index ea0684d..66074b9 100644 --- a/src/kernel/wm.c +++ b/src/kernel/wm.c @@ -377,6 +377,7 @@ void wm_handle_click(int x, int y) { if (y < menu_y + 25) { // Explorer win_explorer.visible = true; win_explorer.focused = true; + explorer_reset(); // Bring to front int max_z = 0; for (int i = 0; i < window_count; i++) { @@ -411,6 +412,7 @@ void wm_handle_click(int x, int y) { } else if (y < menu_y + 85) { // CMD win_cmd.visible = true; win_cmd.focused = true; + cmd_reset(); int max_z = 0; for (int i = 0; i < window_count; i++) { if (all_windows[i]->z_index > max_z) {