cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
marcoventurini
Adventurer
Adventurer
36,591 Views
Registered: ‎10-02-2014

Zynq + Petalinux reserve a DDR memory region

Jump to solution

Hi all,

 

I' working on a system where Petalinux and a custom AXI DMA share a common area of the DD3 memory.

 

I'm an experienced FPGA designer but i have no experince in linux sw development. ;)

 

The idea is that the PS writes that area of memory and then commands the FPGA to read it or viceversa.

I have already made it work with a bare metal application, now i have to try with linux.

 

So far i got a register interface(not mapped in the DDR address sapce) working with the UIO driver.

My system will have lik 128 Mbytes for linux and 384 of shared buffer.

 

The buffer must not be chached and must be accessible from userspace.

 

My first question is :

Should i limit the RAM size in the petalinux BSP? (by changing the main_memory_size override)

How do i write/read withpu cache ? is there some guide or some snippet like "write a word to address 0x10000000" ?

 

Thanks

 

Marco

 

 

 

 

 

0 Kudos
1 Solution

Accepted Solutions
doreenyen
Explorer
Explorer
47,874 Views
Registered: ‎06-23-2013

As Soren B. mentioned, altering the devicetree in the boot partition, what was originally 0x40000000 is now 0x30000000,

gives us 256MB taken away from Ubuntu kernel to use as shared memory with FPGA which we have been using for over a year. 

 

memory {
device_type = "memory";
reg = <0x00000000 0x30000000>;
};

dogbytes

View solution in original post

43 Replies
muzaffer
Teacher
Teacher
35,359 Views
Registered: ‎03-31-2012
you can put "memmap=1M$2G" to reserve a 1M address space at 2G which creates a hole in the address space and os doesn't touch it at all. Then you can use MMAP_FIXED | MMAP_ANON parameters to mmap to get a pointer to it in user space and use the returned pointer just as a regular pointer to read & write.
- Please mark the Answer as "Accept as solution" if information provided is helpful.
Give Kudos to a post which you think is helpful and reply oriented.
0 Kudos
marcoventurini
Adventurer
Adventurer
35,352 Views
Registered: ‎10-02-2014

Sorry for the ignorance, where should i add it? In my application?

 

Thanks,

 

Marco

0 Kudos
muzaffer
Teacher
Teacher
35,340 Views
Registered: ‎03-31-2012
memmap is a linux kernel parameter: https://www.kernel.org/doc/Documentation/kernel-parameters.txt
- Please mark the Answer as "Accept as solution" if information provided is helpful.
Give Kudos to a post which you think is helpful and reply oriented.
0 Kudos
sorenb
Xilinx Employee
Xilinx Employee
35,331 Views
Registered: ‎03-13-2012

I don't know whether it is an appropriate solution for this problem, but DT bindings for reserving memory exist: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt

0 Kudos
marcoventurini
Adventurer
Adventurer
35,288 Views
Registered: ‎10-02-2014

Thanks for your suggestion

 

i tried the following command line

 

mem=512M memmap=256M$256M

 

but i get always

cat /proc/iomem 
00000000-1fffffff : System RAM
  00008000-004eefd3 : Kernel code
  00bc8000-00c1146f : Kernel data
e0001000-e0001ffe : xuartps
e0100000-e0100fff : mmc0
f8003000-f8003fff : /amba@0/ps7-dma@f8003000
f8007000-f80070ff : xdevcfg


Shouldn't i see the memory marked as reseved?

 

if i decrease mem=512M to mem=256M i get the Hi address correcty set to

0fffffff

 

so i guess i'm on the right track, but no there yet...

 

Thanks

 

0 Kudos
ghalady
Visitor
Visitor
34,814 Views
Registered: ‎02-12-2014

Hi Macro,

             Can you please share the code, if you don't mind on the Forum, as I'm trying something similar and have had no luck so far to get the Petalinux to do DMA between DDR and BRAM implemented in PL part (@4000_0000 to 4001_ffff) however, there is a speedway reference design for the baremetal DMA test between DDR and BRAM, I just couldn't get this work on Petalinux.

 

Thanks in advance

Girish

