From d3536e2e16786332ac44661991212a46def506dc Mon Sep 17 00:00:00 2001 From: Tajus-io Date: Sun, 10 Nov 2024 15:39:01 +0200 Subject: [PATCH] Add EDI-OS project --- EDI-OS/EDI-OS.png | Bin 0 -> 10236 bytes EDI-OS/README.md | 84 ++++++++++++++++ EDI-OS/src/Makefile | 59 ++++++++++++ EDI-OS/src/boot.asm | 184 ++++++++++++++++++++++++++++++++++++ EDI-OS/src/kernel.c | 164 ++++++++++++++++++++++++++++++++ EDI-OS/src/kernel.h | 66 +++++++++++++ EDI-OS/src/kernel_entry.asm | 23 +++++ EDI-OS/src/keyboard.c | 104 ++++++++++++++++++++ EDI-OS/src/keyboard.h | 28 ++++++ EDI-OS/src/linker.ld | 27 ++++++ 10 files changed, 739 insertions(+) create mode 100644 EDI-OS/EDI-OS.png create mode 100644 EDI-OS/README.md create mode 100644 EDI-OS/src/Makefile create mode 100644 EDI-OS/src/boot.asm create mode 100644 EDI-OS/src/kernel.c create mode 100644 EDI-OS/src/kernel.h create mode 100644 EDI-OS/src/kernel_entry.asm create mode 100644 EDI-OS/src/keyboard.c create mode 100644 EDI-OS/src/keyboard.h create mode 100644 EDI-OS/src/linker.ld diff --git a/EDI-OS/EDI-OS.png b/EDI-OS/EDI-OS.png new file mode 100644 index 0000000000000000000000000000000000000000..a462b09465bbca85ad94bf4d4c11b1212456b064 GIT binary patch literal 10236 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 Ru>1qQIeF>?^Z0i^{U1D>uFwDg literal 0 HcmV?d00001 diff --git a/EDI-OS/README.md b/EDI-OS/README.md new file mode 100644 index 0000000..22471c5 --- /dev/null +++ b/EDI-OS/README.md @@ -0,0 +1,84 @@ +# EDI-OS + +EDI-OS is an operating system simplified for educational purposes. This OS covers the minimum requirements of an OS but keeps the source code understandable and easy to comprehend. + +![EDI-OS Boot Screen](./EDI-OS.png) + +## Features + +• Custom bootloader +• 32-bit protected mode kernel +• VGA text mode display (80x25) +• Basic keyboard input handling +• Command-line interface +• Color-coded debug/status messages +• Memory management initialization +• PS/2 keyboard controller support +• Basic command set: help, clear, version, about + +### Dependencies + +• NASM: Netwide Assembler +• GCC with support for 32-bit target +- LD (GNU Linkер) +- QEMU (for emulation) +- Make + +For Debian/Ubuntu-based systems: +```bash +sudo apt-get install nasm gcc gcc-multilib qemu-system-x86 make +``` + +### Running + +For running in QEMU : +```bash +make run +``` + +For debug mode with QEMU monitor: +```bash +make debug +``` + +## Project Structure + +- `boot.asm` - Bootloader with detailed messages +- `kernel.c` - Main kernel with terminal and routines +- `keyboard.c` - Keyboard handling and command processing +- `kernel.h` - Kernel header with type definitions and function declarations +- `linker.ld` - Linker script for kernel building +- `Makefile` - Build automation + +## Boot Sequence + +1. Initialization of bootloader +2. Check memory +3. Initialization of disk system +4. Loading kernel +5. Switch to protected mode +6. Initialization of kernel + - Setup video + - Memory management + - Setup keyboard controller + - Setup interrupt handlers + +## Available Commands + +- `help` - View list of available commands +- `clear` - Clear screen +- `version` - View OS version +- `about` - View information about EDI-OS + +## Technical Details + +Boots from a virtual floppy disk (1.44MB) +Loads at the 1MB mark +Uses a custom GDT setup +imple I/O port handling +VGA text mode with color support +PS/2 keyboard support with scancode mapping + +## Contributing + +Contributions are welcome! Feel free to send a Pull Request. diff --git a/EDI-OS/src/Makefile b/EDI-OS/src/Makefile new file mode 100644 index 0000000..f71da28 --- /dev/null +++ b/EDI-OS/src/Makefile @@ -0,0 +1,59 @@ +# Compiler and flags +CC = gcc +AS = nasm +LD = ld + +CFLAGS = -m32 -fno-pie -ffreestanding -fno-builtin -O2 -Wall -Wextra -fno-stack-protector -nostdlib -nodefaultlibs +ASFLAGS = -f elf32 +LDFLAGS = -m elf_i386 -T linker.ld --oformat binary + +# Source files +BOOT_SRC = boot.asm +KERNEL_ENTRY_SRC = kernel_entry.asm +KERNEL_SRC = kernel.c +KEYBOARD_SRC = keyboard.c + +# Object files +BOOT_BIN = boot.bin +KERNEL_ENTRY_OBJ = kernel_entry.o +KERNEL_OBJ = kernel.o +KEYBOARD_OBJ = keyboard.o +KERNEL_BIN = kernel.bin +OS_IMAGE = os-image.bin + +# Build rules +all: $(OS_IMAGE) + +$(BOOT_BIN): $(BOOT_SRC) + $(AS) -f bin -o $@ $< + +$(KERNEL_ENTRY_OBJ): $(KERNEL_ENTRY_SRC) + $(AS) $(ASFLAGS) -o $@ $< + +$(KERNEL_OBJ): $(KERNEL_SRC) + $(CC) $(CFLAGS) -c $< -o $@ + +$(KEYBOARD_OBJ): $(KEYBOARD_SRC) + $(CC) $(CFLAGS) -c $< -o $@ + +$(KERNEL_BIN): $(KERNEL_ENTRY_OBJ) $(KERNEL_OBJ) $(KEYBOARD_OBJ) + $(LD) $(LDFLAGS) -o $@ $^ + +$(OS_IMAGE): $(BOOT_BIN) $(KERNEL_BIN) + # Create a blank 1.44MB floppy image + dd if=/dev/zero of=$@ bs=1024 count=1440 + # Write boot sector to first sector + dd if=$(BOOT_BIN) of=$@ conv=notrunc + # Write kernel starting at second sector + dd if=$(KERNEL_BIN) of=$@ seek=1 conv=notrunc + +run: $(OS_IMAGE) + qemu-system-i386 -fda $(OS_IMAGE) + +debug: $(OS_IMAGE) + qemu-system-i386 -fda $(OS_IMAGE) -monitor stdio + +clean: + rm -f *.bin *.o + +.PHONY: all clean run debug diff --git a/EDI-OS/src/boot.asm b/EDI-OS/src/boot.asm new file mode 100644 index 0000000..283de70 --- /dev/null +++ b/EDI-OS/src/boot.asm @@ -0,0 +1,184 @@ +[org 0x7c00] +[bits 16] + +; Constants +KERNEL_OFFSET equ 0x1000 +VIDEO_MODE equ 0x03 ; 80x25 text mode +STACK_BASE equ 0x9000 +SECTORS_TO_READ equ 15 ; Number of sectors for kernel + +; Initialize segments and stack +xor ax, ax +mov ds, ax +mov es, ax +mov ss, ax +mov sp, STACK_BASE + +; Save boot drive number +mov [BOOT_DRIVE], dl + +; Set video mode +mov ah, 0x00 +mov al, VIDEO_MODE +int 0x10 + +; Print initial boot message +mov si, MSG_BOOT +call print_string +mov cx, 5 ; Number of delay iterations +call long_delay + +; Print memory check message +mov si, MSG_MEM_CHECK +call print_string +mov cx, 4 +call long_delay + +; Reset disk system and show message +mov si, MSG_DISK_RESET +call print_string +xor ah, ah +mov dl, [BOOT_DRIVE] +int 0x13 +jc disk_error +mov cx, 4 +call long_delay + +; Load kernel message +mov si, MSG_LOAD_KERNEL +call print_string + +; Load kernel +mov bx, KERNEL_OFFSET ; Destination address +mov dh, SECTORS_TO_READ ; Sectors to read +call load_disk +mov cx, 4 +call long_delay + +; Switch to protected mode message +mov si, MSG_PROT_MODE +call print_string +mov cx, 4 +call long_delay + +; Switch to protected mode +cli ; Clear interrupts +lgdt [GDT_DESCRIPTOR] ; Load GDT +mov eax, cr0 +or eax, 0x1 ; Set protected mode bit +mov cr0, eax +jmp CODE_SEG:init_pm ; Far jump to 32-bit code + +; Function to add a longer delay +; cx = number of iterations +long_delay: + push cx ; Save outer loop counter +.outer_loop: + push cx + mov cx, 0xFFFF ; Maximum 16-bit value +.inner_loop1: + push cx + mov cx, 0x0FFF ; Increased inner delay +.inner_loop2: + loop .inner_loop2 + pop cx + loop .inner_loop1 + pop cx + loop .outer_loop + pop cx ; Restore outer loop counter + ret + +load_disk: + push dx ; Save DX + + mov ah, 0x02 ; BIOS read function + mov al, dh ; Number of sectors + mov ch, 0 ; Cylinder 0 + mov dh, 0 ; Head 0 + mov cl, 2 ; Start from sector 2 + mov dl, [BOOT_DRIVE] + + int 0x13 + jc disk_error ; Check for error + + pop dx ; Restore DX + cmp dh, al ; Compare sectors read + jne disk_error ; Error if not equal + + ; Print success message + mov si, MSG_LOAD_OK + call print_string + ret + +disk_error: + mov si, DISK_ERROR_MSG + call print_string + jmp $ + +print_string: + mov ah, 0x0E ; BIOS teletype function +.loop: + lodsb ; Load next character + test al, al ; Check for null terminator + jz .done ; If zero, we're done + int 0x10 ; Otherwise, print + jmp .loop +.done: + ret + +[bits 32] +init_pm: + mov ax, DATA_SEG + mov ds, ax + mov ss, ax + mov es, ax + mov fs, ax + mov gs, ax + + mov ebp, STACK_BASE + mov esp, ebp + + jmp KERNEL_OFFSET + +; Data +BOOT_DRIVE db 0 +MSG_BOOT db 'EDI-OS Bootloader starting...', 0x0D, 0x0A, 0 +MSG_MEM_CHECK db 'Checking memory map...OK', 0x0D, 0x0A, 0 +MSG_DISK_RESET db 'Resetting disk system...', 0x0D, 0x0A, 0 +MSG_LOAD_KERNEL db 'Loading kernel into memory...', 0x0D, 0x0A, 0 +MSG_LOAD_OK db 'Kernel loaded successfully!', 0x0D, 0x0A, 0 +MSG_PROT_MODE db 'Switching to protected mode...', 0x0D, 0x0A, 0 +DISK_ERROR_MSG db 'Disk read error!', 0x0D, 0x0A, 0 + +; GDT +GDT_START: + dq 0 ; Null descriptor + +GDT_CODE: + dw 0xFFFF ; Limit (0-15) + dw 0 ; Base (0-15) + db 0 ; Base (16-23) + db 10011010b ; Access byte + db 11001111b ; Flags and limit (16-19) + db 0 ; Base (24-31) + +GDT_DATA: + dw 0xFFFF + dw 0 + db 0 + db 10010010b + db 11001111b + db 0 + +GDT_END: + +GDT_DESCRIPTOR: + dw GDT_END - GDT_START - 1 + dd GDT_START + +CODE_SEG equ GDT_CODE - GDT_START +DATA_SEG equ GDT_DATA - GDT_START + +; Boot signature +times 510-($-$$) db 0 +dw 0xAA55 diff --git a/EDI-OS/src/kernel.c b/EDI-OS/src/kernel.c new file mode 100644 index 0000000..5e0d894 --- /dev/null +++ b/EDI-OS/src/kernel.c @@ -0,0 +1,164 @@ +#include "kernel.h" +#include "keyboard.h" + +// VGA memory configuration +static uint16_t* const VGA_MEMORY = (uint16_t*)0xB8000; +static const uint32_t VGA_WIDTH = 80; +static const uint32_t VGA_HEIGHT = 25; + +// Make terminal variables accessible to other files +uint32_t terminal_row; +uint32_t terminal_column; +uint8_t terminal_color; + +// Much longer delay function +void delay(uint32_t count) { + for (uint32_t i = 0; i < count; i++) { + for (uint32_t j = 0; j < 0x2FFFFF; j++) { // Increased inner loop + asm volatile("nop"); + } + } +} + +uint8_t make_color(enum vga_color fg, enum vga_color bg) { + return (uint8_t)fg | ((uint8_t)bg << 4); +} + +static uint16_t make_vgaentry(char c, uint8_t color) { + uint16_t c16 = c; + uint16_t color16 = color; + return c16 | color16 << 8; +} + +void init_video(void) { + terminal_row = 0; + terminal_column = 0; + terminal_color = make_color(VGA_WHITE, VGA_BLUE); + + // Clear screen + for (uint32_t y = 0; y < VGA_HEIGHT; y++) { + for (uint32_t x = 0; x < VGA_WIDTH; x++) { + const uint32_t index = y * VGA_WIDTH + x; + VGA_MEMORY[index] = make_vgaentry(' ', terminal_color); + } + } +} + +void clear_screen(void) { + init_video(); +} + +void terminal_putentryat(char c, uint8_t color, uint32_t x, uint32_t y) { + const uint32_t index = y * VGA_WIDTH + x; + VGA_MEMORY[index] = make_vgaentry(c, color); +} + +void terminal_putchar(char c) { + if (c == '\n') { + terminal_column = 0; + if (++terminal_row >= VGA_HEIGHT) { + terminal_row = 0; + } + return; + } + + terminal_putentryat(c, terminal_color, terminal_column, terminal_row); + + if (++terminal_column == VGA_WIDTH) { + terminal_column = 0; + if (++terminal_row == VGA_HEIGHT) { + terminal_row = 0; + } + } +} + +void print_string(const char* str) { + for (uint32_t i = 0; str[i] != '\0'; i++) { + terminal_putchar(str[i]); + } +} + +void print_colored(const char* str, uint8_t color) { + uint8_t old_color = terminal_color; + terminal_color = color; + print_string(str); + terminal_color = old_color; +} + +void kernel_main(void) { + // Initialize terminal + init_video(); + + // Show initialization messages with longer delays + print_colored("EDI-OS Kernel Loading...\n", make_color(VGA_CYAN, VGA_BLUE)); + delay(4); // Increased delay + + print_colored("[....] Checking CPU status", make_color(VGA_YELLOW, VGA_BLUE)); + delay(2); + terminal_column -= 25; // Move back to overwrite the status + print_colored("[OK] CPU status verified\n", make_color(VGA_GREEN, VGA_BLUE)); + delay(3); + + print_colored("[....] Initializing video driver", make_color(VGA_YELLOW, VGA_BLUE)); + delay(2); + terminal_column -= 27; + print_colored("[OK] Video initialization complete\n", make_color(VGA_GREEN, VGA_BLUE)); + delay(3); + + print_colored("[....] Setting up memory management", make_color(VGA_YELLOW, VGA_BLUE)); + delay(2); + terminal_column -= 30; + print_colored("[OK] Memory management initialized\n", make_color(VGA_GREEN, VGA_BLUE)); + delay(3); + + // Initialize keyboard with status display + print_colored("[....] Configuring keyboard controller", make_color(VGA_YELLOW, VGA_BLUE)); + init_keyboard(); + delay(2); + terminal_column -= 33; + print_colored("[OK] Keyboard controller initialized\n", make_color(VGA_GREEN, VGA_BLUE)); + delay(3); + + print_colored("[....] Setting up interrupt handlers", make_color(VGA_YELLOW, VGA_BLUE)); + delay(2); + terminal_column -= 31; + print_colored("[OK] Interrupt handlers configured\n", make_color(VGA_GREEN, VGA_BLUE)); + delay(3); + + // Print system information + print_colored("\n================================\n", make_color(VGA_CYAN, VGA_BLUE)); + delay(1); + print_colored("Welcome to EDI-OS v0.2\n", make_color(VGA_WHITE, VGA_BLUE)); + delay(1); + print_colored("================================\n", make_color(VGA_CYAN, VGA_BLUE)); + delay(1); + + print_colored("\nSystem Status:\n", make_color(VGA_YELLOW, VGA_BLUE)); + delay(1); + print_colored("- CPU Mode: Protected Mode (32-bit)\n", make_color(VGA_WHITE, VGA_BLUE)); + delay(1); + print_colored("- Memory: 640KB Base Memory\n", make_color(VGA_WHITE, VGA_BLUE)); + delay(1); + print_colored("- Video: VGA Text Mode 80x25\n", make_color(VGA_WHITE, VGA_BLUE)); + delay(1); + print_colored("- Keyboard: PS/2 Controller Active\n", make_color(VGA_WHITE, VGA_BLUE)); + delay(1); + print_colored("- Interrupts: Configured and Enabled\n", make_color(VGA_WHITE, VGA_BLUE)); + delay(1); + + print_colored("\nSystem initialized successfully!\n", make_color(VGA_GREEN, VGA_BLUE)); + delay(2); + print_string("\nType 'help' for available commands\n\n"); + delay(2); + + // Initialize command prompt + print_colored("> ", make_color(VGA_GREEN, VGA_BLUE)); + + // Main kernel loop + while (1) { + // Check for keyboard input + if (inb(KEYBOARD_STATUS_PORT) & 0x1) { + keyboard_handler(); + } + } +} diff --git a/EDI-OS/src/kernel.h b/EDI-OS/src/kernel.h new file mode 100644 index 0000000..b265453 --- /dev/null +++ b/EDI-OS/src/kernel.h @@ -0,0 +1,66 @@ +#ifndef KERNEL_H +#define KERNEL_H + +// Type definitions +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; + +// VGA colors enum +enum vga_color { + VGA_BLACK, + VGA_BLUE, + VGA_GREEN, + VGA_CYAN, + VGA_RED, + VGA_MAGENTA, + VGA_BROWN, + VGA_LIGHT_GREY, + VGA_DARK_GREY, + VGA_LIGHT_BLUE, + VGA_LIGHT_GREEN, + VGA_LIGHT_CYAN, + VGA_LIGHT_RED, + VGA_LIGHT_MAGENTA, + VGA_YELLOW, + VGA_WHITE, +}; + +// String comparison function +static inline int strcmp(const char* str1, const char* str2) { + while (*str1 && (*str1 == *str2)) { + str1++; + str2++; + } + return *(unsigned char*)str1 - *(unsigned char*)str2; +} + +// Port I/O functions +static inline void outb(uint16_t port, uint8_t val) { + asm volatile ( "outb %0, %1" : : "a"(val), "Nd"(port) ); +} + +static inline uint8_t inb(uint16_t port) { + uint8_t ret; + asm volatile ( "inb %1, %0" : "=a"(ret) : "Nd"(port) ); + return ret; +} + +// Terminal state variables +extern uint32_t terminal_row; +extern uint32_t terminal_column; +extern uint8_t terminal_color; + +// Function declarations +void kernel_main(void); +void clear_screen(void); +void print_string(const char* str); +void print_colored(const char* str, uint8_t color); +void init_video(void); +uint8_t make_color(enum vga_color fg, enum vga_color bg); +void terminal_putentryat(char c, uint8_t color, uint32_t x, uint32_t y); +void terminal_putchar(char c); +void delay(uint32_t count); + +#endif diff --git a/EDI-OS/src/kernel_entry.asm b/EDI-OS/src/kernel_entry.asm new file mode 100644 index 0000000..3f39fff --- /dev/null +++ b/EDI-OS/src/kernel_entry.asm @@ -0,0 +1,23 @@ +[bits 32] +[extern kernel_main] + +section .text + global _start + +_start: + ; Set up stack + mov esp, stack_top + + ; Call kernel + call kernel_main + + ; Hang if kernel returns + cli + hlt + jmp $ + +section .bss +align 4 +stack_bottom: + resb 16384 ; 16 KB stack +stack_top: diff --git a/EDI-OS/src/keyboard.c b/EDI-OS/src/keyboard.c new file mode 100644 index 0000000..0e84643 --- /dev/null +++ b/EDI-OS/src/keyboard.c @@ -0,0 +1,104 @@ +#include "keyboard.h" + +char command_buffer[KEYBOARD_BUFFER_SIZE]; +uint32_t buffer_position = 0; +static uint8_t shift_pressed = 0; + +// Scancode to ASCII mapping (US QWERTY layout) +static const char ascii_lower[] = { + 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, + 0, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0, + 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', + 0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, + '*', 0, ' ' +}; + +static const char ascii_upper[] = { + 0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0, + 0, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 0, + 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', + 0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 0, + '*', 0, ' ' +}; + +void init_keyboard(void) { + // Clear command buffer + for (uint32_t i = 0; i < KEYBOARD_BUFFER_SIZE; i++) { + command_buffer[i] = 0; + } + buffer_position = 0; +} + +char get_ascii(uint8_t scancode) { + if (scancode >= sizeof(ascii_lower)) { + return 0; + } + + return shift_pressed ? ascii_upper[scancode] : ascii_lower[scancode]; +} + +void keyboard_handler(void) { + uint8_t scancode = inb(KEYBOARD_DATA_PORT); + + // Handle shift keys + if (scancode == SC_LSHIFT || scancode == SC_RSHIFT) { + shift_pressed = 1; + return; + } else if (scancode == SC_LSHIFT_REL || scancode == SC_RSHIFT_REL) { + shift_pressed = 0; + return; + } + + // Only handle key press events (ignore key release) + if (scancode & 0x80) { + return; + } + + // Handle special keys + if (scancode == SC_ENTER) { + print_string("\n"); + command_buffer[buffer_position] = '\0'; + handle_command(command_buffer); + buffer_position = 0; + print_colored("> ", make_color(VGA_GREEN, VGA_BLUE)); + return; + } else if (scancode == SC_BACKSPACE && buffer_position > 0) { + buffer_position--; + command_buffer[buffer_position] = 0; + // Move cursor back and clear character + if (terminal_column > 0) { + terminal_column--; + terminal_putentryat(' ', terminal_color, terminal_column, terminal_row); + } + return; + } + + // Convert scancode to ASCII and handle regular keys + char ascii = get_ascii(scancode); + if (ascii && buffer_position < KEYBOARD_BUFFER_SIZE - 1) { + command_buffer[buffer_position++] = ascii; + terminal_putchar(ascii); + } +} + +void handle_command(char* command) { + if (strcmp(command, "help") == 0) { + print_string("Available commands:\n"); + print_string(" help - Show this help message\n"); + print_string(" clear - Clear the screen\n"); + print_string(" version - Show OS version\n"); + print_string(" about - About EDI-OS\n"); + } else if (strcmp(command, "clear") == 0) { + clear_screen(); + print_colored("> ", make_color(VGA_GREEN, VGA_BLUE)); + } else if (strcmp(command, "version") == 0) { + print_string("EDI-OS version 0.2\n"); + } else if (strcmp(command, "about") == 0) { + print_colored("EDI-OS v0.2\n", make_color(VGA_CYAN, VGA_BLUE)); + print_string("A simple operating system for learning purposes\n"); + } else if (command[0] != '\0') { + print_string("Unknown command: "); + print_string(command); + print_string("\nType 'help' for available commands\n"); + } +} diff --git a/EDI-OS/src/keyboard.h b/EDI-OS/src/keyboard.h new file mode 100644 index 0000000..f566994 --- /dev/null +++ b/EDI-OS/src/keyboard.h @@ -0,0 +1,28 @@ +#ifndef KEYBOARD_H +#define KEYBOARD_H + +#include "kernel.h" + +#define KEYBOARD_DATA_PORT 0x60 +#define KEYBOARD_STATUS_PORT 0x64 +#define KEYBOARD_BUFFER_SIZE 256 + +// Scan code constants +#define SC_ENTER 0x1C +#define SC_BACKSPACE 0x0E +#define SC_LSHIFT 0x2A +#define SC_RSHIFT 0x36 +#define SC_LSHIFT_REL 0xAA +#define SC_RSHIFT_REL 0xB6 + +// Function declarations +void init_keyboard(void); +void keyboard_handler(void); +char get_ascii(uint8_t scancode); +void handle_command(char* command); + +// Command buffer +extern char command_buffer[KEYBOARD_BUFFER_SIZE]; +extern uint32_t buffer_position; + +#endif diff --git a/EDI-OS/src/linker.ld b/EDI-OS/src/linker.ld new file mode 100644 index 0000000..016f3f0 --- /dev/null +++ b/EDI-OS/src/linker.ld @@ -0,0 +1,27 @@ +ENTRY(_start) + +SECTIONS { + /* Kernel starts at 1MB */ + . = 0x1000; + + .text BLOCK(4K) : ALIGN(4K) + { + *(.text) + } + + .rodata BLOCK(4K) : ALIGN(4K) + { + *(.rodata) + } + + .data BLOCK(4K) : ALIGN(4K) + { + *(.data) + } + + .bss BLOCK(4K) : ALIGN(4K) + { + *(COMMON) + *(.bss) + } +}