Write to physical ram address

I am trying to write data to specific physical ram addresses from within the Linux OS and read that data from the FPGA. I am currently working on writing/reading to/from ram from the HPS. I am using /dev/mem along with mmap() to write and read the data from the HPS, but I ran into segmentation faults when trying to write ~80Mb or writing certain locations in memory. Depending on where the offset is; the OS crashes…I think I might be writing to another process’s memory or the OS memory.

Can I find out what portions or addresses of ram are safe to write to? Also, if I make a tempfs or ramfs, is it possible to write to a physical location from by accessing them from mmap() or would I only be dealing with virtual addresses?

Is there a better method for writing to a physical address? Once written I need to pass the address to the FPGA so it can read from that location.

Thank you!

(Just a note, I am a noobie in this field. I have never worked with Linux before except as a user.)

are you writing from fpga to ddr3 linux memory ?
have you reserved the memory from linux side via uboot directives ?
you must limit linux memory and reserve a space for fpga and after access to static address via mmap().

Hi diego,

I am only reading from ddr4 in the FPGA and writing to ddr4 in my Linux OS.

I added a “mem=512M” in UBoot for the bootargs to reserve memory for Linux. I just added this after some looking around and I am still testing it. It looks like it is working correctly, but I still need to build the FPGA-side to read from RAM.

Does “mem” prevent the OS from accessing the other portions of RAM? From what I have collected, the upper portions of RAM should be free. In this case, I should be able to write from my application starting from 0x20000000 without worrying about overwriting RAM locations that are already in use. Is my assumption correct?

thank you

The foolproof way to do things is to write a kernel module and reserve ddr memory via kmalloc() or something similar, although i realise you probably don’t want to bother with that.
Based on addresses i’ve seem from kmalloc(), i’d say starting from 0x10000000 is a safer bet for rough-and-ready usage.

You have to use kmalloc() to allocate a phisically contiguous buffer in memory. It will give you the physical address you can access from the FPGA and a virtual access to access the buffer from inside the driver. But kmalloc is in cached memory so you have to add 0x80000000 to the physical address and use that address from the FPGA to access through ACP port in a coherent way. The problem is that you need to first configure ACP.
If you want to access from the L3 to SDRAM port you , first you have to allocate a buffer with dma_alloc_coherent(). This function allocates physically contiguous buffer non-cached.
You can check my example in:https://github.com/robertofem/CycloneVSoC_Examples/tree/master/DE1-SoC/Linux_Modules/DMA_PL330_LKM_basic It allocates the 2 kinds of buffer, configures ACP and performs a DMA transfer from processor memories to FPGA. It is still not well documented but I think its easy to understand and you can see how functions are called.

roberbot - I see this is an old post but I am just getting into some SDRAM access and could use a good example. I followed the link in your post but it is gone now from Github. Do you have an alternate location for it? -Thanks

Yeah, the folder name changed
This is the link: https://github.com/robertofem/CycloneVSoC-examples/tree/master/Linux-modules/DMA_PL330_LKM_basic

You may also be interested in a fully generic driver to control DMA from applications: It is here: https://github.com/robertofem/CycloneVSoC-examples/tree/master/Linux-modules/DMA_PL330_LKM
and an example on how to use it to move data from processor and FPGA here:

And now everything is well documented in its corresponding README


Thanks! Gave it a quick read thru, I downloaded it and can’t wait to get into the thick of it!