* Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@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.
- 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?
- 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?
- 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.
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.
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.
Suggestions for solving the problems mentioned above:
- Always wrap shared function definitions in SHARED macros.
yes. this is how it should be done.
- Make sure the assignment "ret (*func)(args) attr= stage0_##func"
happens only once per final linked object.
agreed.
- 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.