Advertisement
Guest User

Kernel Memory

a guest
May 20th, 2018
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.87 KB | None | 0 0
  1. #pragma once
  2. /**
  3.  * Kernel - Memory Map
  4.  *
  5.  * @author  GoblinSloth
  6.  * @version 0.1.0
  7.  * @license MIT License
  8.  */
  9. #ifndef _KERNEL_MEMORY_H
  10. #define _KERNEL_MEMORY_H
  11.  
  12. #include <utility.h>
  13.  
  14. /**
  15.  * Memory block size
  16.  * NOTE: No clue if 4096 is the right optimal size for memory blocks,
  17.  * ... but the first google search says so.
  18.  */
  19. #define MEMORY_BLOCK_SIZE (4096)
  20.  
  21. /**
  22.  * Memory alignment functions
  23.  */
  24. // Align an memory item/block to the left
  25. static uint32_t kmemory_align_left(const uint32_t item)
  26. {
  27.   return (item / MEMORY_BLOCK_SIZE) * MEMORY_BLOCK_SIZE;
  28. }
  29. // Align an memory item/block to the right
  30. static uint32_t kmemory_align_right(const uint32_t item)
  31. {
  32.   return (item / MEMORY_BLOCK_SIZE + (item % MEMORY_BLOCK_SIZE != 0)) * MEMORY_BLOCK_SIZE;
  33. }
  34.  
  35. /**
  36.  * Representation of a region of memory
  37.  */
  38. typedef struct memory_region
  39. {
  40.   /**
  41.    * The memory region base address pointer.
  42.    */
  43.   address_t *base;
  44.  
  45.   /**
  46.    * The memory region size.
  47.    */
  48.   size_t size;
  49. } kernel_memory_region_t;
  50.  
  51. /**
  52.  * Representation of a memory map
  53.  */
  54. typedef struct memory_map
  55. {
  56.   /**
  57.    * The memory bitmap base address
  58.    */
  59.   uint8_t *bitmap_address;
  60.  
  61.   /**
  62.    * The amount of bitmap blocks
  63.    */
  64.   size_t bitmap_count;
  65.  
  66.   /**
  67.    * The memory base address
  68.    */
  69.   uint8_t *data_address;
  70.  
  71.   /**
  72.    * The amount of data blocks
  73.    */
  74.   size_t data_count;
  75.  
  76.   /**
  77.    * The amount of blocks used
  78.    */
  79.   size_t used;
  80. } kernel_memory_map_t;
  81.  
  82. /**
  83.  * Initialize the memory map
  84.  * @param region. The kernel memory region
  85.  */
  86. void kmemory_init(kernel_memory_map_t *mm, const kernel_memory_region_t &region)
  87. {
  88.   // Get the first, and last memory block
  89.   uint32_t first_block = kmemory_align_right((uint32_t)region.base);
  90.   uint32_t last_block  = kmemory_align_left((uint32_t)region.base + region.size);
  91.  
  92.   // The total blocks of the memory region
  93.   uint32_t size = last_block - first_block;
  94.   // The block count of the memory region
  95.   uint32_t block_count = size / MEMORY_BLOCK_SIZE;
  96.   // The amount of blocks required for the memory map
  97.   uint32_t blocks_required = (block_count / MEMORY_BLOCK_SIZE + (block_count % MEMORY_BLOCK_SIZE != 0)) / MEMORY_BLOCK_SIZE + ((block_count / MEMORY_BLOCK_SIZE + (block_count % MEMORY_BLOCK_SIZE != 0)) % MEMORY_BLOCK_SIZE != 0);
  98.  
  99.   // The memory map bitmap
  100.   mm->bitmap_address = reinterpret_cast<uint8_t *>(first_block);
  101.   mm->bitmap_count   = blocks_required;
  102.  
  103.   // The memory map data
  104.   mm->data_address = reinterpret_cast<uint8_t *>(first_block + blocks_required * MEMORY_BLOCK_SIZE);
  105.   mm->data_count   = block_count - blocks_required;
  106.  
  107.   // Allocate the memory map into memory
  108.   for(size_t i = 0; i < blocks_required; i++)
  109.   {
  110.     *(mm->bitmap_address + i) = 0;
  111.   }
  112.  
  113.   // mark 0 so whe can compare it to 0x0 or NULL, as
  114.   kmemory_mark_block_used(mm, 0);
  115. }
  116.  
  117. /**
  118.  * Mark a memory block as free
  119.  * @param mm. The kernel memory map
  120.  * @param block. The block inside the memory map to set
  121.  */
  122. void kmemory_mark_block_free(kernel_memory_map_t *mm, const uint32_t block)
  123. {
  124.   if (block < mm->data_count)
  125.   {
  126.     reinterpret_cast<uint32_t *>(mm->data_address)[block/32] |= ~(1 << (block % 32));
  127.   }
  128. }
  129.  
  130. /**
  131.  * Mark a memory block as used
  132.  * @param mm. The kernel memory map
  133.  * @param block. The block inside the memory map to set
  134.  */
  135. void kmemory_mark_block_used(kernel_memory_map_t *mm, const uint32_t block)
  136. {
  137.   if (block < mm->data_count)
  138.   {
  139.     reinterpret_cast<uint32_t *>(mm->data_address)[block/32] &= ~(1 << (block % 32));
  140.   }
  141. }
  142.  
  143. /**
  144.  * Get the total block count of the memory map
  145.  */
  146. size_t kmemory_block_count(const kernel_memory_map_t *mm)
  147. {
  148.   return mm->data_count;
  149. }
  150.  
  151. /**
  152.  * Get the amount of used blocks in the memory map
  153.  * @param mm. The kernel memory map
  154.  * @return The amount of used blocks in the memory map
  155.  */
  156. size_t kmemory_block_used_count(const kernel_memory_map_t* mm)
  157. {
  158.   return mm->used;
  159. }
  160.  
  161. /**
  162.  * Get the amount of free blocks in the memory map
  163.  * @param mm. The kernel memory map
  164.  * @return The amount of free blocks in the memory map
  165.  */
  166. size_t kmemory_block_free_count(const kernel_memory_map_t* mm)
  167. {
  168.   return mm->data_count - mm->used;
  169. }
  170.  
  171. /**
  172.  * Allocate blocks on the memory map
  173.  * @param mm. The kernel memory map
  174.  * @param count. The amount of blocks to allocate
  175.  * @return The base address of the allocated blocks, or null if allocation failed.
  176.  */
  177. address_t* kmemory_allocate_blocks(kernel_memory_map_t* mm, const uint32_t count)
  178. {
  179.   // don't allocate 0 blocks
  180.   if (count == 0)
  181.   {
  182.     return nullptr;
  183.   }
  184.  
  185.   uint32_t current_block_count = 0;
  186.   for(size_t i = 0; i < mm->data_count; i++)
  187.   {
  188.     // try to find enough blocks to allocate
  189.     if (!(i < mm->block_count) && !(reinterpret_cast<uint32_t *>(mm->data_address)[i/32] & (1 << (i % 32))))
  190.     {
  191.       current_block_count++;
  192.     }
  193.     else {
  194.       current_block_count = 0;
  195.     }
  196.  
  197.     if (current_block_count == count)
  198.     {
  199.       size_t first_block = i + 1 - count;
  200.  
  201.       for (size_t block = 0; block < count; block++)
  202.       {
  203.         kmemory_mark_block_used(mm, first_block + block);
  204.       }
  205.       mm->used += count;
  206.       return mm->data_address + first_block + MEMORY_BLOCK_SIZE;
  207.     }
  208.   }
  209.  
  210.   return nullptr;
  211. }
  212.  
  213. /**
  214.  * Free blocks on the memory map
  215.  * @param mm. The kernel memory map
  216.  * @param address. The base address to free
  217.  */
  218. void kmemory_free_blocks(kernel_memory_map_t* mm, const address_t* address)
  219. {
  220.   uint32_t offset = reinterpret_cast<uint32_t *>(reinterpret_cast<uint8_t*>(address) - reinterpret_cast<uint32_t>(mm->data_address));
  221.  
  222.   if (offset % MEMORY_BLOCK_SIZE == 0)
  223.   {
  224.     uint32_t block = offset / MEMORY_BLOCK_SIZE;
  225.  
  226.     if (!(block < mm->block_count) && !(reinterpret_cast<uint32_t *>(mm->data_address)[block/32] & (1 << (block % 32))))
  227.     {
  228.       mm->used--;
  229.     }
  230.  
  231.     kmemory_mark_block_free(mm, block);
  232.   }
  233. }
  234.  
  235. #endif /* end of kernel.h */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement