├── .gitattributes ├── .gitignore ├── README.md ├── boot.asm ├── buildos.bat ├── include ├── common.c ├── common.h ├── error.c ├── error.h ├── fat.c ├── fat.h ├── gdt.c ├── gdt.h ├── idt.c ├── idt.h ├── irq.c ├── irq.h ├── isr.c ├── isr.h ├── kbd.c ├── kbd.h ├── screencontroller.c ├── screencontroller.h ├── shell.c ├── shell.h ├── timer.c ├── timer.h ├── vga.c └── vga.h ├── kernel.c ├── linker.ld ├── os_image.bin └── run.bat /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear on external disk 35 | .Spotlight-V100 36 | .Trashes 37 | 38 | # Directories potentially created on remote AFP share 39 | .AppleDB 40 | .AppleDesktop 41 | Network Trash Folder 42 | Temporary Items 43 | .apdisk 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # This has been succeeded by [codeOS2](http://github.com/aaron-sonin/codeOS2). 2 | ## CodeOS 3 | An operating system made completely from scratch by me. (Not linux) Requires grub. 4 | 5 | The file you want to add to grub is OS_IMAGE.bin. 6 | -------------------------------------------------------------------------------- /boot.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; boot.s -- Kernel start location. Also defines multiboot header. 3 | ; Based on Bran's kernel development tutorial file start.asm 4 | ; 5 | 6 | MBOOT_PAGE_ALIGN equ 1<<0 ; Load kernel and modules on a page boundary 7 | MBOOT_MEM_INFO equ 1<<1 ; Provide your kernel with memory info 8 | MBOOT_HEADER_MAGIC equ 0x1BADB002 ; Multiboot Magic value 9 | ; NOTE: We do not use MBOOT_AOUT_KLUDGE. It means that GRUB does not 10 | ; pass us a symbol table. 11 | MBOOT_HEADER_FLAGS equ MBOOT_PAGE_ALIGN | MBOOT_MEM_INFO 12 | MBOOT_CHECKSUM equ -(MBOOT_HEADER_MAGIC + MBOOT_HEADER_FLAGS) 13 | 14 | 15 | [BITS 32] 16 | 17 | [GLOBAL mboot] 18 | [EXTERN code] 19 | [EXTERN bss] 20 | [EXTERN end] 21 | 22 | mboot: 23 | dd MBOOT_HEADER_MAGIC 24 | dd MBOOT_HEADER_FLAGS 25 | dd MBOOT_CHECKSUM 26 | dd mboot 27 | dd code 28 | dd bss 29 | dd end 30 | dd start 31 | 32 | [GLOBAL start] 33 | [EXTERN main] 34 | 35 | start: 36 | push ebx 37 | cli 38 | call main 39 | jmp $ 40 | 41 | global gdt_flush 42 | extern gp 43 | gdt_flush: 44 | lgdt [gp] ; Load the GDT with our '_gp' which is a special pointer 45 | mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment 46 | mov ds, ax 47 | mov es, ax 48 | mov fs, ax 49 | mov gs, ax 50 | mov ss, ax 51 | jmp 0x08:flush2 ; 0x08 is the offset to our code segment: Far jump! 52 | flush2: 53 | ret ; Returns back to the C code! 54 | 55 | global idt_load 56 | extern idtp 57 | idt_load: 58 | lidt [idtp] 59 | ret 60 | 61 | global isr0 62 | global isr1 63 | global isr2 64 | global isr3 65 | global isr4 66 | global isr5 67 | global isr6 68 | global isr7 69 | global isr8 70 | global isr9 71 | global isr10 72 | global isr11 73 | global isr12 74 | global isr13 75 | global isr14 76 | global isr15 77 | global isr16 78 | global isr17 79 | global isr18 80 | global isr19 81 | global isr20 82 | global isr21 83 | global isr22 84 | global isr23 85 | global isr24 86 | global isr25 87 | global isr26 88 | global isr27 89 | global isr28 90 | global isr29 91 | global isr30 92 | global isr31 93 | 94 | %macro ISR_NOCODE 1 95 | isr%1: 96 | cli 97 | push byte 0 98 | push byte %1 99 | jmp isr_common_stub 100 | %endmacro 101 | 102 | %macro ISR_CODE 1 103 | isr%1: 104 | cli 105 | push byte %1 106 | jmp isr_common_stub 107 | %endmacro 108 | 109 | 110 | ;Divide By Zero Exception 111 | ISR_NOCODE 0 112 | 113 | ;Debug Exception 114 | ISR_NOCODE 1 115 | 116 | ;Non Maskable Interrrupt Exception 117 | ISR_NOCODE 2 118 | 119 | ;Breakpoint Exception 120 | ISR_NOCODE 3 121 | 122 | ;Into Detected Overflow Exception 123 | ISR_NOCODE 4 124 | 125 | ;Out of Bounds Exception 126 | ISR_NOCODE 5 127 | 128 | ;Invalid Opcode Exception 129 | ISR_NOCODE 6 130 | 131 | ;No Coprocessor Exception 132 | ISR_NOCODE 7 133 | 134 | ;Double Fault Exception 135 | ISR_CODE 8 136 | 137 | ;Coprocessor Segment Overrun Exception 138 | ISR_NOCODE 9 139 | 140 | ;Bad TSS Exception 141 | ISR_CODE 10 142 | 143 | ;Segment Not Present Exception 144 | ISR_CODE 11 145 | 146 | ;Stack Fault Exception 147 | ISR_CODE 12 148 | 149 | ;General Protection Fault Exception 150 | ISR_CODE 13 151 | 152 | ;Page Fault Exception 153 | ISR_CODE 14 154 | 155 | ;Unknown Interrupt Exception 156 | ISR_NOCODE 15 157 | 158 | ;Coprocessor Fault Exception 159 | ISR_NOCODE 16 160 | 161 | ;Alignment Check Exception 162 | ISR_NOCODE 17 163 | 164 | ;Machine Check Exception 165 | ISR_NOCODE 18 166 | 167 | ;Reserved 168 | ISR_NOCODE 19 169 | 170 | ;Reserved 171 | ISR_NOCODE 20 172 | 173 | ;Reserved 174 | ISR_NOCODE 21 175 | 176 | ;Reserved 177 | ISR_NOCODE 22 178 | 179 | ;Reserved 180 | ISR_NOCODE 23 181 | 182 | ;Reserved 183 | ISR_NOCODE 24 184 | 185 | ;Reserved 186 | ISR_NOCODE 25 187 | 188 | ;Reserved 189 | ISR_NOCODE 26 190 | 191 | ;Reserved 192 | ISR_NOCODE 27 193 | 194 | ;Reserved 195 | ISR_NOCODE 28 196 | 197 | ;Reserved 198 | ISR_NOCODE 29 199 | 200 | ;Reserved 201 | ISR_NOCODE 30 202 | 203 | ;Reserved 204 | ISR_NOCODE 31 205 | 206 | extern fault_handler 207 | isr_common_stub: 208 | pusha 209 | push ds 210 | push es 211 | push fs 212 | push gs 213 | mov ax, 0x10 ; Load the Kernel Data Segment descriptor! 214 | mov ds, ax 215 | mov es, ax 216 | mov fs, ax 217 | mov gs, ax 218 | mov eax, esp ; Push us the stack 219 | push eax 220 | mov eax, fault_handler 221 | call eax ; A special call, preserves the 'eip' register 222 | pop eax 223 | pop gs 224 | pop fs 225 | pop es 226 | pop ds 227 | popa 228 | add esp, 8 ; Cleans up the pushed error code and pushed ISR number 229 | iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP! 230 | 231 | global irq0 232 | global irq1 233 | global irq2 234 | global irq3 235 | global irq4 236 | global irq5 237 | global irq6 238 | global irq7 239 | global irq8 240 | global irq9 241 | global irq10 242 | global irq11 243 | global irq12 244 | global irq13 245 | global irq14 246 | global irq15 247 | 248 | %macro make_irq 1 249 | irq%1: 250 | cli 251 | push byte 0 252 | push byte %1+32 253 | jmp irq_common_stub 254 | %endmacro 255 | 256 | make_irq 0 257 | make_irq 1 258 | make_irq 2 259 | make_irq 3 260 | make_irq 4 261 | make_irq 5 262 | make_irq 6 263 | make_irq 7 264 | make_irq 8 265 | make_irq 9 266 | make_irq 10 267 | make_irq 11 268 | make_irq 12 269 | make_irq 13 270 | make_irq 14 271 | make_irq 15 272 | 273 | extern irq_handler 274 | 275 | ; This is a stub that we have created for IRQ based ISRs. This calls 276 | ; '_irq_handler' in our C code. We need to create this in an 'irq.c' 277 | irq_common_stub: 278 | pusha 279 | push ds 280 | push es 281 | push fs 282 | push gs 283 | mov ax, 0x10 284 | mov ds, ax 285 | mov es, ax 286 | mov fs, ax 287 | mov gs, ax 288 | mov eax, esp 289 | push eax 290 | mov eax, irq_handler 291 | call eax 292 | pop eax 293 | pop gs 294 | pop fs 295 | pop es 296 | pop ds 297 | popa 298 | add esp, 8 299 | iret -------------------------------------------------------------------------------- /buildos.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | del "os_image.bin" 2>NUL 1>NUL 3 | echo building boot... 4 | nasm -felf32 boot.asm -o boot.o 5 | echo building kernel... 6 | i686-elf-gcc -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra -Wno-unused-parameter 7 | echo building common... 8 | i686-elf-gcc -c include/common.c -o common.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra -Wno-unused-parameter 9 | echo building vga... 10 | i686-elf-gcc -c include/vga.c -o vga.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra -Wno-unused-parameter 11 | echo building error... 12 | i686-elf-gcc -c include/error.c -o error.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra -Wno-unused-parameter 13 | echo building screencontroller... 14 | i686-elf-gcc -c include/screencontroller.c -o screencontroller.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra -Wno-unused-parameter 15 | echo building gdt... 16 | i686-elf-gcc -c include/gdt.c -o gdt.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra -Wno-unused-parameter 17 | echo building idt... 18 | i686-elf-gcc -c include/idt.c -o idt.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra -Wno-unused-parameter 19 | echo building isr... 20 | i686-elf-gcc -c include/isr.c -o isr.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra -Wno-unused-parameter 21 | echo building irq... 22 | i686-elf-gcc -c include/irq.c -o irq.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra -Wno-unused-parameter 23 | echo building kbd... 24 | i686-elf-gcc -c include/kbd.c -o kbd.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra -Wno-unused-parameter 25 | echo building timer... 26 | i686-elf-gcc -c include/timer.c -o timer.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra -Wno-unused-parameter 27 | echo building shell... 28 | i686-elf-gcc -c include/shell.c -o shell.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra -Wno-unused-parameter 29 | echo building fat... 30 | i686-elf-gcc -c include/fat.c -o fat.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra -Wno-unused-parameter 31 | echo linking... 32 | i686-elf-gcc -T linker.ld -o os_image.bin -ffreestanding -O2 -nostdlib boot.o kernel.o fat.o shell.o kbd.o timer.o irq.o isr.o idt.o gdt.o error.o vga.o common.o screencontroller.o -lgcc -std=gnu99 -Wno-unused-parameter 33 | copy os_image.bin boot 2>NUL 1>NUL 34 | cd boot 2>NUL 1>NUL 35 | del CodeOSKernel 2>NUL 1>NUL 36 | rename "os_image.bin" "CodeOSKernel" 2>NUL 1>NUL 37 | cd .. 2>NUL 1>NUL 38 | if exist "os_image.bin" ( 39 | COLOR 02 40 | echo BUILD SUCCEEDED 41 | ) else ( 42 | COLOR 0C 43 | echo BUILD FAILED 44 | ) 45 | del *.o 2>NUL 1>NUL 46 | PAUSE -------------------------------------------------------------------------------- /include/common.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | // Write a byte out to the specified port. 4 | void outb(u16int port, u8int value) 5 | { 6 | asm volatile ("outb %1, %0" : : "dN" (port), "a" (value)); 7 | } 8 | 9 | u8int inb(u16int port) 10 | { 11 | u8int ret; 12 | asm volatile("inb %1, %0" : "=a" (ret) : "dN" (port)); 13 | return ret; 14 | } 15 | 16 | u16int inw(u16int port) 17 | { 18 | u16int ret; 19 | asm volatile ("inw %1, %0" : "=a" (ret) : "dN" (port)); 20 | return ret; 21 | } 22 | 23 | void *memcpy(void *dest, const void *src, int count) 24 | { 25 | const char *sp = (const char *)src; 26 | char *dp = (char *)dest; 27 | for(; count != 0; count--) *dp++ = *sp++; 28 | return dest; 29 | } 30 | 31 | void *memset(void *dest, char val, int count) 32 | { 33 | char *temp = (char *)dest; 34 | for( ; count != 0; count--) *temp++ = val; 35 | return dest; 36 | } 37 | 38 | unsigned short *memsetw(unsigned short *dest, unsigned short val, int count) 39 | { 40 | unsigned short *temp = (unsigned short *)dest; 41 | for( ; count != 0; count--) *temp++ = val; 42 | return dest; 43 | } 44 | 45 | int strlen(const char *str) 46 | { 47 | int retval; 48 | for(retval = 0; *str != '\0'; str++) retval++; 49 | return retval; 50 | } 51 | 52 | int strcmp(string str1,string str2){ 53 | int i=0,flag=0; 54 | 55 | while(str1[i]!='\0' && str2[i]!='\0'){ 56 | if(str1[i]!=str2[i]){ 57 | flag=1; 58 | break; 59 | } 60 | i++; 61 | } 62 | 63 | if (flag==0 && str1[i]=='\0' && str2[i]=='\0') 64 | return 1; 65 | else 66 | return 0; 67 | 68 | } 69 | 70 | void concat(string a, string b, string c){ 71 | int len = strlen(a)+strlen(b); 72 | int i = 0; 73 | while(i < strlen(a)){ 74 | c[i] = a[i]; 75 | i++; 76 | } 77 | i = 0; 78 | while(i < strlen(b)){ 79 | c[i+strlen(a)] = b[i]; 80 | i++; 81 | } 82 | c[len] = '\0'; 83 | } 84 | 85 | void concatc(string a, char b, string c){ 86 | int len = strlen(a)+1; 87 | int i = 0; 88 | while(i < strlen(a)){ 89 | c[i] = a[i]; 90 | i++; 91 | } 92 | c[i] = b; 93 | c[len] = '\0'; 94 | } 95 | 96 | void remchar(string a, string b){ 97 | int i = 0; 98 | while(i < strlen(a)-1){ 99 | b[i] = a[i]; 100 | i++; 101 | } 102 | b[i] = '\0'; 103 | } 104 | 105 | int toHex(char c){ 106 | if(c == '0'){ 107 | return 0x0; 108 | }if(c == '1'){ 109 | return 0x1; 110 | }if(c == '2'){ 111 | return 0x2; 112 | }if(c == '3'){ 113 | return 0x3; 114 | }if(c == '4'){ 115 | return 0x4; 116 | }if(c == '5'){ 117 | return 0x5; 118 | }if(c == '6'){ 119 | return 0x6; 120 | }if(c == '7'){ 121 | return 0x7; 122 | }if(c == '8'){ 123 | return 0x8; 124 | }if(c == '9'){ 125 | return 0x9; 126 | }if(c == 'a' || c == 'A'){ 127 | return 0xa; 128 | }if(c == 'b' || c == 'B'){ 129 | return 0xb; 130 | }if(c == 'c' || c == 'C'){ 131 | return 0xc; 132 | }if(c == 'd' || c == 'D'){ 133 | return 0xd; 134 | }if(c == 'e' || c == 'E'){ 135 | return 0xe; 136 | }if(c == 'f' || c == 'F'){ 137 | return 0xf; 138 | } 139 | return -1; 140 | } 141 | 142 | int strncmp(string a, string b, int l){ 143 | int c = 0; 144 | 145 | while (a[c] == b[c] && c < l) { 146 | c++; 147 | } 148 | 149 | if (c == l) 150 | return 1; 151 | else 152 | return 0; 153 | } 154 | 155 | int startswith(string a, string b){ 156 | return strncmp(a,b,strlen(b)); 157 | } 158 | 159 | void preparedisk(int disk, int addr){ 160 | outb(0x1F1,0x00); 161 | outb(0x1F2,0x01); 162 | outb(0x1F3,(unsigned char)addr); 163 | outb(0x1F4,(unsigned char)(addr >> 8)); 164 | outb(0x1F5,(unsigned char)(addr >> 16)); 165 | outb(0x1F6,0xE0 | (disk << 4) | ((addr >> 24) & 0x0F)); 166 | outb(0x1F7,0x20); 167 | while (!(inb(0x1F7) & 0x08)) {} 168 | } 169 | 170 | void strcpy(char a[], char b[]){ 171 | for(int i = 0; i < strlen(a); i++){ 172 | b[i] = a[i]; 173 | } 174 | } 175 | 176 | char tolower(char a){ 177 | if(a >= 'A' && a <= 'Z') 178 | return a+32; 179 | return a; 180 | } 181 | 182 | void strtolower(char a[], char b[]){ 183 | for(int i = 0; i < strlen(a); i++){ 184 | b[i] = tolower(a[i]); 185 | } 186 | } 187 | 188 | void substring(char a[], char b[], int index){ 189 | int i = index; 190 | while(i < strlen(a)){ 191 | b[i-index] = a[i]; 192 | i++; 193 | } 194 | b[i-index] = '\0'; 195 | } -------------------------------------------------------------------------------- /include/common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H 2 | #define COMMON_H 3 | typedef unsigned int u32int; 4 | typedef int s32int; 5 | typedef unsigned short u16int; 6 | typedef short s16int; 7 | typedef unsigned char u8int; 8 | typedef char s8int; 9 | typedef char *string; 10 | 11 | void outb(u16int port, u8int value); 12 | u8int inb(u16int port); 13 | u16int inw(u16int port); 14 | void *memcpy(void *dest, const void *src, int count); 15 | void *memset(void *dest, char val, int count); 16 | unsigned short *memsetw(unsigned short *dest, unsigned short val, int count); 17 | int strlen(const char *str); 18 | int strcmp(string str1,string str2); 19 | void concat(string a, string b, string c); 20 | void concatc(string a, char b, string c); 21 | void remchar(string a, string b); 22 | int toHex(char a); 23 | int strncmp(string a, string b, int l); 24 | int startswith(string a, string b); 25 | void preparedisk(int disk, int addr); 26 | void strcpy(char a[], char b[]); 27 | char tolower(char a); 28 | void strtolower(char a[], char b[]); 29 | void substring(char a[], char b[], int index); 30 | #endif -------------------------------------------------------------------------------- /include/error.c: -------------------------------------------------------------------------------- 1 | #include "error.h" 2 | 3 | void bsod(int error){ 4 | clear_screen(0x1f); 5 | center_print("***CODEOS ERROR***",0x1f); 6 | printf("CodeOS Encountered an error and needed to stop your computer.",0x1f); 7 | printf("\n\nError Code:",0x1f); 8 | printInt(error,0x1f); 9 | for(;;); 10 | } 11 | 12 | void bsodmsg(string message){ 13 | clear_screen(0x1f); 14 | center_print("***CODEOS ERROR***",0x1f); 15 | printf("CodeOS Encountered an error and needed to stop your computer.",0x1f); 16 | printf("\n\nError Code: ",0x1f); 17 | printf(message,0x1f); 18 | for(;;); 19 | } -------------------------------------------------------------------------------- /include/error.h: -------------------------------------------------------------------------------- 1 | #ifndef ERROR_H 2 | #define ERROR_H 3 | #include "vga.h" 4 | 5 | void bsod(int error); 6 | 7 | void bsodmsg(string message); 8 | 9 | #endif -------------------------------------------------------------------------------- /include/fat.c: -------------------------------------------------------------------------------- 1 | #include "fat.h" 2 | void listFiles(int disk, int addr, int len){ 3 | int listed = 0; 4 | for(int s = 0; s < len; s++){ 5 | preparedisk(disk,addr+s); 6 | unsigned char sect[512]; 7 | for(int i = 0; i < 255; i++){ 8 | u16int tmpword = (u16int)inw(0x1F0); 9 | sect[i*2] = ((unsigned char)(tmpword)); 10 | sect[i*2+1] = ((unsigned char)(tmpword >> 8)); 11 | } 12 | for(int i = 0; i < 512; i+=32){ 13 | if(sect[i+11] != 0x0f && sect[i] != 0xe5 && sect[i+11] != 0x08 && sect[i] != 0){ 14 | if(listed == 23){ 15 | println("Press any key to continue..."); 16 | pause(); 17 | listed = 0; 18 | } 19 | listed++; 20 | for(int j = 0; j < 11; j++){ 21 | if(sect[i+j] != 0x20){ 22 | printchar(sect[i+j]); 23 | } 24 | if(j == 7 && (sect[i+11] >> 4) != 0x1){ 25 | printchar('.'); 26 | } 27 | } 28 | if((sect[i+11] >> 4) == 0x1){ 29 | print(" "); 30 | } 31 | println(""); 32 | } 33 | } 34 | } 35 | } 36 | 37 | int isDir(int disk, int addr, int len, string name){ 38 | string namebuf = " "; 39 | for(int s = 0; s < len; s++){ 40 | preparedisk(disk,addr+s); 41 | unsigned char sect[512]; 42 | for(int i = 0; i < 255; i++){ 43 | u16int tmpword = (u16int)inw(0x1F0); 44 | sect[i*2] = ((unsigned char)(tmpword)); 45 | sect[i*2+1] = ((unsigned char)(tmpword >> 8)); 46 | } 47 | for(int i = 0; i < 512; i+=32){ 48 | if(sect[i+11] != 0x0f && sect[i] != 0xe5 && sect[i+11] != 0x08){ 49 | int k = 0; 50 | for(int j = 0; j < 11; j++){ 51 | if(sect[i+j] != 0x20){ 52 | namebuf[k] = sect[i+j]; 53 | k++; 54 | } 55 | if(j == 7 && (sect[i+11] >> 4) != 0x1){ 56 | namebuf[k] = '.'; 57 | k++; 58 | } 59 | } 60 | namebuf[k] = '\0'; 61 | strtolower(name,name); 62 | strtolower(namebuf,namebuf); 63 | if(strcmp(namebuf,name) && (sect[i+11] >> 4) == 0x1){ 64 | return 1; 65 | } 66 | } 67 | } 68 | } 69 | return 0; 70 | } 71 | 72 | int getFile(int disk, int addr, int len, string name){ 73 | int spc = getClusterSize(disk); 74 | int re = getRootEntries(disk); 75 | int root = getRoot(disk); 76 | string namebuf = " "; 77 | for(int s = 0; s < len; s++){ 78 | preparedisk(disk,addr+s); 79 | unsigned char sect[512]; 80 | for(int i = 0; i < 255; i++){ 81 | u16int tmpword = (u16int)inw(0x1F0); 82 | sect[i*2] = ((unsigned char)(tmpword)); 83 | sect[i*2+1] = ((unsigned char)(tmpword >> 8)); 84 | } 85 | for(int i = 0; i < 512; i+=32){ 86 | if(sect[i+11] != 0x0f && sect[i] != 0xe5 && sect[i+11] != 0x08){ 87 | int k = 0; 88 | for(int j = 0; j < 11; j++){ 89 | if(sect[i+j] != 0x20){ 90 | namebuf[k] = sect[i+j]; 91 | k++; 92 | } 93 | if(j == 7 && (sect[i+11] >> 4) != 0x1){ 94 | namebuf[k] = '.'; 95 | k++; 96 | } 97 | } 98 | namebuf[k] = '\0'; 99 | strtolower(name,name); 100 | strtolower(namebuf,namebuf); 101 | if(strcmp(name,namebuf)){ 102 | int cluster = (((int)sect[i+27] << 8)+sect[i+26])-2; 103 | if(cluster < 0){ 104 | return getRoot(disk); 105 | } 106 | return (spc*cluster)+root+((re*32)/512); 107 | } 108 | } 109 | } 110 | } 111 | return -1; 112 | } 113 | 114 | int getRoot(int disk){ 115 | int pos = getFirstPart(disk); 116 | preparedisk(0,pos); 117 | int rsects = 0; 118 | int fats = 0; 119 | int size = 0; 120 | for(int i = 0; i < 255; i++){ 121 | u16int tmpword = (u16int)inw(0x1F0); 122 | if(i == 0x7){ 123 | rsects = (char)(tmpword); 124 | } 125 | if(i == 0x8){ 126 | fats = (char)(tmpword); 127 | } 128 | if(i == 0xb){ 129 | size = tmpword; 130 | } 131 | } 132 | return fats*size+rsects+pos; 133 | } 134 | 135 | int getFirstPart(int disk){ 136 | preparedisk(disk,0); 137 | u16int pos = 0; 138 | for(int i = 0; i <= 255; i++){ 139 | u16int tmpword = (u16int)inw(0x1F0); 140 | if(i == 227){ 141 | pos = tmpword; 142 | } 143 | } 144 | return pos; 145 | } 146 | 147 | int getClusterSize(int disk){ 148 | preparedisk(disk,getFirstPart(disk)); 149 | for(int i = 0; i < 255; i++){ 150 | u16int tmpword = (u16int)inw(0x1F0); 151 | if(i == 0x6){ 152 | return (unsigned char)tmpword; 153 | } 154 | } 155 | return -1; 156 | } 157 | 158 | int getRootEntries(int disk){ 159 | preparedisk(disk,getFirstPart(disk)); 160 | int a = 0; 161 | int b = 0; 162 | for(int i = 0; i < 255; i++){ 163 | u16int tmpword = (u16int)inw(0x1F0); 164 | if(i == 0x8){ 165 | a = tmpword >> 8; 166 | } 167 | if(i == 0x9){ 168 | b = tmpword << 8; 169 | } 170 | } 171 | return a+b; 172 | } 173 | 174 | int getDirLength(int disk, int addr){ 175 | int len = 1; 176 | while(1 == 1){ 177 | preparedisk(disk,addr+len); 178 | unsigned char sect[512]; 179 | for(int i = 0; i < 255; i++){ 180 | u16int tmpword = (u16int)inw(0x1F0); 181 | sect[i*2] = ((unsigned char)(tmpword)); 182 | sect[i*2+1] = ((unsigned char)(tmpword >> 8)); 183 | } 184 | int entriesGood = 16; 185 | int allzero = 0; 186 | for(int i = 0; i < 512; i+=32){ 187 | if(i > 0 && sect[i] == (unsigned char)'.' && sect[i+11] == 0x10){ 188 | return len; 189 | } 190 | if(sect[i+11] != 0x0f){ 191 | if(((sect[i+11] & ( 1 << 6 )) >> 6) == 1){ 192 | entriesGood--; 193 | } 194 | } 195 | if(sect[i+11] == (unsigned char)0){ 196 | if(sect[i+12] != (unsigned char)0 && sect[i+10] != (unsigned char)0){ 197 | entriesGood--; 198 | } 199 | else if(sect[i+12] == (unsigned char)0 && sect[i+10] == (unsigned char)0){ 200 | allzero++; 201 | } 202 | } 203 | } 204 | if(entriesGood < 16){ 205 | return len; 206 | } 207 | if(allzero >= 15){ 208 | return len; 209 | } 210 | len++; 211 | } 212 | return len; 213 | } -------------------------------------------------------------------------------- /include/fat.h: -------------------------------------------------------------------------------- 1 | #ifndef FAT_H 2 | #define FAT_H 3 | #include "common.h" 4 | #include "screencontroller.h" 5 | #include "kbd.h" 6 | void listFiles(int disk, int len, int addr); 7 | int getRoot(int disk); 8 | int getFirstPart(int disk); 9 | int isDir(int disk, int addr, int len, string name); 10 | int getClusterSize(int disk); 11 | int getRootEntries(int disk); 12 | int getFile(int disk, int addr, int len, string name); 13 | int getDirLength(int disk, int addr); 14 | #endif -------------------------------------------------------------------------------- /include/gdt.c: -------------------------------------------------------------------------------- 1 | #include "gdt.h" 2 | 3 | struct gdt_entry gdt[3]; 4 | struct gdt_ptr gp; 5 | 6 | extern void gdt_flush(); 7 | 8 | void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran){ 9 | gdt[num].base_low = (base & 0xFFFF); 10 | gdt[num].base_middle = (base >> 16) & 0xFF; 11 | gdt[num].base_high = (base >> 24) & 0xFF; 12 | 13 | gdt[num].limit_low = (limit & 0xFFFF); 14 | gdt[num].granularity = ((limit >> 16) & 0x0F); 15 | 16 | gdt[num].granularity |= (gran & 0xF0); 17 | gdt[num].access = access; 18 | } 19 | 20 | void gdt_install(){ 21 | gp.limit = (sizeof(struct gdt_entry) * 3) - 1; 22 | gp.base = (int)&gdt; 23 | 24 | gdt_set_gate(0, 0, 0, 0, 0); 25 | 26 | gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); 27 | 28 | gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); 29 | 30 | gdt_flush(); 31 | } -------------------------------------------------------------------------------- /include/gdt.h: -------------------------------------------------------------------------------- 1 | #ifndef GDT_H 2 | #define GDT_H 3 | 4 | struct gdt_entry 5 | { 6 | unsigned short limit_low; 7 | unsigned short base_low; 8 | unsigned char base_middle; 9 | unsigned char access; 10 | unsigned char granularity; 11 | unsigned char base_high; 12 | } __attribute__((packed)); 13 | 14 | /* Special pointer which includes the limit: The max bytes 15 | * taken up by the GDT, minus 1. Again, this NEEDS to be packed */ 16 | struct gdt_ptr 17 | { 18 | unsigned short limit; 19 | unsigned int base; 20 | } __attribute__((packed)); 21 | 22 | void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran); 23 | 24 | void gdt_install(); 25 | 26 | #endif -------------------------------------------------------------------------------- /include/idt.c: -------------------------------------------------------------------------------- 1 | #include "idt.h" 2 | 3 | struct idt_entry idt[256]; 4 | struct idt_ptr idtp; 5 | 6 | /* This exists in 'start.asm', and is used to load our IDT */ 7 | extern void idt_load(); 8 | 9 | void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags){ 10 | /* The interrupt routine's base address */ 11 | idt[num].base_lo = (base & 0xFFFF); 12 | idt[num].base_hi = (base >> 16) & 0xFFFF; 13 | 14 | /* The segment or 'selector' that this IDT entry will use 15 | * is set here, along with any access flags */ 16 | idt[num].sel = sel; 17 | idt[num].always0 = 0; 18 | idt[num].flags = flags; 19 | } 20 | 21 | void idt_install() 22 | { 23 | /* Sets the special IDT pointer up, just like in 'gdt.c' */ 24 | idtp.limit = (sizeof (struct idt_entry) * 256) - 1; 25 | idtp.base = (int)&idt; 26 | 27 | /* Clear out the entire IDT, initializing it to zeros */ 28 | memset(&idt, 0, sizeof(struct idt_entry) * 256); 29 | 30 | /* Add any new ISRs to the IDT here using idt_set_gate */ 31 | 32 | /* Points the processor's internal register to the new IDT */ 33 | idt_load(); 34 | } -------------------------------------------------------------------------------- /include/idt.h: -------------------------------------------------------------------------------- 1 | #ifndef IDT_H 2 | #define IDT_H 3 | 4 | #include "common.h" 5 | /* Defines an IDT entry */ 6 | struct idt_entry 7 | { 8 | unsigned short base_lo; 9 | unsigned short sel; /* Our kernel segment goes here! */ 10 | unsigned char always0; /* This will ALWAYS be set to 0! */ 11 | unsigned char flags; /* Set using the above table! */ 12 | unsigned short base_hi; 13 | } __attribute__((packed)); 14 | 15 | struct idt_ptr 16 | { 17 | unsigned short limit; 18 | unsigned int base; 19 | } __attribute__((packed)); 20 | 21 | void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags); 22 | 23 | void idt_install(); 24 | 25 | #endif -------------------------------------------------------------------------------- /include/irq.c: -------------------------------------------------------------------------------- 1 | #include "irq.h" 2 | extern void irq0(); 3 | extern void irq1(); 4 | extern void irq2(); 5 | extern void irq3(); 6 | extern void irq4(); 7 | extern void irq5(); 8 | extern void irq6(); 9 | extern void irq7(); 10 | extern void irq8(); 11 | extern void irq9(); 12 | extern void irq10(); 13 | extern void irq11(); 14 | extern void irq12(); 15 | extern void irq13(); 16 | extern void irq14(); 17 | extern void irq15(); 18 | void *irq_routines[16] ={ 19 | 0, 0, 0, 0, 0, 0, 0, 0, 20 | 0, 0, 0, 0, 0, 0, 0, 0 21 | }; 22 | void irq_install_handler(int irq, void (*handler)(struct regs *r)){ 23 | irq_routines[irq] = handler; 24 | } 25 | void irq_uninstall_handler(int irq){ 26 | irq_routines[irq] = 0; 27 | } 28 | void irq_remap(void){ 29 | outb(0x20, 0x11); 30 | outb(0xA0, 0x11); 31 | outb(0x21, 0x20); 32 | outb(0xA1, 0x28); 33 | outb(0x21, 0x04); 34 | outb(0xA1, 0x02); 35 | outb(0x21, 0x01); 36 | outb(0xA1, 0x01); 37 | outb(0x21, 0x0); 38 | outb(0xA1, 0x0); 39 | } 40 | void irq_install(){ 41 | irq_remap(); 42 | idt_set_gate(32, (unsigned)irq0, 0x08, 0x8E); 43 | idt_set_gate(33, (unsigned)irq1, 0x08, 0x8E); 44 | idt_set_gate(34, (unsigned)irq2, 0x08, 0x8E); 45 | idt_set_gate(35, (unsigned)irq3, 0x08, 0x8E); 46 | idt_set_gate(36, (unsigned)irq4, 0x08, 0x8E); 47 | idt_set_gate(37, (unsigned)irq5, 0x08, 0x8E); 48 | idt_set_gate(38, (unsigned)irq6, 0x08, 0x8E); 49 | idt_set_gate(39, (unsigned)irq7, 0x08, 0x8E); 50 | idt_set_gate(40, (unsigned)irq8, 0x08, 0x8E); 51 | idt_set_gate(41, (unsigned)irq9, 0x08, 0x8E); 52 | idt_set_gate(42, (unsigned)irq10, 0x08, 0x8E); 53 | idt_set_gate(43, (unsigned)irq11, 0x08, 0x8E); 54 | idt_set_gate(44, (unsigned)irq12, 0x08, 0x8E); 55 | idt_set_gate(45, (unsigned)irq13, 0x08, 0x8E); 56 | idt_set_gate(46, (unsigned)irq14, 0x08, 0x8E); 57 | idt_set_gate(47, (unsigned)irq15, 0x08, 0x8E); 58 | } 59 | void irq_handler(struct regs *r){ 60 | /* This is a blank function pointer */ 61 | void (*handler)(struct regs *r); 62 | 63 | /* Find out if we have a custom handler to run for this 64 | * IRQ, and then finally, run it */ 65 | handler = irq_routines[r->int_no - 32]; 66 | if (handler) 67 | { 68 | handler(r); 69 | } 70 | 71 | /* If the IDT entry that was invoked was greater than 40 72 | * (meaning IRQ8 - 15), then we need to send an EOI to 73 | * the slave controller */ 74 | if (r->int_no >= 40) 75 | { 76 | outb(0xA0, 0x20); 77 | } 78 | 79 | /* In either case, we need to send an EOI to the master 80 | * interrupt controller too */ 81 | outb(0x20, 0x20); 82 | } 83 | -------------------------------------------------------------------------------- /include/irq.h: -------------------------------------------------------------------------------- 1 | #ifndef IRQ_H 2 | #define IRQ_H 3 | #include "isr.h" 4 | void irq_install_handler(int irq, void (*handler)(struct regs *r)); 5 | void irq_uninstall_handler(int irq); 6 | void irq_remap(void); 7 | void irq_install(); 8 | void irq_handler(struct regs *r); 9 | #endif -------------------------------------------------------------------------------- /include/isr.c: -------------------------------------------------------------------------------- 1 | #include "isr.h" 2 | extern void isr0(); 3 | extern void isr1(); 4 | extern void isr2(); 5 | extern void isr3(); 6 | extern void isr4(); 7 | extern void isr5(); 8 | extern void isr6(); 9 | extern void isr7(); 10 | extern void isr8(); 11 | extern void isr9(); 12 | extern void isr10(); 13 | extern void isr11(); 14 | extern void isr12(); 15 | extern void isr13(); 16 | extern void isr14(); 17 | extern void isr15(); 18 | extern void isr16(); 19 | extern void isr17(); 20 | extern void isr18(); 21 | extern void isr19(); 22 | extern void isr20(); 23 | extern void isr21(); 24 | extern void isr22(); 25 | extern void isr23(); 26 | extern void isr24(); 27 | extern void isr25(); 28 | extern void isr26(); 29 | extern void isr27(); 30 | extern void isr28(); 31 | extern void isr29(); 32 | extern void isr30(); 33 | extern void isr31(); 34 | char *exception_messages[] = { 35 | "ERR_DIVISION_BY_0", 36 | "ERR_DEBUG", 37 | "ERR_NON_MASKABLE_INTERRUPT", 38 | "ERR_BREAKPOINT", 39 | "ERR_INTO_DETECTED_OVERFLOW", 40 | "ERR_OUT_OF_BOUNDS", 41 | "ERR_INVALID_OPCODE", 42 | "ERR_NO_COPROCESSOR", 43 | "ERR_DOUBLE_FAULT", 44 | "ERR_COPROCESSOR_SEGMENT_OVERRUN", 45 | "ERR_BAD_TSS", 46 | "ERR_SEGMENT_NOT_PRESENT", 47 | "ERR_STACK_FAULT", 48 | "ERR_GENERAL_PROTECTION_FAULT", 49 | "ERR_PAGE_FAULT", 50 | "ERR_UNKNOWN_INTERRUPT", 51 | "ERR_COPROCESSOR_FAULT", 52 | "ERR_ALIGNMENT_CHECK", 53 | "ERR_MACHINE_CHECK", 54 | "ISR HANDLER 19", 55 | "ISR HANDLER 20", 56 | "ISR HANDLER 21", 57 | "ISR HANDLER 22", 58 | "ISR HANDLER 23", 59 | "ISR HANDLER 24", 60 | "ISR HANDLER 25", 61 | "ISR HANDLER 26", 62 | "ISR HANDLER 27", 63 | "ISR HANDLER 28", 64 | "ISR HANDLER 29", 65 | "ISR HANDLER 30", 66 | "ISR HANDLER 31" 67 | }; 68 | void isrs_install(){ 69 | idt_set_gate(0, (unsigned)isr0, 0x08, 0x8E); 70 | idt_set_gate(1, (unsigned)isr1, 0x08, 0x8E); 71 | idt_set_gate(2, (unsigned)isr2, 0x08, 0x8E); 72 | idt_set_gate(3, (unsigned)isr3, 0x08, 0x8E); 73 | idt_set_gate(4, (unsigned)isr4, 0x08, 0x8E); 74 | idt_set_gate(5, (unsigned)isr5, 0x08, 0x8E); 75 | idt_set_gate(6, (unsigned)isr6, 0x08, 0x8E); 76 | idt_set_gate(7, (unsigned)isr7, 0x08, 0x8E); 77 | idt_set_gate(8, (unsigned)isr8, 0x08, 0x8E); 78 | idt_set_gate(9, (unsigned)isr9, 0x08, 0x8E); 79 | idt_set_gate(10, (unsigned)isr10, 0x08, 0x8E); 80 | idt_set_gate(11, (unsigned)isr11, 0x08, 0x8E); 81 | idt_set_gate(12, (unsigned)isr12, 0x08, 0x8E); 82 | idt_set_gate(13, (unsigned)isr13, 0x08, 0x8E); 83 | idt_set_gate(14, (unsigned)isr14, 0x08, 0x8E); 84 | idt_set_gate(15, (unsigned)isr15, 0x08, 0x8E); 85 | idt_set_gate(16, (unsigned)isr16, 0x08, 0x8E); 86 | idt_set_gate(17, (unsigned)isr17, 0x08, 0x8E); 87 | idt_set_gate(18, (unsigned)isr18, 0x08, 0x8E); 88 | idt_set_gate(19, (unsigned)isr19, 0x08, 0x8E); 89 | idt_set_gate(20, (unsigned)isr20, 0x08, 0x8E); 90 | idt_set_gate(21, (unsigned)isr21, 0x08, 0x8E); 91 | idt_set_gate(22, (unsigned)isr22, 0x08, 0x8E); 92 | idt_set_gate(23, (unsigned)isr23, 0x08, 0x8E); 93 | idt_set_gate(24, (unsigned)isr24, 0x08, 0x8E); 94 | idt_set_gate(25, (unsigned)isr25, 0x08, 0x8E); 95 | idt_set_gate(26, (unsigned)isr26, 0x08, 0x8E); 96 | idt_set_gate(27, (unsigned)isr27, 0x08, 0x8E); 97 | idt_set_gate(28, (unsigned)isr28, 0x08, 0x8E); 98 | idt_set_gate(29, (unsigned)isr29, 0x08, 0x8E); 99 | idt_set_gate(30, (unsigned)isr30, 0x08, 0x8E); 100 | idt_set_gate(31, (unsigned)isr31, 0x08, 0x8E); 101 | } 102 | 103 | void fault_handler(struct regs *r) 104 | { 105 | /* Is this a fault whose number is from 0 to 31? */ 106 | if (r->int_no < 32) 107 | { 108 | bsodmsg(exception_messages[r->int_no]); 109 | } 110 | } -------------------------------------------------------------------------------- /include/isr.h: -------------------------------------------------------------------------------- 1 | #ifndef ISR_H 2 | #define ISR_H 3 | 4 | #include "screencontroller.h" 5 | #include "idt.h" 6 | #include "error.h" 7 | 8 | struct regs{ 9 | unsigned int gs, fs, es, ds; /* pushed the segs last */ 10 | unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; /* pushed by 'pusha' */ 11 | unsigned int int_no, err_code; /* our 'push byte #' and ecodes do this */ 12 | unsigned int eip, cs, eflags, useresp, ss; /* pushed by the processor automatically */ 13 | }; 14 | 15 | void isrs_install(); 16 | 17 | void fault_handler(struct regs *r); 18 | 19 | #endif -------------------------------------------------------------------------------- /include/kbd.c: -------------------------------------------------------------------------------- 1 | #include "kbd.h" 2 | unsigned char kbdus[256] = { 3 | 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */ 4 | '9', '0', '-', '=', '\b', /* Backspace */ 5 | '\t', /* Tab */ 6 | 'q', 'w', 'e', 'r', /* 19 */ 7 | 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', /* Enter key */ 8 | 0, /* 29 - Control */ 9 | 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 39 */ 10 | '\'', '`', 0, /* Left shift */ 11 | '\\', 'z', 'x', 'c', 'v', 'b', 'n', /* 49 */ 12 | 'm', ',', '.', '/', 0, /* Right shift */ 13 | '*', 14 | 0, /* Alt */ 15 | ' ', /* Space bar */ 16 | 0, /* Caps lock */ 17 | 0, /* 59 - F1 key ... > */ 18 | 0, 0, 0, 0, 0, 0, 0, 0, 19 | 0, /* < ... F10 */ 20 | 0, /* 69 - Num lock*/ 21 | 0, /* Scroll Lock */ 22 | 0, /* Home key */ 23 | 0, /* Up Arrow */ 24 | 0, /* Page Up */ 25 | '-', 26 | 0, /* Left Arrow */ 27 | 0, 28 | 0, /* Right Arrow */ 29 | '+', 30 | 0, /* 79 - End key*/ 31 | 0, /* Down Arrow */ 32 | 0, /* Page Down */ 33 | 0, /* Insert Key */ 34 | 0, /* Delete Key */ 35 | 0, 0, 0, 36 | 0, /* F11 Key */ 37 | 0, /* F12 Key */ 38 | 0, 39 | 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 40 | '\b', '\t', 41 | 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 42 | 0, 43 | 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', 44 | '\"', '~', 0, '|', 45 | 'Z', 'X', 'C', 'V', 'B', 'N', 'M', 46 | '<', '>', '?', 0, '*', 47 | 0, /* Alt */ 48 | ' ', /* Space bar */ 49 | 0, /* Caps lock */ 50 | 0, /* 59 - F1 key ... > */ 51 | 0, 0, 0, 0, 0, 0, 0, 0, 52 | 0, /* < ... F10 */ 53 | 0, /* 69 - Num lock*/ 54 | 0, /* Scroll Lock */ 55 | 0, /* Home key */ 56 | 0, /* Up Arrow */ 57 | 0, /* Page Up */ 58 | '-', 59 | 0, /* Left Arrow */ 60 | 0, 61 | 0, /* Right Arrow */ 62 | '+', 63 | 0, /* 79 - End key*/ 64 | 0, /* Down Arrow */ 65 | 0, /* Page Down */ 66 | 0, /* Insert Key */ 67 | 0, /* Delete Key */ 68 | 0, 0, 0, 69 | 0, /* F11 Key */ 70 | 0, /* F12 Key */ 71 | 0 72 | 73 | }; 74 | 75 | int shift = 0; 76 | 77 | void pause(){ 78 | int i = 0; 79 | while(i < 100000000){ 80 | i++; 81 | } 82 | while(inb(0x60) & 0x80){ 83 | 84 | }; 85 | } 86 | void keyboard_handler(struct regs *r){ 87 | unsigned char scancode; 88 | 89 | scancode = inb(0x60); 90 | 91 | if (scancode & 0x80) 92 | { 93 | if(scancode == 0xAA) 94 | shift = 0; 95 | } 96 | else 97 | { 98 | if(scancode == 0x2a){shift = 1;return;} 99 | if(scancode == 0x1c){shell_enterpressed();return;} 100 | if(scancode == 0x0e){ 101 | if(shell_can_backspace()){ 102 | printchar(kbdus[scancode]); 103 | } 104 | shell_backspace(); 105 | return; 106 | } 107 | if(shift){ 108 | printchar(kbdus[scancode+90]); 109 | shell_addchar(kbdus[scancode+90]); 110 | }else{ 111 | printchar(kbdus[scancode]); 112 | shell_addchar(kbdus[scancode]); 113 | } 114 | } 115 | } -------------------------------------------------------------------------------- /include/kbd.h: -------------------------------------------------------------------------------- 1 | #ifndef KBD_H 2 | #define KBD_H 3 | #include "isr.h" 4 | #include "shell.h" 5 | void keyboard_handler(struct regs *r); 6 | void pause(); 7 | #endif -------------------------------------------------------------------------------- /include/screencontroller.c: -------------------------------------------------------------------------------- 1 | #include "screencontroller.h" 2 | u8int color = 0x0f; 3 | 4 | void setcolor(u8int c){ 5 | color = c; 6 | } 7 | 8 | void print(string s){ 9 | printf(s,color); 10 | } 11 | 12 | void println(string s){ 13 | printf(s,color); 14 | printf("\n",color); 15 | } 16 | 17 | void printnum(int num){ 18 | printInt(num,color); 19 | } 20 | 21 | void cls(){ 22 | clear_screen(color); 23 | } 24 | 25 | void printchar(char c){ 26 | putchar(c,color); 27 | } 28 | 29 | void colorRestOfScreen(){ 30 | char *vidmem = (char *)0xb8000; 31 | int position = getPos(); 32 | while(position < 80*25*2){ 33 | position++; 34 | vidmem[position] = color; 35 | position++; 36 | } 37 | } 38 | 39 | void printhex(int n){ 40 | s32int tmp; 41 | 42 | print("0x"); 43 | 44 | char noZeroes = 1; 45 | 46 | int i; 47 | for (i = 28; i > 0; i -= 4) 48 | { 49 | tmp = (n >> i) & 0xF; 50 | if (tmp == 0 && noZeroes != 0) 51 | { 52 | continue; 53 | } 54 | 55 | if (tmp >= 0xA) 56 | { 57 | noZeroes = 0; 58 | printchar(tmp-0xA+'a'); 59 | } 60 | else 61 | { 62 | noZeroes = 0; 63 | printchar(tmp+'0'); 64 | } 65 | } 66 | 67 | tmp = n & 0xF; 68 | if (tmp >= 0xA) 69 | { 70 | printchar(tmp-0xA+'a'); 71 | } 72 | else 73 | { 74 | printchar(tmp+'0'); 75 | } 76 | 77 | } -------------------------------------------------------------------------------- /include/screencontroller.h: -------------------------------------------------------------------------------- 1 | #ifndef SCREENCONTROLLER_H 2 | #define SCREENCONTROLLER_H 3 | #include "vga.h" 4 | void setcolor(u8int c); 5 | void print(string s); 6 | void println(string s); 7 | void cls(); 8 | void printnum(int num); 9 | void printchar(char c); 10 | void colorRestOfScreen(); 11 | void printhex(int n); 12 | #endif -------------------------------------------------------------------------------- /include/shell.c: -------------------------------------------------------------------------------- 1 | #include "shell.h" 2 | string buffer = "\0 "; 3 | 4 | u8int maincolor = 0x0f; 5 | int cBlock = 0; 6 | int cDirLength = 0; 7 | 8 | void shell_enterpressed(){ 9 | printchar('\n'); 10 | shell(); 11 | } 12 | 13 | void shell_addchar(char c){ 14 | concatc(buffer,c,buffer); 15 | } 16 | 17 | void shell_backspace(){ 18 | remchar(buffer,buffer); 19 | } 20 | 21 | int shell_can_backspace(){ 22 | if(strlen(buffer) > 0) 23 | return 1; 24 | return 0; 25 | } 26 | 27 | void init_shell(){ 28 | setcolor(maincolor); 29 | cBlock = getRoot(0); 30 | cDirLength = (getRootEntries(0)*32)/512; 31 | print("CodeOS>"); 32 | } 33 | 34 | void shell(){ 35 | findCommand(buffer); 36 | buffer[0] = '\0'; 37 | setcolor(maincolor); 38 | if(getY() == 0) 39 | print("CodeOS>"); 40 | else 41 | print("\nCodeOS>"); 42 | } 43 | 44 | void findCommand(string command){ 45 | if(strcmp(command,"ping")){ 46 | setcolor(0xf0); 47 | print("pong!"); 48 | setcolor(0x0f); 49 | }else if(strcmp(command,"who is the best")){ 50 | print("Well, of course it's Aaron."); 51 | }else if(strcmp(command,"cls")){ 52 | cls(); 53 | }else if(startswith(command,"setcolor")){ 54 | int a = toHex(command[11]); 55 | int b = toHex(command[12]); 56 | if(startswith(command, "setcolor 0x") && strlen(command) == 13 && a != -1 && b != -1){ 57 | maincolor = (a * 16)+b; 58 | setcolor(maincolor); 59 | colorRestOfScreen(); 60 | print("color set to 0x"); 61 | printchar(command[11]); 62 | printchar(command[12]); 63 | }else{ 64 | setcolor(0x04); 65 | print("Please specify a color."); 66 | } 67 | }else if(strcmp(command,"ls")){ 68 | listFiles(0,cBlock,cDirLength); 69 | }else if(startswith(command,"cd")){ 70 | if(startswith(command, "cd ") && strlen(command) > strlen("cd ")){ 71 | substring(command,command,3); 72 | if(isDir(0,cBlock,cDirLength,command)){ 73 | int block = getFile(0,cBlock,cDirLength,command); 74 | if(block == getRoot(0)){ 75 | cDirLength = (getRootEntries(0)*32)/512; 76 | }else{ 77 | cDirLength = getDirLength(0,block); 78 | } 79 | cBlock = block; 80 | }else if(strcmp("\\",command)){ 81 | cDirLength = (getRootEntries(0)*32)/512; 82 | cBlock = getRoot(0); 83 | }else{ 84 | setcolor(0x04); 85 | print("\""); 86 | print(command); 87 | print("\" is not a directory!"); 88 | } 89 | }else{ 90 | setcolor(0x04); 91 | print("Please specify a directory."); 92 | } 93 | }else if(strcmp(command,"test")){ 94 | printnum(getDirLength(0,cBlock)); 95 | }else if(strcmp(command,"diskinfo")){ 96 | println("DISK 0:"); 97 | println(" PARTITION 0:"); 98 | print(" LOCATION: "); 99 | printhex(getFirstPart(0)); 100 | print("\n ROOT LOCATION: "); 101 | printhex(getRoot(0)); 102 | print("\n SECTORS PER CLUSTER: "); 103 | printhex(getClusterSize(0)); 104 | print("\n ROOT ENTRIES: "); 105 | printhex(getRootEntries(0)); 106 | }else if(strcmp(command,"help")){ 107 | println("Commands:"); 108 | println("ping: Says pong."); 109 | println("cls: Clears the screen."); 110 | println("setcolor 0x##: Set the attribute byte of the screen."); 111 | println("who is the best: Try it."); 112 | }else{ 113 | int bg = maincolor/16; 114 | if(bg == 0x4) 115 | setcolor((bg*16)+0xf); 116 | else 117 | setcolor((bg*16)+0x4); 118 | print("No such command "); 119 | print(command); 120 | print("."); 121 | } 122 | } -------------------------------------------------------------------------------- /include/shell.h: -------------------------------------------------------------------------------- 1 | #ifndef SHELL_H 2 | #define SHELL_H 3 | #define MAX_COMMANDS 100 4 | #include "screencontroller.h" 5 | #include "kbd.h" 6 | #include "fat.h" 7 | 8 | void init_shell(); 9 | void shell(); 10 | void shell_addchar(char c); 11 | void shell_enterpressed(); 12 | void shell_backspace(); 13 | void findCommand(string command); 14 | int shell_can_backspace(); 15 | #endif -------------------------------------------------------------------------------- /include/timer.c: -------------------------------------------------------------------------------- 1 | #include "timer.h" 2 | int timer_ticks = 0; 3 | void timer_handler(struct regs *r){ 4 | /* Increment our 'tick count' */ 5 | timer_ticks++; 6 | 7 | //ONE SECOND = 18 TICKS 8 | } -------------------------------------------------------------------------------- /include/timer.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMER_H 2 | #define TIMER_H 3 | #include "isr.h" 4 | void timer_handler(struct regs *r); 5 | #endif -------------------------------------------------------------------------------- /include/vga.c: -------------------------------------------------------------------------------- 1 | #include "vga.h" 2 | u8int cursor_x = 0; 3 | u8int cursor_y = 0; 4 | char *vidmem = (char *)0xb8000; 5 | 6 | void clear_screen(u8int color){ 7 | int i; 8 | for(i = 0; i < 80*25*2; i++){ 9 | vidmem[i++] = ' '; 10 | vidmem[i] = color; 11 | } 12 | cursor_x = 0; 13 | cursor_y = 0; 14 | move_cursor(); 15 | } 16 | 17 | void move_cursor() 18 | { 19 | u16int cursorLocation = cursor_y * 80 + cursor_x; 20 | outb(0x3D4, 14); // Tell the VGA board we are setting the high cursor byte. 21 | outb(0x3D5, cursorLocation >> 8); // Send the high cursor byte. 22 | outb(0x3D4, 15); // Tell the VGA board we are setting the low cursor byte. 23 | outb(0x3D5, cursorLocation); // Send the low cursor byte. 24 | } 25 | 26 | void putchar(char c, u8int color){ 27 | u16int location; 28 | if(c == 0x08 && cursor_x){ 29 | cursor_x--; 30 | location = (cursor_y * 80 + cursor_x)*2; 31 | vidmem[location] = ' '; 32 | vidmem[location+1] = 0x0f; 33 | }else if(c == 0x09){ 34 | cursor_x = (cursor_x+8) & ~(8-1); 35 | }else if(c == '\r'){ 36 | cursor_x = 0; 37 | }else if(c == '\n'){ 38 | cursor_x = 0; 39 | cursor_y++; 40 | }else if(c >= ' '){ 41 | location = (cursor_y * 80 + cursor_x)*2; 42 | vidmem[location] = c; 43 | vidmem[location + 1] = color; 44 | cursor_x++; 45 | } 46 | 47 | if(cursor_x >= 80){ 48 | cursor_x = 0; 49 | cursor_y++; 50 | } 51 | scroll(color); 52 | move_cursor(); 53 | } 54 | 55 | void printf(char *c, u8int color){ 56 | int i = 0; 57 | while(c[i]){ 58 | putchar(c[i++], color); 59 | } 60 | } 61 | 62 | void printInt(int n, u8int color){ 63 | if(n == 0){ 64 | printf("0",color); 65 | return; 66 | } 67 | char buffer[50]; 68 | int i = 0; 69 | 70 | int isNeg = n<0; 71 | 72 | unsigned int n1 = isNeg ? -n : n; 73 | 74 | while(n1!=0) 75 | { 76 | buffer[i++] = n1%10+'0'; 77 | n1=n1/10; 78 | } 79 | 80 | if(isNeg) 81 | buffer[i++] = '-'; 82 | 83 | buffer[i] = '\0'; 84 | 85 | for(int t = 0; t < i/2; t++) 86 | { 87 | buffer[t] ^= buffer[i-t-1]; 88 | buffer[i-t-1] ^= buffer[t]; 89 | buffer[t] ^= buffer[i-t-1]; 90 | } 91 | 92 | printf(buffer, color); 93 | } 94 | 95 | void scroll(u8int color){ 96 | if(cursor_y >= 25){ 97 | int i = 80*2; 98 | while(i < 80*25*2){ 99 | vidmem[i-(80*2)] = vidmem[i]; 100 | i++; 101 | } 102 | i = 80*2*24; 103 | while(i < 80*25*2){ 104 | vidmem[i++] = ' '; 105 | vidmem[i++] = 0x07; 106 | } 107 | cursor_y--; 108 | } 109 | } 110 | 111 | void center_print(char *c, u8int color){ 112 | if(cursor_x > 0){ 113 | printf("\n",color); 114 | } 115 | int i = 0; 116 | while(c[i]){ 117 | i++; 118 | } 119 | if(i > 80){ 120 | printf(c,color); 121 | }else{ 122 | if(i % 2 == 0){ 123 | int h = (80-i)/2; 124 | int j = 0; 125 | while(j < h){ 126 | putchar(' ', color); 127 | j++; 128 | } 129 | printf(c,color); 130 | j = 0; 131 | while(j < h){ 132 | putchar(' ', color); 133 | j++; 134 | } 135 | }else{ 136 | int h = (80-i)/2; 137 | int j = 0; 138 | while(j < h){ 139 | putchar(' ', color); 140 | j++; 141 | } 142 | printf(c,color); 143 | j = 0; 144 | h--; 145 | while(j < h+2){ 146 | putchar(' ', color); 147 | j++; 148 | } 149 | } 150 | } 151 | } 152 | 153 | int getY(){ 154 | return cursor_y; 155 | } 156 | 157 | int getX(){ 158 | return cursor_x; 159 | } 160 | 161 | int getPos(){ 162 | return ((cursor_y*80)+cursor_x)*2; 163 | } -------------------------------------------------------------------------------- /include/vga.h: -------------------------------------------------------------------------------- 1 | #ifndef VGA_H 2 | #define VGA_H 3 | #include "common.h" 4 | 5 | void clear_screen(u8int color); 6 | 7 | void putchar(char c, u8int color); 8 | 9 | void printf(char *c, u8int color); 10 | 11 | void move_cursor(); 12 | 13 | void scroll(u8int color); 14 | 15 | void printInt(int i, u8int color); 16 | 17 | void center_print(char *c, u8int color); 18 | 19 | int getX(); 20 | 21 | int getY(); 22 | 23 | int getPos(); 24 | 25 | #endif -------------------------------------------------------------------------------- /kernel.c: -------------------------------------------------------------------------------- 1 | #include "include/common.h" 2 | #include "include/kbd.h" 3 | #include "include/vga.h" 4 | #include "include/error.h" 5 | #include "include/screencontroller.h" 6 | #include "include/gdt.h" 7 | #include "include/idt.h" 8 | #include "include/isr.h" 9 | #include "include/irq.h" 10 | #include "include/timer.h" 11 | #include "include/shell.h" 12 | 13 | void startscreen(); 14 | 15 | int main(){ 16 | startscreen(); 17 | gdt_install(); 18 | idt_install(); 19 | isrs_install(); 20 | irq_install_handler(0,timer_handler); 21 | irq_install_handler(1,keyboard_handler); 22 | irq_install(); 23 | asm volatile("sti"); 24 | cls(); 25 | init_shell(); 26 | return 0xDEADBABA; 27 | } 28 | 29 | void startscreen(){ 30 | cls(); 31 | center_print("",0x36); 32 | center_print("",0x36); 33 | center_print("",0x36); 34 | center_print("",0x36); 35 | center_print("",0x36); 36 | center_print("",0x36); 37 | center_print("",0x36); 38 | center_print("",0x36); 39 | center_print("------------------------------",0x36); 40 | center_print("| Welcome to CodeOS! |",0x36); 41 | center_print("| Version 0.3 |",0x36); 42 | center_print("| Copyright 2015 Codepixl |",0x36); 43 | center_print("| (Aaron Sonin) |",0x36); 44 | center_print("| Press any key to continue |",0x36); 45 | center_print("------------------------------",0x36); 46 | center_print("",0x36); 47 | center_print("",0x36); 48 | center_print("",0x36); 49 | center_print("",0x36); 50 | center_print("",0x36); 51 | center_print("",0x36); 52 | center_print("",0x36); 53 | center_print("",0x36); 54 | setcolor(0x36); 55 | colorRestOfScreen(); 56 | while(inb(0x60) & 0x80){}; 57 | setcolor(0x0f); 58 | cls(); 59 | } -------------------------------------------------------------------------------- /linker.ld: -------------------------------------------------------------------------------- 1 | /* Link.ld -- Linker script for the kernel - ensure everything goes in the */ 2 | /* Correct place. */ 3 | /* Original file taken from Bran's Kernel Development */ 4 | /* tutorials: http://www.osdever.net/bkerndev/index.php. */ 5 | 6 | ENTRY(start) 7 | SECTIONS 8 | { 9 | .text 0x100000 : 10 | { 11 | code = .; _code = .; __code = .; 12 | *(.text) 13 | . = ALIGN(4096); 14 | } 15 | 16 | .data : 17 | { 18 | data = .; _data = .; __data = .; 19 | *(.data) 20 | *(.rodata) 21 | . = ALIGN(4096); 22 | } 23 | 24 | .bss : 25 | { 26 | bss = .; _bss = .; __bss = .; 27 | *(.bss) 28 | . = ALIGN(4096); 29 | } 30 | 31 | end = .; _end = .; __end = .; 32 | } -------------------------------------------------------------------------------- /os_image.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/byteduck/CodeOS/8a89c3168a4230a16cbc45392e04d5817a86a0b1/os_image.bin -------------------------------------------------------------------------------- /run.bat: -------------------------------------------------------------------------------- 1 | qemu-system-i386 -kernel os_image.bin --------------------------------------------------------------------------------