diff --git a/build.bat b/build.bat new file mode 100644 index 00000000..6e9cefde --- /dev/null +++ b/build.bat @@ -0,0 +1,21 @@ +mkdir bin +nasm -f elf32 src\kernel_loader.asm -o kernel_loader.o +gcc -m32 -c -I src\. src\kernel.c -o kernel.o +cd bin +gcc -m32 -c -I ..\src\. ..\src\Drivers\*.c +gcc -m32 -c -I ..\src\. ..\src\System\*.c +gcc -m32 -c -I ..\src\. ..\src\Graphics\*.c +gcc -m32 -c -I ..\src\. ..\src\FS\*.c +gcc -m32 -c -I ..\src\. ..\src\Shell\*.c +gcc -m32 -c -I ..\src\. ..\src\Mego-Runtime\*.c +gcc -m32 -c -I ..\src\. ..\src\Terminal-Runtime\*.c +gcc -m32 -c -I ..\src\. ..\src\Util\*.c +ld ..\kernel_loader.o ..\kernel.o *.o -o kernel.e +del *.o +del ..\*.o +objcopy -Felf32-i386 kernel.e kernel.bin +del *.e +qemu-system-x86_64.exe -kernel kernel.bin +cd .. +del bin +pause diff --git a/limine.cfg b/limine.cfg new file mode 100644 index 00000000..0668b96c --- /dev/null +++ b/limine.cfg @@ -0,0 +1,6 @@ + +TIMEOUT=0 +: limine-boot kernel +KERNEL_PATH=boot:///kernel.bin + +PROTOCOL=multiboot \ No newline at end of file diff --git a/linker.ld b/linker.ld new file mode 100644 index 00000000..313002bc --- /dev/null +++ b/linker.ld @@ -0,0 +1,19 @@ +SECTIONS { + .text ALIGN(2K) : { + *(.text*) + } + .rodata ALIGN(2K) : { + *(.rodata*) + } + .data ALIGN(2K) : { + *(.data*) + } + .bss ALIGN(2K) : { + *(COMMON) + *(.bss*) + + _stack_bottom = .; + . += 8K; + _stack_top = .; + } +} \ No newline at end of file diff --git a/src/Drivers/Keyboard.c b/src/Drivers/Keyboard.c new file mode 100644 index 00000000..7f89d9b4 --- /dev/null +++ b/src/Drivers/Keyboard.c @@ -0,0 +1,46 @@ +#include"Screen.h" +char * keycode = "\e 1234567890-=\b\tqwertyuiop[]\n\0asdfghjkl;'`\0\\zxcvbnm,./\0\0\0 "; +char * keycode2 = "\e !@#$%^&*()_+\b\tQWERTYUIOP{}\n\0ASDFGHJKL:'~\0|ZXCVBNM<>?\0\0\0 "; +int isShift= 0; +#include +char readChar(){ + int run = 1; + char out = 0; + while(run){ + if(inportb(0x64) & 0x1){ + if(inportb(0x60)==0x2A&&!isShift)isShift=1; + else if(inportb(0x60)==0xAA&&isShift)isShift=0; + if(!isShift) + out = keycode[inportb(0x60)]; + else if(isShift) + out = keycode2[inportb(0x60)]; + if(out!=0&&inportb(0x60)<60)run=0; + } + } + return out; +} + char * input(){ + char tp=0; + char * out=""; + int index = 0; + while((tp=readChar())!='\n'){ + out[index]=tp; + out[index+1]=0; + if(out[index]=='\b'){ + if(index>0){ + out[index]=0; + out[index-1]=0; + backspace(); + index-=1; + } + } + else{ + printChar(tp,Screen->defaultColor); + index++; + } + } + return out; +} +char getChar(){ + if(inportb(0x60)<60&&inportb(0x60)>0&&keycode[inportb(0x60)]>0&&keycode[inportb(0x60)]<254)return keycode[inportb(0x60)]; +} \ No newline at end of file diff --git a/src/Drivers/Keyboard.h b/src/Drivers/Keyboard.h new file mode 100644 index 00000000..475408a9 --- /dev/null +++ b/src/Drivers/Keyboard.h @@ -0,0 +1,4 @@ +#pragma once +char readChar(); +char * input(); +char getChar(); \ No newline at end of file diff --git a/src/Drivers/Screen.c b/src/Drivers/Screen.c new file mode 100644 index 00000000..c1b6e865 --- /dev/null +++ b/src/Drivers/Screen.c @@ -0,0 +1,85 @@ +#include"Screen.h" +#include + +void scroll(); +void printChar(char ch,int color){ + if(ch=='\b'){backspace();return;} + if(Screen->cursorY>=24){scroll();} + if(ch=='\n'||Screen->cursorX==160){ + Screen->cursorY++; + Screen->cursorX = 0; + } + if(ch!='\n'){ + Screen->vga[(Screen->cursorY*160)+Screen->cursorX]=ch; + Screen->vga[(Screen->cursorY*160)+Screen->cursorX+1]=color; + Screen->cursorX+=2; + } + setCursorPosition(Screen->cursorX,Screen->cursorY); +} +void setCursorPosition(int xe,int ye){ + unsigned temp; + temp = ye * 80 + (xe/2); + outportb(0x3D4, 14); + outportb(0x3D5, temp >> 8); + outportb(0x3D4, 15); + outportb(0x3D5, temp); +} +void printC(char a){ + printChar(a,Screen->defaultColor); +} +void print(const char * str,int color){ + for(int i = 0;str[i]!=0;i++){ + printChar(str[i],color); + } + setCursorPosition(Screen->cursorX,Screen->cursorY); +} +void printW(const char * str){ + print(str,Screen->defaultColor); + setCursorPosition(Screen->cursorX,Screen->cursorY); +} +void clearScreen(){ + Screen->cursorX = 0; + Screen->cursorY = 0; + for(int i = 0;i<160*25;i+=2){ + Screen->vga[i]=0; + } +} + +void screen_init(){ + Screen->vga = (char *) 0xB8000; + Screen->cursorX = 0; + Screen->cursorY = 0; + Screen->defaultColor = 0x07; +} +void setDefaultColor(int color){ + Screen->defaultColor = color; +} +void clearLine(int line){ + for(int i = 0;i<160;i++){ + Screen->vga[(160*line)+i]=0; + } +} +void setScreenColor(int color){ + setDefaultColor(color); + char * vga = (char *) 0xB8000; + for(int i = 1;i<160*26;i+=2){ + vga[i] = (color-(color%16))+(vga[i]%16); + } +} +void scroll(){ + char * * lines; + for(int i = 1;icursorY+1;i++){ + for(int j = 0;j<160;j++){ + Screen->vga[(160*(i-1))+j] = Screen->vga[(160*i)+j]; + } + } + clearLine(Screen->cursorY); + Screen->cursorY--; + setScreenColor(Screen->defaultColor); +} +void backspace(){ + if(Screen->cursorX!=0)Screen->cursorX-=2; + else{Screen->cursorX=160;Screen->cursorY--;} + Screen->vga[(Screen->cursorY*160)+Screen->cursorX]=0; + setCursorPosition(Screen->cursorX,Screen->cursorY); +} \ No newline at end of file diff --git a/src/Drivers/Screen.h b/src/Drivers/Screen.h new file mode 100644 index 00000000..af645beb --- /dev/null +++ b/src/Drivers/Screen.h @@ -0,0 +1,18 @@ +#pragma once +struct sc{ + int cursorX; + int cursorY; + int defaultColor; + char * vga; +}; +static struct sc * Screen; +void screen_init(); +void clearScreen(); +void printChar(char ch,int color); +void print(const char * str,int color); +void printW(const char * str); +void setScreenColor(int color); +void setDefaultColor(int color); +void setCursorPosition(int xe,int ye); +void backspace(); +void printC(char a); \ No newline at end of file diff --git a/src/FS/fs.c b/src/FS/fs.c new file mode 100644 index 00000000..ce52d45d --- /dev/null +++ b/src/FS/fs.c @@ -0,0 +1,102 @@ +#include"fs.h" +#include +char * fs = (char *)0x70000; +int fs_index = 0; +int file_index = 0; +void createNativeFiles(); +void fs_init(){ + createNativeFiles(); +} +void createFile(char * fn){ + for(int i = fs_index;i<=fs_index+2048;i++){ + fs[i] = 0; + } + for(int i = 0;i + +int length(char * in); +void setDefaultScreenColor(int color); +void setCharAt(int xex,int ye,char ae,int color){ + int xe = xex*2; + char * vga = (char *) 0xB8000; + vga[(ye*160)+xe]=ae; + vga[(ye*160)+xe+1]=color; +} +void printAt(int xe,int ye,char * tex,int color){ + for(int i = 0;ivga[(y*160)+(x*4)]=219; + Screen->vga[(y*160)+(x*4)+1]=color; + Screen->vga[(y*160)+(x*4)+2]=219; + Screen->vga[(y*160)+(x*4)+3]=color; + +} \ No newline at end of file diff --git a/src/Graphics/Graphics.h b/src/Graphics/Graphics.h new file mode 100644 index 00000000..9aa7fb1b --- /dev/null +++ b/src/Graphics/Graphics.h @@ -0,0 +1,5 @@ +#pragma once +void setCharAt(int xe,int ye,char ae,int color); +void printAt(int xe,int ye,char * tex,int color); +void printCenter(int ye,char * text,int color); +void setBlockAt(int x,int y,int color); \ No newline at end of file diff --git a/src/Graphics/Image.c b/src/Graphics/Image.c new file mode 100644 index 00000000..c4f1b975 --- /dev/null +++ b/src/Graphics/Image.c @@ -0,0 +1,18 @@ +#include +typedef int * Image; +int he,we; +void drawImage(int xe,int ye,int * img){ + we = img[0]; + he = img[1]; + int temp = 2; + xe*=2; + for(int i = 0;ivga[(160*(i+ye))+j+xe]=219; + Screen->vga[(160*(i+ye))+j+1+xe]=img[temp]/16; + Screen->vga[(160*(i+ye))+j+2+xe]=219; + Screen->vga[(160*(i+ye))+j+3+xe]=img[temp]/16; + temp++; + } + } +} \ No newline at end of file diff --git a/src/Graphics/Image.h b/src/Graphics/Image.h new file mode 100644 index 00000000..0e3a8562 --- /dev/null +++ b/src/Graphics/Image.h @@ -0,0 +1,2 @@ +#pragma once +void drawImage(int xe,int ye,int * img); \ No newline at end of file diff --git a/src/Mego-Runtime/Command.c b/src/Mego-Runtime/Command.c new file mode 100644 index 00000000..5bf973b8 --- /dev/null +++ b/src/Mego-Runtime/Command.c @@ -0,0 +1,7 @@ +#include"Runtime.h" +#include +void execute_command(int command){ + if(command==0x1){ + printC(getRegValueOf(3)); + } +} \ No newline at end of file diff --git a/src/Mego-Runtime/Memory.c b/src/Mego-Runtime/Memory.c new file mode 100644 index 00000000..87ee34d5 --- /dev/null +++ b/src/Mego-Runtime/Memory.c @@ -0,0 +1,76 @@ +#include +int AA = 0; +int AB = 0; +int AC = 0; +int AD = 0; +int AE = 0; +int AF = 0; +int AG = 0; +int AH = 0; +int AI = 0; +int AJ = 0; +int AK = 0; +int AL = 0; +int * virtual_memory = (int *)0xFF; +int stack_pointer = 0; + +void mem_init(){ + AA = 0; + AB = 0; + AC = 0; + AD = 0; + AE = 0; + AF = 0; + AH = 0; + AI = 0; + AJ = 0; + AK = 0; + AL = 0; +} +void setRegValueOf(int in,int value){ + if(in==1)AA = value; + if(in==2)AB = value; + if(in==3)AC = value; + if(in==4)AD = value; + if(in==5)AE = value; + if(in==6)AF = value; + if(in==7)AG = value; + if(in==8)AH = value; + if(in==9)AI = value; + if(in==10)AJ = value; + if(in==11)AK = value; + if(in==12)AL = value; +} +int getRegValueOf(int in){ + if(in==1)return AA; + if(in==2)return AB; + if(in==3)return AC; + if(in==4)return AD; + if(in==5)return AE; + if(in==6)return AF; + if(in==7)return AG; + if(in==8)return AH; + if(in==9)return AI; + if(in==10)return AJ; + if(in==11)return AK; + if(in==12)return AL; + else return 0; +} +void push(int in){ + virtual_memory[stack_pointer] = in; + stack_pointer++; +} +int pop(){ + int out = virtual_memory[0]; + for(int i = 0;iarg2){ + condition = 1; + } + else condition = 0; + } + if(command==43){ + //EQU + if(getRegValueOf(arg1)==arg2){ + condition = 1; + } + else condition = 0; + } + if(command==44){ + //OUTB + setMemoryAt(getRegValueOf(arg1),getRegValueOf(arg2)); + } + if(command==45){ + //INB + setRegValueOf(arg1,getMemoryAt(getRegValueOf(arg2))); + } +} \ No newline at end of file diff --git a/src/Mego-Runtime/Runtime.c b/src/Mego-Runtime/Runtime.c new file mode 100644 index 00000000..0c96a73d --- /dev/null +++ b/src/Mego-Runtime/Runtime.c @@ -0,0 +1,43 @@ +#include"Runtime.h" +int cpu_pointer = 0; +void run_block(int * block){ + int * instruction = (int *)"\0\0\0\0"; + int temp = 0; + for(cpu_pointer = 0;block[cpu_pointer]!=0;cpu_pointer++){ + if(block[cpu_pointer]!='\e'){ + instruction[temp]=block[cpu_pointer]; + temp++; + } + else{ + run_instruction(instruction); + temp = 0; + instruction = (int *)"\0\0\0\0"; + } + } +} +void setMemory(int * mem){ + for(int i = 0;mem[i]!=0;i++) + setMemoryAt(i+50,mem[i]); +} +void setCpuPointer(int in){ + cpu_pointer = in; +} +void execute_program(int * program){ + mem_init(); + int * program_block=(int *)0xFFFF; + int * mem=(int *)0xAAAA; + for(int i = 0;i<1000;i++){ + mem[i]=0; + program_block[i]=0; + } + int tempy = 0; + for(int i = 0;program[i]!='\r'&&program[i]!=0;i++){ + program_block[i] = program[i]; + tempy = i+2; + } + for(int i = tempy;program[i]!=0;i++){ + mem[i-tempy]=program[i]; + } + setMemory(mem); + run_block(program_block); +} \ No newline at end of file diff --git a/src/Mego-Runtime/Runtime.h b/src/Mego-Runtime/Runtime.h new file mode 100644 index 00000000..9a8ecb81 --- /dev/null +++ b/src/Mego-Runtime/Runtime.h @@ -0,0 +1,14 @@ +#pragma once +void push(int in); +int getRegValueOf(int in); +void setRegValueOf(int in,int value); +int pop(); +void exec_instruction(int command,int arg1,int arg2); +void run_instruction(int * instruction); +void mem_init(); +void execute_command(int command); +void setCpuPointer(int in); +void run_block(int * block); +void setMemoryAt(int in,int mem); +int getMemoryAt(int in); +void execute_program(int * program); \ No newline at end of file diff --git a/src/Shell/shell.c b/src/Shell/shell.c new file mode 100644 index 00000000..32b497d2 --- /dev/null +++ b/src/Shell/shell.c @@ -0,0 +1,25 @@ +#include "shell.h" +#include +#include +#include +#include +#include +#include +void shell_main(){ + printW("Radical OS [Version 2.0.0]\n"); + printW("Copyright (c) 2021 Radical Foundation. All rights reserved.\n\n"); + printW("Welcome to Radical OS. Hope you have fun :)\n\n"); + printW("Setting up VFS... "); + fs_init(); + print("[done]\n\n",0x02); + printW("Time from boot: "); + printW(toString(getTimeFromBoot())); + printC('\n'); + start_shell(); +} +void start_shell(){ + while(1){ + print("\nuser@radical:-$ ",0x0e); + system(input()); + } +} \ No newline at end of file diff --git a/src/Shell/shell.h b/src/Shell/shell.h new file mode 100644 index 00000000..2d10f232 --- /dev/null +++ b/src/Shell/shell.h @@ -0,0 +1,3 @@ +#pragma once +void shell_main(); +void start_shell(); \ No newline at end of file diff --git a/src/System/IO.c b/src/System/IO.c new file mode 100644 index 00000000..0372416e --- /dev/null +++ b/src/System/IO.c @@ -0,0 +1,16 @@ +#include + +uint8 inportb (uint16 _port) +{ + uint8 rv; + __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port)); + return rv; +} + +void outportb (uint16 _port, uint8 _data) +{ +__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data)); +} +void cli(){ + __asm__("cli"); +} \ No newline at end of file diff --git a/src/System/IO.h b/src/System/IO.h new file mode 100644 index 00000000..5b9a8d1f --- /dev/null +++ b/src/System/IO.h @@ -0,0 +1,15 @@ +#pragma once +typedef signed char int8; +typedef unsigned char uint8; + +typedef signed short int16; +typedef unsigned short uint16; + +typedef signed int int32; +typedef unsigned int uint32; + +typedef signed long long int64; +typedef unsigned long long uint64; +uint8 inportb (uint16 _port); +void outportb (uint16 _port, uint8 _data); +void cli(); \ No newline at end of file diff --git a/src/System/Logo.c b/src/System/Logo.c new file mode 100644 index 00000000..4e70cb6c --- /dev/null +++ b/src/System/Logo.c @@ -0,0 +1,19 @@ +#include +int length(char * in); +void printLogo(){ +char * logo[7]; +logo[0] = " OOOOOO OO OOOOO OOOOOOO OOOOO OO O\n"; +logo[1] = " O O O O O O O O O O O\n"; +logo[2] = " O O O O O O O O O O O\n"; +logo[3] = " OOOOOO OOOOOO O O O O OOOOOO O\n"; +logo[4] = " O O O O O O O O O O O\n"; +logo[5] = " O O O O O O O O O O O\n"; +logo[6] = " O O O O OOOOO OOOOOOO OOOOO O O OOOOOOO\n"; +for(int i = 0;i<7;i++) + for(int j = 0;j +int random(){ + return (getSeconds()*getTimeFromBoot()*getSeconds()*getMinutes())*getSeconds(); +} \ No newline at end of file diff --git a/src/System/Random.h b/src/System/Random.h new file mode 100644 index 00000000..214f42d0 --- /dev/null +++ b/src/System/Random.h @@ -0,0 +1,2 @@ +#pragma once +int random(); \ No newline at end of file diff --git a/src/System/System.c b/src/System/System.c new file mode 100644 index 00000000..77ee6af6 --- /dev/null +++ b/src/System/System.c @@ -0,0 +1,12 @@ +#include "System.h" +#include +#include +void restart(){ + uint8 good = 0x02; + while (good & 0x02) + good = inportb(0x64); + outportb(0x64, 0xFE); +} +void shutdown(){ + __asm__ __volatile__("int $0x10"); +} diff --git a/src/System/System.h b/src/System/System.h new file mode 100644 index 00000000..7f0a1421 --- /dev/null +++ b/src/System/System.h @@ -0,0 +1,3 @@ +#pragma once +void restart(); +void shutdown(); \ No newline at end of file diff --git a/src/System/SystemTime.c b/src/System/SystemTime.c new file mode 100644 index 00000000..e879a83a --- /dev/null +++ b/src/System/SystemTime.c @@ -0,0 +1,52 @@ +#include"SystemTime.h" +#include"IO.h" + +long long TimeAtBoot = 0; +int readPit(void) { + unsigned count = 0; + cli(); + outportb(0x43,0b0000000); + count = inportb(0x40); + count |= inportb(0x40)<<8; + return count; +} +void setPit(unsigned count) { + cli(); + outportb(0x40,count&0xFF); // Low byte + outportb(0x40,(count&0xFF00)>>8); // High byte + return; +} + +int getSeconds(){ + int cmos_address = 0x70; + int cmos_data = 0x71; + outportb(cmos_address, 0x0); + int second = inportb(cmos_data); + second = (second & 0x0F) + ((second / 16) * 10); + return second; +} +int getMinutes(){ + int cmos_address = 0x70; + int cmos_data = 0x71; + outportb(cmos_address, 0x02); + int minute = inportb(cmos_data); + minute = (minute & 0x0F) + ((minute / 16) * 10); + return minute; +} +int getHours(){ + int cmos_address = 0x70; + int cmos_data = 0x71; + outportb(cmos_address, 0x04); + int hour = inportb(cmos_data); + hour = (hour & 0x0F) + ((hour / 16) * 10); + return hour; +} +void time_init(){ + TimeAtBoot = (getSeconds()+(getMinutes()*60)+(getHours()*3600)); +} +long long currentTime(){ + return (getSeconds()+(getMinutes()*60)+(getHours()*3600)); +} +long long getTimeFromBoot(){ + return (getSeconds()+(getMinutes()*60)+(getHours()*3600))-TimeAtBoot; +} \ No newline at end of file diff --git a/src/System/SystemTime.h b/src/System/SystemTime.h new file mode 100644 index 00000000..99af4ff6 --- /dev/null +++ b/src/System/SystemTime.h @@ -0,0 +1,7 @@ +#pragma once +void time_init(); +int getSeconds(); +int getMinutes(); +int getHours(); +long long getTimeFromBoot(); +long long currentTime(); \ No newline at end of file diff --git a/src/System/Time.asm b/src/System/Time.asm new file mode 100644 index 00000000..9a387d30 --- /dev/null +++ b/src/System/Time.asm @@ -0,0 +1 @@ +;Time.asm \ No newline at end of file diff --git a/src/Terminal-Runtime/Terminal-Runtime.c b/src/Terminal-Runtime/Terminal-Runtime.c new file mode 100644 index 00000000..d5a6fffe --- /dev/null +++ b/src/Terminal-Runtime/Terminal-Runtime.c @@ -0,0 +1,98 @@ +#include"Terminal-Runtime.h" +#include +#include +#include +#include +#include +int runFile(char * in){ + if(readFile(in)[0]!=0){ + printC('\n'); + int * pro = (int *)"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + for(int i = 0;i +int length(string abc){ + for(int i = 0;;i++) + if(abc[i]=='\0')return i; +} +string reverse(string in){ + string out = (string)""; + int temp = 0; + for(int i = length(in)-1;i>-1;i--){ + out[temp] = in[i]; + temp++; + } + return out; +} +string toString(int val){ + if(val==0)return (string)"0"; + string out = (string)""; + int base = 10; + char buf[32] = {0}; + int i = 30; + for(; val && i ; --i, val /= base) + buf[i] = "0123456789abcdef"[val % base]; + out = &buf[i+1]; + return out; +} +int parseInt(string a){ + int n = length(a); + int out = 0; + int ae = 1; + for(int i = n-1;i>-1;i--){ + out+=(a[i]-'0')*ae; + ae*=10; + } + return out; +} +int max(int a,int b){ + if(a>b)return a; + else return b; +} +int equal(string a,string b){ + for(int i = 0;i +#include +#include +#include +#include +#include +void printLogo(); +int kmain(){ + screen_init(); + clearScreen(); + time_init(); + printCenter(2,"Welcome to",0x0b); + Screen->cursorY = 5; + printLogo(); + setCursorPosition(-1,-1); + printCenter(15,"Opreating System",0x0c); + printCenter(17,"Press Any Key to start",0x09); + printCenter(24,"(C) Krish",0x0f); + readChar(); + clearScreen(); + shell_main(); + for(;;){} + return 0; +} \ No newline at end of file diff --git a/src/kernel_loader.asm b/src/kernel_loader.asm new file mode 100644 index 00000000..585bb694 --- /dev/null +++ b/src/kernel_loader.asm @@ -0,0 +1,12 @@ +bits 32 + dd 0x1BADB002 + dd 0x0 + dd - 0x1BADB002 + +extern _kmain + cli + call _kmain + jmp $ + + +