├── .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
--------------------------------------------------------------------------------