大佬教程收集整理的这篇文章主要介绍了linux – 为什么我不应该在ARMv6的系统内存上使用ioremap?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
有关该主题(第443页)的第15章(共Linux Device Drivers,Third Edition页):
我已经完成了这个以及其他一些事情:
>除了mem之外,我还在使用memmap bootarg. kernel boot parameters documentation建议在使用mem时始终使用memmap以避免地址冲突.
>我在调用ioremap之前使用了request_mem_region,当然,在继续前进之前,我检查它是否成功.
这是我完成所有这些后系统的样子:
# cat /proc/cmdline root=/dev/mtdblock2 console=ttyS0,115200 init=/sbin/preinit earlyprintk debug @H_795_18@mem=255M memmap=1M$255M@H_502_35@ # cat /proc/iomem 000-0fffffff : PCIe Outbound Window,Port 0 000-082fffff : PCI Bus 0001:01 000-081fffff : 0001:01:00.0 08200000-08207fff : 0001:01:00.0 18000300-18000307 : serial 18000400-18000407 : serial 1800c000-1800cfff : dmu_regs 18012000-18012fff : pcie0 18013000-18013fff : pcie1 18014000-18014fff : pcie2 19000000-19000fff : cru_regs 1e000000-1fffffff : norflash 40000000-47ffffff : PCIe Outbound Window,Port 1 40000000-403fffff : PCI Bus 0002:01 40000000-403fffff : 0002:01:00.0 40400000-409fffff : PCI Bus 0002:01 40400000-407fffff : 0002:01:00.0 4 00-40807fff : 0002:01:00.0 80000000-8fefffff : System RAM 80052000-8045dfff : Kernel text 80478000-80500143 : Kernel data 8ff00000-8fffffff : foo@H_502_35@mem=mem=255Mdmabuf = ioremap (0xFF00000 /* 255M */,0x100000 /* 1M */);mem=mem=255Mdmabuf = ioremap (0xFF00000 /* 255M */,0x100000 /* 1M */);
到目前为止,一切看起来都很好,我的司机工作得很好.我能够直接读取和写入我选择的特定物理地址.
但是,在启动过程中,触发了一个很大的可怕警告(™):
BUG: Your driver calls ioremap() on system memory. This leads to architecturally unpreDictable behavIoUr on ARMv6+,and ioremap() will fail in the next kernel release. Please fix your driver. ------------[ cut here ]------------ WARNING: at arch/arm/mm/ioremap.c:211 __arm_ioremap_pfn_caller+0x8c/0x144() Modules linked in: [] (unwind_BACktrace+0x0/0xf8) from [] (warn_slowpath_common+0x4c/0x64) [] (warn_slowpath_common+0x4c/0x64) from [] (warn_slowpath_null+0x1c/0x24) [] (warn_slowpath_null+0x1c/0x24) from [] (__arm_ioremap_pfn_caller+0x8c/0x144) [] (__arm_ioremap_pfn_caller+0x8c/0x144) from [] (__arm_ioremap_caller+0x50/0x58) [] (__arm_ioremap_caller+0x50/0x58) from [] (foo_init+0x204/0x2b0) [] (foo_init+0x204/0x2b0) from [] (do_one_initcall+0x30/0x19C) [] (do_one_initcall+0x30/0x19C) from [] (kernel_init+0x154/0x218) [] (kernel_init+0x154/0x218) from [] (kernel_thread_exit+0x0/0x8) ---[ end trace 1a4cab5dbc05c3e7 ]---
触发自:arc/arm/mm/ioremap.c
/* * Don't allow RAM to be mapped - this causes problems with ARMv6+ */ if (pfn_valid(pfn)) { printk(KERN_WARNING "BUG: Your driver calls ioremap() on system memory. This leads\n" KERN_WARNING "to architecturally unpreDictable behavIoUr on ARMv6+,and ioremap()\n" KERN_WARNING "will fail in the next kernel release. Please fix your driver.\n"); WARN_ON(1); }
确切地说,这会导致什么问题?他们能减轻吗?我有什么选择?
提供内核命令行(例如/ proc / cmdlinE)和生成的内存映射(即/ proc / iomem)来验证这一点.
在系统内存上使用ioremap()的问题是,您最终会将冲突的属性分配给内存,从而导致“不可预测”的行为.
请参阅文章“ARM’s multiply-mapped memory mess”,该文章提供了您正在触发的警告的历史记录.
请注意,“系统内存”是由内核管理的RAm.
触发警告的事实表明您的代码正在为内存区域生成多个映射.
您必须确保您想要ioremap()的RAM不是“系统内存”,即由内核管理.
另见this answer.
附录
关注您的此警告是pfn_valid(pfn)返回TRUE而不是falSE的结果.
基于您为2.6.37版提供的Linux交叉引用链接,
pfn_valid()只是返回结果
@H_74_17@memblock_is_memory(pfn << PAGE_SHIFT);
这反过来只是返回结果
@H_74_17@memblock_search(&memblock.memory,addr) != -1;
我建议破解内核代码,以便揭示冲突.
在调用ioremap()之前,将TRUE赋值给全局变量memblock_debug.
以下补丁应显示有关内存冲突的重要信息.
(memblock列表按基址排序,因此memblock_search()在此列表上执行二进制搜索,因此使用mid作为索引.)
static int __init_memblock memblock_search(struct memblock_type *type,phys_addr_t addr) { unsigned int left = 0,right = type->cnt; do { unsigned int mid = (right + left) / 2; if (addr < type->regions[mid].basE) right = mid; else if (addr >= (type->regions[mid].base + type->regions[mid].sizE)) left = mid + 1; - else + else { + if (memblock_debug) + pr_info("MATCH for 0x%x: m=0x%x b=0x%x s=0x%x\n",+ addr,mid,+ type->regions[mid].base,+ type->regions[mid].sizE); return mid; + } } while (left < right); return -1; }
如果要查看所有内存块,请使用变量memblock_debug调用memblock_dump_all()为TRUE.
[有趣的是,这实际上是一个编程问题,但我们还没有看到你的任何代码.]
附录2
由于您可能正在使用ATAG(而不是设备树),并且您想要专用内存区域,请修复ATAG_MEM以反映这种较小的物理内存大小.
假设您对引导代码进行了零更改,ATAG_MEM仍然指定了完整的RAM,因此这可能是导致警告的系统内存冲突的根源.
见this answer about ATAGs和this related answer.
以上是大佬教程为你收集整理的linux – 为什么我不应该在ARMv6的系统内存上使用ioremap?全部内容,希望文章能够帮你解决linux – 为什么我不应该在ARMv6的系统内存上使用ioremap?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。