0 Kudos
doreenyen
Explorer
Explorer
47,875 Views
Registered: ‎06-23-2013

As Soren B. mentioned, altering the devicetree in the boot partition, what was originally 0x40000000 is now 0x30000000,

gives us 256MB taken away from Ubuntu kernel to use as shared memory with FPGA which we have been using for over a year. 

 

memory {
device_type = "memory";
reg = <0x00000000 0x30000000>;
};

dogbytes

View solution in original post

marcoventurini
Adventurer
Adventurer
34,047 Views
Registered: ‎10-02-2014

Thanks doreenyen, it almost worked as you suggested

 

i reduced the memory  and then i added a shared area that i accessed with the UIO user space driver

 

 

reserved_memory {
device_type = "reserved_memory";
reg = <0x30000000 0x0F000000>;
compatible = "generic-uio" };

 Marco

32,829 Views
Registered: ‎05-16-2015

 Hi,

 


@muzaffer wrote:
you can put "memmap=1M$2G" to reserve a 1M address space at 2G which creates a hole in the address space and os doesn't touch it at all. Then you can use MMAP_FIXED | MMAP_ANON parameters to mmap to get a pointer to it in user space and use the returned pointer just as a regular pointer to read & write.

I'm trying to work with your approach above.

I know that your post is quite old, but the maybe you can help on this.

 

I set the kernel arg to: memmap=256M$512M

There is a way to verify on the running machine, that this is set correctly?

 

Here my application code:

 

u32 page_size=sysconf(_SC_PAGESIZE);
int fd=open("/dev/mem",O_RDWR);
if(fd<1)
{
return -1;
}

memoryPtr=mmap(0x20000000, page_size, PROT_READ|PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS, fd, 0x20000000);

 

 

The issue is that the returned pointer is always -1, meaning an error has occured.

Thank you for your hint.

0 Kudos
abbascit
Contributor
Contributor
28,128 Views
Registered: ‎12-30-2015

Dear marcoventurini,

 

I am also doing same kind of thing. I have Baremetal having DMA at core1 it is writing and reading to DDR. But i want to ask that how linux(running at core 0) will read and write to DDR? 

 

I really need help regarding this. I got stuck here from last couple of weeks.

 

please help me.

 

Thanks

 

Regards

 

Tags (3)
0 Kudos
jeffdaq
Explorer
Explorer
27,848 Views
Registered: ‎11-22-2015
 

  This is quite old but since I had an issue I thougth I would add a comment.   The kernel cmdline arg, memmap, does not work for ARM so don't use it.   If I had read the kernel documentation I would have saved some time instead of wondering why it didn't work. 

  As suggensted, you can used the reserved-memory block in the DT.  You do not have to change the amount of memory as the reserved-memory seem to create a hole of for the reserved memory.

 

jeff

0 Kudos
shankarst
Newbie
Newbie
27,113 Views
Registered: ‎06-23-2016

Can anyone share the device tree file for this? I tried to add the same entry as reserved memory in this thread right next memory node it did not work. I do not see anythin in /sys/class/uio path.

 

My entry was 

 

reserved-memory{

     reg = <0x20000000 0x20000000>;

     comaptible = "generic-uio";

};

 

I am trying to reserve 512 MB for shared memory with FPGA.

0 Kudos
muzaffer
Teacher
Teacher
27,110 Views
Registered: ‎03-31-2012

I am not sure what you are trying to do but uio is mainly for getting interrupts easily into user space. It's unlikely that a memory region will interrupt ;-)

 

Also you have a typo here:

 

     comaptible = "generic-uio";

 

- Please mark the Answer as "Accept as solution" if information provided is helpful.
Give Kudos to a post which you think is helpful and reply oriented.
0 Kudos
shankarst
Newbie
Newbie
27,094 Views
Registered: ‎06-23-2016

Good catch! but in my DTS file it is correct you know was lazy to scp the original dts file to windows :)

 

I have FPGA module acquiring high speed data and DMAing it to the memory regiion I am reserving. I need a way to read it into the PS running linux. 

After editing uio_pdrv_genericirq file with the compat string it works. I can see it listed as a uio device under /dev/uiox.

 

