Pergunta

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?

Foi útil?

Solução

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.

Outras dicas

You don't seem to be booting the vmlinux kernel file so you don't have to worry about entry points. The decompression code at the beginning of the image will relocate the kernel as required and jump to the correct entry point when its done. You just have to jump the beginning of the image which uBoot seems to be doing correctly.

I'd turn on kernel debugging, especially the earlyprintk and lowlevel debugging options and try booting again. At least you get to see where it stuffs up.

Edit: As pointed out, my answer only applies if uBoot is doing it's thing correctly in the first place. In this case, there is a possibility that it isn't. Maybe you could create and attempt to boot a dummy 'kernel' which simply switches on some LEDs or outputs some register values to serial (r0, r1 and r2 in particular). Then you can at least check and/or rule out uBoot as the culprit.

Could it be that the file that U-Boot is loading is actually the binary image of vmlinux file instead the self-extracting zImage/bzImage? It's just a guess, I'm not an expert on this.

This question I recently asked on Unix Stack Exchange could be of interest for you: https://unix.stackexchange.com/questions/197225/is-vmlinuz-and-bzimage-really-the-same

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top