• 内核内存管理


    作者:朱涵俊
    链接:https://zhuanlan.zhihu.com/p/140274586
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
     

    内存管理分为虚拟地址空间管理,物理内存管理,内核堆栈管理。

    内核在启动的过程中需要不断申请内存,这些内存申请之后一般就不需要释放。频繁的申请释放会导致内存碎片,性能下降。因此内核堆kheap管理的原则是申请一次,终身使用。堆内存分为2类,一是小内存,而是页对齐的内存。因为有的内核对象需要页对齐,比如页表。

    kernel/kheap.c

    1. //由于只申请不释放,不会有很多内存块。主要是BIOS,内核数据等引起的。
    2. #define MAX_HEAP_HOLE 10
    3. #define MAX_SMALL_HOLE 100
    4. #if 1
    5. #define DEBUG_PRINT printk
    6. #else
    7. #define DEBUG_PRINT inline_printk
    8. #endif
    9. struct kheap_t;
    10. struct kheap_t {
    11. ulong addr;
    12. ulong size;
    13. ulong orgin_size;
    14. struct kheap_t *pnext;
    15. };
    16. static struct kheap_t *pfree4k;
    17. static struct kheap_t *phead4k;
    18. static struct kheap_t heap_holes[MAX_HEAP_HOLE];
    19. static struct kheap_t heap_small_holes[MAX_SMALL_HOLE];
    20. __thread static spinlock_t spin_4k;
    21. __thread static spinlock_t spin_small;
    22. static struct kheap_t *pfree_small;
    23. static struct kheap_t *phead_small;
    24. void init_kheap()
    25. {
    26. for (int i = 0; i < MAX_HEAP_HOLE - 1; i++) {
    27. heap_holes[i].pnext = &heap_holes[i + 1];
    28. }
    29. heap_holes[MAX_HEAP_HOLE - 1].pnext = 0;
    30. pfree4k = heap_holes;
    31. phead4k = 0;
    32. init_spinlock(&spin_4k);
    33. for (int i = 0; i < MAX_SMALL_HOLE - 1; i++) {
    34. heap_small_holes[i].pnext = &heap_small_holes[i + 1];
    35. }
    36. heap_small_holes[MAX_SMALL_HOLE - 1].pnext = 0;
    37. pfree_small = heap_small_holes;
    38. phead_small = 0;
    39. init_spinlock(&spin_small);
    40. }
    41. void free_kheap_4k(ulong addr, ulong size)
    42. {
    43. struct kheap_t *p;
    44. struct kheap_t *ph;
    45. ASSERT((addr & 0xfff) == 0 && (size & 0xfff) == 0); //4k aligned
    46. p = pfree4k;
    47. if (!p) {
    48. panic("MAX_HEAP_HOLE too small!\n");
    49. }
    50. spin_lock(&spin_4k);
    51. pfree4k = pfree4k->pnext;
    52. p->addr = addr;
    53. p->orgin_size = size;
    54. p->size = size;
    55. //sort by addr asc,early init can only use low kheap
    56. if (!phead4k || phead4k->addr > p->addr) {
    57. p->pnext = phead4k;
    58. phead4k = p;
    59. spin_unlock(&spin_4k);
    60. return;
    61. }
    62. ph = phead4k;
    63. while (ph->pnext && ph->pnext->addr < p->addr) {
    64. ph = ph->pnext;
    65. }
    66. p->pnext = ph->pnext;
    67. ph->pnext = p;
  • 相关阅读:
    什么测试自动化测试?
    拓扑排序及其衍生
    uniapp(uncloud) 使用生态开发接口详情1(创建项目)
    Spring创建、Bean对象的存储和读取
    阿里云搭建博客之如何设置网页为中文
    JS+Jquery用法
    华为云HECS云服务器docker环境下安装nacos
    Python 教程之 Python中的高级交互式仪表板,连接不同的 API 以创建用于分析的高级交互式仪表板
    花生好车基于 KubeSphere 的微服务架构实践
    规范的项目流程图怎么写
  • 原文地址:https://blog.csdn.net/lingshengxiyou/article/details/127820693