我需要从内核中保留一个物理连续RAM的大缓冲区,并且能够保证缓冲区将始终使用特定的硬编码物理地址.此缓冲区应保留为内核的整个生命周期.我编写了一个chardev驱动程序作为用户空间中访问此缓冲区的接口.我的平台是一个嵌入式系统,ARMv7架构运行2.6 Linux内核.
Linux设备驱动程序,第三版的第15章对该主题(第443页)有以下说明:
保留RAM的顶部是通过
mem=在引导时将参数传递给内核来完成的.例如,如果您有256 MB,则参数mem=255M使内核不使用最高兆字节.您的模块稍后可以使用以下代码来访问此类内存:dmabuf = ioremap (0xFF00000 /* 255M */, 0x100000 /* 1M */);
我已经完成了这个以及其他一些事情:
memmap除了那个之外我还在使用bootarg mem.该内核的启动参数文件建议总是使用memmap,只要你使用mem,以避免地址冲突.request_mem_region在打电话之前使用过ioremap,当然,我在前进之前检查它是否成功.这是我完成所有这些后系统的样子:
# cat /proc/cmdline
root=/dev/mtdblock2 console=ttyS0,115200 init=/sbin/preinit earlyprintk debug mem=255M memmap=1M$255M
# cat /proc/iomem
08000000-0fffffff : PCIe Outbound Window, Port 0
08000000-082fffff : PCI Bus 0001:01
08000000-081fffff : 0001:01:00.0
08200000-08207fff : 0001:01:00.0
18000300-18000307 : serial
18000400-18000407 : serial
1800c000-1800cfff : dmu_regs
18012000-18012fff : …Run Code Online (Sandbox Code Playgroud) http://www.mjmwired.net/kernel/Documentation/IO-mapping.txt
153 - remapping and writing:
154 /*
155 * remap framebuffer PCI memory area at 0xFC000000,
156 * size 1MB, so that we can access it: We can directly
157 * access only the 640k-1MB area, so anything else
158 * has to be remapped.
159 */
160 void __iomem *baseptr = ioremap(0xFC000000, 1024*1024);
161
162 /* write a 'A' to the offset 10 of the area */
163 writeb('A',baseptr+10);
164
165 /* unmap when we unload the driver …Run Code Online (Sandbox Code Playgroud) 我遇到过一个术语 - Linux中的内存漏洞.我相信这是重新映射I/O的内存.我的理解是否正确?
我是内核编程的新手,现在尝试将一些值写入设备驱动程序中的32位GPIO寄存器。I / O被ioremap()设置为内存地址。问题是,我不知道如何writel()/ writeb()/ writew()该地址写入位。
供应商文件说该寄存器已打开0xE5200000。我要写入的[0:3]位是这些位,其余的28位(这些[4:31]位)保留为零。
这是到目前为止我编写的设备驱动程序代码的一部分:
#define TCON_ADDR 0xE250000 // The address as provided by the vendor
static void *TIMER_CON_ADDR;
// I have to map and write to the address when the device is opened
static int on_dev_open(struct inode *inode, struct file *file) {
unsigned int data;
TIMER_CON_ADDR = ioremap(TCON_ADDR, 4); // Map the [0:4] bits to TIMER_CON_ADDR
data = 4; // 0100 in binary
writel(data, TIMER_CON_ADDR); …Run Code Online (Sandbox Code Playgroud)