cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
alain_k
Observer
Observer
8,837 Views
Registered: ‎06-27-2014

Zynq Increase Kernel memory

Jump to solution

Hello,

 

I have to write a driver that grabs data from a VDMA. To do that I try to allocate a buffer where the VDMA can write it's data into. I do that with dma_alloc_coherent, but that failes. I found out, that the problem might be that there is not enough memory available in the kernel space, which is why I tried to boot the kernel with the mem=128M parameter. But that leads to a kernel panic. I think the kernel tries to access something it shouldn't, but I don't know where it can access and where not. I looked at the Address Map in the SDK and saw that ps7_ddr_0 starts at address 0x00100000, so I tried it with mem=128M@0x00100000. That didn't work either. I already set the coherent_pool parameter to a bigger size, so that is not the problem. That gave me a different error. So how can I tell the kernel which physical addresses really are RAM and how can I find that addresses? Was I right with my ps7_ddr_0 guess? Or am I completely wrong with my approach?

 

I am using a MicroZed board which is equipped with a Zynq 7020 and 2GB DDR3 RAM. I use ISE 14.7 to generate the hardware and the bootimage. I use the latest 3.14 kernel from the xilinx github repository. That's the output if the kernel panics:

 

U-Boot 2014.01-dirty (Sep 26 2014 - 14:56:23)

I2C: ready
Memory: ECC disabled
DRAM: 1 GiB
MMC: zynq_sdhci: 0
Using default environment

