- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我已经开始学习 linux 设备驱动程序。作为我学习的一部分,我正在做一些示例程序。为了理解内存映射 IO,我编写了以下代码。(此处仅显示 init)。没有硬件映射到基地址。
static unsigned long base = 0xfed00000;
unsigned long device_base=0;
unsigned long virtual_base=0;
static int __init sharedirqmodule_init(void) {
u32 register1=0;
u32 value=0x23456789;
device_base=base;
void *address=0;
if(!request_mem_region(device_base,8,"device"))
return -ENODEV;
virtual_base = (unsigned long) ioremap(device_base, 8);
address=(void *)virtual_base;
printk(KERN_ERR "Sharedirq : Address value: %lx\n",address);
iowrite32(value,address);
wmb();
register1=(u32)ioread32(address);
rmb();
printk(KERN_ERR "Shared irq :value: %d \n",register1);
return 0;
}
模块正在安装。但是我没有得到我在使用 ioread32 时写的正确值。我得到以下输出,
[20441.627344] Sharedirq : Address value: ffffc900001ce000
[20441.627365] Shared irq :value: -1
程序出了什么问题?如果错误是愚蠢的,我会很感激一个线索而不是一个直接的解决方案。(很抱歉为相同的值使用多个变量.. virtual_base 和地址)
最佳答案
There is no hardware mapped at the base address. ... What is going wrong in the program?
正如@AndreasBombe 指出的那样,写入然后读取没有硬件(既没有 RAM 也没有设备寄存器/内存)的内存位置将产生未定义的结果。
I just request_mem_region that region and did a ioremap to use that region. Shouldn't that work? I thought it kind of simulate the memory mapped IO usage.
在您不会从这些调用中收到任何错误的意义上,这应该“有效”。但由于这些物理位置没有硬件,因此访问这些虚拟地址没有任何意义。
The value should be saved in physical memory as the virtual address provided by ioremap would have mapped to a physical address.
这些例程并不像您认为的那样。您之前写过物理地址处没有硬件。调用这些例程后也不会再有。
request_mem_region() 本质上是“分配”给定的物理地址范围(也就是说,它被记录为“正在被该驱动程序使用”)。就这样;除了地址管理,别无其他。
ioremap() 是特定于体系结构的,目的是为物理地址区域提供虚拟地址映射。 Linux 代码只能使用虚拟地址来引用内存,所以现在那些设备寄存器/内存是可以访问的。
request_mem_region() 或 ioremap() 实际上都不会提供任何物理内存供您的驱动程序使用。
I thought iowrite and ioread get converted to ordinary MOV instruction in memory mapped IO case.Is my understanding wrong?
内存映射 I/O 位置将作为虚拟内存操作访问。如果 CPU 的指令集使用 MOV 操作码来访问内存,那么你是对的。
但是为了正确执行您的程序,在那些可以响应存储和获取操作的位置必须有实际的硬件。
I understand it will fail in I/O mapped case
不存在“I/O 映射”这样的东西。
存在“端口映射 I/O”,其设备地址位于与内存不同的空间中,并使用输入 和输出 指令进行访问。
How does a driver written for a memory mapped IO device use the memory it requested using request_mem_region() & ioremap()?
从技术上讲,内存不是“请求的”。我会把它表述为“设备内存(或寄存器)被映射到虚拟内存(空间)”。
在 include/asm-generic/iomap.h 中,ioremap() 返回的值被描述为 cookie,因此不应用作虚拟内存地址由驱动程序,但通过访问函数,如 ioread*() & iowrite*():
17 /*
18 * Read/write from/to an (offsettable) iomem cookie. It might be a PIO
19 * access or a MMIO access, these functions don't care. The info is
20 * encoded in the hardware mapping set up by the mapping functions
21 * (or the cookie itself, depending on implementation and hw).
22 *
23 * The generic routines just encode the PIO/MMIO as part of the
24 * cookie, and coldly assume that the MMIO IO mappings are not
25 * in the low address range. Architectures for which this is not
26 * true can't use this generic implementation.
27 */
28
ioread*() 和 iowrite*() 的通用版本通常被特定于体系结构的版本所取代。
Will ioread() and iowrite() automatically work in that case?
如果“自动”意味着“总是”,那么“不”。并非每个设备寄存器都是可读和/或可写的。
ioread*() 只应在可读的寄存器上执行。 iowrite*() 只应在可写的寄存器上执行。例如。设备状态寄存器当然是可读的,很可能是不可写的。
关于linux - ioread32 后跟 iowrite32 没有给出相同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26831583/
我是一名优秀的程序员,十分优秀!