I trying to write into system control register from linux kernel. But result is segmentation fault:
Unable to handle kernel paging request at virtual address 20050004
Code from kernel module:
#define REGBASE 0x20050000
void writeRegister(void){
__raw_writel( 0x00000002, REGBASE + 0x0004 );
}
How to access on-chip memory where system control registers located?
I'm guessing that REGBASE is a physical address and not a virtual one. You need to ask the kernel to map it into the address space before you can use it. Most of the time you'd use ioremap
to map it in.
For example:
void __iomem *io = ioremap(REGBASE, SZ_4K);
writel(0x00000002, io + 0x0004);
I know that is not exactly the answer you are looking for, but there is a way to do it in user space, if you want to avoid to program a kernel module for your application.
This is an example for GPIO access in Raspberry Pi3:
#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;
}
Now you have a simply pointer variable *gpio that links to the hardware's memory address. You do it mapping "mem" device on memory, that exists for you "for free" :-)
Regards.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With