开机预留内存的方法

工作中,遇到需要开机时预先给用户态程序预留一部分内存供用户态程序使用。如果有新方法再更新:

一、bootargs中增加“mem = 4096m”

通过在bootargs中增加“mem = 4096m”指定内核认为的可用物理内存大小为4G。这种方法设置后基本上只能使用使用4G以内的空间,如果物理空间大于4G基本上等于浪费了(设计架构的知识还没懂,有新的认知了再补充)。
所以这种办法没办法做开机预留,只是做可用内存空间限制,当涉及地址长度受限时使用(比如32位地址只能最大方位4G存储空间)。

二、在设备树增加 reserved-memory 节点

先通过 cat /proc/iomem 看哪块内存没被预留,挑选一块区域(要求最好是扇区整数倍,400000字节是一个扇区)

按照自己选定的要预留的内存修改设备树:

/ {
        reserved-memory {
                #address-cells = <2>;
                #size-cells = <2>;
                ranges;
                /* Limit memory in 4G Bytes for user space APP*/
                ecat_reserved: hahahaha@142000000 {
                        no-map;
                        reg = <0x1 0x42000000 0x0 0x80000000>;
                };
        };
};

然后编译设备树,使用新设备树。

然后使用自己预留的起始内存的物理地址做mmap映射,核心代码(续上面的例子):

off_t pa_offset = 142000000;
int lendth = 0x80000000;//可比自己预留的小一些
fd = open("/dev/mem", O_RDWR | O_SYNC);
pbase = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED , fd, pa_offset);

然后就可用根据mmap返回的虚拟地址通过memcpy操纵预留的内存,但实验发现,memcpy每次写入的字节数需要为8的倍数,否则会有bus error报错。可能跟mmap函数的 non-cacheable特性有关。

三、在内核代码中通过 dma_alloc_coherent 预留

部分内核代码:

ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
reserve_base = dma_alloc_coherent(&pdev->dev, LENGTH_RESERVE, &reserve_dma, GFP_KERNEL);
pr_info("%s:%d  reserve_dma:0x%llx \n", __func__, __LINE__, reserve_dma);
if (!reserve_base) {
	ret = -ENOMEM;
	pr_info("%s:%d dma_alloc_coherent error\n", __func__, __LINE__);
	dma_free_coherent(&pdev->dev, LENGTH_RESERVE, reserve_base, reserve_dma);
}

通过dmesg查看确实预留了代码,打印出得到的物理地址“reserve_dma”,然后open /dev/mem目录后用mmap使用该物理地址作为偏移量,报mmap失败,该方法有待进一步研究。

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值