[U-Boot] weak functions not being over-ridden (location dependent)

Graeme Russ graeme.russ at gmail.com
Wed Nov 26 13:02:29 CET 2008


Hi All,

I have a very strange problem - I am trying to define a weak function, but
whether or not the function is overridden depends on where I put the
overriding function. Case in point:

common.h defines reset_cpu() thusly:

void	reset_cpu     (ulong addr);

in cpu/i386/reset.c I have:

void __reset_cpu(ulong addr)
{
	printf("Resetting using i386 Triple Fault\n");
	set_vector(13, generate_gpf);  /* general protection fault handler */
	set_vector(8, generate_gpf);   /* double fault handler */
	generate_gpf();                /* start the show */
}
void reset_cpu(ulong addr) __attribute__((weak, alias("__reset_cpu")));

Now, if I implement reset_cpu () in cpu/i386/sc520/reset.c

void reset_cpu(ulong addr)
{
	printf("Resetting using SC520 MMCR\n");
	/* Write a '1' to the SYS_RST of the RESCFG MMCR */
	write_mmcr_word(SC520_RESCFG, 0x0001);

	/* NOTREACHED */
}

and issue a reset from the prompt, it uses the Triple Fault

If I move reset_cpu () in board/eNET/eNET.c, it uses the MMCR

Now, if I remove __reset_cpu () (and the weak definition) and leave the
reset_cpu in cpu/i386/sc520/reset.c, it uses the MMCR to reset the CPU. So
/cpu/i386/sc520/reset.c is being compiled and the library is being linked in.

If I go back to __reset_cpu(), weak function and reset_cpu () in
cpu/i386/sc520, u-boot.map reveals:

 .text          0x000000003804ecd4       0x6d cpu/i386/libi386.a(reset.o)
                0x000000003804ecdb                __reset_cpu
                0x000000003804ecd4                generate_gpf
                0x000000003804ed10                do_reset
                0x000000003804ecdb                reset_cpu

and no other references to reset_cpu

Move reset_cpu () to board/eNET/eNET.c and I get

 .text          0x00000000380499a0      0x312 board/eNET/libeNET.a(eNET.o)
                0x00000000380499f8                dram_init
                0x00000000380499e4                last_stage_init
                0x0000000038049a07                init_sc520_enet
                0x0000000038049a46                reset_cpu
                0x0000000038049a69                board_init
                0x00000000380499bb                board_flash_get_legacy
.
.
.
 .text          0x000000003804ecf8       0x6d cpu/i386/libi386.a(reset.o)
                0x000000003804ecff                __reset_cpu
                0x000000003804ecf8                generate_gpf
                0x000000003804ed34                do_reset


If I do not define the weak function and implement reset_cpu () in BOTH
cpu/i386/reset.c and cpu/i386/sc520/reset.c I get no complaints from the
linker, and the reset is performed via triple-fault. u-boot.map reveals:

 .text          0x000000003804ecd4       0x6d cpu/i386/libi386.a(reset.o)
                0x000000003804ecd4                generate_gpf
                0x000000003804ed10                do_reset
                0x000000003804ecdb                reset_cpu

Why is the linker silently discarding an obvious symbol conflict?

Any ideas?

Thanks,

Graeme







More information about the U-Boot mailing list