├── README.md ├── build_cygwin.sh ├── build_linux.sh ├── include ├── calc.h ├── game.h ├── kb.h ├── screen.h ├── screen_substr.h ├── string.h ├── system.h └── types.h ├── kasm.o ├── kc.o ├── kernel.asm ├── kernel.bin ├── kernel.c └── link.ld /README.md: -------------------------------------------------------------------------------- 1 | # CSE3202-OS-Assignment 2 | 3 | This is a simple OS assignment for my university OS course. 4 | I have followed a few videos from IKnow's youtube series: https://www.youtube.com/watch?v=rr-9w2gITDM&list=PLBK_0GOKgqn3hjBdrf5zQ0g7UkQP_KLC3 5 | 6 | But I've fixed critical flaws and bugs in this version. 7 | 8 | # Just a demo 9 | 10 | This is not intended to be any useful OS. It is just a demo for students. 11 | 12 | # How to run on Linux 13 | 14 | 1. Install packages: nasm, gcc, qemu 15 | sudo apt-get install nasm 16 | sudo apt-get install gcc 17 | sudo apt-get install qemu 18 | 2. Apply execute permission on build_linux.sh 19 | 3. Run build_linux.sh 20 | ./build.sh 21 | 22 | # How to run on Windows 23 | 24 | 1. Download preconfigured cygwin from http://www.mediafire.com/file/hakdoz32a7kspv6/IknowPackageOS_EP4_cross_tools.7z 25 | It has the necessary packages install and configured to run the OS in qemu 26 | Alternatively, download cygwin from the official website and install qemu, nasm and gcc add add them to path variable yourself 27 | 28 | 2. Open cygwin.bat 29 | 3. Navigate to the OS folder 30 | 4. RUn ./build_cygwin.sh 31 | -------------------------------------------------------------------------------- /build_cygwin.sh: -------------------------------------------------------------------------------- 1 | nasm -f elf -o kasm.o kernel.asm 2 | i586-elf-gcc -m32 -o kc.o -c kernel.c 3 | i586-elf-ld -m elf_i386 -T link.ld -o kernel.bin kasm.o kc.o 4 | qemu-system-i386 -kernel kernel.bin 5 | -------------------------------------------------------------------------------- /build_linux.sh: -------------------------------------------------------------------------------- 1 | nasm -f elf32 kernel.asm -o kasm.o 2 | gcc -m32 -c kernel.c -o kc.o 3 | ld -m elf_i386 -T link.ld -o kernel.bin kasm.o kc.o 4 | qemu-system-i386 -kernel kernel.bin 5 | -------------------------------------------------------------------------------- /include/calc.h: -------------------------------------------------------------------------------- 1 | #ifndef CALC_H 2 | #define CALC_H 3 | 4 | int32 strToInt(string str, uint8 len) 5 | { 6 | int32 res = 0; 7 | uint16 i = 0; 8 | if (str[0] == '-') i = 1; 9 | for (i; i < len && str[i] != '\0'; ++i) 10 | res = res*10 + str[i] - '0'; 11 | if (str[0] == '-') 12 | return -res; 13 | else 14 | return res; 15 | } 16 | 17 | void calculator() { 18 | int32 a, b, res; 19 | char op; 20 | 21 | print("KUETsoft fx-038 KS calculator\n"); 22 | print("a = +\n"); 23 | print("s = -\n"); 24 | print("m = *\n"); 25 | print("d = /\n"); 26 | print("exit = return to OS\n"); 27 | while (1) { 28 | print("> "); 29 | string inp = readStr(); 30 | if (strEql(inp, "exit")) break; 31 | uint8 i=0; 32 | while (inp[i] >= '0' && inp[i] <= '9' || inp[i] == '-') i++; 33 | a = strToInt(inp, i); 34 | 35 | while (inp[i] != 0 && inp[i] != 'a' && inp[i] != 's' && inp[i] != 'm' && inp[i] != 'd') i++; 36 | if (inp[i] == 0) { 37 | print("Input Error\n"); 38 | continue; 39 | } 40 | op = inp[i]; 41 | 42 | while (inp[i] != 0 && inp[i] != '-' && (inp[i] < '0' || inp[i] > '9')) i++; 43 | if (inp[i] == 0) { 44 | print("Input Error\n"); 45 | continue; 46 | } 47 | b = strToInt((string) (inp + i), 999); 48 | 49 | if (op == 'a') res = a + b; 50 | if (op == 's') res = a - b; 51 | if (op == 'm') res = a * b; 52 | if (op == 'd') res = a / b; 53 | 54 | printnum(res); 55 | print("\n"); 56 | } 57 | } 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /include/game.h: -------------------------------------------------------------------------------- 1 | #ifndef GAME_H 2 | #define GAME_H 3 | 4 | struct player { 5 | uint8 x; 6 | uint8 y; 7 | char c; 8 | }; 9 | struct player a = {4, 4, 'A'}; 10 | struct player b = {20, 20, 'B'}; 11 | 12 | uint8 boundX(uint8 x) { 13 | if (x < 1) return 1; 14 | if (x >= sw-1) return sw-2; 15 | return x; 16 | } 17 | uint8 boundY(uint8 y) { 18 | if (y < 1) return 1; 19 | if (y >= sh-1) return sh-2; 20 | return y; 21 | } 22 | 23 | void game_putchar(char c, uint8 x, uint8 y) { 24 | string vidmem = (string) 0xb8000; 25 | vidmem[(y*sw+x)*sd]=c; 26 | vidmem[(y*sw+x)*sd+1] = 0x0F; 27 | } 28 | void game_printborder(char c) { 29 | uint16 i,j; 30 | for (i=0, j=0; i 0) { 86 | printch('\b'); 87 | i--; 88 | buffstr[i] = 0; 89 | } 90 | break; 91 | /* case 15: 92 | printch('\t'); Tab button 93 | buffstr[i] = '\t'; 94 | i++; 95 | break;*/ 96 | case 16: 97 | printch('q'); 98 | buffstr[i] = 'q'; 99 | i++; 100 | break; 101 | case 17: 102 | printch('w'); 103 | buffstr[i] = 'w'; 104 | i++; 105 | break; 106 | case 18: 107 | printch('e'); 108 | buffstr[i] = 'e'; 109 | i++; 110 | break; 111 | case 19: 112 | printch('r'); 113 | buffstr[i] = 'r'; 114 | i++; 115 | break; 116 | case 20: 117 | printch('t'); 118 | buffstr[i] = 't'; 119 | i++; 120 | break; 121 | case 21: 122 | printch('y'); 123 | buffstr[i] = 'y'; 124 | i++; 125 | break; 126 | case 22: 127 | printch('u'); 128 | buffstr[i] = 'u'; 129 | i++; 130 | break; 131 | case 23: 132 | printch('i'); 133 | buffstr[i] = 'i'; 134 | i++; 135 | break; 136 | case 24: 137 | printch('o'); 138 | buffstr[i] = 'o'; 139 | i++; 140 | break; 141 | case 25: 142 | printch('p'); 143 | buffstr[i] = 'p'; 144 | i++; 145 | break; 146 | case 26: 147 | printch('['); 148 | buffstr[i] = '['; 149 | i++; 150 | break; 151 | case 27: 152 | printch(']'); 153 | buffstr[i] = ']'; 154 | i++; 155 | break; 156 | case 28: 157 | printch('\n'); 158 | buffstr[i] = 0; 159 | i++; 160 | reading = 0; 161 | break; 162 | /* case 29: 163 | printch('q'); Left Control 164 | buffstr[i] = 'q'; 165 | i++; 166 | break;*/ 167 | case 30: 168 | printch('a'); 169 | buffstr[i] = 'a'; 170 | i++; 171 | break; 172 | case 31: 173 | printch('s'); 174 | buffstr[i] = 's'; 175 | i++; 176 | break; 177 | case 32: 178 | printch('d'); 179 | buffstr[i] = 'd'; 180 | i++; 181 | break; 182 | case 33: 183 | printch('f'); 184 | buffstr[i] = 'f'; 185 | i++; 186 | break; 187 | case 34: 188 | printch('g'); 189 | buffstr[i] = 'g'; 190 | i++; 191 | break; 192 | case 35: 193 | printch('h'); 194 | buffstr[i] = 'h'; 195 | i++; 196 | break; 197 | case 36: 198 | printch('j'); 199 | buffstr[i] = 'j'; 200 | i++; 201 | break; 202 | case 37: 203 | printch('k'); 204 | buffstr[i] = 'k'; 205 | i++; 206 | break; 207 | case 38: 208 | printch('l'); 209 | buffstr[i] = 'l'; 210 | i++; 211 | break; 212 | case 39: 213 | printch(';'); 214 | buffstr[i] = ';'; 215 | i++; 216 | break; 217 | case 40: 218 | printch((char)44); // Single quote (') 219 | buffstr[i] = (char)44; 220 | i++; 221 | break; 222 | case 41: 223 | printch((char)44); // Back tick (`) 224 | buffstr[i] = (char)44; 225 | i++; 226 | break; 227 | /* case 42: Left shift 228 | printch('q'); 229 | buffstr[i] = 'q'; 230 | i++; 231 | break; 232 | case 43: \ (< for somekeyboards) 233 | printch((char)92); 234 | buffstr[i] = 'q'; 235 | i++; 236 | break;*/ 237 | case 44: 238 | printch('z'); 239 | buffstr[i] = 'z'; 240 | i++; 241 | break; 242 | case 45: 243 | printch('x'); 244 | buffstr[i] = 'x'; 245 | i++; 246 | break; 247 | case 46: 248 | printch('c'); 249 | buffstr[i] = 'c'; 250 | i++; 251 | break; 252 | case 47: 253 | printch('v'); 254 | buffstr[i] = 'v'; 255 | i++; 256 | break; 257 | case 48: 258 | printch('b'); 259 | buffstr[i] = 'b'; 260 | i++; 261 | break; 262 | case 49: 263 | printch('n'); 264 | buffstr[i] = 'n'; 265 | i++; 266 | break; 267 | case 50: 268 | printch('m'); 269 | buffstr[i] = 'm'; 270 | i++; 271 | break; 272 | case 51: 273 | printch(','); 274 | buffstr[i] = ','; 275 | i++; 276 | break; 277 | case 52: 278 | printch('.'); 279 | buffstr[i] = '.'; 280 | i++; 281 | break; 282 | case 53: 283 | printch('/'); 284 | buffstr[i] = '/'; 285 | i++; 286 | break; 287 | case 54: 288 | printch('.'); 289 | buffstr[i] = '.'; 290 | i++; 291 | break; 292 | case 55: 293 | printch('/'); 294 | buffstr[i] = '/'; 295 | i++; 296 | break; 297 | /*case 56: 298 | printch(' '); Right shift 299 | buffstr[i] = ' '; 300 | i++; 301 | break;*/ 302 | case 57: 303 | printch(' '); 304 | buffstr[i] = ' '; 305 | i++; 306 | break; 307 | } 308 | } 309 | } 310 | return buffstr; 311 | } 312 | #endif 313 | -------------------------------------------------------------------------------- /include/screen.h: -------------------------------------------------------------------------------- 1 | #ifndef SCREEN_H 2 | #define SCREEN_H 3 | #include "types.h" 4 | #include "system.h" 5 | #include "string.h" 6 | int cursorX = 0, cursorY = 0; 7 | const uint8 sw = 80,sh = 25,sd = 2; //We define the screen width, height, and depth. 8 | void clearLine(uint8 from,uint8 to) 9 | { 10 | uint16 i = sw * from * sd; 11 | string vidmem=(string)0xb8000; 12 | for(i;i<(sw*to*sd);i+=2) 13 | { 14 | vidmem[i] = 0x0; 15 | vidmem[i+1] = 0x0F; 16 | } 17 | } 18 | void updateCursor() 19 | { 20 | unsigned temp; 21 | 22 | temp = cursorY * sw + cursorX; // Position = (y * width) + x 23 | 24 | outportb(0x3D4, 14); // CRT Control Register: Select Cursor Location 25 | outportb(0x3D5, temp >> 8); // Send the high byte across the bus 26 | outportb(0x3D4, 15); // CRT Control Register: Select Send Low byte 27 | outportb(0x3D5, temp); // Send the Low byte of the cursor location 28 | } 29 | void clearScreen() 30 | { 31 | clearLine(0,sh-1); 32 | cursorX = 0; 33 | cursorY = 0; 34 | updateCursor(); 35 | } 36 | 37 | void scrollUp(uint8 lineNumber) 38 | { 39 | string vidmem = (string)0xb8000; 40 | uint16 i = 0; 41 | clearLine(0,lineNumber-1); //updated 42 | for (i;i=sh-1) 64 | { 65 | scrollUp(1); 66 | } 67 | } 68 | 69 | void printch(char c) 70 | { 71 | string vidmem = (string) 0xb8000; 72 | switch(c) 73 | { 74 | case (0x08): 75 | if(cursorX > 0) 76 | { 77 | cursorX--; 78 | vidmem[(cursorY * sw + cursorX)*sd]=0x00; 79 | } 80 | break; 81 | /* case (0x09): 82 | cursorX = (cursorX + 8) & ~(8 - 1); 83 | break;*/ 84 | case ('\r'): 85 | cursorX = 0; 86 | break; 87 | case ('\n'): 88 | cursorX = 0; 89 | cursorY++; 90 | break; 91 | default: 92 | vidmem [((cursorY * sw + cursorX))*sd] = c; 93 | vidmem [((cursorY * sw + cursorX))*sd+1] = 0x0F; 94 | cursorX++; 95 | break; 96 | 97 | } 98 | if(cursorX >= sw) 99 | { 100 | cursorX = 0; 101 | cursorY++; 102 | } 103 | updateCursor(); 104 | newLineCheck(); 105 | } 106 | 107 | void print (string ch) 108 | { 109 | uint16 i = 0; 110 | uint8 length = strlength(ch); //Updated (Now we store string length on a variable to call the function only once) 111 | for(i;i "); 37 | inp = readStr(); 38 | if(strEql(inp,"cmd")) 39 | { 40 | print("You are allready in cmd\n"); 41 | } 42 | else if(strEql(inp,"clear")) 43 | { 44 | clearScreen(); 45 | } 46 | else if(strEql(inp,"game")) 47 | { 48 | clearScreen(); 49 | game(); 50 | clearScreen(); 51 | } 52 | else if(strEql(inp,"calc")) 53 | { 54 | clearScreen(); 55 | calculator(); 56 | clearScreen(); 57 | } 58 | else if(strEql(inp,"substr")) 59 | { 60 | print("String to match: "); 61 | inp = readStr(); 62 | screen_substr(inp); 63 | } 64 | else if(strEql(inp,"strlen")) 65 | { 66 | print("Enter string: "); 67 | inp = readStr(); 68 | print("The length of string is: "); 69 | printnum(strlength(inp)); 70 | print("\n"); 71 | } 72 | else if(strEql(inp,"clearline")) 73 | { 74 | print("Enter line no: "); 75 | inp = readStr(); 76 | uint8 lineno = (uint8) strToInt(inp, 999); 77 | if (lineno < 1 || lineno > cursorY-1) { 78 | print("Line no is out of screen\n"); 79 | continue; 80 | } 81 | clearLine(lineno-1, lineno); 82 | uint8 i,j; 83 | string vidmem = (string)0xb8000; 84 | for (i = lineno-1 +1; i<=cursorY; i++) { 85 | for (j = 0; j