如何查找ARM Linux的入口点时,它未能uncom preSS? [英] How do I find ARM Linux entry point when it fails to uncompress?

查看:581
本文介绍了如何查找ARM Linux的入口点时,它未能uncom preSS?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过U-boot的一个定制电路板启动Linux与i.MX6(CPU内核的ARM Cortex A9)

我们似乎已经成功地移植达斯的U-Boot(2009.08)。但引导Linux失败,在最后的U-Boot的消息:启动内核......

下面是我的相关环境:

  bootargs = =控制台vmalloc的ttymxc1,115200 400M = =根的/ dev / mmcblk0p1 rootwait consoleblank = 0 earlyprintk视频= mxcfb0:开发= LCD,LCD-ORTUS,如果= RGB24视频= mxcfb1:开发= HDMI,1280x720M @ 60,如果= RGB24校准tsdev = TSC2004 fbmem = 10M,28M
bootcmd = ext2load MMC 0:1 1080的/ boot / uImage执行; bootm 1080

引导输出

 从MMC设备加载文件的/ boot / uImage执行0:1(xxa1)
4043552字节读
##从引导传统形象的内核在1080 ...
   图片名称:Linux-3.0.35
   图像类型:ARM Linux内核映像(uncom pressed)
   数据大小:4043488字节= 3.9 MB
   加载地址:10008000
   入口点:10008000
   验证校验和... OK
   加载内核映像... OK
好启动内核...

当我objdump的内核,在地址80008000,我看到在入口点弓/ ARM /内核/ head.S中,而不是在arch / ARM /开机/ COM pressed / head.S中

我看到的是,内核甚至不DECOM preSS。我尝试添加一些寄存器操作code信号在COM pressed / head.S中的GPIO没有响应。

我的问题是,我如何才能确保的U-Boot调用正确的切入点?

完全相同的内核二进制文件飞思卡尔的参考板成功启动,使用相同的U-Boot命令。

编辑:我加了一些痕迹的U-Boot。只调用内核前,指针theKernel是10008000,而不是10800000.这是否意味着的U-boot是在错误的位置跳?


解决方案

  

我们似乎已经成功地移植达斯的U-Boot。


有证据表明,这是一个错误的假设。


  

只需调用内核前,指针theKernel是10008000,而不是10800000.


您使用的是哪个的U-Boot版本?结果
在这两种2012.10和2013.04版本的U-Boot,变量 theKernel 的只有声明,并像AVR32和MIPS拱门使用code。结果
没有ARM code,它应该使用 theKernel

 的u-boot-2012.10 $找到。 -print | xargs的grep的theKernel
./arch/avr32/lib/bootm.c:无效(* theKernel)(INT魔法,无效* tagtable);
./arch/avr32/lib/bootm.c:theKernel =(void *的)图像 - > EP;
./arch/avr32/lib/bootm.c:theKernel,params_start);
./arch/avr32/lib/bootm.c:theKernel(ATAG_MAGIC,params_start);
./arch/microblaze/lib/bootm.c:无效(* theKernel)(字符*,ULONG,ULONG);
./arch/microblaze/lib/bootm.c:theKernel =(无效(*)(字符*,ULONG,ULONG))图像 - > EP;
./arch/microblaze/lib/bootm.c:(ULONG)theKernel,rd_data_start,(ULONG)of_flat_tree);
./arch/microblaze/lib/bootm.c:theKernel(命令行,rd_data_start,(ULONG)of_flat_tree);
./arch/mips/lib/bootm.c:无效(* theKernel)(INT,CHAR **,**炭,为int *);
./arch/mips/lib/bootm.c:theKernel =(无效(*)(INT,CHAR **,**字符,诠释*))图像 - > EP;
./arch/mips/lib/bootm.c:(ULONG)theKernel);
./arch/mips/lib/bootm.c:theKernel(linux_argc,linux_argv,linux_env,0);
./arch/mips/lib/bootm_qemu_mips.c:无效(* theKernel)(INT,CHAR **,**炭,为int *);
./arch/mips/lib/bootm_qemu_mips.c:theKernel =(无效(*)(INT,CHAR **,**字符,诠释*))图像 - > EP;
./arch/mips/lib/bootm_qemu_mips.c:(ULONG)theKernel);
./arch/mips/lib/bootm_qemu_mips.c:theKernel(0,NULL,NULL,0);
./arch/nds32/lib/bootm.c:无效(* theKernel)(INT零,诠释拱,UINT PARAMS);
./arch/nds32/lib/bootm.c:theKernel =(无效(*)(INT,INT,UINT))图像 - > EP;
./arch/nds32/lib/bootm.c:(ULONG)theKernel);
./arch/nds32/lib/bootm.c:theKernel(0,machid,BD-> bi_boot_params);
的u-boot-2012.10 $

