[LinuxBIOS] printk()/post_code(): Compile failure for all hardware targets in v3

Carl-Daniel Hailfinger c-d.hailfinger.devel.2006 at gmx.net
Tue Nov 20 17:44:02 CET 2007

On 20.11.2007 14:14, Stefan Reinauer wrote:
> * Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net> [071120 11:46]:
>> The reason is similar for all of them:
>> include/console.h specifies
>>> void post_code(u8 value);
>> include/post_code.h specifies (because _SHARED is defined)
>>> void stage0_post_code(u8 value) ;
>>> void (*post_code)(u8 value) = stage0_post_code;
>> Of  course these definitions do conflict.
> This issue seems trivial. include/console.h must not define a prototype
> for post_code. I wonder how that double definition sneaked.

Because simply deleting it causes compilation problems somewhere else?

>> * The conflicting post_code() definitions above are not alone, the same
>> happens for printk.
> How so? I could not find a printk prototype in any other file. Where's
> the bad part?

Maybe I mixed that up with the multiple printk definitions below.

>> * If you remove post_code() from include/console.h everywhere
>> post_code() is shared, you encounter the next problem: If two files with
>> _SHARED are linked together, each of them will contain the assignment
>> (*post_code)=stage0_post_code, resulting in linker errors because a
>> symbol appears twice.
> This is interesting. I never had any of these problems and I have been
> testing that code quite a bit. What distribution and what toolchain are
> you using?

openSUSE 10.3 (i386)
gcc (GCC) 4.2.1 (SUSE Linux)
GNU ld (GNU Binutils) (SUSE Linux)

>> * Even if you manage to avoid all the problems above, a new problem
>> arises: We have to build a LAR archive in one continuous flow because we
>> can't extract the location of the stage0 symbols from an existing
>> bootblock in a LAR archive and thus can't link initram and stage2
>> against an existing bootblock. Because of that, we never can do partial
>> BIOS updates, which defeats the whole purpose of LAR.
> Wait: You can not change the toolchain nor the version of the bootblock
> in between. This is only a rather small limitation. But its not very
> elegant, I agree.

My point was: For a given bootblock, we can't build the rest of the ROM
based on the bootblock alone because it has been stripped of symbols.

> Which is why I suggested a function pointer array with defined function
> pointers at fixed, defined offsets. Yes. This means we have to define an
> interface, something the Linux guys really hate.

I see no way around a function pointer array. However, we could avoid
the fixed offsets if we use the same technology the Linux kernel uses
for its symbol tables.

> The Amiga did a very similar thing. All functions in a shared library
> would be available through a function pointer array. The callable
> functions would be defined through the library version. So a program
> could always react on finding a too old or not-existing library sanely
> instead of just spitting out a linker error like our unix/elf based systems
> do these days.

That's probably overkill.

>> Suggestions for solving the problems mentioned above:
>> * Always wrap shared function definitions in SHARED macros.
> yes. this is how it should be done.

Can you prepare a patch?

>> * Make sure the assignment "ret (*func)(args) attr= stage0_##func"
>> happens only once per final linked object.
> agreed.

That will get messy. Maybe move the assignment to a separate object
which is linked to the final object?

>> * Include a .map file of shared stage0 functions in the LAR.
> My first thought. but the map file is not sufficient for linking with
> those symbols. You need the object file for that. Which is bad.

Can we recreate an object file from the map file? Or can we avoid
stripping all symbols from stage0/1?


More information about the coreboot mailing list