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

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

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

  1. void __init setup_arch(char **cmdline_p)
  2. {
  3. struct machine_desc *mdesc;
  4. unwind_init();
  5. setup_processor();
  6. mdesc = setup_machine_fdt(__atags_pointer);
  7. if (!mdesc)
  8. mdesc = setup_machine_tags(machine_arch_type);
  9. machine_desc = mdesc;
  10. machine_name = mdesc->name;
  11. if (mdesc->soft_reboot)
  12. reboot_setup("s");
  13. init_mm.start_code = (unsigned long) _text;
  14. init_mm.end_code = (unsigned long) _etext;
  15. init_mm.end_data = (unsigned long) _edata;
  16. init_mm.brk = (unsigned long) _end;
  17. strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
  18. *cmdline_p = cmd_line;
  19. parse_early_param();
  20. sanity_check_meminfo();
  21. arm_memblock_init(&meminfo, mdesc);
  22. paging_init(mdesc);
  23. request_standard_resources(mdesc);
  24. unflatten_device_tree();
  25. #ifdef CONFIG_SMP
  26. if (is_smp())
  27. smp_init_cpus();
  28. #endif
  29. reserve_crashkernel();
  30. cpu_init();
  31. tcm_init();
  32. #ifdef CONFIG_MULTI_IRQ_HANDLER
  33. handle_arch_irq = mdesc->handle_irq;
  34. #endif
  35. #ifdef CONFIG_VT
  36. #if defined(CONFIG_VGA_CONSOLE)
  37. conswitchp = &vga_con;
  38. #elif defined(CONFIG_DUMMY_CONSOLE)
  39. conswitchp = &dummy_con;
  40. #endif
  41. #endif
  42. early_trap_init();
  43. if (mdesc->init_early)
  44. mdesc->init_early();
  45. }

在上面的注释中,我已经表明了重点和解析,下面我细化下:

(1)获取参数部分

通过parse_early_param();函数可以解析内核启动参数中的许多字符串,但是对于我们这次分析内存的话主要是分析以下两个参数:

mem=size@start参数,她为初始化struct meminfo meminfo;(我们一直关注的内存信息哦~)提供信息。具体的获取信息的函数(同样位于setup.c (arch\arm\kernel)):

  1. int __init arm_add_memory(phys_addr_t start, unsigned long size)
  2. {
  3. struct membank *bank = &meminfo.bank[meminfo.nr_banks];
  4. if (meminfo.nr_banks >= NR_BANKS) {
  5. printk(KERN_CRIT "NR_BANKS too low, "
  6. "ignoring memory at 0xllx\n", (long long)start);
  7. return -EINVAL;
  8. }
  9. /*
  10. * Ensure that start/size are aligned to a page boundary.
  11. * Size is appropriately rounded down, start is rounded up.
  12. */
  13. size -= start & ~PAGE_MASK;
  14. bank->start = PAGE_ALIGN(start);
  15. bank->size = size & PAGE_MASK;
  16. /*
  17. * Check whether this memory region has non-zero size or
  18. * invalid node number.
  19. */
  20. if (bank->size == 0)
  21. return -EINVAL;
  22. meminfo.nr_banks++;
  23. return 0;
  24. }
  25. /*
  26. * Pick out the memory size. We look for mem=size@start,
  27. * where start and size are "size[KkMm]"
  28. */
  29. static int __init early_mem(char *p)
  30. {
  31. static int usermem __initdata = 0;
  32. unsigned long size;
  33. phys_addr_t start;
  34. char *endp;
  35. /*
  36. * If the user specifies memory size, we
  37. * blow away any automatically generated
  38. * size.
  39. */
  40. if (usermem == 0) {
  41. usermem = 1;
  42. meminfo.nr_banks = 0;
  43. }
  44. start = PHYS_OFFSET;
  45. size = memparse(p, &endp);
  46. if (*endp == @)
  47. start = memparse(endp + 1, NULL);
  48. arm_add_memory(start, size);
  49. return 0;
  50. }
  51. early_param("mem", early_mem);

vmalloc=size参数,她为初始化vmalloc_min(需要保留的内核虚拟地址空间大小,也就是这个内核虚拟地址空间中除去逻辑地址空间和必要的防止越界的保护空洞后最少要预留的地址空间)提供信息。具体的实现函数(位于mmu.c (arch\arm\mm)):

  1. static void * __initdata vmalloc_min = (void *)(VMALLOC_END - SZ_128M);

  1. /*
  2. * vmalloc=size forces the vmalloc area to be exactly size
  3. * bytes. This can be used to increase (or decrease) the vmalloc
  4. * area - the default is 128m.
  5. */
  6. static int __init early_vmalloc(char *arg)
  7. {
  8. unsigned long vmalloc_reserve = memparse(arg, NULL);
  9. if (vmalloc_reserve < SZ_16M) {
  10. vmalloc_reserve = SZ_16M;
  11. printk(KERN_WARNING
  12. "vmalloc area too small, limiting to %luMB\n",
  13. vmalloc_reserve >> 20);
  14. }
  15. if (vmalloc_reserve > VMALLOC_END - (PAGE_OFFSET + SZ_32M)) {
  16. vmalloc_reserve = VMALLOC_END - (PAGE_OFFSET + SZ_32M);
  17. printk(KERN_WARNING
  18. "vmalloc area is too big, limiting to %luMB\n",
  19. vmalloc_reserve >> 20);
  20. }
  21. vmalloc_min = (void *)(VMALLOC_END - vmalloc_reserve);
  22. return 0;
  23. }
  24. early_param("vmalloc", early_vmalloc);

(2)在获得了必要的信息(初始化好struct meminfo meminfo

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

网站地图

Top