结果
请解释一下你如何能够追踪不应界定或分配在ARM处理器上的变量。

之后的U-Boot打印下输出启动内核......应为Uncom pressing Linux的......结果
对于飞思卡尔弓这个文本输出取决于机型数量的正确传递(又名 arch_id )接U -boot内核。结果
您需要验证此机器类型号正确的U-Boot的定义。

什么是对U-Boot的配置文件是什么样子?


  

我尝试添加一些寄存器操作code,没有响应信号的GPIO在COM pressed / head.S中。


你合法性检查该code,以确保它像您期望的作品?结果
你是从U-Boot命令行试用GPIO操作?


  

我的问题是,我如何才能确保U-Boot的调用正确的切入点?


对于ARM拱,这是跳转到在 bootm 命令指定的地址。结果
由于负载的uImage地址和 bootm 指定相同的0x10800000地址,这应该是很好的(假设U-Boot的正确配置,并内置了ARM)。


  

只需调用内核前,指针theKernel是10008000,而不是10800000.这是否意味着的U-boot是在错误的位置跳?


结果
如果你检查源$ C ​​$ C(为AVR32或MIPS),你会发现, theKernel 从图像头分配,具体的入口点值。随后的U-Boot将跳转到该位置。结果
但真正的问题是,你的ARM Cortex A9不应该使用这种code或将此变量。
结果
看来,如果没有配置正确的弓和/或机器类型的U-Boot可能无法正确​​定义。

更正

由于OP指出,旧版本的U-Boot没有使用变量 theKernel 即使是ARM拱。

的U-Boot输出的行:

 加载内核映像... OK

表示的U-Boot有(成功)从的 bootm 地址复制的内核映像(无图像信息标题)0x10800000(加偏移0X40的头部长度)到0x10008000加载地址。此内存移动操作由程序 bootm_load_os()普通/ cmd_bootm.c 执行。

所以,你报0x10008000的值是 theKernel 正确的。结果
没有任何迹象表明,U-Boot的是跳跃到错误的位置。

正如前面提到的,你应该确认的机器类型是否正确定义。该值将在使用__ arch_decomp_setup()在<一个href=\"http://lxr.free-electrons.com/source/arch/arm/plat-mxc/include/mach/uncom$p$pss.h?v=3.0;a=arm#L24\"相对=nofollow>弓/ ARM /高原-MXC /有/马赫/ uncom press.h 这样的文字可能是内核启动之前DECOM pression期间输出。

I am trying to boot Linux via U-boot on a custom board with i.MX6 (CPU core is ARM Cortex A9)

We seem to have ported Das U-Boot(2009.08) successfully. But booting Linux fails at the last U-Boot message: "Starting kernel ..."

Here is my relevant environment:

bootargs=console=ttymxc1,115200 vmalloc=400M root=/dev/mmcblk0p1 rootwait consoleblank=0 earlyprintk video=mxcfb0:dev=lcd,LCD-ORTUS,if=RGB24 video=mxcfb1:dev=hdmi,1280x720M@60,if=RGB24 calibration tsdev=tsc2004 fbmem=10M,28M
bootcmd=ext2load mmc 0:1 10800000 /boot/uImage ; bootm 10800000

The boot output is

Loading file "/boot/uImage" from mmc device 0:1 (xxa1)  
4043552 bytes read  
## Booting kernel from Legacy Image at 10800000 ...  
   Image Name:   Linux-3.0.35  
   Image Type:   ARM Linux Kernel Image (uncompressed)  
   Data Size:    4043488 Bytes =  3.9 MB  
   Load Address: 10008000  
   Entry Point:  10008000  
   Verifying Checksum ... OK  
   Loading Kernel Image ... OK  
OK  

Starting kernel ...  

When I objdump the kernel, at address 80008000, I see the entry point at arch/arm/kernel/head.S, and not arch/arm/boot/compressed/head.S

What I see is, the kernel does not even decompress. I tried adding some register manipulation code to signal GPIOs in compressed/head.S with no response.

My question is, how can I make sure U-Boot is calling the correct entry point?

The exact same kernel binary successfully boots on Freescale's reference board, using the same U-Boot commands.

EDIT: I added some traces to U-Boot. Just before calling the kernel, the pointer theKernel is 10008000 and not 10800000. Does this mean U-boot is jumping at the wrong location?

解决方案

We seem to have ported Das U-Boot successfully.

There's evidence that that is a faulty assumption.

