04-15-2015 10:16 AM
I'm using a Zed-Board and I'm trying to boot Linux on it. I'm using the plain Linux kernel, which Xilinx offers on GitHub.
Let me describe my hardware design:
I'm having a memory device in the address range 0x4000_0000 to 0x6000_0000 which forwards the memory requests via the HP0 interface to the DDR controller. I have now 2 paths how I can write the DDR memory: Via 0x000_0000 to 0x2000_0000 and via 0x4000_0000 to 0x6000_0000. However, I'm trying to get Linux to use the later address range.
I'm trying now to compile Linux, such that it boots from address 0x42008000. To do so, I compile it the following way:
make ARCH=arm UIMAGE_LOADADDR=0x42008000 uImage
Unfortuantely, u-boot cannot boot. It stucks at:
Starting kernel ...
Here is the complete log:
Copying Linux from SD to RAM...
3459344 bytes read in 862 ms (3.8 MiB/s)
9173 bytes read in 15 ms (596.7 KiB/s)
## Booting kernel from Legacy Image at 45008000 ...
Image Name: Linux-3.18.0-xilinx-06524-gd51de
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 3459280 Bytes = 3.3 MiB
Load Address: 42008000
Entry Point: 42008000
Verifying Checksum ... OK
## Flattened Device Tree blob at 42a00000
Booting using the fdt blob at 0x42a00000
Loading Kernel Image ... OK
Loading Device Tree to 1ed1d000, end 1ed223d4 ... OK
Starting kernel ...
When I move the kernel to address 0x8000 it boots successfully.
Can someone guide me, how to boot from this different address range?
04-15-2015 10:21 AM
It fails booting Linux, as soon as I leave the region 0-512MB.
Downloading and verifying the image works! Also within the address range 0x4000_0000 to 0x6000_0000.
04-15-2015 11:27 AM
I would turn early printk on to get some console output (maybe).
Maybe this is the issue, the fact that the device tree gets loaded into 1ed1d000, end 1ed223d4 which is likely not considered valid memory by Linux if you changed the device tree memory range?
Because u-boot has valid low memory it assumes that Linux does too in general. You can control where the device tree gets loaded by u-boot by setting the fdt_high environment variable. Setting it to 0xFFFFFFFF causes it to not relocate it I believe so I might try that 1st.
04-16-2015 01:39 AM
I enabled early printk from the Linux confiuration for Xilinx UART 1 (default UART). I also changed U-Boot to load the the devicetree blob from 0x44000000. However, I get the same behaviour :(
I started Vivado to trace on the memory bus. One interesting thing here:
It writes breaks after wrint to address 0x4000_4000 and 0x4000_40004.
It then starts continuously reading from address 0x4000_001C.
The strange here, how does it come to that memory?
04-16-2015 01:48 AM
One very strange thing I just saw:
There is somehow a memory offset of 0x40.
I saw reading the device from address 0x4200340, but the actual returned content is from address 0x380 from the uImage.
04-16-2015 06:02 AM
It sounds to me like the h/w may be in question. I would test with a standalone application before Linux if you have not done that as it's much easier to debug.
04-17-2015 03:28 AM
The hardware works. Standalone programs are no problem.
After some debugging, I made some progress. The kernel is decompressing correctly and is starting.
I get first outputs but still end up in a kernel panic:
Uncompressing Linux... done, booting the kernel.
Setup arch: console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 3.18.0-xilinx-06524-gd51de5a-dirty (rschilling@hp18-lin) (gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-23) ) #56 SMP PREEMPT Fri Apr 17 10:51:21 CEST 2015
[ 0.000000] CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[ 0.000000] Machine model: Zynq Zed Development Board
[ 0.000000] Base 0x0 MAX_PHYS 0x4069a400ffffffff
[ 0.000000] phys_offset 0x42000000
[ 0.000000] Ignoring memory block 0x0 - 0x20000000
[ 0.000000] bootconsole [earlycon0] enabled
memblock_reserve: [0x000000420082c0-0x0000004273ae37] flags 0x0 arm_memblock_init+0x24/0x180
memblock_reserve: [0x00000042004000-0x00000042007fff] flags 0x0 arm_memblock_init+0x110/0x180
memblock_reserve: [0x00000041000000-0x00000041002fff] flags 0x0 early_init_fdt_scan_reserved_mem+0x34/0x8c
memblock_reserve: [0x00000041000000-0x00000041002fff] flags 0x0 early_init_fdt_scan_reserved_mem+0x68/0x8c
[ 0.000000] Kernel panic - not syncing: ERROR: Failed to allocate 0x2000 bytes below 0x0.
[ 0.000000] ---[ end Kernel panic - not syncing: ERROR: Failed to allocate 0x2000 bytes below 0x0.
04-17-2015 05:58 AM
You didn't attach your device tree. What is the memory node set to?
04-17-2015 06:13 AM
I further mad some investigations. It seems the DTB isn't read correctly.
When it tries to read the memory configuration it reads a base adress 0f 0x0 and a size of 0x20000000, which is the default memory layout. If I hardcode these values ine the kernel to base=0x42000000 and size = 0x1E000000 the kernel almost boots successfully (fails mounting the rootfs).
So the question is why it fails rading the DTB.
Here is my device tree:
model = "Zynq Zed Development Board";
compatible = "xlnx,zynq-zed", "xlnx,zynq-7000";
ethernet0 = &gem0;
serial0 = &uart1;
spi0 = &qspi;
device_type = "memory";
reg = <0x42000000 0x1e000000>;
bootargs = "console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait";
linux,stdout-path = "/amba/serial@e0001000";
This is located at 0x50000000 now. When doing a memory dump at this address within u-boot I see the correct data.
07-07-2016 02:16 AM
it worked for me (loading kernel at address 0x40000000 as kernel image was to big to be laoded at 0x10000000) with petalinux 2014.4 and 2015.2, but fails with petalinux 2016.1 and petalinux 2016.2
07-07-2016 09:53 AM