Linux 如何为ARM上的虚拟内存选择静态IO内存映射

Linux 如何为ARM上的虚拟内存选择静态IO内存映射,linux,kernel,arm,Linux,Kernel,Arm,我正在研究如何将Linux内核移植到新的ARM平台。 我注意到一些平台实现在map\u IO函数中有从物理IO地址到虚拟地址的静态映射 我的问题是如何在structuremap\u desc中确定“虚拟”地址?我可以将物理IO映射到任意虚拟内存吗?还是有一些规则或良好的实践?我检查了一下,但没有找到任何答案 以下是map\u desc和map\u io的一些示例: 评论太长了 不是专家,但是,因为map_desc用于静态映射。它应该来自系统手册。虚拟是从内核虚拟空间访问外围设备的方式,pfn

我正在研究如何将Linux内核移植到新的ARM平台。 我注意到一些平台实现在
map\u IO
函数中有从物理IO地址到虚拟地址的静态映射

我的问题是如何在structure
map\u desc
中确定“虚拟”地址?我可以将物理IO映射到任意虚拟内存吗?还是有一些规则或良好的实践?我检查了一下,但没有找到任何答案

以下是
map\u desc
map\u io
的一些示例:


评论太长了

不是专家,但是,因为map_desc用于静态映射。它应该来自系统手册。虚拟是从内核虚拟空间访问外围设备的方式,pfn(页面帧号)是按页面单元的物理地址

问题是,如果你在内核空间,你正在使用内核虚拟空间映射,所以即使你想访问某个物理地址,你也需要有一个映射,它可以是一对一的,我相信你从映射描述中得到的

静态映射是映射描述,动态映射是ioremap。所以,如果你想玩物理IO,ioremap是第一件事,如果这不起作用,然后为特殊情况映射描述


为Linux中不同类型的地址映射提供了一个很好的入口点。

这个问题的背景是我需要实现早期的printk宏:addruart、senduart、waituart;“addruart”宏需要UART端口虚拟地址和物理地址。完全回复map_io()以设置映射。物理内存是我可以从硬件手册中找到的东西,但虚拟地址是我需要知道的东西来决定一个值。就背景部分而言,这个问题对你来说不应该是唯一的。在uart重新初始化之前,引导加载程序对早期打印没有帮助吗?对于虚拟地址部分,我想任何低内存都可以。谢谢你的评论。引导加载程序可能进行了一些UART硬件初始化,但将字符放入UART硬件的代码仍然依赖于内核的实现。auselen,你说得对,ioremap对我来说应该足够了。对我之前关于早期printk的addruart的评论进行了一些修正:它没有使用map_io为UART端口进行VM映射,内核引导代码将通过addruart直接获取VM地址,并为我们进行映射。
 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
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         }, {