Now opening it is causing an io error. any hints.

 

Or can I make it 'non uio" device and mmap the reserved memory? I am going to try this today will post the result.:)

0 Kudos
jeffdaq
Explorer
Explorer
27,087 Views
Registered: ‎11-22-2015

Also for UIO you can change the kernel command line, but I modified the driver as you did for something else.  I also have a rsvd block of memory and I just mmap that block in, no UIO.

 

jeff

0 Kudos
rijuxavier
Observer
Observer
27,078 Views
Registered: ‎06-07-2016

what if I would like linux to provide addresses in a particular range say 0x40000000 should i just modify the device tree to start from 0x40000000 instead of 0x00000000 in the below section of .dts file?

 

memory {
device_type = "memory";
reg = <0x00000000 0x40000000>;  
};

 

after modification

memory {
device_type = "memory";
reg = <0x40000000 0x40000000>;  
};

 

I have done that but how can i verify the physical addresses.

0 Kudos
jeffdaq
Explorer
Explorer
27,073 Views
Registered: ‎11-22-2015
that's the entry for your main memory, you don't want to modify that. You can specify any address, here is what I have

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

vin_reserved: vin@0x10000000 {
reg = <0x10000000 0x40000>;
};
};

I have the extra label my userspace app can parse the device-tree in /proc to get the address and size instead of hardcoding the values
rijuxavier
Observer
Observer
27,068 Views
Registered: ‎06-07-2016

So.  Basically here is the situation.  Zynq FPGA is programmed to addresses the DRAM memory from 0x40000000 to 0x7FFFFFFF range.  I need an application running on Linux OS which would provide me virtual addresses for DRAM addresses in the range of 0x40000000 to 0x7FFFFFFF.

0 Kudos
atower
Adventurer
Adventurer
25,932 Views
Registered: ‎09-28-2016

Hi, Marco

 

I meet the similar issue. as I see, there are two methods in this post,

 

the first is add "mem=512M memmap=256M$256M" in kernel parameter,

 

the second as below:

memory {
device_type = "memory";
reg = <0x00000000 0x30000000>;
};

 

so I am confused, which method did you choose at last?

 

Tom

0 Kudos
hokim
Scholar
Scholar
21,388 Views
Registered: ‎10-21-2015

Hi, atower

 

I think it  doesn't work to modify the memory range of memory node in DT.

You can confirm it by converting the converted DT blob int DT source reversely.

These are my solution for reserved memory 

 

1. kernel boot parameter 'mem=256M'  in bootarg  property of device tree

2. u-boot environment 'fdt_high=0x10000000' in uEnv.txt

0 Kudos
atower
Adventurer
Adventurer
21,359 Views
Registered: ‎09-28-2016

Hi, hokim

 

Thanks for your reply. what's the meaning of second procedure "u-boot environment 'fdt_high=0x10000000' in uEnv.txt?

 

where is the file uEnv.txt?

what's the mean of "fdt_high=0x10000000"?

is  "fdt_high" u-boot environment varialbe?

in your solution, what address is the start address of reserved physical space?

 

 

Tom

0 Kudos
hokim
Scholar
Scholar
21,343 Views
Registered: ‎10-21-2015

 

fdt_high is used to restrict the maximum address that the flatten device tree will be copied into upon boot.

In the xilinx u-boot, fdt_high defaults 0x20000000. If you use reserved memory in the high memory region, you should

lower ftd_high value. u-boot in the boot.bin reads and updates environment variables in uEnv.txt where is in the same directory as boot.bin

This my uEnv.txt

kernel_image=uImage

devicetree_image=devicetree.dtb

kernel_load_address=0x2080000

devicetree_load_address=0x2000000

#fdt_high=0x1e000000

bootcmd=mmcinfo && fatload mmc 0 ${kernel_load_address} ${kernel_image} && fatlo
ad mmc 0 ${devicetree_load_address} ${devicetree_image} && bootm ${kernel_load_a
ddress} - ${devicetree_load_address}

0 Kudos
atower
Adventurer
Adventurer
21,312 Views
Registered: ‎09-28-2016

