commit e82fb49c045556809542b1615f40088ea7d74fd3 Author: OusmBlueNinja <89956790+OusmBlueNinja@users.noreply.github.com> Date: Sat Oct 12 22:01:35 2024 -0500 Add files via upload diff --git a/EYOSx86-main/Makefile b/EYOSx86-main/Makefile new file mode 100644 index 0000000..fb5115f --- /dev/null +++ b/EYOSx86-main/Makefile @@ -0,0 +1,51 @@ +# Define paths and files +IMAGE_SIZE_MB := 10 +DISK_IMAGE := dist/x86_64/filesystem.img +KERNEL_BIN := dist/x86_64/kernel.bin +ISO_FILE := dist/x86_64/kernel.iso +ISO_DIR := targets/x86_64/iso + +# List of object files +kernel_source_files := $(shell find src/impl/kernel -name *.c) +kernel_object_files := $(patsubst src/impl/kernel/%.c, build/kernel/%.o, $(kernel_source_files)) + +x86_64_c_source_files := $(shell find src/impl/x86_64 -name *.c) +x86_64_c_object_files := $(patsubst src/impl/x86_64/%.c, build/x86_64/%.o, $(x86_64_c_source_files)) + +x86_64_cpp_source_files := $(shell find src/impl/x86_64 -name *.cpp) +x86_64_cpp_object_files := $(patsubst src/impl/x86_64/%.cpp, build/x86_64/%.o, $(x86_64_cpp_source_files)) + +x86_64_asm_source_files := $(shell find src/impl/x86_64 -name *.asm) +x86_64_asm_object_files := $(patsubst src/impl/x86_64/%.asm, build/x86_64/%.o, $(x86_64_asm_source_files)) + +x86_64_object_files := $(x86_64_c_object_files) $(x86_64_cpp_object_files) $(x86_64_asm_object_files) + +# Rule to compile C files for the kernel +$(kernel_object_files): build/kernel/%.o : src/impl/kernel/%.c + mkdir -p $(dir $@) && \ + x86_64-elf-gcc -c -I src/intf -ffreestanding $(patsubst build/kernel/%.o, src/impl/kernel/%.c, $@) -o $@ + +# Rule to compile C files for x86_64 +$(x86_64_c_object_files): build/x86_64/%.o : src/impl/x86_64/%.c + mkdir -p $(dir $@) && \ + x86_64-elf-gcc -c -I src/intf -ffreestanding $(patsubst build/x86_64/%.o, src/impl/x86_64/%.c, $@) -o $@ + +# Rule to compile C++ files for x86_64 +$(x86_64_cpp_object_files): build/x86_64/%.o : src/impl/x86_64/%.cpp + mkdir -p $(dir $@) && \ + x86_64-elf-g++ -c -I src/intf -ffreestanding $(patsubst build/x86_64/%.o, src/impl/x86_64/%.cpp, $@) -o $@ + +# Rule to assemble ASM files for x86_64 +$(x86_64_asm_object_files): build/x86_64/%.o : src/impl/x86_64/%.asm + mkdir -p $(dir $@) && \ + nasm -f elf64 $(patsubst build/x86_64/%.o, src/impl/x86_64/%.asm, $@) -o $@ + +.PHONY: build-x86_64 +build-x86_64: $(kernel_object_files) $(x86_64_object_files) + mkdir -p dist/x86_64 targets/x86_64/iso && \ + x86_64-elf-ld -n -o $(KERNEL_BIN) -T targets/x86_64/linker.ld $(kernel_object_files) $(x86_64_object_files) && \ + cp $(KERNEL_BIN) $(ISO_DIR)/boot/kernel.bin && \ + dd if=/dev/zero of=$(DISK_IMAGE) bs=1M count=$(IMAGE_SIZE_MB) && \ + mkfs.vfat -F 16 $(DISK_IMAGE) && \ + mcopy -i $(DISK_IMAGE) filesystem/hello/hello.txt ::/ && \ + grub-mkrescue -o $(ISO_FILE) $(ISO_DIR) diff --git a/EYOSx86-main/README.md b/EYOSx86-main/README.md new file mode 100644 index 0000000..a8e5dd6 --- /dev/null +++ b/EYOSx86-main/README.md @@ -0,0 +1,60 @@ +# Write Your Own 64-bit Operating System Kernel From Scratch + +This respository holds all the source code for [this YouTube tutorial series](https://www.youtube.com/playlist?list=PLZQftyCk7_SeZRitx5MjBKzTtvk0pHMtp). + +You can find the revision for a specific episode on [this page](https://github.com/davidcallanan/yt-os-series/tags). + +You can find pre-built ISO files for this kernel at [this repository](https://github.com/davidcallanan/os-series-isos). + +Considering supporting this work via [my Patreon page](http://patreon.com/codepulse). + +## Prerequisites + +- A text editor such as [VS Code](https://code.visualstudio.com/). +- [Docker](https://www.docker.com/) for creating our build-environment. +- [Qemu](https://www.qemu.org/) for emulating our operating system. + - Remember to add Qemu to the path so that you can access it from your command-line. ([Windows instructions here](https://dev.to/whaleshark271/using-qemu-on-windows-10-home-edition-4062)) + +## Setup + +Build an image for our build-environment: + +- `docker build buildenv -t myos-buildenv` + +## Build + +Enter build environment: + +- Linux or MacOS: `docker run --rm -it -v "$(pwd)":/root/env myos-buildenv` +- Windows (CMD): `docker run --rm -it -v "%cd%":/root/env myos-buildenv` +- Windows (PowerShell): `docker run --rm -it -v "${pwd}:/root/env" myos-buildenv` +- Please use the linux command if you are using `WSL`, `msys2` or `git bash` +- NOTE: If you are having trouble with an unshared drive, ensure your docker daemon has access to the drive you're development environment is in. For Docker Desktop, this is in "Settings > Shared Drives" or "Settings > Resources > File Sharing". + +Build for x86 (other architectures may come in the future): + +- `make build-x86_64` +- If you are using Qemu, please close it before running this command to prevent errors. + +To leave the build environment, enter `exit`. + +## Emulate + +You can emulate your operating system using [Qemu](https://www.qemu.org/): (Don't forget to [add qemu to your path](https://dev.to/whaleshark271/using-qemu-on-windows-10-home-edition-4062#:~:text=2.-,Add%20Qemu%20path%20to%20environment%20variables%20settings,-Copy%20the%20Qemu)!) + +- `qemu-system-x86_64 -cdrom dist/x86_64/kernel.iso` +- Note: Close the emulator when finished, so as to not block writing to `kernel.iso` for future builds. + +If the above command fails, try one of the following: + +- Windows: [`qemu-system-x86_64 -cdrom dist/x86_64/kernel.iso -L "C:\Program Files\qemu"`](https://stackoverflow.com/questions/66266448/qemu-could-not-load-pc-bios-bios-256k-bin) +- Linux: [`qemu-system-x86_64 -cdrom dist/x86_64/kernel.iso -L /usr/share/qemu/`](https://unix.stackexchange.com/questions/134893/cannot-start-kvm-vm-because-missing-bios) +- Alternatively, install a custom BIOS binary file and link it to Qemu using the `-L` option. + +Alternatively, you should be able to load the operating system on a USB drive and boot into it when you turn on your computer. (I haven't actually tested this yet.) + +## Cleanup + +Remove the build-evironment image: + +- `docker rmi myos-buildenv -f` diff --git a/EYOSx86-main/build/kernel/main.o b/EYOSx86-main/build/kernel/main.o new file mode 100644 index 0000000..fd4166c Binary files /dev/null and b/EYOSx86-main/build/kernel/main.o differ diff --git a/EYOSx86-main/build/x86_64/boot/header.o b/EYOSx86-main/build/x86_64/boot/header.o new file mode 100644 index 0000000..3dca3e8 Binary files /dev/null and b/EYOSx86-main/build/x86_64/boot/header.o differ diff --git a/EYOSx86-main/build/x86_64/boot/isr.o b/EYOSx86-main/build/x86_64/boot/isr.o new file mode 100644 index 0000000..04d9b85 Binary files /dev/null and b/EYOSx86-main/build/x86_64/boot/isr.o differ diff --git a/EYOSx86-main/build/x86_64/boot/main.o b/EYOSx86-main/build/x86_64/boot/main.o new file mode 100644 index 0000000..c4b2aae Binary files /dev/null and b/EYOSx86-main/build/x86_64/boot/main.o differ diff --git a/EYOSx86-main/build/x86_64/boot/main64.o b/EYOSx86-main/build/x86_64/boot/main64.o new file mode 100644 index 0000000..8d91690 Binary files /dev/null and b/EYOSx86-main/build/x86_64/boot/main64.o differ diff --git a/EYOSx86-main/build/x86_64/driver/disk_io.o b/EYOSx86-main/build/x86_64/driver/disk_io.o new file mode 100644 index 0000000..1a93e47 Binary files /dev/null and b/EYOSx86-main/build/x86_64/driver/disk_io.o differ diff --git a/EYOSx86-main/build/x86_64/driver/fat.o b/EYOSx86-main/build/x86_64/driver/fat.o new file mode 100644 index 0000000..d7dd752 Binary files /dev/null and b/EYOSx86-main/build/x86_64/driver/fat.o differ diff --git a/EYOSx86-main/build/x86_64/driver/fat12.o b/EYOSx86-main/build/x86_64/driver/fat12.o new file mode 100644 index 0000000..5cbfc5e Binary files /dev/null and b/EYOSx86-main/build/x86_64/driver/fat12.o differ diff --git a/EYOSx86-main/build/x86_64/driver/fs.o b/EYOSx86-main/build/x86_64/driver/fs.o new file mode 100644 index 0000000..fe53cfa Binary files /dev/null and b/EYOSx86-main/build/x86_64/driver/fs.o differ diff --git a/EYOSx86-main/build/x86_64/driver/idt.o b/EYOSx86-main/build/x86_64/driver/idt.o new file mode 100644 index 0000000..7538720 Binary files /dev/null and b/EYOSx86-main/build/x86_64/driver/idt.o differ diff --git a/EYOSx86-main/build/x86_64/driver/io.o b/EYOSx86-main/build/x86_64/driver/io.o new file mode 100644 index 0000000..5ce20e0 Binary files /dev/null and b/EYOSx86-main/build/x86_64/driver/io.o differ diff --git a/EYOSx86-main/build/x86_64/driver/irs.o b/EYOSx86-main/build/x86_64/driver/irs.o new file mode 100644 index 0000000..f19d039 Binary files /dev/null and b/EYOSx86-main/build/x86_64/driver/irs.o differ diff --git a/EYOSx86-main/build/x86_64/driver/keydriver.o b/EYOSx86-main/build/x86_64/driver/keydriver.o new file mode 100644 index 0000000..a72ea44 Binary files /dev/null and b/EYOSx86-main/build/x86_64/driver/keydriver.o differ diff --git a/EYOSx86-main/build/x86_64/driver/memory.o b/EYOSx86-main/build/x86_64/driver/memory.o new file mode 100644 index 0000000..26a9ace Binary files /dev/null and b/EYOSx86-main/build/x86_64/driver/memory.o differ diff --git a/EYOSx86-main/build/x86_64/driver/print.o b/EYOSx86-main/build/x86_64/driver/print.o new file mode 100644 index 0000000..d629801 Binary files /dev/null and b/EYOSx86-main/build/x86_64/driver/print.o differ diff --git a/EYOSx86-main/build/x86_64/driver/vector.o b/EYOSx86-main/build/x86_64/driver/vector.o new file mode 100644 index 0000000..22f87ba Binary files /dev/null and b/EYOSx86-main/build/x86_64/driver/vector.o differ diff --git a/EYOSx86-main/build/x86_64/driver/vga.o b/EYOSx86-main/build/x86_64/driver/vga.o new file mode 100644 index 0000000..dacaa0b Binary files /dev/null and b/EYOSx86-main/build/x86_64/driver/vga.o differ diff --git a/EYOSx86-main/build/x86_64/game.o b/EYOSx86-main/build/x86_64/game.o new file mode 100644 index 0000000..435ba97 Binary files /dev/null and b/EYOSx86-main/build/x86_64/game.o differ diff --git a/EYOSx86-main/build/x86_64/stdopt.o b/EYOSx86-main/build/x86_64/stdopt.o new file mode 100644 index 0000000..73fc929 Binary files /dev/null and b/EYOSx86-main/build/x86_64/stdopt.o differ diff --git a/EYOSx86-main/build/x86_64/strings.o b/EYOSx86-main/build/x86_64/strings.o new file mode 100644 index 0000000..bc524e1 Binary files /dev/null and b/EYOSx86-main/build/x86_64/strings.o differ diff --git a/EYOSx86-main/build/x86_64/window.o b/EYOSx86-main/build/x86_64/window.o new file mode 100644 index 0000000..0d333bb Binary files /dev/null and b/EYOSx86-main/build/x86_64/window.o differ diff --git a/EYOSx86-main/buildenv/Dockerfile b/EYOSx86-main/buildenv/Dockerfile new file mode 100644 index 0000000..fa2317d --- /dev/null +++ b/EYOSx86-main/buildenv/Dockerfile @@ -0,0 +1,14 @@ +FROM randomdude/gcc-cross-x86_64-elf + +RUN apt-get update +RUN apt-get upgrade -y +RUN apt-get install -y nasm +RUN apt-get install -y xorriso +RUN apt-get install -y grub-pc-bin +RUN apt-get install -y grub-common +RUN apt-get install -y dosfstools +RUN apt-get install -y mtools + + +VOLUME /root/env +WORKDIR /root/env diff --git a/EYOSx86-main/dist/x86_64/filesystem.img b/EYOSx86-main/dist/x86_64/filesystem.img new file mode 100644 index 0000000..9c08f48 Binary files /dev/null and b/EYOSx86-main/dist/x86_64/filesystem.img differ diff --git a/EYOSx86-main/dist/x86_64/kernel.bin b/EYOSx86-main/dist/x86_64/kernel.bin new file mode 100644 index 0000000..67aca41 Binary files /dev/null and b/EYOSx86-main/dist/x86_64/kernel.bin differ diff --git a/EYOSx86-main/dist/x86_64/kernel.iso b/EYOSx86-main/dist/x86_64/kernel.iso new file mode 100644 index 0000000..aadac5a Binary files /dev/null and b/EYOSx86-main/dist/x86_64/kernel.iso differ diff --git a/EYOSx86-main/filesystem/hello/hello.txt b/EYOSx86-main/filesystem/hello/hello.txt new file mode 100644 index 0000000..8ab686e --- /dev/null +++ b/EYOSx86-main/filesystem/hello/hello.txt @@ -0,0 +1 @@ +Hello, World! diff --git a/EYOSx86-main/src/impl/kernel/main.c b/EYOSx86-main/src/impl/kernel/main.c new file mode 100644 index 0000000..3e30786 --- /dev/null +++ b/EYOSx86-main/src/impl/kernel/main.c @@ -0,0 +1,288 @@ +#include "print.h" +#include "keydriver.h" +#include "stdint.h" +#include "stdopt.h" +#include "strings.h" +#include "io.h" +#include "vga.h" +#include "idt.h" +#include "memory.h" +#include "window.h" +#include "fs.h" +#include "fat12.h" + + + + +#define COMMAND_BUFFER_SIZE 256 // Increase buffer size to handle longer commands +#define BACKSPACE_KEY 8 +#define HISTORY_SIZE 10 +#define COMMAND_BUFFER_SIZE 256 +#define BUFFER_SIZE 4096 + +extern void kpanic(int error_code); + + +void shutdown_system() { + __asm__ ( + "movl $1, %eax\n" // syscall number for sys_reboot (1 in this case) + "movl $0, %ebx\n" // reboot flags + "movl $0, %ecx\n" // no additional arguments + "movl $0, %edx\n" // no additional arguments + "int $0x80\n" // interrupt to invoke syscall + ); +} + + + + +char commandHistory[HISTORY_SIZE][COMMAND_BUFFER_SIZE]; +int currentHistoryIndex = 0; +int historyCount = 0; + +void add_to_history(const char* command) { + if (historyCount < HISTORY_SIZE) { + historyCount++; + } else { + for (int i = 1; i < HISTORY_SIZE; i++) { + strcpy(commandHistory[i - 1], commandHistory[i]); + } + } + strcpy(commandHistory[historyCount - 1], command); + currentHistoryIndex = historyCount; +} + +const char* get_previous_command() { + if (currentHistoryIndex > 0) { + currentHistoryIndex--; + return commandHistory[currentHistoryIndex]; + } + return NULL; +} + +const char* get_next_command() { + if (currentHistoryIndex < historyCount - 1) { + currentHistoryIndex++; + return commandHistory[currentHistoryIndex]; + } + return NULL; +} + + +const void clear() +{ + print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set text color + + move_print_cursor(0, 0); + move_cursor(0, 0); + print_clear(); + print_setup_prompt(); +} + + + + +void halt(){ + print_str("[ WARN ] HALT\n"); + while (1) {} +} + +void commandHandler(char* command) { + printf("\n"); + + if (strcmp(command, "cls") == 0) { + clear(); + } else if (strcmp(command, "knp") == 0) { + kpanic(1); + } else if (int_strncmp(command, "echo ", 5) == 0) { + char* message = command + 5; // Skip the "echo " part + print_str("\n"); + print_str(message); + print_str("\n"); + } else if (int_strncmp(command, "cwin", 4) == 0) { + // Define window properties + Window myWindow; + int x = 8; // X position of the window + int y = 4; // Y position of the window + int width = 30; // Width of the window + int height = 10; // Height of the window + uint8_t borderColor = PRINT_COLOR_RED; // Border color + uint8_t backgroundColor = PRINT_COLOR_BLUE; // Background color + + // Create and display the window + create_window(&myWindow, x, y, width, height, borderColor, backgroundColor, "Main Window"); + + // Print text inside the window + print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLUE); // Set text color + print_text_in_window(&myWindow, 2, 2, "Window Manager is a "); + print_text_in_window(&myWindow, 2, 3, "Work in progress, Sorry :("); // Print text inside the window + print_text_in_window(&myWindow, 2, 4, "do [ cls ] to clear"); // Print text inside the window + + + + } else if (int_strncmp(command, "exit", 4) == 0) { + printf("Driver Call [ shutdown_system(); ] \n"); + shutdown_system(); + + + } else if (int_strncmp(command, "panic_test", 10) == 0) { + int _y = 1/0; + printf("Output %d\n", _y); + + } else if (int_strncmp(command, "test", 4) == 0) { + + //// Test custom malloc and free + //void* block1 = malloc(32); + //void* block2 = malloc(64); + //void* block3 = malloc(128); + // + //// List used blocks + //list_used_blocks(); + // + //// Free a block and check again + //free(block2); + //printf("\nAfter freeing block2:\n"); + //list_used_blocks(); + // + //void* block4 = malloc(64); + // + //list_used_blocks(); + + + create_game(); + + } else if (int_strncmp(command, "split", 5) == 0) { + printf("Kernel Call [ split_string(); ]\n"); + + // Check the length of the command string and use it properly + char** new_command = split_string(command, ",", strlen(command)); + + //char** new_command = {{NULL, NULL, NULL, NULL}}; + + if (new_command) { + // Add a loop to print all the elements in the new_command array for debugging + for (int i = 0; new_command[i] != NULL; i++) { + printf("new_command[%d]: %s\n", i, new_command[i]); + } + + //halt(); // Debug halt + + // Ensure that new_command[1] exists before accessing it + if (new_command[1] != NULL) { + printf("%s\n", new_command[1]); + } else { + printf("Error: new_command[1] is NULL\n"); + } + } else { + printf("Error: split_string returned NULL\n"); + } + + + } else { + printf("Unknown command: %s\n", command); + } +} + + + +void print_setup_prompt() { + move_cursor(0, 0); + print_set_color(PRINT_COLOR_LIGHT_RED, PRINT_COLOR_BLACK); + print_str("-------------------- "); + print_set_color(PRINT_COLOR_GREEN, PRINT_COLOR_BLACK); + print_str("EYOS"); + print_set_color(PRINT_COLOR_LIGHT_RED, PRINT_COLOR_BLACK); + print_str(" --------------------\n"); + print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); + print_str("V 1.5.01\n"); +} + + + +void kernel_main() { + + init_keyboard_driver(); + + + + + idt_install(); + + + print_str("[ WARN ] Skipping File System Initialization...\n[ INFO ] Do [ fsinit ] to initalize the filesystem\n"); + + if (fat12_init() == 0) { + printf("Filesystem mounted\n"); + + fat12_read_root_directory(); + + fat12_dir_entry_t entry; + if (fat12_find_file("HELLOTXT", &entry)) { + printf("File found: HELLO.TXT\n"); + } + } + + + print_setup_prompt(); + + + print_str(" > "); + + // Main loop + char key; + bool keydown = false; + char commandBuffer[COMMAND_BUFFER_SIZE]; + size_t commandLength = 0; // To track the length of the current command + + + while (1) { + key = read_key(); + + if (key != 0) { + if (!keydown) { + CursorPosition pos = get_print_cursor_pos(); + move_cursor(pos.x,pos.y); + if (key == 10) { // Enter key + commandBuffer[commandLength] = '\0'; // Null-terminate the command + commandHandler(commandBuffer); + + // Reset command buffer for the next input + commandLength = 0; + print_str(" > "); + + } else if (key == BACKSPACE_KEY) { // Backspace key + if (commandLength > 0) { + // Remove the last character from the buffer + commandLength--; + commandBuffer[commandLength] = '0'; // Null-terminate after removal + + // Clear the character from the screen (overwrite with space) + // Move cursor back one position + offset_print_cursor(-1,0); + print_char(' '); // Overwrite the character + offset_print_cursor(-1,0); // Move cursor back one position(because its moved left one by the rpintf) + + + } + + } else { + if (key >= 32 && key <= 126) { // Check if the key is a printable character + if (commandLength < COMMAND_BUFFER_SIZE - 1) { + commandBuffer[commandLength++] = key; // Append character to buffer + commandBuffer[commandLength] = '\0'; // Null-terminate the buffer + print_char(key); // Print key to the screen + } + } + } + keydown = true; + } + } else { + keydown = false; + } + + // int x = 100/0; + } + + kpanic(2); + +} diff --git a/EYOSx86-main/src/impl/x86_64/boot/header.asm b/EYOSx86-main/src/impl/x86_64/boot/header.asm new file mode 100644 index 0000000..a6046fd --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/boot/header.asm @@ -0,0 +1,16 @@ +section .multiboot_header +header_start: + ; magic number + dd 0xe85250d6 ; multiboot2 + ; architecture + dd 0 ; protected mode i386 + ; header length + dd header_end - header_start + ; checksum + dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start)) + + ; end tag + dw 0 + dw 0 + dd 8 +header_end: diff --git a/EYOSx86-main/src/impl/x86_64/boot/isr.asm b/EYOSx86-main/src/impl/x86_64/boot/isr.asm new file mode 100644 index 0000000..ae52648 --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/boot/isr.asm @@ -0,0 +1,139 @@ +; isr.asm - ISR assembly stubs + +global isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7, isr8, isr9, isr10, isr11, isr12, isr13, isr14, isr15 +global isr16, isr17, isr18, isr19, isr20, isr21, isr22, isr23, isr24, isr25, isr26, isr27, isr28, isr29, isr30, isr31 +extern isr_common_handler + +section .text + +; ISRs 0 to 13 (no error code pushed by CPU) +isr0: + cli + push 0 ; Push error code (none for isr0) + push 0 ; Push interrupt number + jmp isr_common_handler + +isr1: + cli + push 0 + push 1 + jmp isr_common_handler + +isr2: + cli + push 0 + push 2 + jmp isr_common_handler + +isr3: + cli + push 0 + push 3 + jmp isr_common_handler + +isr4: + cli + push 0 + push 4 + jmp isr_common_handler + +isr5: + cli + push 0 + push 5 + jmp isr_common_handler + +isr6: + cli + push 0 + push 6 + jmp isr_common_handler + +isr7: + cli + push 0 + push 7 + jmp isr_common_handler + +isr8: + cli + push 0 + push 8 + jmp isr_common_handler + +isr9: + cli + push 0 + push 9 + jmp isr_common_handler + +isr10: + cli + push 0 + push 10 + jmp isr_common_handler + +isr11: + cli + push 0 + push 11 + jmp isr_common_handler + +isr12: + cli + push 0 + push 12 + jmp isr_common_handler + +isr13: + cli + push 0 + push 13 + jmp isr_common_handler + +; ISR 14 (Page Fault) requires error code pushed by CPU +isr14: + cli + push 14 ; Push interrupt number + jmp isr_common_handler + +; ISRs 15 to 31 (no error code pushed by CPU) +isr15: + cli + push 0 + push 15 + jmp isr_common_handler + +isr16: + cli + push 0 + push 16 + jmp isr_common_handler + +isr17: + cli + push 0 + push 17 + jmp isr_common_handler + +isr18: + cli + push 0 + push 18 + jmp isr_common_handler + +isr19: + cli + push 0 + push 19 + jmp isr_common_handler + +isr20: + cli + push 0 + push 20 + jmp isr_common_handler + + + + diff --git a/EYOSx86-main/src/impl/x86_64/boot/main.asm b/EYOSx86-main/src/impl/x86_64/boot/main.asm new file mode 100644 index 0000000..38d0421 --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/boot/main.asm @@ -0,0 +1,157 @@ +global start +extern long_mode_start +extern idtp +extern handle_keypress +; idt_load.asm +global idt_load + + + + +section .text +bits 32 +start: + mov esp, stack_top + + call check_multiboot + call check_cpuid + call check_long_mode + + call setup_page_tables + call enable_paging + + lgdt [gdt64.pointer] + jmp gdt64.code_segment:long_mode_start + + hlt + +; Load the IDT +idt_load: + lidt [idtp] + sti ; Enable interrupts + ret + + + + +check_multiboot: + cmp eax, 0x36d76289 + jne .no_multiboot + ret +.no_multiboot: + mov al, 'M' + jmp error + +check_cpuid: + pushfd + pop eax + mov ecx, eax + xor eax, 1 << 21 + push eax + popfd + pushfd + pop eax + push ecx + popfd + cmp eax, ecx + je .no_cpuid + ret +.no_cpuid: + mov al, 'C' + jmp error + +check_long_mode: + mov eax, 0x80000000 + cpuid + cmp eax, 0x80000001 + jb .no_long_mode + + mov eax, 0x80000001 + cpuid + test edx, 1 << 29 + jz .no_long_mode + + ret +.no_long_mode: + mov al, 'L' + jmp error + +setup_page_tables: + mov eax, page_table_l3 + or eax, 0b11 ; present, writable + mov [page_table_l4], eax + + mov eax, page_table_l2 + or eax, 0b11 ; present, writable + mov [page_table_l3], eax + + mov ecx, 0 ; counter +.loop: + + mov eax, 0x200000 ; 2MiB + mul ecx + or eax, 0b10000011 ; present, writable, huge page + mov [page_table_l2 + ecx * 8], eax + + inc ecx ; increment counter + cmp ecx, 512 ; checks if the whole table is mapped + jne .loop ; if not, continue + + ret + +enable_paging: + ; pass page table location to cpu + mov eax, page_table_l4 + mov cr3, eax + + ; enable PAE + mov eax, cr4 + or eax, 1 << 5 + mov cr4, eax + + ; enable long mode + mov ecx, 0xC0000080 + rdmsr + or eax, 1 << 8 + wrmsr + + ; enable paging + mov eax, cr0 + or eax, 1 << 31 + mov cr0, eax + + ret + +error: + ; print "ERR: X" where X is the error code + mov dword [0xb8000], 0x4f524f45 + mov dword [0xb8004], 0x4f3a4f52 + mov dword [0xb8008], 0x4f204f20 + mov byte [0xb800a], al + hlt + + + +section .bss +; Reserve space for the IDT pointer + idtp: + resb 6 ; 2 bytes for limit + 4 bytes for base address +align 4096 +page_table_l4: + resb 4096 +page_table_l3: + resb 4096 +page_table_l2: + resb 4096 +stack_bottom: + resb 4096 * 4 +stack_top: + +section .rodata +gdt64: + dq 0 ; zero entry +.code_segment: equ $ - gdt64 + dq (1 << 43) | (1 << 44) | (1 << 47) | (1 << 53) ; code segment +.pointer: + dw $ - gdt64 - 1 ; length + dq gdt64 ; address diff --git a/EYOSx86-main/src/impl/x86_64/boot/main64.asm b/EYOSx86-main/src/impl/x86_64/boot/main64.asm new file mode 100644 index 0000000..f3ad7cc --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/boot/main64.asm @@ -0,0 +1,16 @@ +global long_mode_start +extern kernel_main + +section .text +bits 64 +long_mode_start: + ; load null into all data segment registers + mov ax, 0 + mov ss, ax + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + call kernel_main + hlt diff --git a/EYOSx86-main/src/impl/x86_64/driver/disk_io.c b/EYOSx86-main/src/impl/x86_64/driver/disk_io.c new file mode 100644 index 0000000..1cc5bd8 --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/driver/disk_io.c @@ -0,0 +1,43 @@ +// disk_io.c + +#include "disk_io.h" +#include "print.h" // Assuming you have a function for kernel printing + +#define SECTOR_SIZE 512 + +// Function to read sectors from disk +int disk_read(uint32_t lba, void *buffer, uint32_t size) { + // lba: logical block address + // buffer: where to store the read data + // size: number of bytes to read + + if (size % SECTOR_SIZE != 0) { + printf("Read size must be a multiple of 512 bytes\n"); + return -1; + } + + for (uint32_t i = 0; i < size / SECTOR_SIZE; i++) { + // Placeholder for actual disk sector read. Replace with proper implementation + if (!bios_read_sector(lba + i, buffer + (i * SECTOR_SIZE))) { + printf("Error reading sector from disk\n"); + return -1; + } + } + + return 0; +} + +// Placeholder function to simulate reading sectors from the disk +// Replace this with actual disk reading logic depending on the platform +int bios_read_sector(uint32_t lba, void *buffer) { + // Simulate disk sector read + // In an actual kernel, you'd use interrupts or other mechanisms to read from disk + + // For now, just zero out the buffer to simulate + for (int i = 0; i < SECTOR_SIZE; i++) { + ((uint8_t*)buffer)[i] = 0; // Fill buffer with zeros + } + + return 1; // Success +} + diff --git a/EYOSx86-main/src/impl/x86_64/driver/fat12.c b/EYOSx86-main/src/impl/x86_64/driver/fat12.c new file mode 100644 index 0000000..90a9da9 --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/driver/fat12.c @@ -0,0 +1,129 @@ +// fat12.c + +#include "fat12.h" +#include "disk_io.h" +#include "print.h" +#include "strings.h" + +#include "fat12.h" +#include "disk_io.h" // Assuming this contains `disk_read` for sector-level disk access + +#define SECTOR_SIZE 512 +#define FAT12_CLUSTER_SIZE 1 // Usually 1 sector per cluster for FAT12 +#define FAT12_EOC 0xFF8 // End of cluster chain marker in FAT12 + +// Function to convert a cluster number to an LBA (Logical Block Address) +static uint32_t cluster_to_lba(uint16_t cluster, const fat12_boot_sector_t *boot_sector) { + uint32_t first_data_sector = boot_sector->reserved_sectors + + (boot_sector->num_fats * boot_sector->fat_size_16) + + boot_sector->root_entry_count * 32 / SECTOR_SIZE; + return first_data_sector + (cluster - 2) * boot_sector->sectors_per_cluster; +} + +// Function to read the FAT to find the next cluster +static uint16_t fat12_get_next_cluster(uint16_t cluster, const fat12_boot_sector_t *boot_sector) { + uint32_t fat_offset = cluster + (cluster / 2); // FAT12 uses 12-bit entries + uint16_t next_cluster; + uint8_t fat_entry[2]; + + // Read the FAT sector where the current cluster is stored + uint32_t fat_sector = boot_sector->reserved_sectors + fat_offset / SECTOR_SIZE; + uint32_t fat_offset_in_sector = fat_offset % SECTOR_SIZE; + + disk_read(fat_sector, fat_entry, sizeof(fat_entry)); + + if (cluster & 1) { + next_cluster = ((fat_entry[1] << 4) | (fat_entry[0] >> 4)) & 0xFFF; // Odd cluster number + } else { + next_cluster = ((fat_entry[1] << 8) | fat_entry[0]) & 0xFFF; // Even cluster number + } + + return next_cluster; +} + +int fat12_read_file(fat12_dir_entry_t *entry, void *buffer) { + fat12_boot_sector_t boot_sector; + uint16_t current_cluster = entry->first_cluster_low; + uint32_t file_size = entry->file_size; + uint8_t *buf_ptr = (uint8_t *)buffer; + uint32_t bytes_read = 0; + + // Load the boot sector (this would need to be done once in initialization, but for simplicity here) + disk_read(0, &boot_sector, sizeof(fat12_boot_sector_t)); + + // Read each cluster of the file + while (current_cluster < FAT12_EOC && bytes_read < file_size) { + // Calculate the LBA of the current cluster + uint32_t lba = cluster_to_lba(current_cluster, &boot_sector); + + // Read the cluster (sector) into the buffer + disk_read(lba, buf_ptr, SECTOR_SIZE); + + buf_ptr += SECTOR_SIZE; + bytes_read += SECTOR_SIZE; + + // Get the next cluster in the FAT chain + current_cluster = fat12_get_next_cluster(current_cluster, &boot_sector); + } + + // Ensure we don’t read beyond the file size + if (bytes_read > file_size) { + bytes_read = file_size; + } + + return bytes_read; // Return the number of bytes read +} + + + + + +static fat12_boot_sector_t boot_sector; +static fat12_dir_entry_t root_directory[ROOT_DIR_ENTRIES]; + +// FAT12 Initialization (called during filesystem mount) +int fat12_init(void) { + // Read boot sector + if (disk_read(0, &boot_sector, sizeof(fat12_boot_sector_t)) != 0) { + printf("Failed to read boot sector\n"); + return -1; + } + + // Check for FAT12 signature + if (*(uint16_t *)((char *)&boot_sector + 510) != FAT12_SIGNATURE) { + printf("Invalid FAT12 filesystem\n"); + return -1; + } + + printf("FAT12 filesystem successfully mounted\n"); + return 0; +} + +// Reads the root directory +int fat12_read_root_directory(void) { + uint32_t root_dir_lba = (boot_sector.reserved_sectors + boot_sector.num_fats * boot_sector.fat_size_16) * boot_sector.bytes_per_sector; + + if (disk_read(root_dir_lba, root_directory, sizeof(root_directory)) != 0) { + printf("Failed to read root directory\n"); + return -1; + } + + printf("Root directory loaded\n"); + return 0; +} + +// Find a file by name in the root directory +int fat12_find_file(const char *filename, fat12_dir_entry_t *entry) { + for (int i = 0; i < ROOT_DIR_ENTRIES; i++) { + if (strncmp(root_directory[i].filename, filename, 8) == 0) { + *entry = root_directory[i]; + return 1; + } + } + + printf("File not found\n"); + return 0; +} + + + diff --git a/EYOSx86-main/src/impl/x86_64/driver/fs.c b/EYOSx86-main/src/impl/x86_64/driver/fs.c new file mode 100644 index 0000000..f142d29 --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/driver/fs.c @@ -0,0 +1,31 @@ +#include "fat12.h" +#include "disk_io.h" +#include "print.h" + +void fs_mount() { + // Load FAT12 boot sector + fat12_boot_sector_t boot_sector; + disk_read(0, &boot_sector, sizeof(boot_sector)); + + + // Initialize FAT12 + fat12_init(); + +} + +void fs_read_file(const char *filename) { + + // Find file in FAT12 root directory and read its contents + fat12_dir_entry_t dir_entry; + + fat12_find_file(filename, &dir_entry); + + // Read file data + uint8_t buffer[dir_entry.file_size]; + fat12_read_file(&dir_entry, buffer); + + // Print or process the data + printf(buffer); + + +} diff --git a/EYOSx86-main/src/impl/x86_64/driver/idt.c b/EYOSx86-main/src/impl/x86_64/driver/idt.c new file mode 100644 index 0000000..ee6424b --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/driver/idt.c @@ -0,0 +1,196 @@ +#include +#include "idt.h" +#include "print.h" +#include "vga.h" + + +#define IDT_ENTRIES 256 +// Declare the IDT and IDT pointer as external symbols +struct idt_entry_t idt[IDT_ENTRIES]; // Assuming 256 entries +struct idt_ptr_t idt_ptr; + + +// Declare ISRs implemented in assembly +extern void isr0(); +extern void isr1(); +extern void isr2(); +extern void isr3(); +extern void isr4(); +extern void isr5(); +extern void isr6(); +extern void isr7(); +extern void isr8(); +extern void isr9(); +extern void isr10(); +extern void isr11(); +extern void isr12(); +extern void isr13(); +extern void isr14(); +extern void isr15(); +extern void isr16(); +extern void isr17(); +extern void isr18(); +extern void isr19(); +extern void isr20(); +// Continue up to the required number of ISRs + + +// IDT entry setup for 64-bit mode +void setup_idt_entry(int index, void (*handler)(), uint16_t selector, uint8_t type_attr) { + uint64_t handler_addr = (uint64_t)handler; + + idt[index].offset_low = handler_addr & 0xFFFF; // Lower 16 bits of handler function address + idt[index].selector = selector; // Segment selector (kernel code segment) + idt[index].ist = 0; // Interrupt Stack Table (IST) + idt[index].type_attr = type_attr; // Type and attributes (P, DPL, S, Type) + idt[index].offset_mid = (handler_addr >> 16) & 0xFFFF; // Middle 16 bits of handler address + idt[index].offset_high = (handler_addr >> 32) & 0xFFFFFFFF; // Higher 32 bits of handler address (for 64-bit) + idt[index].zero = 0; // Reserved (set to 0) +} + +// Initialize the IDT +void init_idt() { + // Setup each IDT entry + setup_idt_entry(0, isr0, 0x08, 0x8E); // Divide-by-zero + setup_idt_entry(1, isr1, 0x08, 0x8E); // Debug + setup_idt_entry(2, isr2, 0x08, 0x8E); // Non-maskable interrupt + setup_idt_entry(3, isr3, 0x08, 0x8E); // Breakpoint + setup_idt_entry(4, isr4, 0x08, 0x8E); // Overflow + setup_idt_entry(5, isr5, 0x08, 0x8E); // Bound Range Exceeded + setup_idt_entry(6, isr6, 0x08, 0x8E); // Invalid Opcode + setup_idt_entry(7, isr7, 0x08, 0x8E); // Device Not Available + setup_idt_entry(8, isr8, 0x08, 0x8E); // Double Fault + setup_idt_entry(9, isr9, 0x08, 0x8E); // Coprocessor Segment Overrun + setup_idt_entry(10, isr10, 0x08, 0x8E); // Invalid TSS + setup_idt_entry(11, isr11, 0x08, 0x8E); // Segment Not Present + setup_idt_entry(12, isr12, 0x08, 0x8E); // Stack-Segment Fault + setup_idt_entry(13, isr13, 0x08, 0x8E); // General Protection Fault + setup_idt_entry(14, isr14, 0x08, 0x8E); // Page Fault + setup_idt_entry(15, isr15, 0x08, 0x8E); // Reserved + setup_idt_entry(16, isr16, 0x08, 0x8E); // x87 FPU Floating-Point Error + setup_idt_entry(17, isr17, 0x08, 0x8E); // Alignment Check + setup_idt_entry(18, isr18, 0x08, 0x8E); // Machine Check + setup_idt_entry(19, isr19, 0x08, 0x8E); // SIMD Floating-Point Exception + setup_idt_entry(20, isr20, 0x08, 0x8E); // Virtualization Exception + // Additional Reserved Entries as needed, or continue with ISR setup + + // Load the IDT + // IDT pointer setup + idt_ptr.limit = sizeof(idt) - 1; + idt_ptr.base = (uint64_t)&idt; + + // Load the IDT with the lidt instruction + __asm__ volatile ("lidt %0" : : "m"(idt_ptr)); + +} + + +void isr_common_handler(uint32_t isr_number) { + printf("Interrupt received: "); + printf("IDT: %d", isr_number); // To verify if the correct ISR is triggered + printf("\n"); + + + kpanic(isr_number); +} + + + +// Define kpanic to handle panic with BSOD and error messages +void kpanic(int error_code) { + // Set the background color to blue and text color to white + print_set_color(PRINT_COLOR_BLUE, PRINT_COLOR_BLUE); + move_print_cursor(0, 0); + + // Fill the entire screen with the background color + for (int y = 0; y < 25; y++) { // Replace SCREEN_HEIGHT with the actual screen height + for (int x = 0; x < 80; x++) { // Replace SCREEN_WIDTH with the actual screen width + print_char(' '); // Print a space to fill the background + } + } + + // Set the text color to white and background color to blue + print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLUE); + move_print_cursor(0, 0); + + // Print the text in the top left corner + print_str(" _ \n"); + print_str(" / )\n"); + print_str(" _ / / \n"); + print_str(" (_)( ( \n"); + print_str(" | | \n"); + print_str(" _ ( ( \n"); + print_str(" (_) \\ \\ \n"); + print_str(" \\_)\n"); + print_str("\n\n\n"); + print_str(" KERNEL PANIC\n\n"); + print_str(" "); + + + switch (error_code) { + case ERROR_DIVIDE_BY_ZERO: + print_str("Error: Divide-by-Zero Exception\n"); + break; + case ERROR_DEBUG: + print_str("Error: Debug Exception\n"); + break; + case ERROR_NMI: + print_str("Error: Non-Maskable Interrupt\n"); + break; + case ERROR_BREAKPOINT: + print_str("Error: Breakpoint Exception\n"); + break; + case ERROR_OVERFLOW: + print_str("Error: Overflow Exception\n"); + break; + case ERROR_BOUND: + print_str("Error: Bound Range Exceeded\n"); + break; + case ERROR_INVALID_OP: + print_str("Error: Invalid Opcode\n"); + break; + case ERROR_DEVICE_NOT_AVAIL: + print_str("Error: Device Not Available\n"); + break; + case ERROR_DOUBLE_FAULT: + print_str("Error: Double Fault\n"); + break; + case ERROR_COPROCESSOR_OVERRUN: + print_str("Error: Coprocessor Segment Overrun\n"); + break; + case ERROR_INVALID_TSS: + print_str("Error: Invalid TSS\n"); + break; + case ERROR_SEGMENT_NOT_PRESENT: + print_str("Error: Segment Not Present\n"); + break; + case ERROR_STACK_SEGMENT: + print_str("Error: Stack-Segment Fault\n"); + break; + case ERROR_GENERAL_PROTECTION: + print_str("Error: General Protection Fault\n"); + break; + case ERROR_PAGE_FAULT: + print_str("Error: Page Fault\n"); + break; + case FILESYSTEM_ERROR: + print_str("Error: Filesystem Error\n"); + break; + default: + printf("Error: Unknown Exception '%d'\n", error_code); + break; + } + + // Halt the system + while (1) {} +} +void idt_install() { + print_set_color(PRINT_COLOR_LIGHT_GRAY, PRINT_COLOR_BLACK); + print_str("[ init ] IDT\n"); + init_idt(); + printf("IDT Base: %p\n", (void*)idt_ptr.base); // For pointer + printf("IDT Limit: %x\n", idt_ptr.limit); // Assuming limit is small enough for %x + + print_set_color(PRINT_COLOR_GREEN, PRINT_COLOR_BLACK); + print_str("[ OK ] IDT\n"); +} diff --git a/EYOSx86-main/src/impl/x86_64/driver/io.c b/EYOSx86-main/src/impl/x86_64/driver/io.c new file mode 100644 index 0000000..f026fde --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/driver/io.c @@ -0,0 +1,15 @@ +// io.c + +#include "io.h" +#include "stdint.h" + + +void outb(uint16_t port, uint8_t value) { + asm volatile ("outb %0, %1" : : "a"(value), "Nd"(port)); +} + +uint8_t inb(uint16_t port) { + uint8_t value; + asm volatile ("inb %1, %0" : "=a"(value) : "Nd"(port)); + return value; +} diff --git a/EYOSx86-main/src/impl/x86_64/driver/irs.c b/EYOSx86-main/src/impl/x86_64/driver/irs.c new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/driver/irs.c @@ -0,0 +1 @@ + diff --git a/EYOSx86-main/src/impl/x86_64/driver/keydriver.c b/EYOSx86-main/src/impl/x86_64/driver/keydriver.c new file mode 100644 index 0000000..fed1166 --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/driver/keydriver.c @@ -0,0 +1,152 @@ +#include "keydriver.h" +#include "print.h" // Make sure you have a print function available + + +// Define the keyboard buffer and index +static char keyboard_buffer[KEYBOARD_BUFFER_SIZE]; +static unsigned int buffer_index = 0; +static int shift_pressed = 0; + +// Updated ASCII conversion table (scan code to ASCII) +const char ascii_table[128] = +{ + 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', // 9 + '9', '0', '-', '=', '\b', // Backspace + '\t', // Tab + 'q', 'w', 'e', 'r', // 19 + 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', // Enter key + 0, // 29 - Control + 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', // 39 + '\'', '`', 0, // Left shift + '\\', 'z', 'x', 'c', 'v', 'b', 'n', // 49 + 'm', ',', '.', '/', 0, // Right shift + '*', + 0, // Alt + ' ', // Space bar + 0, // Caps lock + 0, // 59 - F1 key ... > + 0, 0, 0, 0, 0, 0, 0, 0, + 0, // < ... F10 + 0, // 69 - Num lock + 0, // Scroll Lock + 0, // Home key + 0, // Up Arrow + 0, // Page Up + '-', + 0, // Left Arrow + 0, + 0, // Right Arrow + '+', + 0, // 79 - End key + 0, // Down Arrow + 0, // Page Down + 0, // Insert Key + 0, // Delete Key + 0, 0, 0, + 0, // F11 Key + 0, // F12 Key + 0, // All other keys are undefined +}; + +// Uppercase ASCII conversion table (shift key pressed) +const char shift_ascii_table[128] = +{ + 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', // 9 + '(', ')', '_', '+', '\b', // Backspace + '\t', // Tab + 'Q', 'W', 'E', 'R', // 19 + 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', // Enter key + 0, // 29 - Control + 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', // 39 + '"', '~', 0, // Left shift + '|', 'Z', 'X', 'C', 'V', 'B', 'N', // 49 + 'M', '<', '>', '?', 0, // Right shift + '*', + 0, // Alt + ' ', // Space + 0, // Caps lock + 0, // 59 - F1 key ... > + 0, 0, 0, 0, 0, 0, 0, 0, + 0, // < ... F10 + 0, // 69 - Num lock + 0, // Scroll Lock + 0, // Home key + 0, // Up Arrow + 0, // Page Up + '-', + 0, // Left Arrow + 0, + 0, // Right Arrow + '+', + 0, // 79 - End key + 0, // Down Arrow + 0, // Page Down + 0, // Insert Key + 0, // Delete Key + 0, 0, 0, + 0, // F11 Key + 0, // F12 Key + 0, // All other keys +}; + +// Initialize the keyboard driver +void init_keyboard_driver() { + print_set_color(PRINT_COLOR_LIGHT_GRAY, PRINT_COLOR_BLACK); + print_str("[ init ] KEYDRIVER\n"); + + buffer_index = 0; + shift_pressed = 0; + + print_set_color(PRINT_COLOR_GREEN, PRINT_COLOR_BLACK); + print_str("[ OK ] KEYDRIVER\n"); +} + +// Read a single character from the keyboard +char read_key() { + char key = 0; + + // Read a key from port 0x60 + __asm__("inb $0x60, %0" : "=a"(key)); + + // Check for key release (scan codes 0x80 and above are typically releases) + if (key & 0x80) { + // Handle key release + key &= 0x7F; // Remove the high bit to get the original scan code + if (key == 0x2A || key == 0x36) { // Left or right shift + shift_pressed = 0; + } + return 0; + } else { + // Handle key press + if (key == 0x2A || key == 0x36) { // Left or right shift + shift_pressed = 1; + return 0; + } + + // Convert scan code to ASCII + if (key < 128) { + if (shift_pressed) { + key = shift_ascii_table[(unsigned char)key]; + } else { + key = ascii_table[(unsigned char)key]; + } + } + + // Store the key in the buffer if there's space + if (buffer_index < KEYBOARD_BUFFER_SIZE) { + keyboard_buffer[buffer_index++] = key; + } + + return key; + } +} + +// Get the current buffer index +unsigned int get_buffer_index() { + return buffer_index; +} + +// Retrieve the contents of the keyboard buffer +const char* get_keyboard_buffer() { + return keyboard_buffer; +} diff --git a/EYOSx86-main/src/impl/x86_64/driver/memory.c b/EYOSx86-main/src/impl/x86_64/driver/memory.c new file mode 100644 index 0000000..b279a18 --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/driver/memory.c @@ -0,0 +1,116 @@ +#include "memory.h" +#include "stdint.h" +#include "print.h" +#define MEMORY_POOL_SIZE 0xFFFFF // Define the size of the memory pool +static uint8_t memory_pool[MEMORY_POOL_SIZE]; // Static memory pool +static uint8_t* memory_pool_end = memory_pool; // Pointer to the end of allocated memory + +// Block header to store size and free status +typedef struct block_header { + size_t size; + struct block_header* next; // For linking free blocks + int is_free; +} block_header_t; + +#define HEADER_SIZE sizeof(block_header_t) + +static block_header_t* free_list = NULL; // Head of the free list + +// Custom malloc implementation with block headers +void* malloc(size_t size) { + size = (size + 3) & ~3; // Align size to 4 bytes + + // First, check the free list for a suitable block + block_header_t* current = free_list; + block_header_t* prev = NULL; + + while (current) { + if (current->is_free && current->size >= size) { + current->is_free = 0; // Mark as used + return (void*)((uint8_t*)current + HEADER_SIZE); // Return memory after header + } + prev = current; + current = current->next; + } + + // No suitable block found in free list, allocate new memory from pool + if ((memory_pool_end + size + HEADER_SIZE) > (memory_pool + MEMORY_POOL_SIZE)) { + printf("Failed to allocate memory! Requested: %u bytes\n", size); + return NULL; + } + + block_header_t* header = (block_header_t*)memory_pool_end; + header->size = size; + header->is_free = 0; + header->next = NULL; + + memory_pool_end += size + HEADER_SIZE; + + return (void*)((uint8_t*)header + HEADER_SIZE); +} + +// Custom free implementation to add block back to the free list +void free(void* ptr) { + if (!ptr) { + return; + } + + // Get the block header before the allocated memory + block_header_t* header = (block_header_t*)((uint8_t*)ptr - HEADER_SIZE); + header->is_free = 1; + + // Add the block to the free list + header->next = free_list; + free_list = header; +} + + +void list_used_blocks() { + uint8_t* current_ptr = memory_pool; + + printf("Listing all used blocks:\n"); + + // Traverse the memory pool and print each block's information + while (current_ptr < memory_pool_end) { + block_header_t* header = (block_header_t*)current_ptr; + if (!header->is_free) { + printf("Used block at %p | Size: %u bytes\n", (void*)(current_ptr + HEADER_SIZE), header->size); + } + current_ptr += HEADER_SIZE + header->size; + } + + printf("End of used blocks.\n"); +} + + + + +void* memcpy(void* dst, const void* src, uint16_t num) { + uint8_t* d = (uint8_t*)dst; + const uint8_t* s = (const uint8_t*)src; + while (num--) { + *d++ = *s++; + } + return dst; +} + +void* memset(void* ptr, int value, uint16_t num) { + uint8_t* p = (uint8_t*)ptr; + while (num--) { + *p++ = (uint8_t)value; + } + return ptr; +} + +int memcmp(const void* ptr1, const void* ptr2, uint16_t num) { + const uint8_t* p1 = (const uint8_t*)ptr1; + const uint8_t* p2 = (const uint8_t*)ptr2; + while (num--) { + if (*p1 != *p2) { + return *p1 - *p2; + } + p1++; + p2++; + } + return 0; +} diff --git a/EYOSx86-main/src/impl/x86_64/driver/print.c b/EYOSx86-main/src/impl/x86_64/driver/print.c new file mode 100644 index 0000000..d862def --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/driver/print.c @@ -0,0 +1,343 @@ +#include +#include "print.h" +#include "vga.h" + + +const static size_t NUM_COLS = 80; +const static size_t NUM_ROWS = 25; + +struct Char { + uint8_t character; + uint8_t color; +}; + + + + +struct Char* buffer = (struct Char*) 0xb8000; +size_t col = 0; +size_t row = 0; +uint8_t color = PRINT_COLOR_WHITE | PRINT_COLOR_BLACK << 4; + +void clear_row(size_t row) { + struct Char empty = (struct Char) { + character: ' ', + color: color, + }; + + for (size_t col = 0; col < NUM_COLS; col++) { + buffer[col + NUM_COLS * row] = empty; + } +} + +void print_clear() { + for (size_t i = 0; i < NUM_ROWS; i++) { + clear_row(i); + } +} + +//void print_newline() { +// col = 0; +// +// if (row < NUM_ROWS - 1) { +// row++; +// return; +// } +// +// for (size_t row = 1; row < NUM_ROWS; row++) { +// for (size_t col = 0; col < NUM_COLS; col++) { +// struct Char character = buffer[col + NUM_COLS * row]; +// buffer[col + NUM_COLS * (row - 1)] = character; +// } +// } +// +// clear_row(NUM_COLS - 1); +//} + +void print_newline() { + row++; + col = 0; + + // Check for scrolling + if (row >= NUM_ROWS) { + row = NUM_ROWS - 1; + // Scroll the screen up + // Copy lines up + // Clear the last line + } +} + +CursorPosition get_print_cursor_pos() { + CursorPosition pos; + pos.x = col; // Use col for x + pos.y = row; // Use row for y + + return pos; +} + + +void print_hex(unsigned int num) { + char buffer[9]; // Buffer to hold the hexadecimal string representation + int i = 0; + + // Handle zero case + if (num == 0) { + print_char('0'); + return; + } + + // Convert integer to hexadecimal in reverse order + while (num > 0) { + int digit = num % 16; + if (digit < 10) { + buffer[i++] = digit + '0'; + } else { + buffer[i++] = (digit - 10) + 'A'; + } + num /= 16; + } + + // Print the hexadecimal number in correct order + for (int j = i - 1; j >= 0; j--) { + print_char(buffer[j]); + } +} + +void move_print_cursor(int x, int y) { + col = x; + row = y; + set_cursor_position(col, row); // Move cursor to new position +} + + +void offset_print_cursor(int x, int y) { + col += x; + row += y; + set_cursor_position(col, row); +} + +// Function to print a single character +void print_char(char character) { + if (character == '\n') { + print_newline(); + return; + } + + // Handle wrapping + if (col >= NUM_COLS) { + print_newline(); + } + + // Update the buffer + buffer[col + NUM_COLS * row] = (struct Char) { + .character = (uint8_t) character, + .color = color, + }; + + col++; +} + +// Function to print a string +void print_str(char* str) { + size_t i = 0; + while (str[i] != '\0') { + print_char(str[i]); + i++; + } +} + +void print_set_color(uint8_t foreground, uint8_t background) { + color = foreground + (background << 4); +} + + +void print_int(int num) { + // Handle negative numbers + if (num < 0) { + print_char('-'); + num = -num; + } + + // Convert number to string + char buffer[11]; // Buffer to hold integer string representation + int i = 0; + + if (num == 0) { + buffer[i++] = '0'; + } else { + while (num > 0) { + buffer[i++] = (num % 10) + '0'; + num /= 10; + } + } + + // Print the integer in correct order + for (int j = i - 1; j >= 0; j--) { + print_char(buffer[j]); + } +} + +#include +#include "print.h" + +void print_formatted(const char* format, va_list args) { + while (*format) { + if (*format == '%') { + format++; + switch (*format) { + case 's': { + char* str = va_arg(args, char*); + print_str(str); + break; + } + case 'x': { + unsigned int num = va_arg(args, unsigned int); + print_hex(num); + break; + } + case 'd': { + int num = va_arg(args, int); + print_int(num); + break; + } + case 'c': { + char ch = (char) va_arg(args, int); // Promoted to int + print_char(ch); + break; + } + case 'u': { + unsigned int num = va_arg(args, unsigned int); + print_uint(num); // Custom function for unsigned int + break; + } + case 'p': { + void* ptr = va_arg(args, void*); + print_pointer(ptr); // Custom function for pointers + break; + } + case 'f': { + double num = va_arg(args, double); + print_float(num); // Custom function for floating-point numbers + break; + } + default: + print_char('%'); + print_char(*format); + break; + } + } else { + print_char(*format); + } + format++; + } +} +void print_uint(unsigned int num) { + // Convert to string and print (implementation required) + char buffer[11]; // Enough for 32-bit unsigned int + int i = 0; + if (num == 0) { + print_char('0'); + return; + } + while (num > 0) { + buffer[i++] = '0' + (num % 10); + num /= 10; + } + while (i > 0) { + print_char(buffer[--i]); + } +} +void print_pointer(void* ptr) { + unsigned long num = (unsigned long) ptr; + print_str("0x"); + print_hex(num); // Assuming print_hex handles long +} +void print_float(double num) { + // Simple implementation of floating-point printing + int int_part = (int)num; + int frac_part = (int)((num - int_part) * 1000000); // Six decimal places + + print_int(int_part); + print_char('.'); + + // Ensure fractional part is always printed with six digits + for (int i = 0; i < 6; i++) { + print_char('0' + (frac_part % 10)); + frac_part /= 10; + } +} + +void sscanf(const char *str, const char *format, char *filename, char *content) { + const char *p = str; + char *f = filename; + char *c = content; + + while (*format) { + if (*format == '%') { + format++; + if (*format == 's') { + // Copy the first string + while (*p && *p != ' ' && (f - filename) < MAX_STRING_LENGTH - 1) { + *f++ = *p++; + } + *f = '\0'; + + // Skip any whitespace + while (*p == ' ') p++; + + // Copy the second string + while (*p && (c - content) < MAX_STRING_LENGTH - 1) { + *c++ = *p++; + } + *c = '\0'; + } + } + format++; + } +} + +int my_sscanf(const char *input, const char *format, char *output) { + const char *in_ptr = input; + const char *fmt_ptr = format; + char *out_ptr = output; + int match_count = 0; + + // Skip any leading whitespace in the input + while (*in_ptr && (*in_ptr == ' ' || *in_ptr == '\t')) { + in_ptr++; + } + + // Process the format string + while (*fmt_ptr) { + if (*fmt_ptr == '%' && *(fmt_ptr + 1) == 's') { + // Found a string specifier + fmt_ptr += 2; // Skip %s + + // Copy input string to output until whitespace or end of input + while (*in_ptr && *in_ptr != ' ' && *in_ptr != '\t' && *in_ptr != '\n') { + *out_ptr++ = *in_ptr++; + } + *out_ptr = '\0'; // Null-terminate the output string + match_count++; + } else { + // Match literal characters in format string + if (*fmt_ptr == *in_ptr) { + fmt_ptr++; + in_ptr++; + } else { + // Literal character mismatch + return match_count; + } + } + } + + return match_count; +} + + +void printf(const char* format, ...) { + va_list args; + va_start(args, format); + print_formatted(format, args); + va_end(args); +} diff --git a/EYOSx86-main/src/impl/x86_64/driver/vector.c b/EYOSx86-main/src/impl/x86_64/driver/vector.c new file mode 100644 index 0000000..b5ea922 --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/driver/vector.c @@ -0,0 +1,80 @@ +#include "vector.h" + +// Initial capacity for a new vector +#define VECTOR_INITIAL_CAPACITY 4 + +// Create a new vector +vector* vector_create() { + vector* v = (vector*)malloc(sizeof(vector)); + if (!v) return NULL; // Return NULL if allocation fails + + v->capacity = VECTOR_INITIAL_CAPACITY; + v->size = 0; + v->items = (void**)malloc(sizeof(void*) * v->capacity); + if (!v->items) { + free(v); // Free the vector if item allocation fails + return NULL; + } + + return v; +} + +// Destroy the vector and free allocated memory +void vector_destroy(vector* v) { + if (v) { + free(v->items); + free(v); + } +} + +// Push an item to the back of the vector +int vector_push_back(vector* v, void* item) { + // Resize the vector if it's full + if (v->size == v->capacity) { + if (vector_resize(v, v->capacity * 2) != 0) { + return -1; // Return -1 on failure to resize + } + } + + v->items[v->size++] = item; // Add the new item + return 0; // Success +} + +// Get the item at a specific index +void* vector_get(vector* v, size_t index) { + if (index >= v->size) return NULL; // Return NULL if index is out of bounds + return v->items[index]; +} + +// Set an item at a specific index +int vector_set(vector* v, size_t index, void* item) { + if (index >= v->size) return -1; // Return -1 if index is out of bounds + v->items[index] = item; + return 0; // Success +} + +// Get the size of the vector +size_t vector_size(vector* v) { + return v->size; +} + +// Resize the vector's internal array +int vector_resize(vector* v, size_t new_capacity) { + // Allocate new memory for the resized array + void** new_items = (void**)malloc(sizeof(void*) * new_capacity); + if (!new_items) return -1; // Return -1 on failure + + // Copy the old items into the new array + for (size_t i = 0; i < v->size; i++) { + new_items[i] = v->items[i]; + } + + // Free the old memory + free(v->items); + + // Update the vector's internal state + v->items = new_items; + v->capacity = new_capacity; + + return 0; // Success +} diff --git a/EYOSx86-main/src/impl/x86_64/driver/vga.c b/EYOSx86-main/src/impl/x86_64/driver/vga.c new file mode 100644 index 0000000..2a3918f --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/driver/vga.c @@ -0,0 +1,29 @@ +#include "vga.h" +#include "stdint.h" +#include "io.h" + + +#define VGA_PORT_INDEX 0x3D4 +#define VGA_PORT_DATA 0x3D5 + + +void move_cursor(int x, int y) { + uint16_t position = y * 80 + x; // Assuming 80 columns + outb(0x3D4, 0x0E); // VGA register for high byte + outb(0x3D5, (position >> 8) & 0xFF); + outb(0x3D4, 0x0F); // VGA register for low byte + outb(0x3D5, position & 0xFF); +} + + + + +void set_cursor_position(int x, int y) { + uint16_t position = y * 80 + x; // 80 columns in VGA text mode + outb(VGA_PORT_INDEX, 0x0E); + outb(VGA_PORT_DATA, (position >> 8) & 0xFF); + outb(VGA_PORT_INDEX, 0x0F); + outb(VGA_PORT_DATA, position & 0xFF); +} + + diff --git a/EYOSx86-main/src/impl/x86_64/game.c b/EYOSx86-main/src/impl/x86_64/game.c new file mode 100644 index 0000000..8a102af --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/game.c @@ -0,0 +1,185 @@ +#include "game.h" +#include "print.h" +#include "keydriver.h" +#include "strings.h" +#include "stdint.h" + +// Define constants for the game +#define ROOM_COUNT 5 +#define INVENTORY_SIZE 5 + +// Global variable to hold the game state +static GameState game_state; + +// Room descriptions and connected rooms +typedef struct { + const char* description; + int north; + int south; + int east; + int west; +} Room; + +static const Room rooms[ROOM_COUNT] = { + { "You are in a dark forest. There are paths to the north and east.", 1, -1, 2, -1 }, + { "You are on a beach. There is a cave to the west.", -1, 0, -1, 3 }, + { "You are inside a cave. It’s damp and dark.", -1, -1, -1, 0 }, + { "You are in a small village. There's a shop to the north and a forest to the east.", 4, -1, -1, -1 }, + { "You are in a shop filled with various items. The village is to the south.", -1, 3, -1, -1 } +}; + +// Player's inventory +static const char* inventory[INVENTORY_SIZE]; +static int inventory_count = 0; + +// Command buffer +static char commandBuffer[MAX_COMMAND_LENGTH]; +static size_t commandLength = 0; + +bool keydown = false; + +// Function to handle user input commands +void handle_command(const char* command) { + + + game_clear(); + + + if (strcmp(command, "look") == 0) { + printf(rooms[game_state.current_room].description); + printf("\n"); + } else if (strcmp(command, "north") == 0) { + if (rooms[game_state.current_room].north != -1) { + game_state.current_room = rooms[game_state.current_room].north; + printf("You walk north.\n"); + printf("%s\n", rooms[game_state.current_room].description); + } else { + printf("You can't go that way.\n"); + } + } else if (strcmp(command, "south") == 0) { + if (rooms[game_state.current_room].south != -1) { + game_state.current_room = rooms[game_state.current_room].south; + printf("You walk south.\n"); + printf("%s\n", rooms[game_state.current_room].description); + } else { + printf("You can't go that way.\n"); + } + } else if (strcmp(command, "east") == 0) { + if (rooms[game_state.current_room].east != -1) { + game_state.current_room = rooms[game_state.current_room].east; + printf("You walk east.\n"); + printf("%s\n", rooms[game_state.current_room].description); + } else { + printf("You can't go that way.\n"); + } + } else if (strcmp(command, "west") == 0) { + if (rooms[game_state.current_room].west != -1) { + game_state.current_room = rooms[game_state.current_room].west; + printf("You walk west.\n"); + printf("%s\n", rooms[game_state.current_room].description); + } else { + printf("You can't go that way.\n"); + } + } else if (strcmp(command, "inventory") == 0) { + printf("You are carrying:\n"); + for (int i = 0; i < inventory_count; ++i) { + printf("- %s\n", inventory[i]); + } + if (inventory_count == 0) { + printf("Nothing.\n"); + } + } else if (strcmp(command, "take key") == 0) { + if (game_state.current_room == 1) { + if (inventory_count < INVENTORY_SIZE) { + inventory[inventory_count++] = "key"; + printf("You picked up a key.\n"); + } else { + printf("Your inventory is full.\n"); + } + } else { + printf("There is no key here.\n"); + } + } else if (strcmp(command, "use key") == 0) { + bool has_key = false; + for (int i = 0; i < inventory_count; ++i) { + if (strcmp(inventory[i], "key") == 0) { + has_key = true; + break; + } + } + if (has_key && game_state.current_room == 2) { + printf("You unlock the door in the cave and find a treasure!\n"); + game_state.game_active = false; // End the game + } else { + printf("You can't use the key here.\n"); + } + } else if (strcmp(command, "quit") == 0) { + printf("You quit the game.\n"); + game_state.game_active = false; + } else { + printf("Unknown command.\n"); + } +} + +// Function to print the prompt for the player +void print_prompt() { + printf(" > "); +} + +const void game_clear() +{ + print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set text color + + move_print_cursor(0, 0); + move_cursor(0, 0); + print_clear(); +} + +// Function to initialize and run the game +void create_game() { + // Initialize the game state + game_state.current_room = 0; + game_state.game_active = true; + + printf("Welcome to the text adventure game!\n"); + printf("Type 'look' to see where you are, 'north', 'south', 'east', 'west' to move, or 'quit' to exit.\n"); + printf("You can 'take key' or 'use key' in the appropriate places.\n"); + + print_prompt(); + + // Main game loop + while (game_state.game_active) { + char key = read_key(); // Get key input + + if (key != 0) { + if (!keydown) { + if (key == 10) { // Enter key + printf("\n"); + commandBuffer[commandLength] = '\0'; // Null-terminate the command + handle_command(commandBuffer); // Process the command + commandLength = 0; // Reset command buffer + if (game_state.game_active) { + print_prompt(); // Print prompt for the next command + } + } else if (key == 8) { // Backspace key + if (commandLength > 0) { + commandLength--; + offset_print_cursor(-1, 0); + print_char(' '); // Overwrite the character + offset_print_cursor(-1, 0); + } + } else if (key >= 32 && key <= 126) { // Printable characters + if (commandLength < MAX_COMMAND_LENGTH - 1) { + commandBuffer[commandLength++] = key; + print_char(key); // Display the key on the screen + } + } + keydown = true; + } + } else { + keydown = false; + } + } + + printf("Thanks for playing!\n"); +} diff --git a/EYOSx86-main/src/impl/x86_64/stdopt.c b/EYOSx86-main/src/impl/x86_64/stdopt.c new file mode 100644 index 0000000..8555145 --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/stdopt.c @@ -0,0 +1,127 @@ +#include +#include "strings.h" +#include "memory.h" + + +void prepend(uint8_t* array, uint8_t c) { + // Ensure that size is within bounds and there's space to prepend + + int size = sizeof(array); + + // Shift all elements to the right + for (int i = size; i > 0; i--) { + array[i] = array[i - 1]; + } + + // Insert the new character at the beginning + array[0] = c; +} + +void append(uint8_t* array, uint8_t c) { + // Ensure that size is within bounds and there's space to append + int size = sizeof(array); + + // Insert the new character at the end + array[size] = c; +} + + +void append_first(uint8_t* array, uint8_t c) { + // Shift all elements to the right + int size = sizeof(array); + for (int i = size - 1; i > 0; i--) { + array[i] = array[i - 1]; + } + + // Insert the new character at the beginning + array[0] = c; +} + + +void append_last(uint8_t* array, uint8_t c) { + int size = sizeof(array); + // Shift all elements to the left + + for (int i = 0; i < size - 1; i++) { + array[i] = array[i + 1]; + } + + // Insert the new character at the end + array[0] = c; +} + +char** split_string(const char* str, char delimiter) { + if (str == NULL) { + return NULL; + } + + // Count the number of tokens + int* num_tokens = 1; + for (const char* p = str; *p; ++p) { + if (*p == delimiter) { + (*num_tokens)++; + } + } + + printf("Tokens: %d", num_tokens); + + // Allocate memory for the array of char* + char** tokens = (char**)malloc((*num_tokens + 1) * sizeof(char*)); // +1 for NULL terminator + if (tokens == NULL) { + return NULL; + } + + // Allocate memory for each token and split the string + size_t start = 0; + size_t end = 0; + int index = 0; + while (str[end] != '\0') { + if (str[end] == delimiter) { + size_t length = end - start; + tokens[index] = (char*)malloc((length + 1) * sizeof(char)); // +1 for null terminator + if (tokens[index] == NULL) { + // Free previously allocated memory in case of failure + for (int i = 0; i < index; i++) { + free(tokens[i]); + } + free(tokens); + return NULL; + } + strncpy(tokens[index], &str[start], length); + tokens[index][length] = '\0'; + index++; + start = end + 1; + } + end++; + } + + // Add the last token + size_t length = end - start; + tokens[index] = (char*)malloc((length + 1) * sizeof(char)); // +1 for null terminator + if (tokens[index] == NULL) { + // Free previously allocated memory in case of failure + for (int i = 0; i < index; i++) { + free(tokens[i]); + } + free(tokens); + return NULL; + } + strncpy(tokens[index], &str[start], length); + tokens[index][length] = '\0'; + tokens[index + 1] = NULL; // Null-terminate the array + + return tokens; +} + +// Function to free the memory allocated for the array of strings +void free_split_strings(char** tokens, int num_tokens) { + if (tokens == NULL) { + return; + } + for (int i = 0; i < num_tokens; i++) { + free(tokens[i]); + } + free(tokens); +} + + diff --git a/EYOSx86-main/src/impl/x86_64/strings.c b/EYOSx86-main/src/impl/x86_64/strings.c new file mode 100644 index 0000000..d1f726f --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/strings.c @@ -0,0 +1,92 @@ +#include "strings.h" +#include "stdint.h" + +int int_strncmp(const char* s1, const char* s2, size_t n) { + while (n > 0) { + if (*s1 != *s2) { + return (uint8_t)*s1 - (uint8_t)*s2; + } + if (*s1 == '\0') { + return 0; // End of both strings + } + s1++; + s2++; + n--; + } + return 0; // First n characters are equal +} + + +int strcmp(const char *str1, const char *str2) { + while (*str1 && (*str1 == *str2)) { + str1++; + str2++; + } + return *(unsigned char *)str1 - *(unsigned char *)str2; +} + + + + +void strcpy(char *dest, const char *src) { + while (*src) { + *dest = *src; + dest++; + src++; + } + *dest = '\0'; // Ensure the destination string is null-terminated +} + + + +size_t strlen(const char *str) { + const char *s = str; + while (*s) { + s++; + } + return s - str; +} + + + + +char *strncpy(char *dest, const char *src, size_t n) { + char *d = dest; + while (n && (*d++ = *src++)) { + n--; + } + if (n) { + while (--n) { + *d++ = '\0'; + } + } + return dest; +} + + + +char* strrchr(const char* str, char ch) { + char* result = NULL; + while (*str) { + if (*str == ch) { + result = (char*)str; + } + str++; + } + return result; +} + + +// In strings.c +int strncmp(const char *s1, const char *s2, size_t n) { + while (n && *s1 && (*s1 == *s2)) { + ++s1; + ++s2; + --n; + } + if (n == 0) { + return 0; + } else { + return (*(unsigned char *)s1 - *(unsigned char *)s2); + } +} \ No newline at end of file diff --git a/EYOSx86-main/src/impl/x86_64/window.c b/EYOSx86-main/src/impl/x86_64/window.c new file mode 100644 index 0000000..6ac9190 --- /dev/null +++ b/EYOSx86-main/src/impl/x86_64/window.c @@ -0,0 +1,85 @@ +#include "window.h" +#include "print.h" + +// Define the screen dimensions +#define SCREEN_WIDTH 80 +#define SCREEN_HEIGHT 25 + +// Function to draw the border of the window +static void draw_border(const Window* win) { + // Set the color for the border + print_set_color(win->border_color, win->border_color); + + // Draw top border + for (int i = 0; i < win->size_x; ++i) { + move_print_cursor(win->x + i, win->y); + print_char('#'); + } + + // Draw bottom border + for (int i = 0; i < win->size_x; ++i) { + move_print_cursor(win->x + i, win->y + win->size_y - 1); + print_char('#'); + } + + // Draw left and right borders + for (int i = 1; i < win->size_y - 1; ++i) { + move_print_cursor(win->x, win->y + i); + print_char('#'); + move_print_cursor(win->x + win->size_x - 1, win->y + i); + print_char('#'); + } + + // Draw title + if (win->title[0] != '\0') { + print_set_color(win->border_color, win->background_color); + move_print_cursor(win->x + 1, win->y); + print_str(win->title); + } +} + +// Function to draw the background of the window +static void draw_background(const Window* win) { + // Set the color for the background + print_set_color(win->background_color, win->background_color); + + for (int i = 1; i < win->size_y - 1; ++i) { + for (int j = 1; j < win->size_x - 1; ++j) { + move_print_cursor(win->x + j, win->y + i); + print_char(' '); // Background character + } + } +} + +// Function to create a simple window with border, background, and title +void create_window(Window* win, int x, int y, int size_x, int size_y, uint8_t border_color, uint8_t background_color, const char* title) { + win->x = x; + win->y = y; + win->size_x = size_x; + win->size_y = size_y; + win->border_color = border_color; + win->background_color = background_color; + + // Copy title to window struct + for (int i = 0; i < WINDOW_TITLE_MAX_LENGTH - 1 && title[i] != '\0'; ++i) { + win->title[i] = title[i]; + } + win->title[WINDOW_TITLE_MAX_LENGTH - 1] = '\0'; // Ensure null-termination + + // Draw the window + draw_background(win); + draw_border(win); +} + +// Function to print text inside the window +void print_text_in_window(const Window* win, int x, int y, const char* text) { + // Set the color for the text + print_set_color(PRINT_COLOR_WHITE, win->background_color); + + for (int i = 0; text[i] != '\0'; ++i) { + if (x + i < win->size_x - 1 && y < win->size_y - 1) { + move_print_cursor(win->x + x + i, win->y + y); + print_char(text[i]); + } + } +} diff --git a/EYOSx86-main/src/intf/disk_io.h b/EYOSx86-main/src/intf/disk_io.h new file mode 100644 index 0000000..fef0d39 --- /dev/null +++ b/EYOSx86-main/src/intf/disk_io.h @@ -0,0 +1,17 @@ +// disk_io.h + +#ifndef DISK_IO_H +#define DISK_IO_H + +#include + +// Read sectors from the disk +int disk_read(uint32_t lba, void *buffer, uint32_t size); + +// Optional: Write sectors to the disk (not implemented) +int disk_write(uint32_t lba, const void *buffer, uint32_t size); + + +int bios_read_sector(uint32_t lba, void *buffer); + +#endif // DISK_IO_H \ No newline at end of file diff --git a/EYOSx86-main/src/intf/fat12.h b/EYOSx86-main/src/intf/fat12.h new file mode 100644 index 0000000..b865b9f --- /dev/null +++ b/EYOSx86-main/src/intf/fat12.h @@ -0,0 +1,58 @@ +#ifndef FAT12_H +#define FAT12_H + +#include + +#define FAT12_SIGNATURE 0xAA55 +#define ROOT_DIR_ENTRIES 224 + +typedef struct { + uint8_t jmp_boot[3]; // Jump instruction + char oem_name[8]; // OEM Name + uint16_t bytes_per_sector; + uint8_t sectors_per_cluster; + uint16_t reserved_sectors; + uint8_t num_fats; + uint16_t root_entry_count; + uint16_t total_sectors_16; + uint8_t media; + uint16_t fat_size_16; + uint16_t sectors_per_track; + uint16_t num_heads; + uint32_t hidden_sectors; + uint32_t total_sectors_32; + uint8_t boot_signature; + uint32_t volume_id; + char volume_label[11]; + char fs_type[8]; +} __attribute__((packed)) fat12_boot_sector_t; + +typedef struct { + char filename[8]; + char extension[3]; + uint8_t attributes; + uint8_t reserved; + uint8_t creation_time_tenths; + uint16_t creation_time; + uint16_t creation_date; + uint16_t last_access_date; + uint16_t first_cluster_high; + uint16_t last_mod_time; + uint16_t last_mod_date; + uint16_t first_cluster_low; + uint32_t file_size; +} __attribute__((packed)) fat12_dir_entry_t; + +// FAT12 Filesystem initialization +int fat12_init(void); + +// Read the root directory +int fat12_read_root_directory(void); + +// Find a file in the root directory +int fat12_find_file(const char *filename, fat12_dir_entry_t *entry); + +// Read a file (to be implemented) +int fat12_read_file(fat12_dir_entry_t *entry, void *buffer); + +#endif // FAT12_H diff --git a/EYOSx86-main/src/intf/fs.h b/EYOSx86-main/src/intf/fs.h new file mode 100644 index 0000000..9a02a7d --- /dev/null +++ b/EYOSx86-main/src/intf/fs.h @@ -0,0 +1,47 @@ +#ifndef FS_H +#define FS_H + +#include +#include "fat12.h" +#include "disk_io.h" +#include "print.h" + +#define BLOCK_SIZE 4096 +#define MAX_FILE_NAME 255 +#define MAX_FILES 128 + +// Declarations for block operations +void write_block(uint32_t block_index, const void *data, uint32_t size); +void read_block(uint32_t block_index, void *buffer, uint32_t size); + +// Structure of the superblock +typedef struct { + uint32_t total_blocks; + uint32_t free_blocks; + uint32_t total_inodes; + uint32_t free_inodes; +} Superblock; + +// Structure of an inode +typedef struct { + char name[MAX_FILE_NAME]; + uint32_t size; + uint32_t data_block_start; + uint32_t permissions; +} Inode; + +// Structure of a directory entry +typedef struct { + char name[MAX_FILE_NAME]; + uint32_t inode_index; +} DirectoryEntry; + +// Filesystem operations +void fs_init(); +int fs_create_file(const char *name, uint32_t size); +int fs_write_file(const char *name, const void *data, uint32_t size); +int fs_read_file(const char *name, void *buffer, uint32_t size); +int fs_delete_file(const char *name); +void list_files(); + +#endif // FS_H diff --git a/EYOSx86-main/src/intf/game.h b/EYOSx86-main/src/intf/game.h new file mode 100644 index 0000000..a4922ad --- /dev/null +++ b/EYOSx86-main/src/intf/game.h @@ -0,0 +1,25 @@ +#ifndef GAME_H +#define GAME_H + +#include "stdint.h" + + +// Define the maximum length of a command +#define MAX_COMMAND_LENGTH 128 + +// Game state structure +typedef struct { + int current_room; + bool game_active; +} GameState; + +// Function to initialize and run the game +void create_game(); + +// Function to handle the command input by the player +void handle_command(const char* command); + +// Function to print the current prompt +void print_prompt(); + +#endif diff --git a/EYOSx86-main/src/intf/idt.h b/EYOSx86-main/src/intf/idt.h new file mode 100644 index 0000000..cd01f7b --- /dev/null +++ b/EYOSx86-main/src/intf/idt.h @@ -0,0 +1,46 @@ +#ifndef IDT_H +#define IDT_H + +#include + +struct idt_entry_t { + uint16_t offset_low; // Lower 16 bits of ISR address + uint16_t selector; // Kernel segment selector + uint8_t ist; // Interrupt Stack Table (for 64-bit) + uint8_t type_attr; // Type and attributes (P, DPL, S, Type) + uint16_t offset_mid; // Middle 16 bits of ISR address + uint32_t offset_high; // Upper 32 bits of ISR address (for 64-bit) + uint32_t zero; // Reserved +} __attribute__((packed)); + +struct idt_ptr_t { + uint16_t limit; // Size of the IDT (bytes - 1) + uint64_t base; // Base address of the IDT +} __attribute__((packed)); + + + +#define ERROR_DIVIDE_BY_ZERO 0 +#define ERROR_DEBUG 1 +#define ERROR_NMI 2 +#define ERROR_BREAKPOINT 3 +#define ERROR_OVERFLOW 4 +#define ERROR_BOUND 5 +#define ERROR_INVALID_OP 6 +#define ERROR_DEVICE_NOT_AVAIL 7 +#define ERROR_DOUBLE_FAULT 8 +#define ERROR_COPROCESSOR_OVERRUN 9 +#define ERROR_INVALID_TSS 10 +#define ERROR_SEGMENT_NOT_PRESENT 11 +#define ERROR_STACK_SEGMENT 12 +#define ERROR_GENERAL_PROTECTION 13 +#define ERROR_PAGE_FAULT 14 +#define FILESYSTEM_ERROR 15 // Assuming this relates to your filesystem + + +#define ERROR_RESERVED 16 // Not implemented error +// Function prototypes +void setup_idt_entry(int index, void (*handler)(), uint16_t selector, uint8_t type_attr); +void init_idt(); + +#endif diff --git a/EYOSx86-main/src/intf/io.h b/EYOSx86-main/src/intf/io.h new file mode 100644 index 0000000..536bdd0 --- /dev/null +++ b/EYOSx86-main/src/intf/io.h @@ -0,0 +1,11 @@ +// io.h + +#ifndef IO_H +#define IO_H + +#include "stdint.h" + +void outb(uint16_t port, uint8_t value); +uint8_t inb(uint16_t port); + +#endif // IO_H diff --git a/EYOSx86-main/src/intf/keydriver.h b/EYOSx86-main/src/intf/keydriver.h new file mode 100644 index 0000000..debebf0 --- /dev/null +++ b/EYOSx86-main/src/intf/keydriver.h @@ -0,0 +1,18 @@ +#ifndef KEYDRIVER_H +#define KEYDRIVER_H + +#define KEYBOARD_BUFFER_SIZE 128 + +// Initializes the keyboard driver +void init_keyboard_driver(); + +// Reads a single character from the keyboard and stores it in the buffer +char read_key(); + +// Gets the current index of the buffer +unsigned int get_buffer_index(); + +// Retrieves the contents of the keyboard buffer +const char* get_keyboard_buffer(); + +#endif // KEYDRIVER_H diff --git a/EYOSx86-main/src/intf/memory.h b/EYOSx86-main/src/intf/memory.h new file mode 100644 index 0000000..eac5aa3 --- /dev/null +++ b/EYOSx86-main/src/intf/memory.h @@ -0,0 +1,9 @@ +#pragma once + +#include "stdint.h" + +void* memcpy(void* dst, const void* src, uint16_t num); +void* memset(void* ptr, int value, uint16_t num); +int memcmp(const void* ptr1, const void* ptr2, uint16_t num); +void* malloc(size_t size); +void free(void* ptr); diff --git a/EYOSx86-main/src/intf/print.h b/EYOSx86-main/src/intf/print.h new file mode 100644 index 0000000..3ce4811 --- /dev/null +++ b/EYOSx86-main/src/intf/print.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include +#define MAX_STRING_LENGTH 100 + +typedef struct { + int x; + int y; +} CursorPosition; + +enum { + PRINT_COLOR_BLACK = 0, + PRINT_COLOR_BLUE = 1, + PRINT_COLOR_GREEN = 2, + PRINT_COLOR_CYAN = 3, + PRINT_COLOR_RED = 4, + PRINT_COLOR_MAGENTA = 5, + PRINT_COLOR_BROWN = 6, + PRINT_COLOR_LIGHT_GRAY = 7, + PRINT_COLOR_DARK_GRAY = 8, + PRINT_COLOR_LIGHT_BLUE = 9, + PRINT_COLOR_LIGHT_GREEN = 10, + PRINT_COLOR_LIGHT_CYAN = 11, + PRINT_COLOR_LIGHT_RED = 12, + PRINT_COLOR_PINK = 13, + PRINT_COLOR_YELLOW = 14, + PRINT_COLOR_WHITE = 15, +}; + +void sscanf(const char *str, const char *format, char *filename, char *content); +int my_sscanf(const char *input, const char *format, char *output); +void print_clear(); +void print_char(char character); +void print_str(char* string); +void printf(const char* format, ...); +void print_set_color(uint8_t foreground, uint8_t background); +void move_print_cursor(int x, int y); +void offset_print_cursor(int x, int y); +void print_hex(unsigned int num); +CursorPosition get_print_cursor_pos(); diff --git a/EYOSx86-main/src/intf/stdint.h b/EYOSx86-main/src/intf/stdint.h new file mode 100644 index 0000000..555e8f3 --- /dev/null +++ b/EYOSx86-main/src/intf/stdint.h @@ -0,0 +1,23 @@ +#pragma once + +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed long int int32_t; +typedef unsigned long int uint32_t; +typedef signed long long int int64_t; +typedef unsigned long long int uint64_t; +typedef uint32_t size_t; // Adjust size based on your platform; 32-bit or 64-bit + + +typedef uint8_t bool; + +#define false 0 +#define true 1 + +#define NULL ((void*)0) +#define min(a,b) ((a) < (b) ? (a) : (b)) +#define max(a,b) ((a) > (b) ? (a) : (b)) + +// Define size_t as an unsigned integer type for sizes and indices diff --git a/EYOSx86-main/src/intf/stdopt.h b/EYOSx86-main/src/intf/stdopt.h new file mode 100644 index 0000000..51a7969 --- /dev/null +++ b/EYOSx86-main/src/intf/stdopt.h @@ -0,0 +1,49 @@ +#ifndef BUFFER_OPS_H +#define BUFFER_OPS_H + +#include + +/** + * @brief Inserts a character at the beginning of the array. + * Shifts all elements to the right and removes the last element if the array is full. + * + * @param array Pointer to the array. + * @param c Character to prepend. + */ +void prepend(uint8_t* array, uint8_t c); + +/** + * @brief Inserts a character at the end of the array. + * Shifts all elements to the left and removes the first element if the array is full. + * + * @param array Pointer to the array. + * @param c Character to append. + */ +void append(uint8_t* array, uint8_t c); + +/** + * @brief Inserts a character at the beginning of the array. + * Shifts all elements to the right. Note that this function assumes there is space + * at the beginning of the array. + * + * @param array Pointer to the array. + * @param c Character to insert at the beginning. + */ +void append_first(uint8_t* array, uint8_t c); + +/** + * @brief Inserts a character at the end of the array. + * Shifts all elements to the left. Note that this function assumes there is space + * at the end of the array. + * + * @param array Pointer to the array. + * @param c Character to insert at the end. + */ +void append_last(uint8_t* array, uint8_t c); + + +char** split_string(const char* str, char delimiter, int* num_tokens); +void free_split_strings(char** tokens, int num_tokens); + + +#endif // BUFFER_OPS_H diff --git a/EYOSx86-main/src/intf/strings.h b/EYOSx86-main/src/intf/strings.h new file mode 100644 index 0000000..f9f54fe --- /dev/null +++ b/EYOSx86-main/src/intf/strings.h @@ -0,0 +1,12 @@ + +#include +#include + +int strcmp(const char *str1, const char *str2); +size_t strlen(const char *str); +char *strncpy(char *dest, const char *src, size_t n); +int int_strncmp(const char* s1, const char* s2, size_t n); +void strcpy(char *dest, const char *src); +char* strrchr(const char* str, char ch); + +int strncmp(const char *s1, const char *s2, size_t n); \ No newline at end of file diff --git a/EYOSx86-main/src/intf/vector.h b/EYOSx86-main/src/intf/vector.h new file mode 100644 index 0000000..b3dd73a --- /dev/null +++ b/EYOSx86-main/src/intf/vector.h @@ -0,0 +1,22 @@ +#ifndef VECTOR_H +#define VECTOR_H + +#include + +// Define the vector structure +typedef struct { + void** items; // Pointer to the array of items + size_t capacity; // Maximum number of items the vector can hold + size_t size; // Current number of items in the vector +} vector; + +// Function prototypes +vector* vector_create(); +void vector_destroy(vector* v); +int vector_push_back(vector* v, void* item); +void* vector_get(vector* v, size_t index); +int vector_set(vector* v, size_t index, void* item); +size_t vector_size(vector* v); +int vector_resize(vector* v, size_t new_capacity); + +#endif diff --git a/EYOSx86-main/src/intf/vga.h b/EYOSx86-main/src/intf/vga.h new file mode 100644 index 0000000..110f179 --- /dev/null +++ b/EYOSx86-main/src/intf/vga.h @@ -0,0 +1,6 @@ +#include "stdint.h" +#include "io.h" + + +void set_cursor_position(int x, int y); +void move_cursor(int x, int y); \ No newline at end of file diff --git a/EYOSx86-main/src/intf/window.h b/EYOSx86-main/src/intf/window.h new file mode 100644 index 0000000..dff56de --- /dev/null +++ b/EYOSx86-main/src/intf/window.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#define WINDOW_TITLE_MAX_LENGTH 20 + +typedef struct { + int x; + int y; + int size_x; + int size_y; + uint8_t border_color; + uint8_t background_color; + char title[WINDOW_TITLE_MAX_LENGTH]; +} Window; + +// Function to create and draw a simple window +void create_window(Window* win, int x, int y, int size_x, int size_y, uint8_t border_color, uint8_t background_color, const char* title); +void print_text_in_window(const Window* win, int x, int y, const char* text); diff --git a/EYOSx86-main/targets/x86_64/iso/boot/grub/grub.cfg b/EYOSx86-main/targets/x86_64/iso/boot/grub/grub.cfg new file mode 100644 index 0000000..a1f38c9 --- /dev/null +++ b/EYOSx86-main/targets/x86_64/iso/boot/grub/grub.cfg @@ -0,0 +1,7 @@ +set timeout=0 +set default=0 + +menuentry "my os" { + multiboot2 /boot/kernel.bin + boot +} diff --git a/EYOSx86-main/targets/x86_64/iso/boot/kernel.bin b/EYOSx86-main/targets/x86_64/iso/boot/kernel.bin new file mode 100644 index 0000000..67aca41 Binary files /dev/null and b/EYOSx86-main/targets/x86_64/iso/boot/kernel.bin differ diff --git a/EYOSx86-main/targets/x86_64/linker.ld b/EYOSx86-main/targets/x86_64/linker.ld new file mode 100644 index 0000000..0cf372d --- /dev/null +++ b/EYOSx86-main/targets/x86_64/linker.ld @@ -0,0 +1,16 @@ +ENTRY(start) + +SECTIONS +{ + . = 1M; + + .boot : + { + KEEP(*(.multiboot_header)) + } + + .text : + { + *(.text) + } +}