Just before calling the kernel, the pointer theKernel is 10008000 and not 10800000.

Which version of U-Boot are you using?
In both 2012.10 and 2013.04 versions of U-Boot, the variable theKernel is only declared and used by code for arches like AVR32 and MIPS.
There is no ARM code that should be using theKernel.

u-boot-2012.10$ find . -print | xargs grep theKernel
./arch/avr32/lib/bootm.c:   void    (*theKernel)(int magic, void *tagtable);
./arch/avr32/lib/bootm.c:   theKernel = (void *)images->ep;
./arch/avr32/lib/bootm.c:          theKernel, params_start);
./arch/avr32/lib/bootm.c:   theKernel(ATAG_MAGIC, params_start);
./arch/microblaze/lib/bootm.c:  void    (*theKernel) (char *, ulong, ulong);
./arch/microblaze/lib/bootm.c:  theKernel = (void (*)(char *, ulong,    ulong))images->ep;
./arch/microblaze/lib/bootm.c:      (ulong) theKernel, rd_data_start, (ulong) of_flat_tree);
./arch/microblaze/lib/bootm.c:  theKernel (commandline, rd_data_start, (ulong) of_flat_tree);
./arch/mips/lib/bootm.c:    void (*theKernel) (int, char **, char **, int *);
./arch/mips/lib/bootm.c:    theKernel = (void (*)(int, char **, char **, int *))images->ep;
./arch/mips/lib/bootm.c:        (ulong) theKernel);
./arch/mips/lib/bootm.c:    theKernel(linux_argc, linux_argv, linux_env, 0);
./arch/mips/lib/bootm_qemu_mips.c:  void (*theKernel) (int, char **, char **, int *);
./arch/mips/lib/bootm_qemu_mips.c:  theKernel = (void (*)(int, char **, char **, int *))images->ep;
./arch/mips/lib/bootm_qemu_mips.c:      (ulong) theKernel);
./arch/mips/lib/bootm_qemu_mips.c:  theKernel(0, NULL, NULL, 0);
./arch/nds32/lib/bootm.c:   void    (*theKernel)(int zero, int arch, uint params);
./arch/nds32/lib/bootm.c:   theKernel = (void (*)(int, int, uint))images->ep;
./arch/nds32/lib/bootm.c:          (ulong)theKernel);
./arch/nds32/lib/bootm.c:   theKernel(0, machid, bd->bi_boot_params);
u-boot-2012.10$


Please explain how you are able to trace a variable that should not be defined or assigned on an ARM processor.

The next output after U-Boot prints "Starting kernel ..." should be "Uncompressing Linux...".
For the Freescale arch this text output is dependent on the proper passing of the machine type number (aka arch_id) by U-Boot to the kernel.
You need to verify that this machine type number is properly defined in U-Boot.

What does your configuration file for U-Boot look like?

I tried adding some register manipulation code to signal GPIOs in compressed/head.S with no response.

Did you sanity check this code to ensure that it works as you expect?
Did you try out the GPIO operations from the U-Boot command line?

My question is, how can I make sure U-Boot is calling the correct entry point?

For the ARM arch, it is a jump to the address specified in the bootm command.
Since the uImage load address and the bootm specify the same 0x10800000 address, that should be good (assuming that U-Boot is correctly configured and built for ARM).

Just before calling the kernel, the pointer theKernel is 10008000 and not 10800000. Does this mean U-boot is jumping at the wrong location?

YES.
If you check the source code (for AVR32 or MIPS), you'd find that theKernel is assigned from the image header, specifically the entry point value. U-Boot would then jump to this location.
But the real problem is that your ARM Cortex A9 should not be using this code or this variable.

It seems as if that U-Boot is not configured for the proper arch and/or the machine type may not be correctly defined.

CORRECTIONS:

As the OP pointed out, older versions of U-Boot did use the variable theKernel even for the ARM arch.

The line of U-Boot output:

   Loading Kernel Image ... OK  

indicates that U-Boot has (successfully) copied the kernel image (without the image information header) from the bootm address of 0x10800000 (plus offset 0x40 for the header length) to the load address of 0x10008000. This memory move operation is performed by the procedure bootm_load_os() in common/cmd_bootm.c.

So the value of 0x10008000 that you reported is correct for theKernel.
There is no indication that U-Boot is jumping to the wrong location.

As already mentioned, you should verify that the machine type is correctly defined. The value would be used in __arch_decomp_setup() in arch/arm/plat-mxc/include/mach/uncompress.h so that text could be output during the decompression prior to the kernel booting.

这篇关于如何查找ARM Linux的入口点时,它未能uncom preSS?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