· 9 years ago · Nov 23, 2016, 11:32 AM
1/* Simple command-line kernel prompt useful for
2 controlling the kernel and exploring the system interactively.
3
4
5KEY WORDS
6==========
7CONSTANTS: WHITESPACE, NUM_OF_COMMANDS
8VARIABLES: Command, commands, name, description, function_to_execute, number_of_arguments, arguments, command_string, command_line, command_found
9FUNCTIONS: readline, cprintf, execute_command, run_command_prompt, command_kernel_info, command_help, strcmp, strsplit, start_of_kernel, start_of_uninitialized_data_section, end_of_kernel_code_section, end_of_kernel
10=====================================================================================================================================================================================================
11 */
12
13#include <inc/stdio.h>
14#include <inc/string.h>
15#include <inc/memlayout.h>
16#include <inc/assert.h>
17#include <inc/x86.h>
18
19
20#include <kern/console.h>
21#include <kern/command_prompt.h>
22#include <kern/memory_manager.h>
23#include <kern/trap.h>
24#include <kern/kdebug.h>
25#include <kern/user_environment.h>
26#include <kern/tests.h>
27
28
29/// LAB3.Hands-on.Solution: My int array start address variable
30unsigned int intArrAddress = 0xf1000000;
31//=============================================================
32
33//Structure for each command
34struct Command
35{
36 char *name;
37 char *description;
38 // return -1 to force command prompt to exit
39 int (*function_to_execute)(int number_of_arguments, char** arguments);
40};
41
42//Functions Declaration
43int execute_command(char *command_string);
44int command_writemem(int number_of_arguments, char **arguments);
45int command_readmem(int number_of_arguments, char **arguments);
46int command_meminfo(int , char **);
47
48//Lab2.Hands.On
49//=============
50int command_readblock(int number_of_arguments, char **arguments);
51int command_createIntArray(int number_of_arguments, char **arguments);
52
53//Lab4.Hands.On
54//=============
55int command_show_mapping(int number_of_arguments, char **arguments);
56int command_set_permission(int number_of_arguments, char **arguments);
57int command_share_range(int number_of_arguments, char **arguments);
58
59//Lab5.Examples
60//=============
61int command_nr(int number_of_arguments, char **arguments);
62int command_ap(int , char **);
63int command_fp(int , char **);
64
65//Lab5.Hands-on
66//=============
67int command_asp(int, char **);
68int command_cfp(int, char **);
69
70//Lab6.Examples
71//=============
72int command_run(int , char **);
73int command_kill(int , char **);
74int command_ft(int , char **);
75
76//Assignment4
77//============
78int command_crs(int, char **);
79int command_cum(int, char **);
80int command_dus(int, char **);
81
82uint32 CalculateRequiredSpace(char** arguments);
83void CopyUserMemory(char** arguments);
84void DeleteUserStack(char** arguments);
85
86//Array of commands. (initialized)
87struct Command commands[] =
88{
89 { "help", "Display this list of commands", command_help },
90 { "kernel_info", "Display information about the kernel", command_kernel_info },
91 { "wum", "writes one byte to specific location" ,command_writemem},
92 { "rum", "reads one byte from specific location" ,command_readmem},
93 { "readblock", "reads block of bytes from specific location in given user program" ,command_readblock},
94 { "cia", "Create integer array with the given size and initialize it", command_createIntArray},
95 { "meminfo", "show information about the physical memory" ,command_meminfo},
96
97 //LAB4: Hands-on
98 { "sm", "Lab4.HandsOnSolution", command_show_mapping},
99 { "sp", "Lab4.HandsOnSolution", command_set_permission},
100 { "sr", "Lab4.HandsOnSolution", command_share_range},
101
102 //LAB5: Examples
103 { "nr", "Lab5.Example: show the number of references of the physical frame" ,command_nr},
104 { "ap", "Lab5.Example: allocate one page [if not exists] in the user space at the given virtual address", command_ap},
105 { "fp", "Lab5.Example: free one page in the user space at the given virtual address", command_fp},
106
107 //LAB5: Hands-on
108 { "asp", "Lab5.HandsOn: allocate 2 shared pages with the given virtual addresses" ,command_asp},
109 { "cfp", "Lab5.HandsOn: count the number of free pages in the given range", command_cfp},
110
111 //LAB6: Examples
112 { "ft", "Lab6.Example: Free table", command_ft},
113 { "run", "Lab6.Example: Load and Run User Program", command_run},
114 { "kill", "Lab6.Example: Kill User Program", command_kill},
115
116 //Assignment4 commands
117 //====================
118 { "crs", "ASS4: required number of pages for allocating and mapping the given range",command_crs},
119 { "cum", "ASS4: copy (not share) the given virtual range to the destination range", command_cum},
120
121 //Assignment4.BONUS command
122 //=========================
123 { "dus", "ASS4.B: delete the entire user stack for the given program",command_dus},
124
125};
126
127//Number of commands = size of the array / size of command structure
128#define NUM_OF_COMMANDS (sizeof(commands)/sizeof(commands[0]))
129
130unsigned read_eip();
131
132static int cntOfRuns = 0;
133//invoke the command prompt
134void run_command_prompt()
135{
136 //CAUTION: DON'T CHANGE THIS LINE======
137 if (cntOfRuns < 4)
138 {
139 TestAssignment4(++cntOfRuns);
140 }
141 //=====================================
142
143 char command_line[1024];
144
145 while (1==1)
146 {
147 //get command line
148 readline("FOS> ", command_line);
149
150 //parse and execute the command
151 if (command_line != NULL)
152 if (execute_command(command_line) < 0)
153 break;
154 }
155}
156
157/***** Kernel command prompt command interpreter *****/
158
159//define the white-space symbols
160#define WHITESPACE "\t\r\n "
161
162//Function to parse any command and execute it
163//(simply by calling its corresponding function)
164int execute_command(char *command_string)
165{
166 // Split the command string into whitespace-separated arguments
167 int number_of_arguments;
168 //allocate array of char * of size MAX_ARGUMENTS = 16 found in string.h
169 char *arguments[MAX_ARGUMENTS];
170
171
172 strsplit(command_string, WHITESPACE, arguments, &number_of_arguments) ;
173 if (number_of_arguments == 0)
174 return 0;
175
176 // Lookup in the commands array and execute the command
177 int command_found = 0;
178 int i ;
179 for (i = 0; i < NUM_OF_COMMANDS; i++)
180 {
181 if (strcmp(arguments[0], commands[i].name) == 0)
182 {
183 command_found = 1;
184 break;
185 }
186 }
187
188 if(command_found)
189 {
190 int return_value;
191 return_value = commands[i].function_to_execute(number_of_arguments, arguments);
192 return return_value;
193 }
194 else
195 {
196 //if not found, then it's unknown command
197 cprintf("Unknown command '%s'\n", arguments[0]);
198 return 0;
199 }
200}
201
202/***** Implementations of basic kernel command prompt commands *****/
203
204//print name and description of each command
205int command_help(int number_of_arguments, char **arguments)
206{
207 int i;
208 for (i = 0; i < NUM_OF_COMMANDS; i++)
209 cprintf("%s - %s\n", commands[i].name, commands[i].description);
210
211 cprintf("-------------------\n");
212
213 return 0;
214}
215
216//print information about kernel addresses and kernel size
217int command_kernel_info(int number_of_arguments, char **arguments )
218{
219 extern char start_of_kernel[], end_of_kernel_code_section[], start_of_uninitialized_data_section[], end_of_kernel[];
220
221 cprintf("Special kernel symbols:\n");
222 cprintf(" Start Address of the kernel %08x (virt) %08x (phys)\n", start_of_kernel, start_of_kernel - KERNEL_BASE);
223 cprintf(" End address of kernel code %08x (virt) %08x (phys)\n", end_of_kernel_code_section, end_of_kernel_code_section - KERNEL_BASE);
224 cprintf(" Start addr. of uninitialized data section %08x (virt) %08x (phys)\n", start_of_uninitialized_data_section, start_of_uninitialized_data_section - KERNEL_BASE);
225 cprintf(" End address of the kernel %08x (virt) %08x (phys)\n", end_of_kernel, end_of_kernel - KERNEL_BASE);
226 cprintf("Kernel executable memory footprint: %d KB\n",
227 (end_of_kernel-start_of_kernel+1023)/1024);
228 return 0;
229}
230
231
232int command_readmem(int number_of_arguments, char **arguments)
233{
234 unsigned int address = strtol(arguments[1], NULL, 16);
235 unsigned char *ptr = (unsigned char *)(address ) ;
236
237 cprintf("value at address %x = %c\n", ptr, *ptr);
238
239 return 0;
240}
241int command_writemem(int number_of_arguments, char **arguments)
242{
243 unsigned int address = strtol(arguments[1], NULL, 16);
244 unsigned char *ptr = (unsigned char *)(address) ;
245
246 *ptr = arguments[2][0];
247
248 return 0;
249}
250
251
252int command_meminfo(int number_of_arguments, char **arguments)
253{
254 cprintf("Free frames = %d\n", calculate_free_frames());
255 return 0;
256}
257
258
259//Lab2.Hands.On Solution
260//======================
261int command_readblock(int number_of_arguments, char **arguments)
262{
263 unsigned int phys_address = strtol(arguments[1], NULL, 16);
264
265 unsigned int virtual_address= phys_address + KERNEL_BASE;
266
267 char* ptrToChar = (char*) virtual_address;
268
269 int nBytes = strtol(arguments[2], NULL, 10);
270
271 int i=0;
272 for(i=0; i<nBytes; i++)
273 {
274 cprintf("%c \n", *ptrToChar);
275 ptrToChar++;
276 }
277
278 return 0;
279}
280int command_createIntArray(int number_of_arguments, char **arguments)
281{
282 int nElements= strtol(arguments[1], NULL, 10);
283 int* ptrToInt = (int*)intArrAddress;
284
285 int i=0;
286 for(i=0; i< nElements; i++)
287 {
288 char stringElementValue[20];
289 cprintf("Enter Element %d: ",i);
290 readline("", stringElementValue);
291
292 *ptrToInt = strtol(stringElementValue, NULL, 10);
293
294 ptrToInt++; //note that as this pointer increment, the compiler knows the size of the integer, and it increments the address inside the pointer by 4 bytes automatically
295 }
296
297 // don't forget to update the virtual address for
298 // any new array that user may create
299 intArrAddress = (unsigned int)ptrToInt;
300
301 return 0;
302}
303
304//===========================================================================
305
306//Lab4.Hands.On Solution
307//======================
308int command_show_mapping(int number_of_arguments, char **arguments)
309{
310 uint32 *va = (uint32 *)strtol(arguments[1], NULL, 16) ;
311 uint32 *ptr_page_table = NULL;
312 get_page_table(ptr_page_directory, va, 0, &ptr_page_table) ;
313 if (ptr_page_table != NULL)
314 {
315 int dir_index = PDX(va);
316 int table_index = PTX(va);
317 uint32 fnTable = ptr_page_directory[dir_index] >> 12;
318 uint32 paTable = fnTable * PAGE_SIZE;
319 uint32 fnPage = ptr_page_table[table_index] >> 12;
320 uint32 paPage = fnPage * PAGE_SIZE;
321 int used = ptr_page_table[table_index] & PERM_USED;
322
323 cprintf("DIR Index = %d\nTable Index = %d\nPhysical Address of Page Table = %08x\nPhysical Address of Page Itself = %08x\n", dir_index, table_index, paTable, paPage) ;
324 if (used == 0)
325 cprintf("NOT Used\n");
326 else
327 cprintf("Used\n");
328
329 }
330 return 0 ;
331}
332int command_set_permission(int number_of_arguments, char **arguments)
333{
334 uint32 *va = (uint32 *)strtol(arguments[1], NULL, 16) ;
335 uint32 *ptr_page_table = NULL;
336 get_page_table(ptr_page_directory, va, 0, &ptr_page_table) ;
337 if (ptr_page_table != NULL)
338 {
339 char perm = arguments[2][0];
340 int table_index = PTX(va) ;
341
342 if (perm == 'r')
343 {
344 ptr_page_table[table_index] &= (~PERM_WRITEABLE);
345 }
346 else if (perm == 'w')
347 {
348 ptr_page_table[table_index] |= (PERM_WRITEABLE);
349 }
350 //tlb_invalidate(ptr_page_directory, va); // delete the cache of the given address
351 tlbflush() ; // delete the whole cache
352 }
353 return 0 ;
354}
355
356int command_share_range(int number_of_arguments, char **arguments)
357{
358 char *va1 = (char *)strtol(arguments[1], NULL, 16) ;
359 char *va2 = (char *)strtol(arguments[2], NULL, 16) ;
360 uint32 size = strtol(arguments[3], NULL, 10) ;
361 size *= 1024 ; //convert it to bytes
362 size = ROUNDUP(size, PAGE_SIZE); //round it to the nearest page
363
364 int i = 0;
365 for (i = 0 ; i < size ; i += PAGE_SIZE)
366 {
367 uint32 *ptr_page_table1 = NULL;
368 get_page_table(ptr_page_directory, va1, 0, &ptr_page_table1) ;
369 if (ptr_page_table1 != NULL)
370 {
371 uint32 *ptr_page_table2 = NULL;
372 get_page_table(ptr_page_directory, va2, 1, &ptr_page_table2) ;
373 ptr_page_table2[PTX(va2)] = ptr_page_table1[PTX(va1)];
374 }
375 va1 += PAGE_SIZE;
376 va2 += PAGE_SIZE;
377 }
378 return 0;
379}
380//===========================================================================
381
382//Lab5.Examples
383//==============
384//[1] Number of references on the given physical address
385int command_nr(int number_of_arguments, char **arguments)
386{
387 uint32 pa = strtol(arguments[1], NULL, 16);
388
389 //[1] Get the frame info of the given pa
390 struct Frame_Info * ptr_frame_info ;
391 ptr_frame_info = to_frame_info(pa);
392
393 // [2] Display number of references
394 cprintf("num of refs at pa %x = %d\n", pa, ptr_frame_info->references);
395 return 0;
396}
397
398//[2] Allocate Page: If the given user virtual address is mapped, do nothing. Else, allocate a single frame and map it to a given virtual address in the user space
399int command_ap(int number_of_arguments, char **arguments)
400{
401 //If already mapped, do nothing
402 //Else, allocate & map
403
404 uint32 va = strtol(arguments[1], NULL, 16);
405
406 //[1] Check if exists?
407 uint32 *ptr_table;
408 struct Frame_Info *ptr_frame_info ;
409 ptr_frame_info = get_frame_info(ptr_page_directory, (void*)va, &ptr_table);
410 if (ptr_frame_info != NULL)
411 {
412 cprintf("Page already exists!\n");
413 return 0;
414 }
415
416 //[2] If not exists, allocate
417 int r = allocate_frame(&ptr_frame_info);
418 if (r == E_NO_MEM)
419 {
420 cprintf("No enough memory for the page itself\n");
421 return -1;
422 }
423
424 //[3] map
425 r = map_frame(ptr_page_directory, ptr_frame_info, (void*)va, PERM_WRITEABLE | PERM_USER) ;
426 if (r == E_NO_MEM)
427 {
428 cprintf("No enough memory for the page table\n");
429
430 //free the previously allocated frame
431 free_frame(ptr_frame_info);
432 return -1;
433 }
434
435 return 0 ;
436}
437
438//[3] Free Page: Un-map a single page at the given virtual address in the user space
439int command_fp(int number_of_arguments, char **arguments)
440{
441 uint32 va = strtol(arguments[1], NULL, 16);
442
443 // Un-map the page at this address
444 unmap_frame(ptr_page_directory, (void*) va);
445
446 return 0;
447}
448
449
450//Lab5.Hands-on
451//==============
452//[1] Allocate Shared Pages
453int command_asp(int number_of_arguments, char **arguments)
454{
455 uint32 va1 = strtol(arguments[1], NULL, 16);
456 uint32 va2 = strtol(arguments[2], NULL, 16);
457
458 //[1] Allocate one frame
459 struct Frame_Info* ptr_frame_info ;
460 int r = allocate_frame(&ptr_frame_info);
461 if (r == E_NO_MEM)
462 {
463 cprintf("No enough memory to allocate frame!\n");
464 return -1;
465 }
466
467 //[2] Map the "va1" to the allocated frame
468 r = map_frame(ptr_page_directory, ptr_frame_info, (void*)va1, PERM_USER | PERM_WRITEABLE);
469
470 if (r == E_NO_MEM)
471 {
472 cprintf("No enough memory for the page table!\n");
473 //free the previously allocated frame
474 free_frame(ptr_frame_info);
475 return -1;
476 }
477
478 //[2] Map the "va2" to the allocated frame
479 r = map_frame(ptr_page_directory, ptr_frame_info, (void*)va2, PERM_USER | PERM_WRITEABLE);
480
481 if (r == E_NO_MEM)
482 {
483 cprintf("No enough memory for the page table!\n");
484 //free the previously mapped page
485 unmap_frame(ptr_page_directory, (void*)va1);
486 return -1;
487 }
488 return 0;
489}
490
491
492//[2] Count Free Pages in Range
493int command_cfp(int number_of_arguments, char **arguments)
494{
495 uint32 va1 = strtol(arguments[1], NULL, 16);
496 uint32 va2 = strtol(arguments[2], NULL, 16);
497
498 //[1] Adjust start of the loop at a multiple of 4 KB (i.e. page boundary)
499 va1 = ROUNDDOWN(va1, PAGE_SIZE);
500
501 //[2] For each page in the range, check its existence!
502 uint32* ptr_table ;
503 struct Frame_Info* ptr_frame_info ;
504 uint32 v ;
505 int cnt = 0 ;
506 for (v = va1; v < va2; v += PAGE_SIZE)
507 {
508 ptr_frame_info = get_frame_info(ptr_page_directory, (void*)v, &ptr_table);
509 if (ptr_frame_info == NULL)
510 {
511 cnt++ ;
512 }
513 }
514 cprintf("Number of free pages in [%x, %x) = %d\n", va1, va2, cnt);
515 return 0;
516}
517
518
519//===========================================================================
520
521//Lab6.Examples
522//=============
523
524int command_run(int number_of_arguments, char **arguments)
525{
526 int numOfStackPages = 1;
527 if (number_of_arguments == 3)
528 {
529 numOfStackPages = strtol(arguments[2], NULL, 10);
530 }
531 //[1] Create and initialize a new environment for the program to be run
532 struct UserProgramInfo* ptr_program_info = env_create(arguments[1], numOfStackPages);
533 if(ptr_program_info == 0) return 0;
534
535 //[2] Run the created environment using "env_run" function
536 env_run(ptr_program_info->environment);
537 return 0;
538}
539
540
541int command_kill(int number_of_arguments, char **arguments)
542{
543 //[1] Get the user program info of the program (by searching in the "userPrograms" array
544 struct UserProgramInfo* ptr_program_info = get_user_program_info(arguments[1]) ;
545 if(ptr_program_info == 0) return 0;
546
547 //[2] Kill its environment using "env_free" function
548 env_free(ptr_program_info->environment);
549 ptr_program_info->environment = NULL;
550 return 0;
551}
552
553int command_ft(int number_of_arguments, char **arguments)
554{
555 uint32 va = strtol(arguments[1], NULL, 16) ;
556
557 //Remove the page table itself
558 uint32 *ptr_table = NULL ;
559 get_page_table(ptr_page_directory, (void*)va, 0, &ptr_table) ;
560 if (ptr_table!=NULL)
561 {
562 uint32 pa = K_PHYSICAL_ADDRESS(ptr_table) ;
563 struct Frame_Info *ptr = to_frame_info(pa) ;
564 ptr->references = 0 ;
565 free_frame(ptr) ;
566 ptr_page_directory[PDX(va)] = 0 ;
567
568 //Refresh the whole cache memory
569 tlbflush();
570 }
571 return 0;
572}
573
574
575//========================================================
576/*ASSIGNMENT-4*/
577//========================================================
578//Q2: Calculate Required Space (1.5 MARK)
579
580/*DON'T change this function*/
581int command_crs(int number_of_arguments, char **arguments )
582{
583 //DON'T WRITE YOUR LOGIC HERE, WRITE INSIDE THE CalculateRequiredSpace() FUNCTION
584 uint32 numOfPages = CalculateRequiredSpace(arguments) ;
585 cprintf("The required number of pages = %d\n", numOfPages);
586
587 return 0;
588}
589/*---------------------------------------------------------*/
590
591/*FILL this function
592 * arguments[1]: start virtual address in HEX
593 * arguments[2]: size to be moved
594 * arguments[3]: its unit (K: Kilo, M: Mega)
595 * Return:
596 * Required number of pages and page tables for allocating and mapping the given range.
597 */
598uint32 CalculateRequiredSpace(char** arguments)
599{
600 //Assignment4.Q2
601 //put your logic here
602 //...
603 uint32 startVa = strtol(arguments[1],NULL,16);
604 uint32 size = strtol(arguments[2],NULL,10);
605 if(strcmp(arguments[3],"M")==0)
606 size*=1024*1024;
607 else
608 size*=1024;
609uint32 Addresses [4000];
610memset(Addresses,-1,sizeof(Addresses));
611uint32 ch = 0;
612uint32 endVa = ROUNDUP(startVa+size,PAGE_SIZE);
613startVa = ROUNDDOWN(startVa,PAGE_SIZE);
614 int count = 0;
615 uint32* checker = NULL;
616 for(uint32 i = startVa; i < endVa; i+=PAGE_SIZE)
617 {
618
619 uint32* PointerONPageTable = NULL;
620 //get_page_table(ptr_page_directory,(void*)i,0,&PointerONPageTable);
621 struct Frame_Info * fi=get_frame_info(ptr_page_directory,(void*)i, &PointerONPageTable );
622 if(fi==NULL){
623 count++;
624 }
625 if(ptr_page_directory[PDX(i)]==0)
626 {
627 if(Addresses[PDX(i)]==-1){
628 count++;
629 Addresses[PDX(i)] = i;
630 }
631
632 }
633
634 }
635
636 return count;
637}
638
639//========================================================
640//Q3: Copy User Memory (1.5 MARK)
641
642/*DON'T change this function*/
643int command_cum(int number_of_arguments, char **arguments )
644{
645 //DON'T WRITE YOUR LOGIC HERE, WRITE INSIDE THE CopyUserMemory() FUNCTION
646 CopyUserMemory(arguments) ;
647
648 return 0;
649}
650/*---------------------------------------------------------*/
651
652/*FILL this function
653 * arguments[1]: source virtual address in HEX
654 * arguments[2]: destination virtual address in HEX
655 * arguments[3]: size to be moved
656 * arguments[4]: its unit (K: Kilo, M: Mega)
657 */
658void CopyUserMemory(char** arguments)
659{
660 //Assignment4.Q3
661 //put your logic here
662 //...
663 uint32 startVa1 = strtol(arguments[1],NULL,16);
664 uint32 size = strtol(arguments[3],NULL,10);
665 uint32 startVa2 = strtol(arguments[2],NULL,16);
666 if(strcmp(arguments[4],"M")==0)
667 size*=1024*1024;
668 else
669 size*=1024;
670 uint32 endVa1 = startVa1+size;
671 uint32 endVa2 =startVa2+size;
672 for(int i = startVa1; i < endVa1; i+=PAGE_SIZE,startVa2+=PAGE_SIZE)
673 {
674 uint32* PointerONP= NULL;
675 struct Frame_Info* fi = get_frame_info(ptr_page_directory,(void*)startVa2,&PointerONP);
676 if(fi == NULL){
677 allocate_frame(&fi);
678 map_frame(ptr_page_directory,fi,(void*)startVa2,PERM_PRESENT|PERM_PRESENT|PERM_USER|PERM_WRITEABLE);
679 }
680 uint32* source = (uint32*) i;
681 uint32* destination = (uint32*) startVa2;
682 for(int j = 0; j<1024 && (uint32)(destination+j)<endVa2; j++ )
683 destination[j] = source[j];
684 }
685
686}
687
688//========================================================
689//BONUS: Delete User Stack (1.5 MARK)
690
691/*DON'T change this function*/
692int command_dus(int number_of_arguments, char **arguments )
693{
694 //DON'T WRITE YOUR LOGIC HERE, WRITE INSIDE THE DeleteUserStack() FUNCTION
695 DeleteUserStack(arguments) ;
696
697 return 0;
698}
699/*---------------------------------------------------------*/
700
701/*FILL this function
702 * arguments[1]: program name
703 */
704void DeleteUserStack(char** arguments)
705{
706 //Assignment4.BONUS
707 //put your logic here
708 //...
709 struct UserProgramInfo* User= get_user_program_info(arguments[1]);
710
711 for(uint32 i = USER_HEAP_MAX; i <USTACKTOP;i+=PAGE_SIZE)
712 {
713 uint32* pointerOnP = NULL;
714 struct Frame_Info* fi = get_frame_info(User->environment->env_pgdir,(void*)i, &pointerOnP);
715
716 if(fi!=NULL){
717 unmap_frame(User->environment->env_pgdir,(void*)i);
718 // free_frame(fi);
719 int j;
720 for( j= 0;j < 1024; j++)
721 {
722 if(pointerOnP[j]!=0)
723 break;
724
725 }
726 if(j == 1024)
727 {
728 uint32 physical = K_PHYSICAL_ADDRESS((uint32)pointerOnP);
729 User->environment->env_pgdir[PDX((uint32)pointerOnP)] = 0;
730 struct Frame_Info* fii = to_frame_info(physical);
731 fii->references = 0;
732 free_frame(fii);
733 }
734 }
735
736
737 }
738 tlbflush();
739
740
741 //tlbflush();
742
743
744}
745
746//========================================================