如何从linux内核模块写入寄存器(cpu:ARM)

时间:2013-06-05 08:30:18

标签: linux memory arm

我试图从linux内核写入系统控制寄存器。但结果是分段错误:

  

无法在虚拟地址20050004处理内核分页请求

来自内核模块的代码:

#define REGBASE 0x20050000

void writeRegister(void){
    __raw_writel( 0x00000002, REGBASE + 0x0004 );
}

如何访问系统控制寄存器所在的片上存储器?

2 个答案:

答案 0 :(得分:4)

我猜这个REGBASE是一个物理地址而不是虚拟地址。您需要让内核将其映射到地址空间,然后才能使用它。大多数情况下,您使用ioremap来映射它。

例如:

void __iomem *io = ioremap(REGBASE, SZ_4K);
writel(0x00000002, io + 0x0004);

答案 1 :(得分:1)

我知道这不是您正在寻找的答案,但如果您想避免为您的应用程序编写内核模块,可以在用户空间中执行此操作。

这是Raspberry Pi3中GPIO访问的一个示例:

#define RASPBERRY_PI_PERI_BASE  0x3F000000
#define GPIO_BASE               (RASPBERRY_PI_PERI_BASE + 0x200000) // GPIO controller

#define BLOCK_SIZE              (4*1024)

static volatile uint32_t *gpio = NULL;

int GPIO_init(void) {
    int   fd;

    if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) return -1; // printf("Failed to open /dev/mem, try checking permissions.\n");
    gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE);
    if ((int32_t)gpio == -1) return -1; // printf("Failed mmap (GPIO): %s\n", strerror (errno)); 

    return 0;
}

现在你有一个简单的指针变量* gpio,它链接到硬件的内存地址。你做它映射&#34; mem&#34;内存上的设备,为你而存在&#34;免费&#34; : - )

问候。