thank you for your clarification!!!

 

 

Tom

0 Kudos
martin2015
Newbie
Newbie
20,978 Views
Registered: ‎07-15-2016

On my side no of the solution above are working :-(

I tried:

device tree...

1. bootargs with mem=768M memmap=256M$0x30000000 vmalloc=256M

2. memory {
        device_type = "memory";
        reg = <0x0 0x30000000>;
    };

3. reserved_memory {
            device_type = "reserved_memory";
            reg = <0x30000000 0x10000000>;
            compatible = "generic-uio";
        };

 

And on the software side...

#define BASE_ADDR 0x30000000 //(768*1024*1024)
#define MAPSIZE 256 *1024*1024        // in Bytes
#define MAPMASK (MAPSIZE-1)

    nOffset = BASE_ADDR ;
    udwLimit = 256* 1024 *1024 / 32 ;
    udwDdrWrData = 0 ;

    nFd = open("/dev/mem", O_RDWR|O_SYNC);
    if(nFd == -1)
        printf("mem open failed.\n\r");

    pMemBase = mmap(NULL, MAPSIZE, (PROT_READ | PROT_WRITE) , MAP_SHARED, nFd, BASE_ADDR);

 

And on FPGA side... (Vivado HLS)

#pragma HLS INTERFACE m_axi depth=268435456 port=u32Input offset=slave bundle=myHandler_BUS_DATAIN

...

memcpy((int *) (u32Input+ (i*(DATA_HANDLER_INPUT_BUFFER_SIZE/4))), u32InputBuffer , MY_HANDLER_INPUT_BUFFER_SIZE * sizeof(unsigned int));

 

Do somebody no a working solution? Hope so, because I don't know hat I can try next.

 

Thanks in advance,

 

0 Kudos
davirol
Observer
Observer
19,600 Views
Registered: ‎08-16-2017

Hi @abbascit@marcoventurini,

 

I have a similar problem and I got stuck here from last three weeks. We have Baremetal having SG-DMA at Core1 and linux running at Core 0. Without linux Baremetal is writing and reading to DDR. But with Linux running, Baremetal is not working because of DMA which is not writting to DDR. How did you resolve it? We have tried several approaches but any of them work :(

 

Any help will be very much appreciated, regards,

David

 

 

 

0 Kudos
abbascit
Contributor
Contributor
19,583 Views
Registered: ‎12-30-2015
Hi David,

Sorry for late reply. Actually I am really out of date with this project and did nothing from one year.

Are you using DMA driver with Linux? Or trying without a driver to perform DMA operations?

Regards

MAbbas
0 Kudos
davirol
Observer
Observer
19,573 Views
Registered: ‎08-16-2017

Hi @abbascit,

 

Thank your very much for your reply!

 

About your question we are not using a DMA driver with Linux. We have a baremetal application which performs DMA operations and works fine standalone. However, when we add OpenAMP and we boot Linux in CORE0, the same app is running in CORE1 but only DMA is not working anymore. Is not possible to do this?

 

Thanks in advance,

David

0 Kudos
abbascit
Contributor
Contributor
19,551 Views
Registered: ‎12-30-2015
Hi David,

If you not using DMA driver then it will not work with Linux. Driver interacts with Linux kernel and access the memory, control registers to perform DMA operation.

Regards
Abbas
0 Kudos
davirol
Observer
Observer
19,537 Views
Registered: ‎08-16-2017

Hi Abbas @abbascit

 

Thanks for your reply. Maybe we have not explained well our situation. We are doing the following steps:

 

1) Boot Linux Core0

2) Launch Baremetal application from Linux in Core1

    2.1) Baremetal read data from several sensors in PL

    2.2) Baremetal stores data in DDR using SG-DMA

    2.3) Baremetal sends rpmsg message to Linux when data has been stored in DDR

 

This Baremetal application runs succesfully when executed standalone without Linux, however when we follow previous steps DDR is not correctly updated. For this reason we thought the problem can be related to SG-DMA. We do not understand why we need to use a DMA Driver with Linux when the problem is in the Baremetal.

Thank you in advance!!!!

Regards,

David

0 Kudos