00001 /* ndk - [ ndk.c ] 00002 * 00003 * Contains the main source file for the ndk 00004 * operating system. This is where the system 00005 * comes alive! 00006 * 00007 * Please see: 00008 * /doc/* 00009 * /src/* 00010 * 00011 * (c)2002 dcipher / neuraldk 00012 * www.neuraldk.org 00013 */ 00014 00015 #include "multiboot.h" 00016 #include "pic.h" 00017 #include "idt.h" 00018 #include "gdt.h" 00019 #include "task.h" 00020 #include "vm86.h" 00021 #include "rZero.h" 00022 #include "pager.h" 00023 #include "pmode.h" 00024 #include "memory.h" 00025 #include "console.h" 00026 #include "descgate.h" 00027 00028 // search for VIDINC to make tasks increment video memory again 00029 00030 /* The following are for the multitasking test 00031 * I can't use local variables, because they're 00032 * assigned to the stack in C, and I haven't 00033 * defined separate stacks for each tasks yet ;) 00034 */ 00035 char *videoOne = (char *)0x000B8000 + 0xA0; 00036 char *videoTwo = (char *)0x000B8002 + 0xA0; 00037 char *videoThree = (char *)0x000B8004 + (0xA0 * 11); 00038 char *videoFour = (char *)0x000b8004 + (0xA0 * 12); 00039 00040 #define TASK_STACK_SIZE 4096 00041 #define MAX_TASKS 5 00042 00043 Task task[MAX_TASKS]; 00044 TSS tss[MAX_TASKS]; 00045 char *p0_stack[MAX_TASKS][TASK_STACK_SIZE]; 00046 char *p3_stack[MAX_TASKS][TASK_STACK_SIZE]; 00047 00048 /* 00049 char *stackOne[TASK_STACK_SIZE]; 00050 char *stackTwo[TASK_STACK_SIZE]; 00051 char *stackThree[TASK_STACK_SIZE]; 00052 Task taskOne, taskTwo, taskMain, taskGateTask; 00053 TSS tssOne, tssTwo, tssMain, tssGateTask; 00054 */ 00055 00056 void jobOne(void); 00057 void jobTwo(void); 00058 void jobGateTask(void); 00059 00060 void temp(void); 00061 00062 int bssCheck; 00063 00064 //char *regPrint = "-> Reg: 0x%x .\n"; 00065 00066 void ndkStart(unsigned long magic, unsigned long addr) { 00067 /* div by zero test! */ 00068 void (*rZeroFunction)(void); 00069 void (*rZeroSetProgress)(long); 00070 int x = 3, y = 0; 00071 short *rmIDT = (short *)0x00001000; 00072 short c; 00073 long cs, eip; 00074 long *pages = (long *)0xffc00000; 00075 00076 int i; 00077 long progress = 0; 00078 00079 long linearAddr; 00080 long physAddr; 00081 00082 //stop: goto stop; 00083 00084 /* for the time being, I'll keep this here */ 00085 //mb_main(magic, addr); 00086 00087 //cls(); 00088 consoleInit(); 00089 //consoleOut("0x%8x 0x%8x 0x%8x\n", *consoleOut, consoleOut, consoleOut); 00090 //consoleOut("tesing, and stuff 0x%8x\n"); 00091 multibootInit(magic, addr); 00092 pagerInit(); 00093 idtInit(); 00094 /* setup the PIC */ 00095 picInit(); 00096 rZeroInit(); 00097 timerInit(); 00098 vm86Init(); 00099 memoryInit(); 00100 00101 00102 /* 00103 consoleOut("Allocating a physical page!\n"); 00104 physAddr = (long)memoryAllocUnmappedPage(); 00105 consoleOut("physical address: 0x%8x\n", physAddr); 00106 physAddr = (long)memoryAllocUnmappedPage(); 00107 consoleOut("physical address: 0x%8x\n", physAddr); 00108 physAddr = (long)memoryAllocUnmappedPage(); 00109 consoleOut("physical address: 0x%8x\n", physAddr); 00110 physAddr = (long)memoryAllocUnmappedPage(); 00111 consoleOut("physical address: 0x%8x\n", physAddr); 00112 memoryStackSpecs(&appStack); 00113 */ 00114 00115 // allocate 5 pages 00116 for(i = 0; i < 5; i++) { 00117 linearAddr = (long)memoryAllocPage(); 00118 //linearAddr = 0x80000000; 00119 consoleOut("linear addr: 0x%8x\n", linearAddr); 00120 00121 physAddr = (long)pagerLinToPhys((void *)(linearAddr + 4)); 00122 consoleOut("from pagerLinToPhys: 0x%8x\n", physAddr); 00123 } 00124 00125 consoleOut("Writting to page!\n"); 00126 *(long *)linearAddr = 0xffffff; 00127 00128 //consoleOut("Allocating another page!\n"); 00129 //linearAddr = (long)memoryAllocPage(); 00130 //consoleOut("linear addr: 0x%8x\n", linearAddr); 00131 00132 stackDisplay(&appStack.used); 00133 00134 consoleOut("Deallocating first page!\n"); 00135 memoryFreePage((void *)0x80000000); 00136 //memoryFreePage(linearAddr); 00137 00138 stackDisplay(&appStack.used); 00139 00140 // will cause a page fault :) 00141 //consoleOut("Trying to write to page again!\n"); 00142 //*(long *)linearAddr = 0xffffffff; 00143 00144 consoleOut("Allocating another page!\n"); 00145 linearAddr = (long)memoryAllocPage(); 00146 consoleOut("linear addr: 0x%8x\n", linearAddr); 00147 physAddr = (long)pagerLinToPhys((void *)linearAddr); 00148 consoleOut("physical addr: 0x%8x\n", physAddr); 00149 00150 //memoryFreePage(0x80000000); 00151 00152 /* 00153 for(i = 0; i < 4095; i++) 00154 consoleOut("0x%x ", pages[i]); 00155 */ 00156 00157 //linearAddr = memoryAllocatePages(1); 00158 //consoleOut("Newly allocate space: 0x%8x\n", linearAddr); 00159 //consoleOut("bssCheck: 0x%x\n", &bssCheck); 00160 00161 // enable alignment flag for kernel 00162 /* 00163 asm( 00164 "pushf\n" 00165 "pop %eax\n" 00166 "or $262144, %eax\n" 00167 // IOPL 3 00168 // "or $0x3000, %eax\n" 00169 "push %eax\n" 00170 "popf\n" 00171 ); 00172 */ 00173 00174 //consoleOut("main: %x\n", rZeroImports[0].symbolLocation); 00175 //consoleOut("splashScreen: %x\n", rZeroImports[4].symbolLocation); 00176 //consoleOut("rZero...\n"); 00177 // NOTE: these are hardcoded, and should be changed!!! 00178 rZeroFunction = (void (*)(void))rZeroImports[4].symbolLocation; 00179 rZeroSetProgress = (void (*)(long))rZeroImports[3].symbolLocation; 00180 00181 //x = x / y; 00182 /* 00183 c = 0; 00184 for(i = 0; i < 0x11; i++) { 00185 eip = rmIDT[i*2]; 00186 cs = rmIDT[i*2+1]; 00187 consoleOut("%x, %x:%x\n", i, (long)(cs & 0x0000ffff), (long)(eip & 0x0000ffff)); 00188 } 00189 */ 00190 //consoleOut("0x%x\n", vm86IntHandler); 00191 //consoleOut("0x%x\n", &iretInstruction); 00192 //vm86Test(); 00193 //rZeroFunction(); 00194 //for(;;) { 00195 //consoleOut("%d\n", timerGetTicks()); 00196 //} 00197 00198 /* Exception handler tests... :) 00199 //x = x / y; 00200 00201 // test 00202 createDescriptor(&GDT, 4, 0x0, 0xffffff, D_NOT_PRESENT); 00203 asm( 00204 "mov $0x11111111, %eax\n" 00205 "mov $0x22222222, %ebx\n" 00206 "mov $0x33333333, %ecx\n" 00207 "mov $0x44444444, %edx\n" 00208 "mov $0x12345678, %esi\n" 00209 "mov $0x87654321, %edi\n" 00210 "ljmp $0x28, $0x87654321"); 00211 */ 00212 00213 //taskFillTSS(&tss[0], 0, 0); 00214 tss[0].ldtr = 0; 00215 tss[0].fs = tss[0].gs = 0; 00216 tss[0].ds = tss[0].es = SEL_P0_DATA; 00217 tss[0].ss = SEL_P0_STACK; 00218 tss[0].cs = SEL_P0_CODE; 00219 tss[0].eflags = 0x202L | 1 << 18; // IOPL0, STI, Alignment Check 00220 tss[0].esp = 0; 00221 tss[0].eip = 0; 00222 tss[0].cr3 = getCR3(); 00223 taskCreate(&task[0], &tss[0]); 00224 //consoleOut("Task Main: 0x%x\n", task[0].selector); 00225 00226 //consoleOut("CR3: 0x%x\n", getCR3()); 00227 00228 //consoleOut("Loading TR\n"); 00229 loadTaskReg(task[0].selector); 00230 00231 /* 00232 taskFillTSS(&tss[3], (long)temp, 00233 (long)p0_stack[3] + TASK_STACK_SIZE, 00234 (long)p3_stack[3] + TASK_STACK_SIZE); 00235 tss->eflags = 0x202L | 1 << 18; // PL0, STI, Alignment Check 00236 tss[3].ds = tss[3].es = SEL_P0_DATA | 3; 00237 tss[3].ss = SEL_P0_STACK | 3; 00238 tss[3].cs = SEL_P0_CODE | 3; 00239 00240 //taskCreate(&taskGateTask, &tssGateTask); 00241 taskCreateSelector(&task[3]); 00242 createGate(&IDT, 128, 0, task[3].selector/8, D_TASK); 00243 */ 00244 00245 consoleOut("Creating task #1\n"); 00246 /* 00247 taskFillTSS(&tss[1], (long)jobOne, (long)p0_stack[1] + TASK_STACK_SIZE, 00248 (long)p3_stack[1] + TASK_STACK_SIZE); 00249 taskCreate(&task[1], &tss[1]); 00250 */ 00251 taskNew((void *)jobOne, NULL, 0); 00252 //consoleOut("Task 1: 0x%x\n", task[1].selector); 00253 00254 00255 consoleOut("Creating task #2\n"); 00256 taskFillTSS(&tss[2], (long)jobTwo, (long)p0_stack[2] + TASK_STACK_SIZE, 00257 (long)p3_stack[2] + TASK_STACK_SIZE); 00258 taskCreate(&task[2], &tss[2]); 00259 //consoleOut("Task 2: 0x%x\n", task[2].selector); 00260 00261 // make a call gate 00262 //consoleOut("Creating task gate\n"); 00263 /* 00264 taskFillTSS(&tss[3], (long)temp, (long)p0_stack[3] + TASK_STACK_SIZE, 00265 (long)p3_stack[3] + TASK_STACK_SIZE); 00266 //taskCreate(&task[3], &tss[3]); 00267 taskCreateTaskGate(&task[3], &tss[3]); 00268 */ 00269 //rZeroSetProgress(128); 00270 00271 /* 00272 consoleOut("0x%8x\n", rZeroSetProgress); 00273 asm volatile ( 00274 "pushl $128\n" 00275 "call *%%eax\n" 00276 "popl %%eax\n" 00277 : 00278 : "a" (rZeroSetProgress) 00279 ); 00280 */ 00281 rZeroSetProgress(128); 00282 //rZeroFunction(); 00283 taskNew((void *)*rZeroFunction, NULL, TASK_P0); 00284 rZeroSetProgress(180); 00285 00286 consoleOut("Video loop\n"); 00287 //loopFour: 00288 //VIDINC (*videoFour)++; 00289 //asm("int $0x0\n"); 00290 //rZeroSetProgress(progress++); 00291 // goto loopFour; 00292 while(1); 00293 00294 00295 asm("stop: \n hlt \n jmp stop\n"); 00296 return; 00297 } 00298 00299 /* multitasking test!!! */ 00300 void jobOne(void) { 00301 // Should NOT execute, because of IOPL! 00302 //asm("cli"); 00303 //consoleOut("Task Gate Link: 0x%x, EFlags: 0x%x", tss[3].link, tss[3].eflags); 00304 //if(tss[3].eflags & 16384) 00305 // consoleOut("NT\n"); 00306 //else consoleOut("\n"); 00307 00308 //asm("int $128\n"); 00309 loopOne: 00310 //VIDINC (*videoOne)++; 00311 // for overflow flag... just a test 00312 /* 00313 asm("movl $0xffffffff, %%eax\n" 00314 "addl $0x1, %%eax\n" 00315 : 00316 : 00317 : "eax"); 00318 */ 00319 goto loopOne; 00320 } 00321 00322 void jobTwo(void) { 00323 //consoleOut("Task Gate Link: 0x%x, EFlags: 0x%x", tss[3].link, tss[3].eflags); 00324 /* 00325 asm( 00326 //"pushl %0\n" 00327 "pushl %1\n" 00328 "pushl %0\n" 00329 "call consoleOut\n" 00330 "addl $8, %%esp\n" 00331 : 00332 : "g" (regPrint), "g" (tss[3].eflags) 00333 ); 00334 if(tss[3].eflags & 16384) 00335 consoleOut("NT\n"); 00336 else consoleOut("\n"); 00337 00338 */ 00339 //consoleOut("task 1 eflags: 0x%x .\n", tss[1].eflags); 00340 loopTwo: 00341 // VIDINC (*videoTwo)++; 00342 //asm("int $128\n"); 00343 goto loopTwo; 00344 } 00345 00346 /* 00347 asm( 00348 ".global temp\n" 00349 "temp:\n" 00350 "jmp temp\n" 00351 */ 00352 /* 00353 "push %eax\n" 00354 "push %ds\n" 00355 "pusha\n" 00356 "mov $0x08, %ax\n" 00357 "mov %ax, %ds\n" 00358 "call jobGateTask\n" 00359 "popa\n" 00360 "pop %ds\n" 00361 "pop %ax\n" 00362 */ 00363 /* 00364 "iretl\n" 00365 // following line needed because it's a task gate!!! 00366 "jmp temp\n"); 00367 */ 00368 00369 /* This is a task gate... somewhere here this gate must be 00370 * added to the list of on-going tasks... 00371 */ 00372 /* 00373 void jobGateTask(void) { 00374 //int i; 00375 //for(i = 0; i < 1000; i++) 00376 //consoleOut("->Task Gate Link: 0x%x, EFlags: 0x%x\n", tss[3].link, tss[3].eflags); 00377 00378 asm( 00379 //"pushl %0\n" 00380 "pushf\n" 00381 "pushl %0\n" 00382 "call consoleOut\n" 00383 "addl $8, %%esp\n" 00384 : 00385 : "g" (regPrint) 00386 ); 00387 loopThree: 00388 (*videoThree)++; 00389 goto loopThree; 00390 }*/