所以,当涉及到内核驱动程序,我是一个新手,并有一个关于ioremap函数的问题。
我正在编写一个驱动程序,用于访问使用ARM Cortex-M3和FPGA架构的SoC上的定制VHDL模块中定义的某些寄存器。 看例子,我认为我应该使用ioremap,但是由于Cortex-M3没有MMU,所以我没有看到这一点,如下例所示:
/* Physical addresses */ static u32* rcu_trig_recv_physaddr = ((u32 *) 0x50040000); static int rcu_trig_recv_size = 0x10; // size of 16 for testing /* Virtual addresses */ static u32* rcu_trig_recv_virtbase = NULL; /*removed code not relevant for the question*/ static int __init rcumodule_init(void) { int iResult = 0; // holding result of operations u32 buffer; // Register the driver iResult = register_chrdev(rcuc_majorID, "rcuc", &rcuc_fops); if (iResult < 0) { printk(KERN_INFO "module init: can't register driver\n"); } else{ printk(KERN_INFO "module init: success!\n"); } // Map physical address to virtual address if(rcu_trig_recv_size){ rcu_trig_recv_virtbase = (u32*) ioremap_nocache( (u32 *)rcu_trig_recv_physaddr, rcu_trig_recv_size ); printk("Remapped TRGRECV from 0x%p to 0x%p\n", rcu_trig_recv_physaddr, rcu_trig_recv_virtbase); } // try to read some stuff, expecting 0x17240f09 buffer = readl(rcu_trig_recv_virtbase); printk("read %lx, at 0x%p\n", buffer, rcu_trig_recv_virtbase); return iResult; }
然后这回,当我insmod司机:
# insmod trigger.ko module init: success! Remapped TRGRECV from 0x50040000 to 0x50040000 read 17240f09, at 0x50040000
据此,我只是更好地阅读物理地址。 或者这是一个坏主意,我应该更好地与我的寄存器搞混了吗?
如果你知道你的代码永远不需要在其他设备上使用,那么你可以逃避这一切,但是使用ioremap()会更安全。 基于代码获取和使用由内存映射IO提供的指针将使您的代码比使用硬编码的物理地址更加便携和可维护。
即使你不打算把这个代码放到不同的设备上,当简单地升级到一个新的芯片时,使用物理地址也可能会破坏你的代码。