]> Zhao Yanbai Git Server - minix.git/commitdiff
Allow vm to split blocks in memory map (needed for multiboot, contributed by Feiran...
authorErik van der Kouwe <erik@minix3.org>
Fri, 23 Jul 2010 14:22:13 +0000 (14:22 +0000)
committerErik van der Kouwe <erik@minix3.org>
Fri, 23 Jul 2010 14:22:13 +0000 (14:22 +0000)
servers/vm/utility.c

index 6d85009411f10bb5b8289e8c6c20502bf42d0486..b7f594647d292d82c21cef4f3d1216c53d005fc7 100644 (file)
@@ -70,7 +70,7 @@ struct memory *mem_chunks;                      /* store mem chunks here */
   /* Obtain and parse memory from system environment. */
   if(env_memory_parse(mem_chunks, NR_MEMS) != OK) 
         panic("couldn't obtain memory chunks"); 
-   
+        
   /* Round physical memory to clicks. Round start up, round end down. */
   for (i = 0; i < NR_MEMS; i++) {
         memp = &mem_chunks[i];          /* next mem chunk is stored here */
@@ -95,22 +95,35 @@ PUBLIC void reserve_proc_mem(mem_chunks, map_ptr)
 struct memory *mem_chunks;                      /* store mem chunks here */
 struct mem_map *map_ptr;                        /* memory to remove */
 {
-/* Remove server memory from the free memory list. The boot monitor
- * promises to put processes at the start of memory chunks. The 
- * tasks all use same base address, so only the first task changes
- * the memory lists. The servers and init have their own memory
- * spaces and their memory will be removed from the list.
+/* Remove server memory from the free memory list.
  */
   struct memory *memp;
   for (memp = mem_chunks; memp < &mem_chunks[NR_MEMS]; memp++) {
-        if (memp->base == map_ptr[T].mem_phys) {
-                memp->base += map_ptr[T].mem_len + map_ptr[S].mem_vir;
-                memp->size -= map_ptr[T].mem_len + map_ptr[S].mem_vir;
-                break;
-        }
+               if(memp->base <= map_ptr[T].mem_phys 
+                       && memp->base+memp->size >= map_ptr[T].mem_phys)
+               {
+                       if (memp->base == map_ptr[T].mem_phys) {
+                                       memp->base += map_ptr[T].mem_len + map_ptr[S].mem_vir;
+                                       memp->size -= map_ptr[T].mem_len + map_ptr[S].mem_vir;
+                       } else {
+                               struct memory *mempr;
+                               /* have to split mem_chunks */
+                               if(mem_chunks[NR_MEMS-1].size>0)
+                                       panic("reserve_proc_mem: can't find free mem_chunks to map: 0x%lx",
+                                               map_ptr[T].mem_phys);
+                               for(mempr=&mem_chunks[NR_MEMS-1];mempr>memp;mempr--) {
+                                       *mempr=*(mempr-1);
+                               }
+                               assert(memp < &mem_chunks[NR_MEMS-1]);
+                               (memp+1)->base = map_ptr[T].mem_phys + map_ptr[T].mem_len + map_ptr[S].mem_vir;
+                               (memp+1)->size = memp->base + memp->size 
+                                       - (map_ptr[T].mem_phys + map_ptr[T].mem_len + map_ptr[S].mem_vir);
+                               memp->size = map_ptr[T].mem_phys - memp->base;
+                       }
+                       break;
+               }
   }
-  if (memp >= &mem_chunks[NR_MEMS])
-  {
+  if (memp >= &mem_chunks[NR_MEMS]) {
                panic("reserve_proc_mem: can't find map in mem_chunks: 0x%lx",
                        map_ptr[T].mem_phys);
   }