linux系统启动卡在Loading Ramdisk to 1fa55000, end 1ffffa6e ...

原文地址:http://blog.chinaunix.net/uid-20721651-id-4396359.html

最近,为了实现PS与PL之间的axi高速通信,研究了下ug873中说明的方法。但是,改文档对linux kernel方面的处理讲的不多,如果直接采用mmap映射kernel中的ddr空间,很可能该段地址会被kernel重新分配覆盖掉,or 该段内存已经被使用了,改写时会造成kernel panic。实验结果也表明,直接使用果然kernel panic了。
   
    解决该问题之前,必须先明白引起问题的原因。如下是kernel panic log:

ncompressing Linux... done, booting the kernel.
Booting Linux on physical CPU 0x0
Linux version 3.12.0-xilinx (root@debian) (gcc version 4.6.3 (Wind River Linux Sourcery CodeBench 4.6a-105) ) #4 SMP PREEMPT Sat Jun 7 22:36:15 CST 2014
CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
Machine: Xilinx Zynq Platform, model: Xilinx Zynq
bootconsole [earlycon0] enabled
INITRD: 0x1f61e000+0x005104dd is not a memory region - disabling initrd
Memory policy: Data cache writealloc
Unable to handle kernel paging request at virtual address df619000
pgd = c0004000
[df619000] *pgd=00000000
Internal error: Oops: 5 [#1] PREEMPT SMP ARM
Modules linked in:
CPU: 0 PID: 0 Comm: swapper Not tainted 3.12.0-xilinx #4
task: c053b020 ti: c0530000 task.ti: c0530000
PC is at __unflatten_device_tree+0xd0/0x270
LR is at 0x0
pc : []    lr : [<00000000>]    psr: 600001d3
sp : c0531f60  ip : d00dfeed  fp : 00000000
r10: 00000000  r9 : 413fc090  r8 : 413fc090
r7 : c053bef0  r6 : c05086fc  r5 : c056a790  r4 : df619000
r3 : 00000000  r2 : 00000000  r1 : 00000000  r0 : c056a790
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 = 0xc0530240)
Stack: (0xc0531f60 to 0xc0532000)
1f60: df619000 c05919e0 c05086fc c05919e0 c052514c c0589a18 c0799c40 c051cf00
1f80: 00000000 c0507a64 00000000 18c5387d 413fc090 00000000 00000000 c0397c60
1fa0: c046a00a c0531fbc 00000000 c0531fbc c0530000 00000001 ffffffff c0531fc8
1fc0: 0000406a c05047f4 00000000 00000000 00000000 00000000 00000000 c0526188
1fe0: 18c5387d c05383cc c0526184 c053c000 0000406a 00008074 00000000 00000000
[] (__unflatten_device_tree+0xd0/0x270) from [] (unflatten_device_tree+0x18/0x30)
[] (unflatten_device_tree+0x18/0x30) from [] (setup_arch+0x5bc/0x898)
[] (setup_arch+0x5bc/0x898) from [] (start_kernel+0x78/0x304)
[] (start_kernel+0x78/0x304) from [<00008074>] (0x8074)
Code: e6bf2f32 e59f117c ebfb7a69 e59fc178 (e594e000)
---[ end trace 1b75b31a2719ed1c ]---
Kernel panic - not syncing: Attempted to kill the idle task!

     上面log中,colorful的区域就代 表了两个 问题:
1. rootfs initrd的物理起始地址确实是从uboot传递过来的,通过的渠道就是dtb,它被定义在0x1f61e000+0x005104dd范围内。
2. dtb被导入的内存也被保存在0x1f000000开头的地址上。

这样,无论用bootargs中的mem参数,还是dts中的memory reg参数来限制kernel使用的内存为256M都会有问题。直接导致内核panic,换句话说就是上面两个关键的东西都在kernel访问的非法地址上。因为,一旦配置了mem的限制,那么kernel就会认为该段地址不在是ddr内存,所以,代码访问到该地址时都会有问题,除非是io访问。

    既然问题的原因知道了,那么解决问题的方向也基本明确了。
    很明显,最简单的方式就是将rootfs initrd和dtb的存储地址不放在高地址上了,这个是有bootloader来决定的,所以就从bootloader下手。考虑zynq的特殊性,即它的ddr,clk,cpu,fpga io空间等最基础的配置都是在fsbl中完成的,所以理论上修改uboot中的mem size不会对ddr的访问造成问题。

modify mem size to 256M, bug fixed。

遗留问题:
1. 为何其他arch的kernel可以直接用bootargs mem参数来限制,而zynq的不行?
A:这个可能跟具体的代码实现有关系,没有仔细研究去了,暂时忽略了,呵呵。

2. 理论上在uboot中将dtb load在0x08000000中,为何在kernel中访问时就变到了0x1f000000以上了?
A: uboot在boot kernel之后,将dtb的内容解析到了ddr的偏高位的地址。bootloader的加载log就可以证明。
      Loading Kernel Image ... OK
        Loading Ramdisk to 1f61e000, end 1fb2e602 ... OK
        Loading Device Tree to 1f619000, end 1f61dd22 ... OK

你可能感兴趣的:(linux驱动)