解压失败时如何找到 ARM Linux 入口点? [英] How do I find ARM Linux entry point when it fails to uncompress?

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

问题描述

我正在尝试在带有 i.MX6 的自定义板上通过 U-boot 启动 Linux(CPU 内核是 ARM Cortex A9)

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

我们似乎已经成功移植了 Das U-Boot(2009.08).但是在最后一条 U-Boot 消息中引导 Linux 失败:正在启动内核 ..."

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

这是我的相关环境:

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

开机输出是

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 ...  

当我在地址 80008000 处对内核进行 objdump 时,我看到入口点位于 arch/arm/kernel/head.S,而不是 arch/arm/boot/compressed/head.S

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

我看到的是,内核甚至没有解压缩.我尝试添加一些寄存器操作代码来向compressed/head.S 中的GPIO 发送信号,但没有任何响应.

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.

我的问题是,如何确保 U-Boot 调用了正确的入口点?

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

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

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

我在 U-Boot 中添加了一些痕迹.在调用内核之前,指针 theKernel 是 10008000 而不是 10800000.这是否意味着 U-boot 跳错了位置?

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?

推荐答案

我们似乎已经成功移植了 Das U-Boot.

We seem to have ported Das U-Boot successfully.

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

There's evidence that that is a faulty assumption.

在调用内核之前,指针 theKernel 是 10008000 而不是 10800000.

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

您使用的是哪个版本的 U-Boot?
在 2012.10 和 2013.04 版本的 U-Boot 中,变量 theKernel 仅由 AVR32 和 MIPS 等架构的代码声明和使用.
没有应该使用 theKernel 的 ARM 代码.

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$


请说明您如何能够跟踪不应在 ARM 处理器上定义或分配的变量.

U-Boot 打印Starting kernel ..."后的下一个输出应该是Uncompressing Linux...".
对于飞思卡尔架构,此文本输出取决于 U-Boot 将 机器类型号(又名 arch_id)正确传递给内核.
您需要验证此 机器类型编号 在 U-Boot 中是否正确定义.

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.

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

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

我尝试添加一些寄存器操作代码来向压缩/head.S 中的 GPIO 发送信号,但没有响应.

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

您是否仔细检查了此代码以确保其按预期工作?
您是否尝试过 U-Boot 命令行中的 GPIO 操作?

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?

我的问题是,如何确保 U-Boot 调用了正确的入口点?

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

对于 ARM 架构,它是跳转到 bootm 命令中指定的地址.
由于 uImage 加载地址和 bootm 指定了相同的 0x10800000 地址,这应该很好(假设 U-Boot 已正确配置并为 ARM 构建).

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).

在调用内核之前,指针 theKernel 是 10008000 而不是 10800000.这是否意味着 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?

是的.
如果您检查源代码(对于 AVR32 或 MIPS),您会发现 theKernel 是从图像标题分配的,特别是入口点值.U-Boot 然后会跳转到这个位置.
但真正的问题是您的 ARM Cortex A9 不应该使用此代码或此变量.

似乎 U-Boot 没有为正确的拱门配置和/或机器类型可能没有正确定义.

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.

更正:

正如 OP 所指出的,旧版本的 U-Boot 确实使用了变量 theKernel ,即使对于 ARM 架构也是如此.

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

U-Boot输出的那一行:

The line of U-Boot output:

   Loading Kernel Image ... OK  

表示 U-Boot 已经(成功)将内核映像(没有映像信息头)从 bootm 地址 0x10800000(加上头长度的偏移量 0x40)复制到加载地址0x10008000.此内存移动操作由 common/cmd_bootm.c 中的过程 bootm_load_os() 执行.

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.

因此,您报告的 0x10008000 的值对于 theKernel 是正确的.
没有迹象表明 U-Boot 跳到了错误的位置.

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.

如前所述,您应该验证机器类型是否正确定义.该值将在 arch/arm/plat-mxc/include/mach/uncompress.h 以便在内核启动前的解压过程中输出文本.

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 入口点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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