我正在研究如何将Linux内核移植到新的ARM平台。
我注意到一些平台实现在map_io
函数中具有从物理IO地址到虚拟地址的静态映射。
我的问题是如何决定结构map_desc
中的“虚拟”地址?我可以将物理IO映射到任意虚拟内存吗?或者是否有一些规则或良好做法?我查了http://lxr.free-electrons.com/source/Documentation/arm/memory.txt,但没有找到任何答案。
以下是map_desc
和map_io
的一些示例:
http://lxr.free-electrons.com/source/arch/arm/mach-versatile/versatile_dt.c#L45
44 DT_MACHINE_START(VERSATILE_PB, "ARM-Versatile (Device Tree Support)")
45 .map_io = versatile_map_io,
46 .init_early = versatile_init_early,
47 .init_machine = versatile_dt_init,
48 .dt_compat = versatile_dt_match,
49 .restart = versatile_restart,
50 MACHINE_END
http://lxr.free-electrons.com/source/arch/arm/mach-versatile/core.c#L189
189 void __init versatile_map_io(void)
190 {
191 iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));
192 }
131 static struct map_desc versatile_io_desc[] __initdata __maybe_unused = {
132 {
133 .virtual = IO_ADDRESS(VERSATILE_SYS_BASE),
134 .pfn = __phys_to_pfn(VERSATILE_SYS_BASE),
135 .length = SZ_4K,
136 .type = MT_DEVICE
137 }, {
答案 0 :(得分:1)
不是专家,但是,因为map_desc用于静态映射。它应该来自系统手册。 virtual是如何从内核虚拟空间访问外设的,pfn(页帧号)是按页面单位的物理地址。
事情是,如果你在内核空间,你正在使用内核虚拟空间映射,所以即使你想访问某个物理地址,你需要有一个映射,这可以是一对一,我相信你是什么离开map_desc。
静态映射是map_desc,动态映射是ioremap。因此,如果您想使用物理IO,那么ioremap是第一件事,如果那不适用于特殊情况map_desc。
DMA-API-HOWTO为Linux中不同类型的地址映射提供了一个很好的切入点。