微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > Linux内核高-低端内存设置代码跟踪(ARM构架)

Linux内核高-低端内存设置代码跟踪(ARM构架)

时间:11-21 来源:互联网 点击:

和vmalloc_min)后,内核通过sanity_check_meminfo函数自动去通过vmalloc_min信息来初始化每个meminfo.bank[?]中的highmem成员。此过程中如果有必要,将可能会改变meminfo中的bank数组。处理函数位于mmu.c (arch\arm\mm):

  1. static phys_addr_t lowmem_limit __initdata = 0;
  2. void __init sanity_check_meminfo(void)
  3. {
  4. int i, j, highmem = 0;
  5. for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
  6. struct membank *bank = &meminfo.bank[j];
  7. *bank = meminfo.bank[i];
  8. #ifdef CONFIG_HIGHMEM
  9. if (__va(bank->start) >= vmalloc_min ||
  10. __va(bank->start) < (void *)PAGE_OFFSET)
  11. highmem = 1;
  12. bank->highmem = highmem;
  13. /*
  14. * Split those memory banks which are partially overlapping
  15. * the vmalloc area greatly simplifying things later.
  16. */
  17. if (__va(bank->start) < vmalloc_min &&
  18. bank->size > vmalloc_min - __va(bank->start)) {
  19. if (meminfo.nr_banks >= NR_BANKS) {
  20. printk(KERN_CRIT "NR_BANKS too low, "
  21. "ignoring high memory\n");
  22. } else {
  23. memmove(bank + 1, bank,
  24. (meminfo.nr_banks - i) * sizeof(*bank));
  25. meminfo.nr_banks++;
  26. i++;
  27. bank[1].size -= vmalloc_min - __va(bank->start);
  28. bank[1].start = __pa(vmalloc_min - 1) + 1;
  29. bank[1].highmem = highmem = 1;
  30. j++;
  31. }
  32. bank->size = vmalloc_min - __va(bank->start);
  33. }
  34. #else
  35. bank->highmem = highmem;
  36. /*
  37. * Check whether this memory bank would entirely overlap
  38. * the vmalloc area.
  39. */
  40. if (__va(bank->start) >= vmalloc_min ||
  41. __va(bank->start) < (void *)PAGE_OFFSET) {
  42. printk(KERN_NOTICE "Ignoring RAM at %.8llx-%.8llx "
  43. "(vmalloc region overlap).\n",
  44. (unsigned long long)bank->start,
  45. (unsigned long long)bank->start + bank->size - 1);
  46. continue;
  47. }
  48. /*
  49. * Check whether this memory bank would partially overlap
  50. * the vmalloc area.
  51. */
  52. if (__va(bank->start + bank->size) > vmalloc_min ||
  53. __va(bank->start + bank->size) < __va(bank->start)) {
  54. unsigned long newsize = vmalloc_min - __va(bank->start);
  55. printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx "
  56. "to -%.8llx (vmalloc region overlap).\n",
  57. (unsigned long long)bank->start,
  58. (unsigned long long)bank->start + bank->size - 1,
  59. (unsigned long long)bank->start + newsize - 1);
  60. bank->size = newsize;
  61. }
  62. #endif
  63. if (!bank->highmem && bank->start + bank->size > lowmem_limit)
  64. lowmem_limit = bank->start + bank->size;
  65. j++;
  66. }
  67. #ifdef CONFIG_HIGHMEM
  68. if (highmem) {
  69. const char *reason = NULL;
  70. if (cache_is_vipt_aliasing()) {
  71. /*
  72. * Interactions between kmap and other mappings
  73. * make highmem support with aliasing VIPT caches
  74. * rather difficult.
  75. */
  76. reason = "with VIPT aliasing cache";
  77. }
  78. if (reason) {
  79. printk(KERN_CRIT "HIGHMEM is not supported %s, ignoring high memory\n",
  80. reason);
  81. while (j > 0 && meminfo.bank[j - 1].highmem)
  82. j--;
  83. }
  84. }
  85. #endif
  86. meminfo.nr_banks = j;
  87. memblock_set_current_limit(lowmem_limit);
  88. }

(3)最后必须做的就是排序了,完成了这个工作就可以完全被我们上面提到的find_limits函数使用了,而这个工作就放在了接下来的arm_memblock_init(&meminfo, mdesc);中的一开头:

  1. static int __init meminfo_cmp(const void *_a, const void *_b)
  2. {
  3. const struct membank *a = _a, *b = _b;
  4. long cmp = bank_pfn_start(a) - bank_pfn_start(b);
  5. return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
  6. }
  7. void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
  8. {
  9. int i;
  10. sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
  11. memblock_init();
  12. for (i = 0; i < mi->nr_banks; i++)
  13. memblock_add(mi->bank[i].start, mi->bank[i].size);
  14. /* Register the kernel text, kernel data and initrd with memblock. */
  15. #ifdef CONFIG_XIP_KERNEL
  16. memblock_reserve(__pa(_sdata), _end - _sdata);
  17. #else
  18. memblock_reserve(__pa(_stext), _end - _stext);
  19. #endif
  20. #ifdef CONFIG_BLK_DEV_INITRD
  21. if (phys_initrd_size &&
  22. !memblock_is_region_memory(phys_initrd_start, phys_initrd_size)) {
  23. pr_err("INITRD: 0xlx+0xlx is not a memory region - disabling initrd\n",
  24. phys_initrd_start, phys_initrd_size);

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top