Advertisement
Madmouse

MadOS flat memory manager

Dec 16th, 2015
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.01 KB | None | 0 0
  1. ////////////////////////////////////////////////////////////////////////////////
  2. // THE SCOTCH-WARE LICENSE (Revision 0):
  3. // <aaronryool/gmail.com> wrote this file. As long as you retain this notice you
  4. // can do whatever you want with this stuff. If we meet some day, and you think
  5. // this stuff is worth it, you can buy me a shot of scotch in return
  6. ////////////////////////////////////////////////////////////////////////////////
  7.  
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <multiboot.h>
  11.  
  12. /*****************************************
  13.     Flat memory manager from scratch :D
  14. *****************************************/
  15. uint32_t MEM_POOL = 0;
  16. uint32_t MEM_POOL_END = 0;
  17. uint32_t MEM_POOL_SIZE = 0;
  18.  
  19. typedef struct mem_entry{
  20.     bool free;
  21.     uint32_t prev;
  22.     uint32_t ptr;
  23.     uint32_t next;
  24. } mem_entry_t;
  25.  
  26.  
  27. void mem_initialize(multiboot_uint32_t magic, multiboot_info_t* mbi)
  28. {
  29.     multiboot_memory_map_t* mmap;
  30.     MEM_POOL_SIZE = mbi->mem_upper;
  31.     if(magic != MULTIBOOT_BOOTLOADER_MAGIC) goto skip_multiboot;
  32.  
  33.     if(CHECK_FLAG (mbi->flags, 6))
  34.     {
  35.         for(mmap = (multiboot_memory_map_t *) mbi->mmap_addr;
  36.             (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
  37.             mmap = (multiboot_memory_map_t *) ((unsigned long) mmap
  38.             + mmap->size + sizeof(mmap->size)))
  39.             {
  40.                 if(mmap->type == MULTIBOOT_MEMORY_AVAILABLE && mmap->addr >= (uint32_t) &KERNEL_END)
  41.                 {
  42.                     MEM_POOL = (uint32_t) &KERNEL_END;
  43.                     MEM_POOL_SIZE = (uint32_t) mmap->len - (mmap->addr - (uint32_t) &KERNEL_END);
  44.                     break;
  45.                 }
  46.             }
  47.     }
  48.  
  49. skip_multiboot:
  50.     if(MEM_POOL == 0)
  51.         MEM_POOL = (uint32_t) &KERNEL_END;
  52.     MEM_POOL_END = MEM_POOL + MEM_POOL_SIZE;
  53.  
  54.     // first marker block
  55.     mem_entry_t* a_block =(mem_entry_t*) MEM_POOL;
  56.     a_block->free = false;
  57.     a_block->prev = MEM_POOL;
  58.     a_block->ptr = MEM_POOL + sizeof(mem_entry_t);
  59.     a_block->next = MEM_POOL + sizeof(mem_entry_t);
  60.  
  61.     // first entry block
  62.     mem_entry_t* b_block = (mem_entry_t*) a_block->next;
  63.     b_block->free = true;
  64.     b_block->prev = (uint32_t) a_block;
  65.     b_block->ptr = (uint32_t) b_block + sizeof(mem_entry_t);
  66.     b_block->next = MEM_POOL_END - sizeof(mem_entry_t);
  67.  
  68.     // end marker block
  69.     mem_entry_t* c_block = (mem_entry_t*) b_block->next;
  70.     c_block->free = false;
  71.     c_block->prev = (uint32_t) b_block;
  72.     c_block->ptr = MEM_POOL_END;
  73.     c_block->next = MEM_POOL_END;
  74.  
  75. //    init_paging();
  76. }
  77.  
  78.  
  79. void combine_free_blocks()
  80. {
  81.     // combine contigeous free blocks
  82.     for(uint32_t p = MEM_POOL;((mem_entry_t*)p)->next != MEM_POOL_END;p = ((mem_entry_t*)p)->next)
  83.     {
  84.         if(((mem_entry_t*)p)->free)
  85.         {
  86.             for(mem_entry_t* c = (mem_entry_t*) p;;c = (mem_entry_t*) c->next)
  87.             {
  88.                 if(! c->free)
  89.                 {
  90.                     if(c->prev != p)
  91.                     {
  92.                         ((mem_entry_t*)p)->next = (uint32_t) c;
  93.                         c->prev = p;
  94.                     }
  95.                     else break;
  96.                 }
  97.                 if(c->next == MEM_POOL_END) break;
  98.             }
  99.         }
  100.     }
  101. }
  102.  
  103.  
  104. uint32_t mget_free_block(uint32_t p, size_t size)
  105. {
  106.     combine_free_blocks();
  107.     while(((mem_entry_t*)p)->ptr != MEM_POOL_END)
  108.     {
  109.         if(((mem_entry_t*)p)->free && (((mem_entry_t*)p)->next - ((mem_entry_t*)p)->ptr) >= size) break;
  110.         p = ((mem_entry_t*)p)->next;
  111.     }
  112.     return p;
  113. }
  114.  
  115. void split_block(uint32_t p, size_t size)
  116. {
  117.     mem_entry_t* selected = (mem_entry_t*) p;
  118.     mem_entry_t* split = (mem_entry_t*) (p + sizeof(mem_entry_t) + size);
  119.     mem_entry_t* end_marker = (mem_entry_t*) ((mem_entry_t*) p)->next;
  120.  
  121.     split->free = true;
  122.     split->prev = (uint32_t) selected;
  123.     split->ptr = (uint32_t) split + sizeof(mem_entry_t);
  124.     split->next = (uint32_t) end_marker;
  125.  
  126.     selected->next = (uint32_t) split;
  127.     end_marker->prev = (uint32_t) split;
  128. }
  129.  
  130. void* malloc_flat(size_t size)
  131. {
  132.     mem_entry_t* p = (mem_entry_t*) MEM_POOL;
  133.     p = (mem_entry_t*) mget_free_block((uint32_t) p, size);
  134.     if(p->next == (uint32_t) MEM_POOL_END || (uint32_t) p == MEM_POOL_END)
  135.     {
  136.         panic("malloc", 0);
  137.         halt();
  138.     }
  139.  
  140.     // split free block
  141.     if(p->next - p->ptr >= size + (sizeof(mem_entry_t) * 2))
  142.         split_block((uint32_t) p, size);
  143.  
  144.     // choose one of the two if split and mark not free
  145.     p->free = false;
  146.  
  147.     return (void*) p->ptr;
  148. }
  149.  
  150. malloc_t* malloc = malloc_flat;
  151.  
  152. void free(void* ptr)
  153. {
  154.     mem_entry_t* e = ptr - sizeof(mem_entry_t);
  155.     if(e->ptr == (uint32_t) ptr)
  156.         e->free = true;
  157. }
  158.  
  159.  
  160. void print_memory_blocks(void)
  161. {
  162.     unsigned int free = 0, reserved = 0;
  163.     for(mem_entry_t* p = (mem_entry_t*)((mem_entry_t*) MEM_POOL)->next;p->next != MEM_POOL_END;p = (mem_entry_t*) p->next)
  164.     {
  165.         if(p->free)
  166.             putchar('F');
  167.         else
  168.             putchar('R');
  169.     }
  170. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement