linux板级内存管理之-物理内存描述的两种实现方法

Linux板级内存管理之-物理内存描述的两种实现方法


osboy - mcuos.com站长原创


mcuos.com@gmail.com



(1)物理内存的描述


我们知道物理内存的描述,在linux内核里面是通过meminfo的机构体来实现的。
  1. struct membank {
  2.         unsigned long start;
  3.         unsigned long size;
  4.         unsigned short node;
  5.         unsigned short highmem;
  6. };

  7. struct meminfo {
  8.         int nr_banks;
  9.         struct membank bank[NR_BANKS];
  10. };



对于我们新唐的arm9 nuc900来说,开发板内存是64Mbytes的,所以这里的:
start = 0x0,因为我们是从0x0作为sdram的基地址的,所以填写0.
size = 64M,
node,因为我们板子的内存是平坦式的,不存在多个内存节点node,所以这个只有一个0.
(2)物理内存的信息,是如何告知内核的?

有两种方法:
(2.1)静态设置fixup函数里面的meminfo结构体

  1. MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
  2.         /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
  3.         .phys_io        = REALVIEW_EB_UART0_BASE & SECTION_MASK,
  4.         .io_pg_offst        = (IO_ADDRESS(REALVIEW_EB_UART0_BASE) >> 18) & 0xfffc,
  5.         .boot_params        = PHYS_OFFSET + 0x00000100,
  6.         .fixup                = realview_fixup,
  7.         .map_io                = realview_eb_map_io,
  8.         .init_irq        = gic_init_irq,
  9.         .timer                = &realview_eb_timer,
  10.         .init_machine        = realview_eb_init,
  11. MACHINE_END


  12. /*
  13. * Setup the memory banks.
  14. */
  15. void realview_fixup(struct machine_desc *mdesc, struct tag *tags, char **from,
  16.                     struct meminfo *meminfo)
  17. {
  18.         /*
  19.          * Most RealView platforms have 512MB contiguous RAM at 0x70000000.
  20.          * Half of this is mirrored at 0.
  21.          */
  22. #ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET
  23.         meminfo->bank[0].start = 0x70000000;
  24.         meminfo->bank[0].size = SZ_512M;
  25.         meminfo->nr_banks = 1;
  26. #else
  27.         meminfo->bank[0].start = 0;
  28.         meminfo->bank[0].size = SZ_256M;
  29.         meminfo->nr_banks = 1;
  30. #endif
  31. }
复制代码

(2.2)通过内核参数设置“mem=”来设置

我们新唐的开发板内存64M,所以我这kernel的参数中设置mem=64M。那么内核有专门的解释这个参数的函数:

  1. static int __init early_mem(char *p)
  2. {
  3.         static int usermem __initdata = 0;
  4.         unsigned long size, start;
  5.         char *endp;

  6.         /*
  7.          * If the user specifies memory size, we
  8.          * blow away any automatically generated
  9.          * size.
  10.          */
  11.         if (usermem == 0) {
  12.                 usermem = 1;
  13.                 meminfo.nr_banks = 0;
  14.         }

  15.         start = PHYS_OFFSET;
  16.         size  = memparse(p, &endp);
  17.         if (*endp == '@')
  18.                 start = memparse(endp + 1, NULL);

  19.         arm_add_memory(start, size);

  20.         return 0;
  21. }
  22. early_param("mem", early_mem);
复制代码



内核通过该函数解析64M这个数字,最终通过函数arm_add_memroy函数来初始化meminfo这个结构体变量:

  1. static int __init arm_add_memory(unsigned long 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 %#lx\n", 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.         bank->node  = PHYS_TO_NID(start);

  17.         /*
  18.          * Check whether this memory region has non-zero size or
  19.          * invalid node number.
  20.          */
  21.         if (bank->size == 0 || bank->node >= MAX_NUMNODES)
  22.                 return -EINVAL;

  23.         meminfo.nr_banks++;
  24.         return 0;
  25. }
复制代码



至此,这两种方式都实现了一个功能,那就是把你的板子的内存的起始基地址和内存大小,节点数等信息通知给内核,内核最终会通过meminfo来实现对物理内存的管理。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值