Arria10 Uboot Reserve Linux Memory


I have been trying to reserve a block of HPS DDR memory for the FPGA to write to.
I am using an Arria 10 dev board running the GSRD.

I’m assuming that this need to be done at uboot so that the Linux Kernel knows not to touch that area of memory and it is marked as reserved.

After reading a few examples I tried the following edit to the environment variables.

_setenv mmcboot “setenv bootargs console=ttyS0,115200 mem=512M memmap=512M$1024M root=/dev/mmcblk0p2 rw rootwait;fpgabr 1;bootz 0x8000 - 0x100”

On checking /proc/iomem in Linux I could see that the System RAM size had been halved (with no mem it defaults to 1024M).

00000000-1fffffff : System RAM
00008000-0067b5ff : Kernel code
006d0000-0074c5b3 : Kernel data
ff800000-ff801fff : /sopc@0/ethernet@0xff800000
ff808000-ff808fff : /sopc@0/flash@0xff808000
ffb00000-ffb3ffff : /sopc@0/usb@0xffb00000
ffc02100-ffc0211f : serial
ffc02300-ffc023ff : /sopc@0/i2c@0xffc02300
ffc02900-ffc029ff : /sopc@0/gpio@0xffc02900
ffc02a00-ffc02aff : /sopc@0/gpio@0xffc02a00
ffc02b00-ffc02bff : /sopc@0/gpio@0xffc02b00
ffd00300-ffd003ff : /sopc@0/timer@0xffd00300
ffda1000-ffda1fff : /sopc@0/dma@0xffda1000
ffda5000-ffda50ff : ffda5000.spi

However as can be seen there is no reserved block at 40000000.

In the examples I followed memmap is supposed to create a reserved block visible in iomem.

Now through trial and error I have found that I can write my data via the fpga2hps bus at physical address 0x60000000.
Writing directly after after the top address of system RAM, or at the top of the DDR crashes Linux.
Therefore I would rather write into a reserved block that Linux knows about to avoid any future issues.

I just cant seem to find any info on how to do this.
Does anyone know of a guide or example for reserving a block of HPS DDR on the Arria 10?


Hi, Gary

I used to set bootargs in uboot as below to reserve memory for core0(you can try to remove "maxcpus=1" if dual core is leveraged) running Linux when boot from SSD. Likely you can take it as a reference. tks
mmcboot=setenv bootargs root=/dev/mtdblock1 maxcpus=1 root=/dev/mtdblock1 rw mem=0x10000000 rootfstype=ext3 console=ttyS0,115200 root=${mmcroot} rw rootwait;bootz ${loadaddr} - ${fdtaddr}

Adeli Wang

plus, mmcroot=/dev/mmcblk0p2

Thanks Adeli, I’ll give it a go.

OK, I finally got to the bottom of what was going on.

Originally I was setting the following as my mmcboot line:

setenv mmcboot “setenv bootargs console=ttyS0,115200 mem=1024M memmap=385M$0x60000000 root=/dev/mmcblk0p2 rw rootwait;fpgabr 1;bootz 0x8000 - 0x100”

But on checking cat /proc/cmdline when Linux had booted only the mem option was visable.
After a lot of googling I found a forum post pointing out that an escape character was needed.


setenv mmcboot “setenv bootargs console=ttyS0,115200 mem=1024M memmap=385M$0x60000000 root=/dev/mmcblk0p2 rw rootwait;fpgabr 1;bootz 0x8000 - 0x100”

The memmap option could then be seen in /proc/cmdline.

This fixed my issue & prevented kernel panic’s when the FPGA began writing.

It should be noted that the reserved memmap block of memory still does not appear in /proc/iomem.

Hope this helps someone else.

Nice shot, happy to hear that it’s fixed.

Unfortunately it looks like I was wrong.

After performing a large file write I found that the file contents had appeared in my FPGA-to-HPS buffer area.
Any further FPGA writes after this point caused Kernel panics.

My FPGA-to-HPS buffer sits above the Linux system RAM in the DDR3 physical memory, so it looks like Linux will just use DDR above the System RAM when it need a cache!

Also its becoming clear that my kernel is not processing the memmap command!

I’ve not yet tried (tested) this but was planning on giving the Device Tree method a try.

[kernel source location]/Documentation/devicetree/bindings/reserved-memory
The names fpga_reserved and fpga_private can be any user defined name.

reserved-memory {
	#address-cells = <1>;
	#size-cells = <1>;

	fpga_reserved: fpga_private@78000000 { /* @base_address */
		reg = <0x78000000 0x800000>; /* <base_address size> */

	/* ... */


   /* I "think" this is optional - shows how a device can reference the reserved memory */
fpga_comp0: fpga_component@12300000 { /* @base_address */
	memory-region = <&fpga_reserved>;

	/* ... */


This thread appears to be rather old. Not sure why it just popped up in my email from rocketboards.
If any tries this I’d like to hear the results.