We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

Showing results for 
Search instead for 
Did you mean: 
Registered: ‎03-27-2014

Re: how to read/write from/to a register in Linux?

I have a design which is working well. Till now i am writing my c program in sdk for standalone version and launching through JTAG.

But now I would like to know that if I use linux OS and want to read and write to specific registers how could I do it ?


this subject has been discussed many times,


in a baremetal apps you can directly address physical addresses,

on Linux you can only use a virtual address mapped to the physical address.


That means you can't do stuff like this anymore

(unsigned int*)(FPGA_BASE+0x04) = 0x01; -- write example
val = (unsigned char *)(FPGA_BASE+0x00); -- reading one byte


you can use the /dev/mem driver which allows you to address physical addresses  from userspace

fd = open ("/dev/mem", O_RDWR);
page_addr = (fpga_base_addr & (~(page_size-1))); 
page_offset = fpga_base_addr - page_addr;
virtual_address = mmap(NULL, page_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, page_addr); //memory map

 see this page for nice tutorials mmap


this job is usually done in the kernel space by a driver, here's how to map a virtual pointer to a physical address retrieved from the devicetree

sdev->regs = devm_ioremap_resource(&pdev->dev, res);
     printk(KERN_ERR "devm_ioremap failed for %s\n",
     status = -ENOMEM;
     goto free_dev_name;


NIST - Time Frequency metrology
2 Replies
Observer sconvertini
Registered: ‎09-06-2018

Re: how to read/write from/to a register in Linux?


I followed your instructions to read the register of the global timer (physical address 0xF8F00200 defined in xparameter.h)

so, I open the /dev/mem file as follow:


int memfd;
	memfd = open("/dev/mem", O_RDWR | O_SYNC); // to open this, the program needs to be run as root
	if (memfd == -1) {
		printf("Can't open /dev/mem.\n");

to provide the virtual address, I use a custom function as follow:



void *getvaddr(int phys_addr, int memfd) {
	void *mapped_base;

	void *mapped_dev_base;
	off_t dev_base = phys_addr;

	// Map one page of memory into user space such that the device is in that page, but it may not
	// be at the start of the page

	mapped_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, memfd,
			dev_base & ~MAP_MASK);
	if (mapped_base == (void *) -1) {
		printf("Can't map the memory to user space.\n");

	// get the address of the device in user space which will be an offset from the base
	// that was mapped as memory is mapped at the start of the page

	mapped_dev_base = mapped_base + (dev_base & MAP_MASK);
	return mapped_dev_base;

Then I initialized a variable as follow:



int *global_timer_addr = getvaddr(XPAR_PS7_GLOBALTIMER_0_S_AXI_BASEADDR, memfd);
	int *timer_0 = global_timer_addr;

I'm using a while statement to test the timer register as follow:

while (1) {
		if (*timer_0 > 333333333) {
			*timer_0 = 0;

I have no problem in reading *timer0 but whe I attempt to write 0 value in *timer, my MicroZed freezes and I need to hardware reset the board.

Do you have any idea how to solve it?

Thank you for your support.


0 Kudos
Registered: ‎02-15-2019

Re: how to read/write from/to a register in Linux?

0 Kudos