我正在尝试使用i.MX6(CPU内核为ARM Cortex A9)在自定义主板上通过U-boot启动Linux
我们似乎成功移植了Das U-Boot(2009.08)。但是,在最后一个U-Boot消息启动Linux失败:“启动内核......”
以下是我的相关环境:
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 ...
当我objdump内核时,在地址80008000处,我看到了arch / arm / kernel / head.S的入口点,而不是arch / arm / boot / compressed / head.S
我看到的是,内核甚至没有解压缩。我尝试添加一些寄存器操作代码来发送压缩/ head.S中的GPIO信号,但没有响应。
我的问题是,如何确保U-Boot正在调用正确的入口点?
完全相同的内核二进制文件使用相同的U-Boot命令在飞思卡尔的参考板上成功引导。
编辑:我在U-Boot中添加了一些痕迹。在调用内核之前,指针theKernel是10008000而不是10800000.这是否意味着U-boot在错误的位置跳转?答案 0 :(得分:7)
我们似乎成功移植了Das U-Boot。
有证据表明这是一个错误的假设。
在调用内核之前,指针theKernel是10008000而不是10800000.
您使用的是哪个版本的U-Boot?
在2012.10和2013.04版本的U-Boot中,变量theKernel
仅由AVR32和MIPS等拱门的代码声明和使用。
没有应该使用theKernel
的ARM代码。
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将machine type number
(又名arch_id
)正确传递给内核。
您需要验证在U-Boot中是否正确定义了此machine type number
。
U-Boot的配置文件是什么样的?
我尝试添加一些寄存器操作代码来发送压缩/ head.S中的GPIO信号,但没有响应。
您是否理智检查此代码以确保其按预期工作? 您是否从U-Boot命令行尝试了GPIO操作?
我的问题是,如何确保U-Boot正在调用正确的入口点?
对于ARM arch,它是跳转到 bootm 命令中指定的地址。
由于uImage加载地址和 bootm 指定相同的0x10800000地址,因此应该是好的(假设U-Boot已正确配置并为ARM构建)。
在调用内核之前,指针theKernel是10008000而不是10800000.这是否意味着U-boot在错误的位置跳转?
是强>
如果检查源代码(对于AVR32或MIPS),您会发现从映像头分配了theKernel
,特别是入口点值。然后U-Boot会跳转到这个位置
但真正的问题是你的ARM Cortex A9不应该使用这个代码或这个变量。
似乎没有为正确的拱门配置U-Boot和/或可能无法正确定义机器类型。
更正:
正如OP指出的那样,旧版本的U-Boot确实使用了变量theKernel
,即使对于ARM拱也是如此。
U-Boot输出行:
Loading Kernel Image ... OK
表示U-Boot已经(成功)将内核映像(没有映像信息头)从bootm
地址0x10800000(加上报头长度的偏移量0x40)复制到加载地址0x10008000。此内存移动操作由 common / cmd_bootm.c 中的过程bootm_load_os()
执行。
因此,您报告的0x10008000的值对theKernel
是正确的
没有迹象表明U-Boot跳到了错误的位置。
如前所述,您应该验证是否正确定义了机器类型。该值将在arch/arm/plat-mxc/include/mach/uncompress.h中的__arch_decomp_setup()
中使用,以便在内核引导之前的解压缩期间输出文本。
答案 1 :(得分:4)
您似乎没有启动vmlinux内核文件,因此您不必担心入口点。图像开头的解压缩代码将根据需要重新定位内核,并在完成后跳转到正确的入口点。你只需要跳过uBoot似乎正确执行的图像的开头。
我打开内核调试,尤其是earlyprintk和lowlevel调试选项,然后再次尝试启动。至少你可以看到它的内容。
编辑:正如所指出的,我的答案仅适用于uBoot首先正确地做到这一点。在这种情况下,有可能不是。也许你可以创建并尝试启动虚拟“内核”,它只是打开一些LED或输出一些寄存器值到串行(特别是r0,r1和r2)。然后你至少可以检查和/或排除uBoot作为罪魁祸首。
答案 2 :(得分:0)
可能是U-Boot加载的文件实际上是vmlinux
文件的二进制图像而不是自解压zImage
/ bzImage
?这只是猜测,我不是这方面的专家。
我最近在Unix Stack Exchange上提出的这个问题对你很感兴趣:https://unix.stackexchange.com/questions/197225/is-vmlinuz-and-bzimage-really-the-same