我試圖從linux內核寫入系統控制寄存器。但結果是分段錯誤:如何從linux內核模塊寫入寄存器(cpu:ARM)
無法在虛擬地址從內核模塊20050004
代碼來處理內核尋呼請求:
#define REGBASE 0x20050000
void writeRegister(void){
__raw_writel(0x00000002, REGBASE + 0x0004);
}
如何訪問片上存儲器,其中系統控制寄存器位於?
我試圖從linux內核寫入系統控制寄存器。但結果是分段錯誤:如何從linux內核模塊寫入寄存器(cpu:ARM)
無法在虛擬地址從內核模塊20050004
代碼來處理內核尋呼請求:
#define REGBASE 0x20050000
void writeRegister(void){
__raw_writel(0x00000002, REGBASE + 0x0004);
}
如何訪問片上存儲器,其中系統控制寄存器位於?
我猜REGBASE是一個物理地址,而不是一個虛擬的。您需要讓內核將其映射到地址空間,然後才能使用它。大多數時候,你會使用ioremap
它在映射
例如:
void __iomem *io = ioremap(REGBASE, SZ_4K);
writel(0x00000002, io + 0x0004);
正確答案! – JohnnyFromBF
我知道這是不是正是你正在尋找的答案,但有一個辦法做到這一點的用戶空間,如果你想避免爲你的應用程序編寫一個內核模塊。
這是在覆盆子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鏈接到硬件的內存地址。你做它映射「內存」設備的內存,這是爲你「免費」:-)
問候。
可能的重複:[request_mem_region()'做什麼?](http://stackoverflow.com/questions/7682422/what-does-request-mem-region-actually-do-and-when-it-是需要的) –