├── Makefile ├── README.md ├── build ├── boot.o ├── gdts.o └── idt.o ├── ethos.png ├── linker.ld └── src ├── boot.s ├── ethos ├── boot │ ├── grub │ │ └── grub.cfg │ └── kernel │ │ └── kernel └── kernel ├── fat.c ├── fat.h ├── gdt.c ├── gdt.h ├── gdt.s ├── idt.c ├── idt.h ├── idt.s ├── kernel.c ├── keyboard.c ├── keyboard.h ├── malloc.c ├── malloc.h ├── mem.c ├── mem.h ├── multiboot.h ├── paging.h ├── stdint.h ├── stdlib ├── stdio.c └── stdio.h ├── string.c ├── string.h ├── strings.h ├── timer.c ├── timer.h ├── util.c ├── util.h ├── vfs.c ├── vfs.h ├── vga.c └── vga.h /Makefile: -------------------------------------------------------------------------------- 1 | gcc = ~/opt/cross/bin/i686-elf-gcc 2 | ld = ~/opt/cross/bin/i686-elf-ld 3 | flags = -c -ffreestanding 4 | 5 | all: kernel boot assemble 6 | 7 | kernel: 8 | ### Kernel ##### 9 | $(gcc) $(flags) src/kernel.c -o build/kernel.o 10 | $(gcc) $(flags) src/stdlib/stdio.c -o build/stdio.o 11 | $(gcc) $(flags) src/vga.c -o build/vga.o 12 | $(gcc) $(flags) src/gdt.c -o build/gdt.o 13 | $(gcc) $(flags) src/timer.c -o build/timer.o 14 | $(gcc) $(flags) src/util.c -o build/util.o 15 | $(gcc) $(flags) src/idt.c -o build/idts.o 16 | $(gcc) $(flags) src/keyboard.c -o build/keyboard.o 17 | $(gcc) $(flags) src/malloc.c -o build/malloc.o 18 | $(gcc) $(flags) src/mem.c -o build/mem.o 19 | $(gcc) $(flags) src/vfs.c -o build/vfs.o 20 | $(gcc) $(flags) src/string.c -o build/string.o 21 | 22 | boot: 23 | ## bootloader ### 24 | nasm -f elf32 src/boot.s -o build/boot.o 25 | nasm -f elf32 src/gdt.s -o build/gdts.o 26 | nasm -f elf32 src/idt.s -o build/idt.o 27 | 28 | ### else ##### 29 | 30 | assemble: 31 | $(ld) -T linker.ld -o kernel build/boot.o build/kernel.o build/vga.o build/gdts.o build/gdt.o build/idts.o build/idt.o build/util.o build/timer.o build/stdio.o build/keyboard.o build/malloc.o build/mem.o build/string.o build/vfs.o 32 | mv kernel src/ethos/boot/kernel 33 | dd if=/dev/zero of=ethos.iso bs=1M count=100 34 | mkfs.fat -F32 ethos.iso 35 | #sudo losetup /dev/loop0 ethos.iso 36 | #mkdir /mnt 37 | #mkdir /mnt/disk 38 | #mkdir /mnt/disk/boot 39 | #sudo mount /dev/loop0 /mnt/disk 40 | #sudo grub-install --force --target=i386-pc --boot-directory=/mnt/disk/boot/ /dev/loop0 41 | #cp -r src/ethos/boot/kernel /mnt/disk/boot 42 | #sudo cp src/ethos/boot/grub/grub.cfg /mnt/disk/boot 43 | #mkdir /mnt/disk/bin 44 | #mkdir /mnt/disk/usr 45 | #umount /mnt/disk 46 | #losetup -d /dev/loop0 47 | #rm -rf /mnt/disk 48 | ##qemu-system-x86_64 -drive format=raw,file=ethos.iso 49 | grub-mkrescue -o build/ethos.iso src/ethos/ 50 | qemu-system-i386 build/ethos.iso 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 𝙒𝙝𝙖𝙩 𝙪𝙥 𝙜𝙪𝙮𝙨 𝙬𝙚𝙡𝙘𝙤𝙢𝙚 𝙩𝙤 𝙢𝙮 𝙊𝙎 𝙥𝙧𝙤𝙟𝙚𝙘𝙩 𝙨𝙚𝙧𝙞𝙚𝙨 𝙛𝙧𝙤𝙢 𝙮𝙤𝙪𝙩𝙪𝙗𝙚 2 | 3 | 𝙘𝙝𝙚𝙘𝙠 𝙤𝙪𝙩 𝙩𝙝𝙚 𝙨𝙚𝙧𝙞𝙚𝙨 𝙤𝙣 𝙢𝙮 𝙮𝙩: 𝙝𝙩𝙩𝙥𝙨://𝙬𝙬𝙬.𝙮𝙤𝙪𝙩𝙪𝙗𝙚.𝙘𝙤𝙢/@𝙚𝙥𝙧𝙤𝙜𝙧𝙖𝙢𝙨 4 | 5 | ![2024-10-17-173456_723x408_scrot](https://github.com/user-attachments/assets/01662f1e-1d9c-4500-a71b-5f7786cfcb50) 6 | 7 | Done 8 | - Boot_into_grub ✔️ 9 | - VGA_driver ✔️ 10 | - GDT ✔️ 11 | - enabled_interrupts ✔️ 12 | - timer ✔️ 13 | - keyboard_input ✔️ 14 | - malloc ✔️ 15 | - paging ✔️ 16 | - vfs (virtual fs) ✔️ 17 | 18 | Needed 19 | - terminal_with_commands 20 | - syscalls 21 | - network stuff 22 | - filesystem 23 | - gui_library 24 | - window_manager 25 | - code_editor 26 | 27 | ### Dependencies 28 | * NASM 29 | * C Compiler 30 | * grub 31 | * xorriso 32 | * GNU Make 33 | * qemu 34 | 35 | 36 | ## Compile and Run 37 | ``` sh 38 | # To compile OS and build .iso file and run 39 | make 40 | 41 | ``` 42 | -------------------------------------------------------------------------------- /build/boot.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethanprogramser/eth-os/b9143dd77b67c4f44d6ff194db1dd8aa5855e9dc/build/boot.o -------------------------------------------------------------------------------- /build/gdts.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethanprogramser/eth-os/b9143dd77b67c4f44d6ff194db1dd8aa5855e9dc/build/gdts.o -------------------------------------------------------------------------------- /build/idt.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethanprogramser/eth-os/b9143dd77b67c4f44d6ff194db1dd8aa5855e9dc/build/idt.o -------------------------------------------------------------------------------- /ethos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethanprogramser/eth-os/b9143dd77b67c4f44d6ff194db1dd8aa5855e9dc/ethos.png -------------------------------------------------------------------------------- /linker.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | SECTIONS { 3 | . = 0x00100000; 4 | 5 | .multiboot ALIGN(4K): { 6 | *(.multiboot) 7 | } 8 | 9 | .note.gnu.build-id ALIGN(4K): { 10 | *(.note.gnu.build-id) 11 | } 12 | 13 | .boot ALIGN(4K) : { 14 | *(.boot) 15 | } 16 | 17 | . += 0xC0000000; 18 | 19 | .text ALIGN(4K): AT(ADDR(.text) - 0xC0000000){ 20 | *(.text) 21 | } 22 | 23 | .rodata ALIGN(4K): AT(ADDR(.rodata) - 0xC0000000){ 24 | *(.rodata) 25 | } 26 | 27 | .data ALIGN(4K): AT(ADDR(.data) - 0xC0000000){ 28 | *(.data) 29 | } 30 | 31 | .bss ALIGN(4K): AT(ADDR(.bss) - 0xC0000000){ 32 | *(COMMON) 33 | *(.bss) 34 | } 35 | 36 | _kernel_end = .; 37 | 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/boot.s: -------------------------------------------------------------------------------- 1 | bits 32 2 | 3 | MBOOT_PAGE_ALIGN EQU 1 << 0 4 | MBOOT_MEM_INFO EQU 1 << 1 5 | MBOOT_USE_GFX EQU 0 6 | 7 | MBOOT_MAGIC EQU 0x1BADB002 8 | MBOOT_FLAGS EQU MBOOT_PAGE_ALIGN | MBOOT_MEM_INFO | MBOOT_USE_GFX 9 | MBOOT_CHECKSUM EQU -(MBOOT_MAGIC + MBOOT_FLAGS) 10 | 11 | section .multiboot 12 | ALIGN 4 13 | DD MBOOT_MAGIC 14 | DD MBOOT_FLAGS 15 | DD MBOOT_CHECKSUM 16 | DD 0, 0, 0, 0, 0 17 | 18 | DD 0 19 | DD 800 20 | DD 600 21 | DD 32 22 | 23 | SECTION .bss 24 | ALIGN 16 25 | stack_bottom: 26 | RESB 16384 * 8 27 | stack_top: 28 | 29 | section .boot 30 | 31 | global _start 32 | _start: 33 | MOV ecx, (initial_page_dir - 0xC0000000) 34 | MOV cr3, ecx 35 | 36 | MOV ecx, cr4 37 | OR ecx, 0x10 38 | MOV cr4, ecx 39 | 40 | MOV ecx, cr0 41 | OR ecx, 0x80000000 42 | MOV cr0, ecx 43 | 44 | JMP higher_half 45 | 46 | section .text 47 | 48 | higher_half: 49 | MOV esp, stack_top 50 | PUSH ebx 51 | PUSH eax 52 | XOR ebp, ebp 53 | extern main 54 | CALL main 55 | 56 | halt: 57 | hlt 58 | JMP halt 59 | 60 | 61 | section .data 62 | align 4096 63 | global initial_page_dir 64 | initial_page_dir: 65 | DD 10000011b 66 | TIMES 768-1 DD 0 67 | 68 | DD (0 << 22) | 10000011b 69 | DD (1 << 22) | 10000011b 70 | DD (2 << 22) | 10000011b 71 | DD (3 << 22) | 10000011b 72 | TIMES 256-4 DD 0 73 | -------------------------------------------------------------------------------- /src/ethos/boot/grub/grub.cfg: -------------------------------------------------------------------------------- 1 | menuentry "ethos" { 2 | multiboot /boot/kernel/kernel 3 | boot 4 | } 5 | -------------------------------------------------------------------------------- /src/ethos/boot/kernel/kernel: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethanprogramser/eth-os/b9143dd77b67c4f44d6ff194db1dd8aa5855e9dc/src/ethos/boot/kernel/kernel -------------------------------------------------------------------------------- /src/ethos/kernel: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ethanprogramser/eth-os/b9143dd77b67c4f44d6ff194db1dd8aa5855e9dc/src/ethos/kernel -------------------------------------------------------------------------------- /src/fat.c: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/fat.h: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | uint8_t jump[3]; 3 | char oem_name[8]; 4 | uint16_t bytes_per_sector; 5 | uint8_t sectors_per_cluster; 6 | uint16_t reserved_sectors; 7 | uint8_t num_fats; 8 | uint16_t root_entry_count; 9 | uint16_t total_sectors_16; 10 | uint8_t media; 11 | uint16_t fat_size_16; 12 | uint16_t sectors_per_track; 13 | uint16_t num_heads; 14 | uint32_t hidden_sectors; 15 | uint32_t total_sectors_32; 16 | uint32_t fat_size_32; 17 | uint16_t ext_flags; 18 | uint16_t fs_version; 19 | uint32_t root_cluster; 20 | uint16_t fs_info; 21 | uint16_t backup_boot_sector; 22 | uint8_t reserved[12]; 23 | uint8_t drive_number; 24 | uint8_t reserved1; 25 | uint8_t boot_signature; 26 | uint32_t volume_id; 27 | char volume_label[11]; 28 | char fs_type[8]; 29 | } __attribute__((packed)) FAT32_BootSector; 30 | 31 | typedef struct { 32 | char name[11]; 33 | uint8_t attr; 34 | uint8_t nt_res; 35 | uint8_t crt_time_tenth; 36 | uint16_t crt_time; 37 | uint16_t crt_date; 38 | uint16_t lst_acc_date; 39 | uint16_t fst_clust_hi; 40 | uint16_t wrt_time; 41 | uint16_t wrt_date; 42 | uint16_t fst_clust_lo; 43 | uint32_t file_size; 44 | } __attribute__((packed)) FAT32_DirEntry; 45 | 46 | 47 | void load_boot_sector(); 48 | -------------------------------------------------------------------------------- /src/gdt.c: -------------------------------------------------------------------------------- 1 | #include "gdt.h" 2 | #include "util.h" 3 | 4 | 5 | extern void gdt_flush(uint32_t); 6 | extern void tss_flush(); 7 | 8 | struct gdt_entry_struct gdt_entries[6]; 9 | struct gdt_ptr_struct gdt_ptr; 10 | struct tss_entry_struct tss_entry; 11 | 12 | void initGdt(){ 13 | gdt_ptr.limit = (sizeof(struct gdt_entry_struct) * 6) - 1; 14 | gdt_ptr.base = (uint32_t)&gdt_entries; 15 | 16 | setGdtGate(0,0,0,0,0); //Null segment 17 | setGdtGate(1,0,0xFFFFFFFF, 0x9A, 0xCF); //Kernel code segment 18 | setGdtGate(2,0,0xFFFFFFFF, 0x92, 0xCF); //Kernel data segment 19 | setGdtGate(3,0,0xFFFFFFFF, 0xFA, 0xCF); //User code segment 20 | setGdtGate(4,0,0xFFFFFFFF, 0xF2, 0xCF); //User data segment 21 | writeTSS(5,0x10, 0x0); 22 | 23 | gdt_flush((uint32_t)&gdt_ptr); 24 | tss_flush(); 25 | 26 | } 27 | 28 | void writeTSS(uint32_t num, uint16_t ss0, uint32_t esp0){ 29 | uint32_t base = (uint32_t) &tss_entry; 30 | uint32_t limit = base + sizeof(tss_entry); 31 | 32 | setGdtGate(num, base, limit, 0xE9, 0x00); 33 | memset(&tss_entry, 0, sizeof(tss_entry)); 34 | 35 | tss_entry.ss0 = ss0; 36 | tss_entry.esp0 = esp0; 37 | 38 | tss_entry.cs = 0x08 | 0x3; 39 | tss_entry.ss = tss_entry.ds = tss_entry.es = tss_entry.fs = tss_entry.gs = 0x10 | 0x3; 40 | } 41 | 42 | void setGdtGate(uint32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran){ 43 | 44 | gdt_entries[num].base_low = (base & 0xFFFF); 45 | gdt_entries[num].base_middle = (base >> 16) & 0xFF; 46 | gdt_entries[num].base_high = (base >> 24) & 0xFF; 47 | 48 | gdt_entries[num].limit = (limit & 0xFFFF); 49 | gdt_entries[num].flags = (limit >> 16) & 0x0F; 50 | gdt_entries[num].flags |= (gran & 0xF0); 51 | 52 | gdt_entries[num].access = access; 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/gdt.h: -------------------------------------------------------------------------------- 1 | #include "stdint.h" 2 | 3 | struct gdt_entry_struct{ 4 | uint16_t limit; 5 | uint16_t base_low; 6 | uint8_t base_middle; 7 | uint8_t access; 8 | uint8_t flags; 9 | uint8_t base_high; 10 | }__attribute__((packed)); 11 | 12 | struct gdt_ptr_struct{ 13 | uint16_t limit; 14 | unsigned int base; 15 | }__attribute__((packed)); 16 | 17 | struct tss_entry_struct{ 18 | uint32_t prev_tss; 19 | uint32_t esp0; 20 | uint32_t ss0; 21 | uint32_t esp1; 22 | uint32_t ss1; 23 | uint32_t esp2; 24 | uint32_t ss2; 25 | uint32_t cr3; 26 | uint32_t eip; 27 | uint32_t eflags; 28 | uint32_t eax; 29 | uint32_t ecx; 30 | uint32_t edx; 31 | uint32_t ebx; 32 | uint32_t esp; 33 | uint32_t ebp; 34 | uint32_t esi; 35 | uint32_t edi; 36 | uint32_t es; 37 | uint32_t cs; 38 | uint32_t ss; 39 | uint32_t ds; 40 | uint32_t fs; 41 | uint32_t gs; 42 | uint32_t ldt; 43 | uint32_t trap; 44 | uint32_t iomap_base; 45 | } __attribute__((packed)); 46 | 47 | void initGdt(); 48 | void setGdtGate(uint32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran); 49 | void writeTSS(uint32_t num, uint16_t ss0, uint32_t esp0); 50 | -------------------------------------------------------------------------------- /src/gdt.s: -------------------------------------------------------------------------------- 1 | global gdt_flush 2 | 3 | gdt_flush: 4 | MOV eax, [esp+4] 5 | LGDT [eax] 6 | 7 | MOV eax, 0x10 8 | MOV ds, ax 9 | MOV es, ax 10 | MOV fs, ax 11 | MOV gs, ax 12 | MOV ss, ax 13 | JMP 0x08:.flush 14 | .flush: 15 | RET 16 | 17 | global tss_flush 18 | tss_flush: 19 | MOV ax, 0x2B 20 | LTR ax 21 | RET 22 | -------------------------------------------------------------------------------- /src/idt.c: -------------------------------------------------------------------------------- 1 | #include "stdint.h" 2 | #include "util.h" 3 | #include "vga.h" 4 | #include "idt.h" 5 | 6 | struct idt_entry_struct idt_entries[256]; 7 | struct idt_ptr_struct idt_ptr; 8 | 9 | extern void idt_flush(uint32_t); 10 | 11 | void initIdt(){ 12 | idt_ptr.limit = sizeof(struct idt_entry_struct) * 256 - 1; 13 | idt_ptr.base = (uint32_t) &idt_entries; 14 | 15 | memset(&idt_entries, 0, sizeof(struct idt_entry_struct) * 256); 16 | 17 | //0x20 commands and 0x21 data 18 | //0xA0 commands and 0xA1 data 19 | outPortB(0x20, 0x11); 20 | outPortB(0xA0, 0x11); 21 | 22 | outPortB(0x21, 0x20); 23 | outPortB(0xA1, 0x28); 24 | 25 | outPortB(0x21,0x04); 26 | outPortB(0xA1,0x02); 27 | 28 | outPortB(0x21, 0x01); 29 | outPortB(0xA1, 0x01); 30 | 31 | outPortB(0x21, 0x0); 32 | outPortB(0xA1, 0x0); 33 | 34 | setIdtGate(0, (uint32_t)isr0,0x08, 0x8E); 35 | setIdtGate(1, (uint32_t)isr1,0x08, 0x8E); 36 | setIdtGate(2, (uint32_t)isr2,0x08, 0x8E); 37 | setIdtGate(3, (uint32_t)isr3,0x08, 0x8E); 38 | setIdtGate(4, (uint32_t)isr4, 0x08, 0x8E); 39 | setIdtGate(5, (uint32_t)isr5, 0x08, 0x8E); 40 | setIdtGate(6, (uint32_t)isr6, 0x08, 0x8E); 41 | setIdtGate(7, (uint32_t)isr7, 0x08, 0x8E); 42 | setIdtGate(8, (uint32_t)isr8, 0x08, 0x8E); 43 | setIdtGate(9, (uint32_t)isr9, 0x08, 0x8E); 44 | setIdtGate(10, (uint32_t)isr10, 0x08, 0x8E); 45 | setIdtGate(11, (uint32_t)isr11, 0x08, 0x8E); 46 | setIdtGate(12, (uint32_t)isr12, 0x08, 0x8E); 47 | setIdtGate(13, (uint32_t)isr13, 0x08, 0x8E); 48 | setIdtGate(14, (uint32_t)isr14, 0x08, 0x8E); 49 | setIdtGate(15, (uint32_t)isr15, 0x08, 0x8E); 50 | setIdtGate(16, (uint32_t)isr16, 0x08, 0x8E); 51 | setIdtGate(17, (uint32_t)isr17, 0x08, 0x8E); 52 | setIdtGate(18, (uint32_t)isr18, 0x08, 0x8E); 53 | setIdtGate(19, (uint32_t)isr19, 0x08, 0x8E); 54 | setIdtGate(20, (uint32_t)isr20, 0x08, 0x8E); 55 | setIdtGate(21, (uint32_t)isr21, 0x08, 0x8E); 56 | setIdtGate(22, (uint32_t)isr22, 0x08, 0x8E); 57 | setIdtGate(23, (uint32_t)isr23, 0x08, 0x8E); 58 | setIdtGate(24, (uint32_t)isr24, 0x08, 0x8E); 59 | setIdtGate(25, (uint32_t)isr25, 0x08, 0x8E); 60 | setIdtGate(26, (uint32_t)isr26, 0x08, 0x8E); 61 | setIdtGate(27, (uint32_t)isr27, 0x08, 0x8E); 62 | setIdtGate(28, (uint32_t)isr28, 0x08, 0x8E); 63 | setIdtGate(29, (uint32_t)isr29, 0x08, 0x8E); 64 | setIdtGate(30, (uint32_t)isr30, 0x08, 0x8E); 65 | setIdtGate(31, (uint32_t)isr31, 0x08, 0x8E); 66 | 67 | setIdtGate(32, (uint32_t)irq0, 0x08, 0x8E); 68 | setIdtGate(33, (uint32_t)irq1, 0x08, 0x8E); 69 | setIdtGate(34, (uint32_t)irq2, 0x08, 0x8E); 70 | setIdtGate(35, (uint32_t)irq3, 0x08, 0x8E); 71 | setIdtGate(36, (uint32_t)irq4, 0x08, 0x8E); 72 | setIdtGate(37, (uint32_t)irq5, 0x08, 0x8E); 73 | setIdtGate(38, (uint32_t)irq6, 0x08, 0x8E); 74 | setIdtGate(39, (uint32_t)irq7, 0x08, 0x8E); 75 | setIdtGate(40, (uint32_t)irq8, 0x08, 0x8E); 76 | setIdtGate(41, (uint32_t)irq9, 0x08, 0x8E); 77 | setIdtGate(42, (uint32_t)irq10, 0x08, 0x8E); 78 | setIdtGate(43, (uint32_t)irq11, 0x08, 0x8E); 79 | setIdtGate(44, (uint32_t)irq12, 0x08, 0x8E); 80 | setIdtGate(45, (uint32_t)irq13, 0x08, 0x8E); 81 | setIdtGate(46, (uint32_t)irq14, 0x08, 0x8E); 82 | setIdtGate(47, (uint32_t)irq15, 0x08, 0x8E); 83 | 84 | 85 | setIdtGate(128, (uint32_t)isr128, 0x08, 0x8E); //System calls 86 | setIdtGate(177, (uint32_t)isr177, 0x08, 0x8E); //System calls 87 | 88 | idt_flush((uint32_t)&idt_ptr); 89 | 90 | } 91 | 92 | void setIdtGate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags){ 93 | 94 | idt_entries[num].base_low = base & 0xFFFF; 95 | idt_entries[num].base_high = (base >> 16) & 0xFFFF; 96 | idt_entries[num].sel = sel; 97 | idt_entries[num].always0 = 0; 98 | idt_entries[num].flags = flags | 0x60; 99 | 100 | } 101 | 102 | char* exception_messages[] = { 103 | "Division By Zero", 104 | "Debug", 105 | "Non Maskable Interrupt", 106 | "Breakpoint", 107 | "Into Detected Overflow", 108 | "Out of Bounds", 109 | "Invalid Opcode", 110 | "No Coprocessor", 111 | "Double fault", 112 | "Coprocessor Segment Overrun", 113 | "Bad TSS", 114 | "Segment not present", 115 | "Stack fault", 116 | "General protection fault", 117 | "Page fault", 118 | "Unknown Interrupt", 119 | "Coprocessor Fault", 120 | "Alignment Fault", 121 | "Machine Check", 122 | "Reserved", 123 | "Reserved", 124 | "Reserved", 125 | "Reserved", 126 | "Reserved", 127 | "Reserved", 128 | "Reserved", 129 | "Reserved", 130 | "Reserved", 131 | "Reserved", 132 | "Reserved", 133 | "Reserved", 134 | "Reserved" 135 | }; 136 | 137 | void isr_handler(struct InterruptRegisters* regs){ 138 | if (regs->int_no < 32){ 139 | print(exception_messages[regs->int_no]); 140 | print("\n"); 141 | print("Exception! System Halted\n"); 142 | for (;;); 143 | } 144 | } 145 | 146 | void *irq_routines[16] = { 147 | 0,0,0,0,0,0,0,0, 148 | 0,0,0,0,0,0,0,0 149 | }; 150 | 151 | void irq_install_handler (int irq, void (*handler)(struct InterruptRegisters *r)){ 152 | irq_routines[irq] = handler; 153 | } 154 | 155 | void irq_uninstall_handler(int irq){ 156 | irq_routines[irq] = 0; 157 | } 158 | 159 | void irq_handler(struct InterruptRegisters* regs){ 160 | void (*handler)(struct InterruptRegisters *regs); 161 | 162 | handler = irq_routines[regs->int_no - 32]; 163 | 164 | if (handler){ 165 | handler(regs); 166 | } 167 | 168 | if (regs->int_no >= 40){ 169 | outPortB(0xA0, 0x20); 170 | } 171 | 172 | outPortB(0x20,0x20); 173 | } 174 | -------------------------------------------------------------------------------- /src/idt.h: -------------------------------------------------------------------------------- 1 | 2 | struct idt_entry_struct{ 3 | uint16_t base_low; 4 | uint16_t sel; 5 | uint8_t always0; 6 | uint8_t flags; 7 | uint16_t base_high; 8 | }__attribute__((packed)); 9 | 10 | struct idt_ptr_struct{ 11 | uint16_t limit; 12 | uint32_t base; 13 | }__attribute__((packed)); 14 | 15 | void initIdt(); 16 | void setIdtGate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags); 17 | 18 | void isr_handler(struct InterruptRegisters* regs); 19 | void irq_install_handler (int irq, void (*handler)(struct InterruptRegisters *r)); 20 | 21 | extern void isr0(); 22 | extern void isr1(); 23 | extern void isr2(); 24 | extern void isr3(); 25 | extern void isr4(); 26 | extern void isr5(); 27 | extern void isr6(); 28 | extern void isr7(); 29 | extern void isr8(); 30 | extern void isr9(); 31 | extern void isr10(); 32 | extern void isr11(); 33 | extern void isr12(); 34 | extern void isr13(); 35 | extern void isr14(); 36 | extern void isr15(); 37 | extern void isr16(); 38 | extern void isr17(); 39 | extern void isr18(); 40 | extern void isr19(); 41 | extern void isr20(); 42 | extern void isr21(); 43 | extern void isr22(); 44 | extern void isr23(); 45 | extern void isr24(); 46 | extern void isr25(); 47 | extern void isr26(); 48 | extern void isr27(); 49 | extern void isr28(); 50 | extern void isr29(); 51 | extern void isr30(); 52 | extern void isr31(); 53 | 54 | extern void isr128(); 55 | extern void isr177(); 56 | 57 | extern void irq0(); 58 | extern void irq1(); 59 | extern void irq2(); 60 | extern void irq3(); 61 | extern void irq4(); 62 | extern void irq5(); 63 | extern void irq6(); 64 | extern void irq7(); 65 | extern void irq8(); 66 | extern void irq9(); 67 | extern void irq10(); 68 | extern void irq11(); 69 | extern void irq12(); 70 | extern void irq13(); 71 | extern void irq14(); 72 | extern void irq15(); -------------------------------------------------------------------------------- /src/idt.s: -------------------------------------------------------------------------------- 1 | global idt_flush 2 | idt_flush: 3 | MOV eax, [esp+4] 4 | LIDT [eax] 5 | STI 6 | RET 7 | 8 | %macro ISR_NOERRCODE 1 9 | global isr%1 10 | isr%1: 11 | CLI 12 | PUSH LONG 0 13 | PUSH LONG %1 14 | JMP isr_common_stub 15 | %endmacro 16 | 17 | %macro ISR_ERRCODE 1 18 | global isr%1 19 | isr%1: 20 | CLI 21 | PUSH LONG %1 22 | JMP isr_common_stub 23 | %endmacro 24 | 25 | %macro IRQ 2 26 | global irq%1 27 | irq%1: 28 | CLI 29 | PUSH LONG 0 30 | PUSH LONG %2 31 | JMP irq_common_stub 32 | %endmacro 33 | 34 | ISR_NOERRCODE 0 35 | ISR_NOERRCODE 1 36 | ISR_NOERRCODE 2 37 | ISR_NOERRCODE 3 38 | ISR_NOERRCODE 4 39 | ISR_NOERRCODE 5 40 | ISR_NOERRCODE 6 41 | ISR_NOERRCODE 7 42 | 43 | ISR_ERRCODE 8 44 | ISR_NOERRCODE 9 45 | ISR_ERRCODE 10 46 | ISR_ERRCODE 11 47 | ISR_ERRCODE 12 48 | ISR_ERRCODE 13 49 | ISR_ERRCODE 14 50 | ISR_NOERRCODE 15 51 | ISR_NOERRCODE 16 52 | ISR_NOERRCODE 17 53 | ISR_NOERRCODE 18 54 | ISR_NOERRCODE 19 55 | ISR_NOERRCODE 20 56 | ISR_NOERRCODE 21 57 | ISR_NOERRCODE 22 58 | ISR_NOERRCODE 23 59 | ISR_NOERRCODE 24 60 | ISR_NOERRCODE 25 61 | ISR_NOERRCODE 26 62 | ISR_NOERRCODE 27 63 | ISR_NOERRCODE 28 64 | ISR_NOERRCODE 29 65 | ISR_NOERRCODE 30 66 | ISR_NOERRCODE 31 67 | ISR_NOERRCODE 128 68 | ISR_NOERRCODE 177 69 | 70 | IRQ 0, 32 71 | IRQ 1, 33 72 | IRQ 2, 34 73 | IRQ 3, 35 74 | IRQ 4, 36 75 | IRQ 5, 37 76 | IRQ 6, 38 77 | IRQ 7, 39 78 | IRQ 8, 40 79 | IRQ 9, 41 80 | IRQ 10, 42 81 | IRQ 11, 43 82 | IRQ 12, 44 83 | IRQ 13, 45 84 | IRQ 14, 46 85 | IRQ 15, 47 86 | 87 | extern isr_handler 88 | isr_common_stub: 89 | pusha 90 | mov eax,ds 91 | PUSH eax 92 | MOV eax, cr2 93 | PUSH eax 94 | 95 | MOV ax, 0x10 96 | MOV ds, ax 97 | MOV es, ax 98 | MOV fs, ax 99 | MOV gs, ax 100 | 101 | PUSH esp 102 | CALL isr_handler 103 | 104 | ADD esp, 8 105 | POP ebx 106 | MOV ds, bx 107 | MOV es, bx 108 | MOV fs, bx 109 | MOV gs, bx 110 | 111 | POPA 112 | ADD esp, 8 113 | STI 114 | IRET 115 | 116 | extern irq_handler 117 | irq_common_stub: 118 | pusha 119 | mov eax,ds 120 | PUSH eax 121 | MOV eax, cr2 122 | PUSH eax 123 | 124 | MOV ax, 0x10 125 | MOV ds, ax 126 | MOV es, ax 127 | MOV fs, ax 128 | MOV gs, ax 129 | 130 | PUSH esp 131 | CALL irq_handler 132 | 133 | ADD esp, 8 134 | POP ebx 135 | MOV ds, bx 136 | MOV es, bx 137 | MOV fs, bx 138 | MOV gs, bx 139 | 140 | POPA 141 | ADD esp, 8 142 | STI 143 | IRET 144 | -------------------------------------------------------------------------------- /src/kernel.c: -------------------------------------------------------------------------------- 1 | #include "vga.h" 2 | #include "stdint.h" 3 | #include "gdt.h" 4 | #include "idt.h" 5 | #include "timer.h" 6 | #include "util.h" 7 | #include "stdlib/stdio.h" 8 | #include "keyboard.h" 9 | #include "malloc.h" 10 | #include "vfs.h" 11 | #include "multiboot.h" 12 | #include "mem.h" 13 | 14 | void main(uint32_t magic, struct multiboot_info* boot); 15 | 16 | void set_screen_color(uint8_t color); 17 | 18 | void set_screen_color(uint8_t color) { 19 | uint8_t* video_memory = (uint8_t*)0xC00B8000; 20 | 21 | for (int i = 0; i < width * height * 2; i += 2) { 22 | video_memory[i + 1] = color; // Set the background color byte 23 | } 24 | } 25 | 26 | 27 | void main(uint32_t magic, struct multiboot_info* boot) { 28 | initGdt(); 29 | initIdt(); 30 | initTimer(); 31 | initKeyboard(); 32 | uint32_t mod1 = *(uint32_t*)(boot->mods_addr + 4); 33 | uint32_t physicalAllocStart = (mod1 + 0xFFF) & ~0xFFF; 34 | initMemory(boot->mem_upper * 1024, physicalAllocStart); 35 | kmallocInit(0x1000); 36 | init(); 37 | create("p.txt", "ethos starter"); 38 | create("p.c", ""); 39 | print("gdt[done]\n"); 40 | print("idt[done]\n"); 41 | print("timer[done]\nkeyboard[done]\n"); 42 | print("paging[done]\nvfs[done]\n"); 43 | print("######################\n"); 44 | print("# ETHOS #\n"); 45 | print("######################\n"); 46 | print("ethos-->"); 47 | set_screen_color(0x6F); 48 | for(;;); 49 | } 50 | -------------------------------------------------------------------------------- /src/keyboard.c: -------------------------------------------------------------------------------- 1 | #include "stdint.h" 2 | #include "util.h" 3 | #include "idt.h" 4 | #include "stdlib/stdio.h" 5 | #include "keyboard.h" 6 | #include "vga.h" 7 | #include "vfs.h" 8 | #include "strings.h" 9 | 10 | 11 | bool capsOn; 12 | bool capsLock; 13 | 14 | char text[100] = { 0 }; 15 | 16 | const uint32_t UNKNOWN = 0xFFFFFFFF; 17 | const uint32_t ESC = 0xFFFFFFFF - 1; 18 | const uint32_t CTRL = 0xFFFFFFFF - 2; 19 | const uint32_t LSHFT = 0xFFFFFFFF - 3; 20 | const uint32_t RSHFT = 0xFFFFFFFF - 4; 21 | const uint32_t ALT = 0xFFFFFFFF - 5; 22 | const uint32_t F1 = 0xFFFFFFFF - 6; 23 | const uint32_t F2 = 0xFFFFFFFF - 7; 24 | const uint32_t F3 = 0xFFFFFFFF - 8; 25 | const uint32_t F4 = 0xFFFFFFFF - 9; 26 | const uint32_t F5 = 0xFFFFFFFF - 10; 27 | const uint32_t F6 = 0xFFFFFFFF - 11; 28 | const uint32_t F7 = 0xFFFFFFFF - 12; 29 | const uint32_t F8 = 0xFFFFFFFF - 13; 30 | const uint32_t F9 = 0xFFFFFFFF - 14; 31 | const uint32_t F10 = 0xFFFFFFFF - 15; 32 | const uint32_t F11 = 0xFFFFFFFF - 16; 33 | const uint32_t F12 = 0xFFFFFFFF - 17; 34 | const uint32_t SCRLCK = 0xFFFFFFFF - 18; 35 | const uint32_t HOME = 0xFFFFFFFF - 19; 36 | const uint32_t UP = 0xFFFFFFFF - 20; 37 | const uint32_t LEFT = 0xFFFFFFFF - 21; 38 | const uint32_t RIGHT = 0xFFFFFFFF - 22; 39 | const uint32_t DOWN = 0xFFFFFFFF - 23; 40 | const uint32_t PGUP = 0xFFFFFFFF - 24; 41 | const uint32_t PGDOWN = 0xFFFFFFFF - 25; 42 | const uint32_t END = 0xFFFFFFFF - 26; 43 | const uint32_t INS = 0xFFFFFFFF - 27; 44 | const uint32_t DEL = 0xFFFFFFFF - 28; 45 | const uint32_t CAPS = 0xFFFFFFFF - 29; 46 | const uint32_t NONE = 0xFFFFFFFF - 30; 47 | const uint32_t ALTGR = 0xFFFFFFFF - 31; 48 | const uint32_t NUMLCK = 0xFFFFFFFF - 32; 49 | 50 | 51 | const uint32_t lowercase[128] = { 52 | UNKNOWN,ESC,'1','2','3','4','5','6','7','8', 53 | '9','0','-','=','\b','\t','q','w','e','r', 54 | 't','y','u','i','o','p','[',']','\n',CTRL, 55 | 'a','s','d','f','g','h','j','k','l',';', 56 | '\'','`',LSHFT,'\\','z','x','c','v','b','n','m',',', 57 | '.','/',RSHFT,'*',ALT,' ',CAPS,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,NUMLCK,SCRLCK,HOME,UP,PGUP,'-',LEFT,UNKNOWN,RIGHT, 58 | '+',END,DOWN,PGDOWN,INS,DEL,UNKNOWN,UNKNOWN,UNKNOWN,F11,F12,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN, 59 | UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN, 60 | UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN, 61 | UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN 62 | }; 63 | const uint32_t uppercase[128] = { 64 | UNKNOWN,ESC,'!','@','#','$','%','^','&','*','(',')','_','+','\b','\t','Q','W','E','R', 65 | 'T','Y','U','I','O','P','{','}','\n',CTRL,'A','S','D','F','G','H','J','K','L',':','"','~',LSHFT,'|','Z','X','C', 66 | 'V','B','N','M','<','>','?',RSHFT,'*',ALT,' ',CAPS,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,NUMLCK,SCRLCK,HOME,UP,PGUP,'-', 67 | LEFT,UNKNOWN,RIGHT,'+',END,DOWN,PGDOWN,INS,DEL,UNKNOWN,UNKNOWN,UNKNOWN,F11,F12,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN, 68 | UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN, 69 | UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN, 70 | UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN 71 | }; 72 | 73 | const uint32_t val[128] = {'c'}; 74 | 75 | void append(char *part) { 76 | uint8_t i = 0; 77 | uint8_t j = 0; 78 | while(text[i] != '\0') { 79 | i++; 80 | } 81 | while(part[j] != '\0') { 82 | text[i] = part[j]; 83 | i++; 84 | j++; 85 | } 86 | } 87 | 88 | void rm() { 89 | uint8_t i = 0; 90 | while(text[i] != '\0') { 91 | i++; 92 | } 93 | text[--i] = text[i]; 94 | } 95 | 96 | 97 | void clear() { 98 | uint8_t p = 0; 99 | while(text[p] != '\0') { 100 | text[p] = '\0'; 101 | p++; 102 | } 103 | } 104 | 105 | void delp(char p, char *t) { 106 | if(p == 0) { 107 | append(t); 108 | print(t); 109 | } 110 | } 111 | 112 | void keyboardHandler(struct InterruptRegisters *regs){ 113 | char scanCode = inPortB(0x60) & 0x7F; //What key is pressed 114 | char press = inPortB(0x60) & 0x80; //Press down, or released 115 | 116 | switch(scanCode){ 117 | case 1: 118 | case 29: 119 | case 16: 120 | delp(press, "q"); 121 | break; 122 | case 17: 123 | delp(press, "w"); 124 | break; 125 | case 18: 126 | delp(press, "e"); 127 | break; 128 | case 19: 129 | delp(press, "r"); 130 | break; 131 | case 20: 132 | delp(press, "t"); 133 | break; 134 | case 21: 135 | delp(press, "y"); 136 | break; 137 | case 22: 138 | delp(press, "u"); 139 | break; 140 | case 23: 141 | delp(press, "i"); 142 | break; 143 | case 24: 144 | delp(press, "o"); 145 | break; 146 | case 25: 147 | delp(press, "p"); 148 | break; 149 | case 30: 150 | delp(press, "a"); 151 | break; 152 | case 31: 153 | delp(press, "s"); 154 | break; 155 | case 32: 156 | delp(press, "d"); 157 | break; 158 | case 33: 159 | delp(press, "f"); 160 | break; 161 | case 34: 162 | delp(press, "g"); 163 | break; 164 | case 35: 165 | delp(press, "h"); 166 | break; 167 | case 36: 168 | delp(press, "j"); 169 | break; 170 | case 37: 171 | delp(press, "k"); 172 | break; 173 | case 38: 174 | delp(press, "l"); 175 | break; 176 | case 45: 177 | delp(press, "x"); 178 | break; 179 | case 46: 180 | delp(press, "c"); 181 | break; 182 | case 47: 183 | delp(press, "v"); 184 | break; 185 | case 48: 186 | delp(press, "b"); 187 | break; 188 | case 49: 189 | delp(press, "n"); 190 | break; 191 | case 50: 192 | delp(press, "m"); 193 | break; 194 | case 57: 195 | delp(press, " "); 196 | break; 197 | case 28: 198 | if(press == 0) { 199 | if(comp("clear", text) != 0) { 200 | Reset(); 201 | } 202 | else if(comp("exit", text) != 0) { 203 | print("\t exit"); 204 | } 205 | else if(comp("info", text) != 0) { 206 | print("\tbasic commands exit, clear, info"); 207 | } 208 | else if(comp("ls", text) != 0) { 209 | print("\n__FILES__\n"); 210 | printfs(); 211 | } 212 | else{ 213 | print("\tcommand not found"); 214 | } 215 | print("\nethos-->"); 216 | clear(); 217 | } 218 | break; 219 | //case 15: 220 | //print("hello world"); 221 | //if(press == 0) { 222 | // rm(); 223 | // } 224 | //break; 225 | case 56: 226 | case 59: 227 | case 60: 228 | case 61: 229 | case 62: 230 | case 63: 231 | case 64: 232 | case 65: 233 | case 66: 234 | case 67: 235 | case 68: 236 | case 87: 237 | case 88: 238 | break; 239 | case 42: 240 | //shift key 241 | if (press == 0){ 242 | capsOn = true; 243 | }else{ 244 | capsOn = false; 245 | } 246 | break; 247 | case 58: 248 | if (!capsLock && press == 0){ 249 | capsLock = true; 250 | }else if (capsLock && press == 0){ 251 | capsLock = false; 252 | } 253 | break; 254 | default: 255 | if (press == 0){ 256 | if(lowercase[scanCode] == '\b') { 257 | rm(); 258 | print("\b"); 259 | break; 260 | } 261 | if (capsOn || capsLock){ 262 | printf("%c", uppercase[scanCode]); 263 | } 264 | else{ 265 | printf("%c", lowercase[scanCode]); 266 | } 267 | } 268 | 269 | 270 | } 271 | 272 | } 273 | 274 | void initKeyboard(){ 275 | capsOn = false; 276 | capsLock = false; 277 | irq_install_handler(1,&keyboardHandler); 278 | } 279 | 280 | 281 | 282 | -------------------------------------------------------------------------------- /src/keyboard.h: -------------------------------------------------------------------------------- 1 | void initKeyboard(); 2 | void keyboardHandler(struct InterruptRegisters *regs); 3 | -------------------------------------------------------------------------------- /src/malloc.c: -------------------------------------------------------------------------------- 1 | #include "stdint.h" 2 | #include "util.h" 3 | #include "mem.h" 4 | #include "malloc.h" 5 | 6 | static uint32_t heapStart; 7 | static uint32_t heapSize; 8 | static uint32_t threshold; 9 | static bool kmallocInitalized = false; 10 | 11 | void *memcpy(void *dest, const void *src, unsigned int n) 12 | { 13 | char *d = (char *)dest; 14 | const char *s = (const char *)src; 15 | for(int i=0;i oldPageTop){ 36 | int diff = newPageTop - oldPageTop; 37 | 38 | for (int i = 0; i < diff; i++){ 39 | uint32_t phys = pmmAllocPageFrame(); 40 | memMapPage(KERNEL_MALLOC + oldPageTop * 0x1000 + i * 0x1000, phys, PAGE_FLAG_WRITE); 41 | } 42 | } 43 | 44 | heapSize = newSize; 45 | } 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/malloc.h: -------------------------------------------------------------------------------- 1 | #ifndef MALLOC_H 2 | #define MALLOC_H 3 | 4 | void kmallocInit(uint32_t heapSize); 5 | void changeHeapSize(int newSize); 6 | void *memcpy(void *dest, const void *src, unsigned int n); 7 | #endif 8 | -------------------------------------------------------------------------------- /src/mem.c: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | #include "mem.h" 3 | #include "stdint.h" 4 | 5 | static uint32_t pageFrameMin; // minimum physical frame 6 | static uint32_t pageFrameMax; // maximum physical frame 7 | static uint32_t totalAlloc; // total amount of allocated frames 8 | int mem_num_vpages; //amount of virtual pages 9 | 10 | #define NUM_PAGES_DIRS 256 // number of page directories 11 | #define NUM_PAGE_FRAMES (0x100000000 / 0x1000 / 8) // number of page frames 12 | 13 | uint8_t physicalMemoryBitmap[NUM_PAGE_FRAMES / 8]; //Dynamically, bit array 14 | 15 | static uint32_t pageDirs[NUM_PAGES_DIRS][1024] __attribute__((aligned(4096)));//# of pagedir 16 | static uint8_t pageDirUsed[NUM_PAGES_DIRS]; // total amount of pagedirused 17 | 18 | void pmm_init(uint32_t memLow, uint32_t memHigh){ 19 | //Calculates pageframemin and pageframeMax based on memlow and memhigh 20 | pageFrameMin = CEIL_DIV(memLow, 0x1000); 21 | pageFrameMax = memHigh / 0x1000; 22 | totalAlloc = 0; 23 | 24 | //clears the bitmap 25 | memset(physicalMemoryBitmap, 0, sizeof(physicalMemoryBitmap)); 26 | } 27 | 28 | uint32_t* memGetCurrentPageDir(){ 29 | uint32_t pd; 30 | asm volatile("mov %%cr3, %0": "=r"(pd)); 31 | pd += KERNEL_START; 32 | //gets the current mem address from cr3 33 | 34 | return (uint32_t*) pd; 35 | } 36 | 37 | void memChangePageDir(uint32_t* pd){ 38 | // Adjusts pd by subtracting KERNEL_START 39 | // then puts it in the cr3 register 40 | pd = (uint32_t*) (((uint32_t)pd)-KERNEL_START); 41 | asm volatile("mov %0, %%eax \n mov %%eax, %%cr3 \n" :: "m"(pd)); 42 | } 43 | 44 | void syncPageDirs(){ 45 | //iterates over the pages and clears certain flags in each page directory if used 46 | for (int i = 0; i < NUM_PAGES_DIRS; i++){ 47 | if (pageDirUsed[i]){ 48 | uint32_t* pageDir = pageDirs[i]; 49 | 50 | for (int i = 768; i < 1023; i++){ 51 | pageDir[i] = initial_page_dir[i] & ~PAGE_FLAG_OWNER; 52 | } 53 | } 54 | } 55 | } 56 | 57 | void memMapPage(uint32_t virutalAddr, uint32_t physAddr, uint32_t flags){ 58 | //Maps a virtual address to a physical address with specific flags 59 | uint32_t *prevPageDir = 0; 60 | 61 | if (virutalAddr >= KERNEL_START){ 62 | prevPageDir = memGetCurrentPageDir(); 63 | if (prevPageDir != initial_page_dir){ 64 | memChangePageDir(initial_page_dir); 65 | } 66 | } 67 | 68 | uint32_t pdIndex = virutalAddr >> 22; 69 | uint32_t ptIndex = virutalAddr >> 12 & 0x3FF; 70 | 71 | uint32_t* pageDir = REC_PAGEDIR; 72 | uint32_t* pt = REC_PAGETABLE(pdIndex); 73 | 74 | if (!(pageDir[pdIndex] & PAGE_FLAG_PRESENT)){ 75 | uint32_t ptPAddr = pmmAllocPageFrame(); 76 | pageDir[pdIndex] = ptPAddr | PAGE_FLAG_PRESENT | PAGE_FLAG_WRITE | PAGE_FLAG_OWNER | flags; 77 | invalidate(virutalAddr); 78 | 79 | for (uint32_t i = 0; i < 1024; i++){ 80 | pt[i] = 0; 81 | } 82 | } 83 | 84 | pt[ptIndex] = physAddr | PAGE_FLAG_PRESENT | flags; 85 | mem_num_vpages++; 86 | invalidate(virutalAddr); 87 | 88 | if (prevPageDir != 0){ 89 | syncPageDirs(); 90 | 91 | if (prevPageDir != initial_page_dir){ 92 | memChangePageDir(prevPageDir); 93 | } 94 | } 95 | 96 | } 97 | 98 | uint32_t pmmAllocPageFrame(){ 99 | // allocates the free bit in the bitmap and allocates the page frame 100 | uint32_t start = pageFrameMin / 8 + ((pageFrameMin & 7) != 0 ? 1 : 0); 101 | uint32_t end = pageFrameMax / 8 - ((pageFrameMax & 7) != 0 ? 1 : 0); 102 | 103 | for (uint32_t b = start; b < end; b++){ 104 | uint8_t byte = physicalMemoryBitmap[b]; 105 | if (byte == 0xFF){ 106 | continue; 107 | } 108 | 109 | for (uint32_t i = 0; i < 8; i++){ 110 | bool used = byte >> i & 1; 111 | 112 | if (!used){ 113 | byte ^= (-1 ^ byte) & (1 << i); 114 | physicalMemoryBitmap[b] = byte; 115 | totalAlloc++; 116 | 117 | uint32_t addr = (b*8*i) * 0x1000; 118 | return addr; 119 | } 120 | } 121 | 122 | } 123 | 124 | return 0; 125 | } 126 | 127 | 128 | void initMemory(uint32_t memHigh, uint32_t physicalAllocStart){ 129 | // sets up memory by initializing the page directories and invalidating entries in the TLB 130 | mem_num_vpages = 0; 131 | initial_page_dir[0] = 0; 132 | invalidate(0); 133 | initial_page_dir[1023] = ((uint32_t) initial_page_dir - KERNEL_START) | PAGE_FLAG_PRESENT | PAGE_FLAG_WRITE; 134 | invalidate(0xFFFFF000); 135 | 136 | pmm_init(physicalAllocStart, memHigh); 137 | memset(pageDirs, 0, 0x1000 * NUM_PAGES_DIRS); 138 | memset(pageDirUsed, 0, NUM_PAGES_DIRS); 139 | } 140 | 141 | 142 | // checks invlpg to make sure the page_tables are insync with memory 143 | void invalidate(uint32_t vaddr){ 144 | asm volatile("invlpg %0" :: "m"(vaddr)); 145 | } 146 | -------------------------------------------------------------------------------- /src/mem.h: -------------------------------------------------------------------------------- 1 | extern uint32_t initial_page_dir[1024]; 2 | extern int mem_num_vpages; 3 | 4 | void initMemory(uint32_t memHigh, uint32_t physicalAllocStart); 5 | void pmm_init(uint32_t memLow, uint32_t memHigh); 6 | void invalidate(uint32_t vaddr); 7 | uint32_t pmmAllocPageFrame(); 8 | uint32_t* memGetCurrentPageDir(); 9 | void memChangePageDir(uint32_t* pd); 10 | void syncPageDirs(); 11 | void memMapPage(uint32_t virutalAddr, uint32_t physAddr, uint32_t flags); 12 | 13 | #define KERNEL_START 0xC0000000 14 | #define KERNEL_MALLOC 0xD000000 15 | #define REC_PAGEDIR ((uint32_t*)0xFFFFF000) 16 | #define REC_PAGETABLE(i) ((uint32_t*) (0xFFC00000 + ((i) << 12))) 17 | 18 | #define PAGE_FLAG_PRESENT (1 << 0) 19 | #define PAGE_FLAG_WRITE (1 << 1) 20 | #define PAGE_FLAG_OWNER (1 << 9) 21 | 22 | -------------------------------------------------------------------------------- /src/multiboot.h: -------------------------------------------------------------------------------- 1 | 2 | struct multiboot_aout_symbol_table 3 | { 4 | uint32_t tabsize; 5 | uint32_t strsize; 6 | uint32_t addr; 7 | uint32_t reserved; 8 | }; 9 | 10 | 11 | 12 | struct multiboot_elf_section_header_table 13 | { 14 | uint32_t num; 15 | uint32_t size; 16 | uint32_t addr; 17 | uint32_t shndx; 18 | }; 19 | 20 | struct multiboot_info{ 21 | uint32_t flags; 22 | uint32_t mem_lower; 23 | uint32_t mem_upper; 24 | uint32_t boot_device; 25 | 26 | uint32_t cmdline; 27 | uint32_t mods_count; 28 | uint32_t mods_addr; 29 | 30 | union{ 31 | struct multiboot_aout_symbol_table aout_sym; 32 | struct multiboot_elf_section_header_table elf_sec; 33 | } u; 34 | 35 | uint32_t mmap_length; 36 | uint32_t mmap_addr; 37 | 38 | uint32_t drives_length; 39 | uint32_t drives_addr; 40 | 41 | uint32_t config_table; 42 | uint32_t boot_loader_name; 43 | 44 | uint32_t apm_table; 45 | 46 | uint32_t vbe_control_info; 47 | uint32_t vbe_mode_info; 48 | uint16_t vbe_mode; 49 | uint16_t vbe_interface_seg; 50 | uint16_t vbe_interface_off; 51 | uint16_t vbe_interface_len; 52 | }; 53 | 54 | struct multiboot_mmap_entry 55 | { 56 | uint32_t size; 57 | uint32_t addr_low; 58 | uint32_t addr_high; 59 | uint32_t len_low; 60 | uint32_t len_high; 61 | #define MULTIBOOT_MEMORY_AVAILABLE 1 62 | #define MULTIBOOT_MEMORY_RESERVED 2 63 | #define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 64 | #define MULTIBOOT_MEMORY_NVS 4 65 | #define MULTIBOOT_MEMORY_BADRAM 5 66 | uint32_t type; 67 | } __attribute__((packed)); 68 | 69 | -------------------------------------------------------------------------------- /src/paging.h: -------------------------------------------------------------------------------- 1 | #ifndef __PAGING_H__ 2 | #define __PAGING_H__ 3 | 4 | #define PAGE_SIZE 4096 5 | #define PAGE_T_SIZE 512 6 | 7 | typedef struct { 8 | unsigned long present : 1; 9 | unsigned long rw : 1; 10 | unsigned long user : 1; 11 | unsigned long pwt : 1; 12 | unsigned long pcd : 1; 13 | unsigned long accessed : 1; 14 | unsigned long dirty : 1; 15 | unsigned long reserved : 1; 16 | uint64_t frame : 52; 17 | }__attribute__((packed)) page_t_e; 18 | 19 | typedef struct { 20 | page_t_e entry[PAGE_T_SIZE]; 21 | }__attribute__((packed)) page_t; 22 | 23 | typedef struct { 24 | page_t *pml4; 25 | }memory_manager; 26 | 27 | void init_paging(memory_manager *mm); 28 | #endif 29 | -------------------------------------------------------------------------------- /src/stdint.h: -------------------------------------------------------------------------------- 1 | typedef signed char int8_t; 2 | typedef unsigned char uint8_t; 3 | 4 | typedef signed short int16_t; 5 | typedef unsigned short uint16_t; 6 | 7 | typedef signed long int int32_t; 8 | typedef unsigned long int uint32_t; 9 | 10 | typedef signed long long int int64_t; 11 | typedef unsigned long long int uint64_t; 12 | 13 | typedef uint8_t bool; 14 | #define true 1 15 | #define false 0 -------------------------------------------------------------------------------- /src/stdlib/stdio.c: -------------------------------------------------------------------------------- 1 | #include "../stdint.h" 2 | #include "stdio.h" 3 | #include "../vga.h" 4 | 5 | void putc(char c){ 6 | print(&c); 7 | } 8 | 9 | void puts(const char* s){ 10 | while (*s){ 11 | putc(*s); 12 | s++; 13 | } 14 | } 15 | 16 | void printf(const char* fmt, ...){ 17 | int* argp = (int*) &fmt; 18 | int state = PRINTF_STATE_START; 19 | int length = PRINTF_LENGTH_START; 20 | int radix = 10; 21 | bool sign = false; 22 | 23 | argp++; 24 | while (*fmt){ 25 | switch(state){ 26 | case PRINTF_STATE_START: 27 | if (*fmt == '%'){ 28 | state = PRINTF_STATE_LENGTH; 29 | }else{ 30 | putc(*fmt); 31 | } 32 | break; 33 | case PRINTF_STATE_LENGTH: 34 | if (*fmt == 'h'){ 35 | length = PRINTF_LENGTH_SHORT; 36 | state = PRINTF_STATE_SHORT; 37 | }else if (*fmt == 'l'){ 38 | length = PRINTF_LENGTH_LONG; 39 | state = PRINTF_STATE_LONG; 40 | }else{ 41 | goto PRINTF_STATE_SPEC_; 42 | } 43 | break; 44 | //hd 45 | case PRINTF_STATE_SHORT: 46 | if (*fmt == 'h'){ 47 | length = PRINTF_LENGTH_SHORT_SHORT; 48 | state = PRINTF_STATE_SPEC; 49 | }else{ 50 | goto PRINTF_STATE_SPEC_; 51 | } 52 | break; 53 | 54 | case PRINTF_STATE_LONG: 55 | if (*fmt == 'l'){ 56 | length = PRINTF_LENGTH_LONG_LONG; 57 | state = PRINTF_STATE_SPEC; 58 | }else{ 59 | goto PRINTF_STATE_SPEC_; 60 | } 61 | break; 62 | 63 | case PRINTF_STATE_SPEC: 64 | PRINTF_STATE_SPEC_: 65 | switch(*fmt){ 66 | case 'c': 67 | putc((char)*argp); 68 | argp++; 69 | break; 70 | case 's': 71 | if (length == PRINTF_LENGTH_LONG || length == PRINTF_LENGTH_LONG_LONG){ 72 | puts(*(const char **)argp); 73 | argp += 2; 74 | }else{ 75 | puts(*(const char **)argp); 76 | argp++; 77 | } 78 | break; 79 | case '%': 80 | putc('%'); 81 | break; 82 | case 'd': 83 | case 'i': 84 | radix = 10; 85 | sign = true; 86 | argp = printf_number(argp, length, sign, radix); 87 | break; 88 | case 'u': 89 | radix = 10; 90 | sign = false; 91 | argp = printf_number(argp, length, sign, radix); 92 | break; 93 | case 'X': 94 | case 'x': 95 | case 'p': 96 | radix = 16; 97 | sign = false; 98 | argp = printf_number(argp, length, sign, radix); 99 | break; 100 | case 'o': 101 | radix = 8; 102 | sign = false; 103 | argp = printf_number(argp, length, sign, radix); 104 | break; 105 | default: 106 | break; 107 | 108 | } 109 | state = PRINTF_STATE_START; 110 | length = PRINTF_LENGTH_START; 111 | radix = 10; 112 | sign = false; 113 | break; 114 | } 115 | fmt++; 116 | } 117 | } 118 | 119 | const char possibleChars[] = "0123456789abcdef"; 120 | 121 | int * printf_number(int* argp, int length, bool sign, int radix){ 122 | char buffer[32] = ""; 123 | uint32_t number; 124 | int number_sign = 1; 125 | int pos = 0; 126 | 127 | switch(length){ 128 | case PRINTF_LENGTH_SHORT_SHORT: 129 | case PRINTF_LENGTH_SHORT: 130 | case PRINTF_LENGTH_START: 131 | if (sign){ 132 | int n = *argp; 133 | if (n < 0){ 134 | n = -n; 135 | number_sign = -1; 136 | } 137 | number = (uint32_t) n; 138 | }else{ 139 | number = *(uint32_t*) argp; 140 | } 141 | argp++; 142 | break; 143 | case PRINTF_LENGTH_LONG: 144 | if (sign){ 145 | long int n = *(long int*)argp; 146 | if (n < 0){ 147 | n = -n; 148 | number_sign = -1; 149 | } 150 | number = (uint32_t) n; 151 | }else{ 152 | number = *(uint32_t*) argp; 153 | } 154 | argp += 2; 155 | break; 156 | case PRINTF_LENGTH_LONG_LONG: 157 | if (sign){ 158 | long long int n = *(long long int*)argp; 159 | if (n < 0){ 160 | n = -n; 161 | number_sign = -1; 162 | } 163 | number = (uint32_t) n; 164 | }else{ 165 | number = *(uint32_t*) argp; 166 | } 167 | argp += 4; 168 | break; 169 | } 170 | 171 | do{ 172 | uint32_t rem = number % radix; 173 | number = number / radix; 174 | 175 | buffer[pos++] = possibleChars[rem]; 176 | }while (number > 0); 177 | 178 | if (sign && number_sign < 0){ 179 | buffer[pos++] = '-'; 180 | } 181 | 182 | while (--pos >= 0){ 183 | putc(buffer[pos]); 184 | } 185 | 186 | return argp; 187 | } 188 | -------------------------------------------------------------------------------- /src/stdlib/stdio.h: -------------------------------------------------------------------------------- 1 | void putc(char c); 2 | void puts(const char* str); 3 | void printf(const char* fmt, ...); 4 | int * printf_number(int*, int, bool, int); 5 | 6 | extern void x86_div64_32(uint64_t, uint32_t, uint64_t*, uint32_t*); 7 | 8 | #define PRINTF_STATE_START 0 9 | #define PRINTF_STATE_LENGTH 1 10 | #define PRINTF_STATE_SHORT 2 11 | #define PRINTF_STATE_LONG 3 12 | #define PRINTF_STATE_SPEC 4 13 | 14 | #define PRINTF_LENGTH_START 0 15 | #define PRINTF_LENGTH_SHORT_SHORT 1 16 | #define PRINTF_LENGTH_SHORT 2 17 | #define PRINTF_LENGTH_LONG 3 18 | #define PRINTF_LENGTH_LONG_LONG 4 19 | -------------------------------------------------------------------------------- /src/string.c: -------------------------------------------------------------------------------- 1 | #include "string.h" 2 | 3 | int strlen(const char *str) { 4 | int len = 0; 5 | while(str[len] != '\0') { 6 | len++; 7 | } 8 | return len; 9 | } 10 | 11 | int strcmp(const char *str1, const char *str2) { 12 | while(*str1 && (*str1 == *str2)) { 13 | str1++; 14 | str2++; 15 | } 16 | return *(const char*)str1 - *(const char *)str2; 17 | } 18 | -------------------------------------------------------------------------------- /src/string.h: -------------------------------------------------------------------------------- 1 | #ifndef __STRING_H__ 2 | #define __STRING_H__ 3 | 4 | int strlen(const char *str); 5 | int strcmp(const char *str1, const char *str2); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/strings.h: -------------------------------------------------------------------------------- 1 | #include "vga.h" 2 | #include "stdint.h" 3 | #include "keyboard.h" 4 | 5 | 6 | int comp(const char *first, const char *second) { 7 | uint8_t i = 0; 8 | uint8_t j = 0; 9 | while(first[i] != '\0') { 10 | i++; 11 | } 12 | while(second[j] != '\0') { 13 | if(second[j] != first[j]) { 14 | return 0; 15 | } 16 | j++; 17 | } 18 | if(i == j) { 19 | return 1; 20 | } 21 | else { 22 | return 0; 23 | } 24 | 25 | } 26 | 27 | void splitter(const char *tex) { 28 | } 29 | -------------------------------------------------------------------------------- /src/timer.c: -------------------------------------------------------------------------------- 1 | #include "stdint.h" 2 | #include "util.h" 3 | #include "idt.h" 4 | #include "vga.h" 5 | #include "timer.h" 6 | 7 | uint64_t ticks; 8 | const uint32_t freq = 100; 9 | 10 | void onIrq0(struct InterruptRegisters *regs){ 11 | ticks += 1; 12 | } 13 | 14 | void initTimer(){ 15 | ticks = 0; 16 | irq_install_handler(0,&onIrq0); 17 | 18 | //119318.16666 Mhz 19 | uint32_t divisor = 1193180/freq; 20 | 21 | //0011 0110 22 | outPortB(0x43,0x36); 23 | outPortB(0x40,(uint8_t)(divisor & 0xFF)); 24 | outPortB(0x40,(uint8_t)((divisor >> 8) & 0xFF)); 25 | } 26 | -------------------------------------------------------------------------------- /src/timer.h: -------------------------------------------------------------------------------- 1 | void initTimer(); 2 | void onIrq0(struct InterruptRegisters *regs); -------------------------------------------------------------------------------- /src/util.c: -------------------------------------------------------------------------------- 1 | #include "stdint.h" 2 | #include "util.h" 3 | 4 | void memset(void *dest, char val, uint32_t count){ 5 | char *temp = (char*) dest; 6 | for (; count != 0; count --){ 7 | *temp++ = val; 8 | } 9 | 10 | } 11 | 12 | void outPortB(uint16_t Port, uint8_t Value){ 13 | asm volatile ("outb %1, %0" : : "dN" (Port), "a" (Value)); 14 | } 15 | 16 | char inPortB(uint16_t port){ 17 | char rv; 18 | asm volatile("inb %1, %0": "=a"(rv):"dN"(port)); 19 | return rv; 20 | } -------------------------------------------------------------------------------- /src/util.h: -------------------------------------------------------------------------------- 1 | #include "stdint.h" 2 | 3 | void memset(void *dest, char val, uint32_t count); 4 | void outPortB(uint16_t Port, uint8_t Value); 5 | char inPortB(uint16_t port); 6 | 7 | #define CEIL_DIV(a,b) (((a + b) - 1)/b) 8 | 9 | struct InterruptRegisters{ 10 | uint32_t cr2; 11 | uint32_t ds; 12 | uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; 13 | uint32_t int_no, err_code; 14 | uint32_t eip, csm, eflags, useresp, ss; 15 | }; 16 | -------------------------------------------------------------------------------- /src/vfs.c: -------------------------------------------------------------------------------- 1 | #include "stdint.h" 2 | #include "vfs.h" 3 | #include "malloc.h" 4 | #include "string.h" 5 | #include "vga.h" 6 | 7 | VFS vfsr; 8 | 9 | void init_vfs(VFS *vfs) { 10 | vfs->file_count = 0; 11 | } 12 | 13 | void create_file(VFS *vfs, const char *filename, const char *data) 14 | { 15 | File *file = &vfs->files[vfs->file_count]; 16 | int name_len = strlen(filename); 17 | int data_len = strlen(data); 18 | memcpy(file->name, filename, name_len+1); 19 | memcpy(file->data, data, data_len+1); 20 | file->size = data_len; 21 | vfs->file_count++; 22 | } 23 | 24 | const char* read_file(VFS *vfs, const char* filename) { 25 | for(int i=0;ifile_count;i++) { 26 | if(strcmp(vfs->files[i].name, filename) == 0) { 27 | return vfs->files[i].data; 28 | } 29 | } 30 | return "notp"; 31 | } 32 | 33 | void delete_file(VFS *vfs, const char *filename) { 34 | File replacement; 35 | for(int i=0;ifile_count;i++) { 36 | if(strcmp(vfs->files[i].name, filename) == 0) { 37 | vfs->files[i] = replacement; 38 | vfs->file_count--; 39 | } 40 | } 41 | } 42 | 43 | void print_vfs(VFS *vfs) { 44 | for(int i=0;ifile_count;i++) { 45 | print(vfs->files[i].name); 46 | print(" "); 47 | } 48 | } 49 | 50 | void init() { 51 | init_vfs(&vfsr); 52 | } 53 | void create(const char *filename, const char *data) { 54 | create_file(&vfsr, filename, data); 55 | } 56 | const char *read(const char *filename) { 57 | return read_file(&vfsr, filename); 58 | } 59 | void delete(const char *filename) { 60 | delete_file(&vfsr, filename); 61 | } 62 | void printfs() { 63 | print_vfs(&vfsr); 64 | } 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/vfs.h: -------------------------------------------------------------------------------- 1 | #ifndef __VFS_H__ 2 | #define __VFS_H__ 3 | 4 | #define MAX_FILES 100 5 | #define MAX_FILE_SIZE 1024 6 | #define MAX_FILE_NAME 32 7 | 8 | 9 | typedef struct { 10 | char name[MAX_FILE_NAME]; 11 | char data[MAX_FILE_SIZE]; 12 | unsigned int size; 13 | } File; 14 | 15 | typedef struct { 16 | File files[MAX_FILES]; 17 | int file_count; 18 | } VFS; 19 | 20 | 21 | void init(); 22 | void create(const char *filename, const char *data); 23 | const char *read(const char *filename); 24 | void delete(const char *filename); 25 | void printfs(); 26 | void print_vfs(VFS *vfs); 27 | void init_vfs(VFS *vfs); 28 | void create_file(VFS *vfs,const char *filename, const char *data); 29 | const char *read_file(VFS *vfs,const char *filename); 30 | void delete_file(VFS *vfs,const char * filename); 31 | #endif 32 | -------------------------------------------------------------------------------- /src/vga.c: -------------------------------------------------------------------------------- 1 | #include "vga.h" 2 | #include "stdint.h" 3 | 4 | uint16_t column = 0; 5 | uint16_t line = 0; 6 | uint16_t* const vga = (uint16_t* const) 0xC00B8000; 7 | const uint16_t defaultColor = (COLOR8_WHITE << 8)|(COLOR8_BROWN << 12); 8 | uint16_t currentColor = defaultColor; 9 | 10 | void Reset(){ 11 | line = 0; 12 | column = 0; 13 | currentColor = defaultColor; 14 | 15 | for (uint16_t y = 0; y < height; y++){ 16 | for (uint16_t x = 0; x < width; x++){ 17 | vga[y * width + x] = ' ' | defaultColor; 18 | } 19 | } 20 | } 21 | 22 | void newLine(){ 23 | if (line < height - 1){ 24 | line++; 25 | column = 0; 26 | } 27 | else{ 28 | scrollUp(); 29 | column = 0; 30 | } 31 | } 32 | 33 | void scrollUp(){ 34 | for (uint16_t y = 0; y < height; y++){ 35 | for (uint16_t x = 0; x < width; x++){ 36 | vga[(y-1) * width + x] = vga[y*width+x]; 37 | } 38 | } 39 | 40 | for (uint16_t x = 0; x < width; x++){ 41 | vga[(height-1) * width + x] = ' ' | currentColor; 42 | } 43 | } 44 | 45 | void print(const char* s){ 46 | while(*s){ 47 | switch(*s){ 48 | case '\n': 49 | newLine(); 50 | break; 51 | case '\r': 52 | column = 0; 53 | break; 54 | case '\b': 55 | if(column == 8) { 56 | vga[line * width + (++column)] = ' ' | currentColor; 57 | break; 58 | } 59 | if (column == 0 && line != 0){ 60 | line--; 61 | column = width; 62 | } 63 | vga[line * width + (--column)] = ' ' | currentColor; 64 | break; 65 | case '\t': 66 | if (column == width){ 67 | newLine(); 68 | } 69 | uint16_t tabLen = 4 - (column % 4); 70 | while (tabLen != 0){ 71 | vga[line * width + (column++)] = ' ' | currentColor; 72 | tabLen--; 73 | } 74 | break; 75 | default: 76 | if (column == width){ 77 | newLine(); 78 | } 79 | 80 | vga[line * width + (column++)] = *s | currentColor; 81 | break; 82 | } 83 | s++; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/vga.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #define COLOR8_BLACK 0 5 | #define COLOR8_BLUE 1 6 | #define COLOR8_GREEN 2 7 | #define COLOR8_CYAN 3 8 | #define COLOR8_RED 4 9 | #define COLOR8_MAGENTA 5 10 | #define COLOR8_BROWN 6 11 | #define COLOR8_LIGHT_GREY 7 12 | #define COLOR8_DARK_GREY 8 13 | #define COLOR8_LIGHT_BLUE 9 14 | #define COLOR8_LIGHT_GREEN 10 15 | #define COLOR8_LIGHT_CYAN 11 16 | #define COLOR8_LIGHT_RED 12 17 | #define COLOR8_LIGHT_MAGENTA 13 18 | #define COLOR8_LIGHT_BROWN 14 19 | #define COLOR8_WHITE 15 20 | 21 | #define width 80 22 | #define height 25 23 | 24 | void print(const char* s); 25 | void scrollUp(); 26 | void newLine(); 27 | void Reset(); 28 | --------------------------------------------------------------------------------