In: serial
Out: serial
Err: serial
Net: Gem.e000b000
Hit any key to stop autoboot: 3  2  1  0
Device: zynq_sdhci
Manufacturer ID: 3
OEM: 5344
Name: SU02G
Tran Speed: 25000000
Rd Block Len: 512
SD version 1.10
High Capacity: No
Capacity: 1.9 GiB
Bus Width: 4-bit
reading uEnv.txt
98 bytes read in 9 ms (9.8 KiB/s)
Loaded environment from uEnv.txt
Importing environment from SD ...
Copying Linux from SD to RAM...
reading uImage
3421560 bytes read in 589 ms (5.5 MiB/s)
reading devicetree.dtb
9276 bytes read in 18 ms (502.9 KiB/s)
reading uramdisk.image.gz
5315172 bytes read in 898 ms (5.6 MiB/s)
## Booting kernel from Legacy Image at 03000000 ...
Image Name: Linux-3.14.0-xilinx-dirty
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 3421496 Bytes = 3.3 MiB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum ... OK
## Loading init Ramdisk from Legacy Image at 02000000 ...
Image Name:
Image Type: ARM Linux RAMDisk Image (gzip compressed)
Data Size: 5315108 Bytes = 5.1 MiB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
## Flattened Device Tree blob at 02a00000
Booting using the fdt blob at 0x2a00000
Loading Kernel Image ... OK
Loading Ramdisk to 1faee000, end 1ffffa24 ... OK
Loading Device Tree to 1fae8000, end 1faed43b ... OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
Booting Linux on physical CPU 0x0
Linux version 3.14.0-xilinx-dirty (alain@ALAIN) (gcc version 4.9.1 (GCC) ) #10 SMP PREEMPT Fri Sep 26 15:12:03 CEST 2014
CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
Machine model: Xilinx Zynq
bootconsole [earlycon0] enabled
INITRD: 0x1faee000+0x00511a24 is not a memory region - disabling initrd
cma: CMA: failed to reserve 128 MiB
Memory policy: Data cache writealloc
Unable to handle kernel paging request at virtual address dfae8000
pgd = c0004000
[dfae8000] *pgd=00000000
Internal error: Oops - BUG: 5 [#1] PREEMPT SMP ARM
Modules linked in:
CPU: 0 PID: 0 Comm: swapper Not tainted 3.14.0-xilinx-dirty #10
task: c06570e8 ti: c064c000 task.ti: c064c000
PC is at __unflatten_device_tree+0x18/0x12c
LR is at unflatten_device_tree+0x1c/0x34
pc : [<c0398ac4>] lr : [<c0636704>] psr: a00001d3
sp : c064df48 ip : 006b8a2b fp : 80000200
r10: c0658090 r9 : c06a73e4 r8 : c06206a4
r7 : c0656e00 r6 : c06889c0 r5 : c063f324 r4 : dfae8000
r3 : edfe0dd0 r2 : c06206a4 r1 : c06b0ff4 r0 : dfae8000
Flags: NzCv IRQs off FIQs off Mode SVC_32 ISA ARM Segment kernel
Control: 18c5387d Table: 0000404a DAC: 00000015
Process swapper (pid: 0, stack limit = 0xc064c240)
Stack: (0xc064df48 to 0xc064e000)
df40: dfae8000 c06b0ff4 c06206a4 c06b0ff4 c06206a4 c063f324
df60: c06889c0 c0656e00 c065ff58 c0636704 c06543c8 c061fa84 ffffffff 18c5387d
df80: c064c000 ffffffff 413fc090 00000000 00000000 c0461afc c056fb3e c0688880
dfa0: 00000001 c06543c0 c064c000 ffffffff 413fc090 00000000 00000000 c061c820
dfc0: 00000000 00000000 00000000 00000000 00000000 c0642810 18c5387d c065440c
dfe0: c064280c c06581a0 0000406a 413fc090 00000000 00008074 00000000 00000000
[<c0398ac4>] (__unflatten_device_tree) from [<c0636704>] (unflatten_device_tree+0x1c/0x34)
[<c0636704>] (unflatten_device_tree) from [<c061fa84>] (setup_arch+0x5bc/0x834)
[<c061fa84>] (setup_arch) from [<c061c820>] (start_kernel+0x80/0x330)
[<c061c820>] (start_kernel) from [<00008074>] (0x8074)
Code: e58d100c 0a00003e e1a08002 e59f30f8 (e5942000)
---[ end trace 3406ff24bd97382e ]---
Kernel panic - not syncing: Attempted to kill the idle task!

Thanks,

Alain

0 Kudos
1 Solution

Accepted Solutions
alain_k
Observer
Observer
13,694 Views
Registered: ‎06-27-2014

Ok, I see. About those 128M, I didn't set that. That seems to be the standard value. I only set coherent_pool and as far as I understand it now this is for atomic allocation. I didn't find where I can increase the whole CMA memory. Anyway, I have omitted the mem= option again, and somehow it works now. I have no idea why it works now and why it didn't before, but thanks for the clarification anyway.

View solution in original post

0 Kudos
4 Replies
vgokhale
Explorer
Explorer
8,824 Views
Registered: ‎10-25-2011

The mem boot time parameter is meant to tell Linux how much total memory is available to it. If you also set CMA to be 128M, that means you are telling Linux that 128MB is the total installed memory of which you want ALL 128MB to be allocated as contiguous memory, something it will not want to do - that is why CMA fails - 

 

cma: CMA: failed to reserve 128 MiB

 

128MB is not enough to run the whole kernel. My Linux installation on the ZC706 board uses up approximately 150MB. That is most likely why it fails.

 

Secondly, the VDMA should not need 128MB. 

 

>>I do that with dma_alloc_coherent, but that failes

 

What error message does it give?

0 Kudos
milosoftware
Scholar
Scholar
8,783 Views
Registered: ‎10-26-2012

If the DDR memory address in your PL is hard-coded, you'll have to punch a hole into RAM at that location.

 

To use dynamic allocation, your driver will need to tell the DDR address to the logic.

 

So either use "ram=" to punch holes, or set the RAM to all available and use dma_alloc... to fetch memory from the pool.

 

And 128MB is rediculous - a Full-HD screen would need 8MB at most.

0 Kudos
alain_k
Observer
Observer
13,695 Views
Registered: ‎06-27-2014

Ok, I see. About those 128M, I didn't set that. That seems to be the standard value. I only set coherent_pool and as far as I understand it now this is for atomic allocation. I didn't find where I can increase the whole CMA memory. Anyway, I have omitted the mem= option again, and somehow it works now. I have no idea why it works now and why it didn't before, but thanks for the clarification anyway.

View solution in original post

0 Kudos
vgokhale
Explorer
Explorer
8,767 Views
Registered: ‎10-25-2011

>>  I have no idea why it works now and why it didn't before, but thanks for the clarification anyway.

 

Usually there's some parameter that changes but you don't do it directly so you don't notice. Either ways, if you got it working I'd suggest making an image of your system in case you need to restore later. That has saved us countless days.

 

To increase/decrease CMA, you can either refer to the defconfig before building the kernel or menuconfig (also before building the kernel). Additionally, you can set a parameter in the devicetree which will override the kernel settings.

0 Kudos