00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "proc/proc.h"
00019 #include "core/kerror.h"
00020 #include "common/ktypes.h"
00021 #include "mm/mm.h"
00022 #include "common/kconst.h"
00023 #include "core/ktask.h"
00024 #include "core/kinit.h"
00025 #include "common/ds/queue.h"
00026 #include "core/kint.h"
00027 #include "gui/svga.h"
00028 #include "fs/fat12.h"
00029
00030 LDT _ldt[MAX_PROC] __attribute__((aligned (8)));
00031 SEG_DESC _ldte[MAX_PROC][3] __attribute__((aligned (8)));
00032
00033 PROC _proc[MAX_PROC];
00034
00035 DW cur_pid = MAX_PROC+1;
00036
00037 DB which_task = 0;
00038
00039 SDB create(char *pathname)
00040 {
00041 DB pid, i, j;
00042 DD addr, base, limit;
00043 DW flags = 0;
00044 SDD pg_num[MAX_PROC_SIZE/_4KB] = {-1};
00045
00046 SEG_DESC temp;
00047 char *c;
00048
00049 for(pid=0 ; pid < MAX_PROC ; pid++)
00050 {
00051 if(_proc[pid].avl == _true)
00052 {
00053 _proc[pid].avl = _false;
00054 break;
00055 }
00056 }
00057
00058 printf("\nPID: %d\n",pid);
00059
00060 if(pid == MAX_PROC)
00061 {
00062 printf("\nFork Failure");
00063 return FORK_FAILURE;
00064 }
00065
00066 for(i = 0 ; i < (MAX_PROC_SIZE/_4KB) ; i++)
00067 {
00068 pg_num[i] = findpage();
00069
00070 if(pg_num[i] == PAGE_NOT_FOUND)
00071 {
00072 for(j = 0 ; j < i ; j++)
00073 freepage(pg_num[j]);
00074
00075 return FORK_FAILURE;
00076 }
00077
00078 addr = KERNEL_SIZE + (pg_num[i] * _4KB);
00079
00080 printf("\tA %x Pg %d",addr,pg_num[i]);
00081 _pgte[pid][i] = addr | 7;
00082 }
00083
00084
00085 _proc[pid].esp = MAX_PROC_SIZE-1;
00086 _proc[pid].eip = 0;
00087
00088 enq(&ready_q,pid);
00089 load(pathname,pid);
00090 return pid;
00091 }
00092
00093 void schedule()
00094 {
00095 SEG_DESC tmp, *t;
00096 clearDESC(&tmp);
00097 DW ldt_flags = 0x882;
00098
00099
00100 if(findq(&ready_q,GUI_PID) == 0)
00101 {
00102 cur_pid = GUI_PID;
00103 }
00104 else
00105 {
00106 cur_pid = deq(&ready_q);
00107
00108 if(cur_pid == NULL_PID)
00109 cur_pid = deq(&ready_q);
00110 }
00111
00112 if(_proc[cur_pid].avl)
00113 {
00114 if(_proc[NULL_PID].avl)
00115 {
00116 while(1)
00117 printf("in where it shouldn't be\n");
00118 memcpy((void *)(KERNEL_SIZE),(void *)null_proc,512);
00119 }
00120
00121 cur_pid = NULL_PID;
00122 }
00123
00124 createDESC(&tmp,(_ldt[cur_pid].hibase<<16)|_ldt[cur_pid].lobase,_ldt[cur_pid].limit,ldt_flags);
00125 addDesc(LDT_USR_SEL,&tmp);
00126
00127 _task[which_task].eip = _proc[cur_pid].eip;
00128 _task[which_task].es = _proc[cur_pid].es;
00129 _task[which_task].fs = _proc[cur_pid].fs;
00130 _task[which_task].gs = _proc[cur_pid].gs;
00131
00132 _task[which_task].eax = _proc[cur_pid].eax;
00133 _task[which_task].ebx = _proc[cur_pid].ebx;
00134 _task[which_task].ecx = _proc[cur_pid].ecx;
00135 _task[which_task].edx = _proc[cur_pid].edx;
00136 _task[which_task].esi = _proc[cur_pid].esi;
00137 _task[which_task].edi = _proc[cur_pid].edi;
00138 _task[which_task].ebp = _proc[cur_pid].ebp;
00139
00140 _task[which_task].cs = _proc[cur_pid].cs;
00141 _task[which_task].ds = _proc[cur_pid].ds;
00142 _task[which_task].ss = _proc[cur_pid].ss;
00143 _task[which_task].esp = _proc[cur_pid].esp;
00144 _task[which_task].ss0 = _system.ss0;
00145 _task[which_task].esp0 = _system.esp0;
00146 _task[which_task].ldt_sel = LDT_USR_SEL*8;
00147 _task[which_task].eflags = _proc[cur_pid].eflags;
00148 _task[which_task].cr3 = _proc[cur_pid].cr3;
00149
00150 _task[which_task].io_map = 0x70;
00151
00152 which_task = !which_task;
00153
00154
00155 t = (SEG_DESC*)(GDT_BASE+SYS_TSS_SEL*8);
00156 t->flags_8_15 &= ~0x2;
00157 asm("ltr %%ax"::"a"(SYS_TSS_SEL*8));
00158 t->flags_8_15 &= ~0x2;
00159
00160 if(which_task)
00161 {
00162 t = (SEG_DESC*)(GDT_BASE+TASK1_TSS_SEL*8);
00163 t->flags_8_15 &= ~0x2;
00164 asm("lcall %0,$0"::"i"(TASK1_TSS_SEL*8));
00165 }
00166 else
00167 {
00168 t = (SEG_DESC*)(GDT_BASE+TASK2_TSS_SEL*8);
00169 t->flags_8_15 &= ~0x2;
00170 asm("lcall %0,$0"::"i"(TASK2_TSS_SEL*8));
00171 }
00172 }
00173
00174
00175 void proc_init()
00176 {
00177 DB pid;
00178 DB pg_dir_offset = (KERNEL_SIZE/_4MB)+((KERNEL_SIZE%_4MB)?1:0);
00179 DW flags = 0;
00180 DD base, limit;
00181
00182 for(pid=0 ; pid < MAX_PROC ; pid++)
00183 {
00184 _proc[pid].avl = _true;
00185 _proc[pid].msg_q_delim = 0;
00186 _proc[pid].wait_int_num = 0xFFFF;
00187 _proc[pid].time_out = 0;
00188
00189 _pgde[pid+pg_dir_offset] = ((DD)_pgte[pid]) | 7;
00190
00191 clearDESC(&_ldte[pid][0]);
00192 clearDESC(&_ldte[pid][1]);
00193 clearDESC(&_ldte[pid][2]);
00194
00195 flags = ((F_G|F_D_B)<<8)|F_P|F_S|F_TYPE_CODE|F_TYPE_R|F_SD_DPL_3;
00196 base = (pid+pg_dir_offset) << 22;
00197 limit = (MAX_PROC_SIZE/_4KB);
00198 createDESC(&_ldte[pid][0],base,limit,flags);
00199
00200 flags = ((F_G|F_D_B)<<8)|F_P|F_S|F_TYPE_DATA|F_TYPE_W|F_SD_DPL_3;
00201 base = (pid+pg_dir_offset) << 22;
00202 limit = (MAX_PROC_SIZE/_4KB);
00203 createDESC(&_ldte[pid][1],base,limit,flags);
00204
00205 flags = ((F_G|F_D_B)<<8)|F_P|F_S|F_TYPE_DATA|F_TYPE_W|F_SD_DPL_3|F_TYPE_E;
00206 base = (pid+pg_dir_offset) << 22;
00207 limit = 0;
00208 createDESC(&_ldte[pid][2],base,limit,flags);
00209
00210 _ldt[pid].hibase = (((DD)&_ldte[pid][0]) >> 16);
00211 _ldt[pid].lobase = (((DD)&_ldte[pid][0]) & 0xFFFF);
00212 _ldt[pid].limit = 3*8 - 1;
00213
00214 _proc[pid].cs = (0x0<<3)|(0x1<<2)|0x3;
00215 _proc[pid].ds = (0x1<<3)|(0x1<<2)|0x3;
00216 _proc[pid].ss = (0x2<<3)|(0x1<<2)|0x3;
00217 _proc[pid].es = (0x1<<3)|(0x1<<2)|0x3;
00218 _proc[pid].fs = (0x1<<3)|(0x1<<2)|0x3;
00219
00220 _proc[pid].cr3 = (_system.cr3 & 0xFFF) | (((DD)_pgde) & 0xFFFFF000);
00221 _proc[pid].eflags = 2 | (1<<9);
00222 }
00223 }
00224
00225
00226 void do_exit(DW pid)
00227 {
00228 DD i;
00229 printf("exit called\n");
00230 ginfo(400,350,"Exit Called");
00231 ginfo(400,400,itoa(pid,10));
00232
00233 remove(&ready_q,pid);
00234
00235 _proc[pid].avl = _true;
00236 _proc[pid].msg_q_delim = 0;
00237 _proc[pid].wait_int_num = 0xFFFF;
00238 _proc[pid].time_out = 0;
00239
00240 for(i = 0; i<(MAX_PROC_SIZE/_4KB);i++)
00241 {
00242 freepage(((_pgte[pid][i] ^ 7) - KERNEL_SIZE)/_4KB);
00243 }
00244 printf("exit pid : %d",pid);
00245
00246
00247 _Z11destroy_wint(pid);
00248
00249
00250 fscloseAll(pid);
00251 }
00252
00253 SDB fork()
00254 {
00255 SDB pid;
00256
00257 if(pid != FORK_FAILURE)
00258 {
00259
00260 _proc[pid].eax = 0;
00261
00262 _proc[cur_pid].eax = pid;
00263 }
00264 return pid;
00265 }
00266
00267 SDW load(char *fname,DW pid)
00268 {
00269 fs_request fs_r;
00270 fs_r.type = LOAD;
00271
00272 fs_r.load.fname = (DB *)fname;
00273 fs_r.from_pid = pid;
00274 if(addfsreq(&fs_r) != 0)
00275 {
00276 do_exit(pid);
00277 }
00278 else
00279 {
00280 remove(&ready_q,pid);
00281 enq(&fs_q,pid);
00282 }
00283 }
00284
00285 void forkNULL()
00286 {
00287 DB pid, i, j;
00288 DD addr, base, limit;
00289 DW flags = 0;
00290 SDD pg_num[MAX_PROC_SIZE/_4KB] = {-1};
00291
00292 SEG_DESC temp;
00293 char *c;
00294
00295 for(pid=0 ; pid < MAX_PROC ; pid++)
00296 {
00297 if(_proc[pid].avl == _true)
00298 {
00299 _proc[pid].avl = _false;
00300 break;
00301 }
00302 }
00303
00304 printf("\nPID: %d\n",pid);
00305
00306 if(pid == MAX_PROC)
00307 {
00308 printf("\nforkNULL Failure");
00309 return FORK_FAILURE;
00310 }
00311
00312 for(i = 0 ; i < (MAX_PROC_SIZE/_4KB) ; i++)
00313 {
00314 pg_num[i] = findpage();
00315
00316 if(pg_num[i] == PAGE_NOT_FOUND)
00317 {
00318 for(j = 0 ; j < i ; j++)
00319 freepage(pg_num[j]);
00320
00321 return FORK_FAILURE;
00322 }
00323
00324 addr = KERNEL_SIZE + (pg_num[i] * _4KB);
00325
00326 printf("\tA %x Pg %d",addr,pg_num[i]);
00327 _pgte[pid][i] = addr | 7;
00328 }
00329
00330 addr = KERNEL_SIZE + (pg_num[0] * _4KB);
00331 kmemcpy((void *)(addr),null_proc,512);
00332
00333
00334 _proc[pid].esp = MAX_PROC_SIZE-1;
00335 _proc[pid].eip = 0;
00336 }
00337
00338 void reti()
00339 {
00340 DD i = 0 , j = 0, _delay = 0x1000;
00341 DB c;
00342 DW data = 0xFF, port = 0x60;
00343
00344 asm("movl $0,%eax");
00345 asm("int %0"::"i"(0x30));
00346
00347 BLOCK
00348 }
00349
00350 void rogue()
00351 {
00352 DD i = 0 , j = 0, _delay = 0x1000;
00353 DB c;
00354 DW data = 0xFF, port = 0x60;
00355
00356 asm("int $200");
00357
00358 BLOCK
00359 }
00360
00361
00362 void null_proc()
00363 {
00364 DB i = 0;
00365
00366 char *str = "Hello";
00367
00368 BLOCK
00369 }