This patch gets Geode LX into initram. It also cleans up some of the generic stage0 and stage1 code for getting through CAR and initram.
At this point I need some help. We get into initram but I think that there is a link problem where the first function call to post_code() is past the beginning of the ROM.
I see the following: lar finds normal/initram at 0xFFFC4B20 The call to 0xFFFC4B20 works and we are executing initram. The call to post_code() is to 0xFFF427d4 <--- BAD!
Also, There aren't any map files being generated. I think that they would be helpful in debugging stuff like this. Any volunteers better at makefiles than I am?
Marc
Acked-by: Ronald G. Minnich rminnich@gmail.com
I will try to look at your other problem tomorrow.
ron
ron minnich wrote:
Acked-by: Ronald G. Minnich rminnich@gmail.com
I will try to look at your other problem tomorrow.
ron
r459
Thanks, Marc
Marc Jones wrote:
This patch gets Geode LX into initram. It also cleans up some of the generic stage0 and stage1 code for getting through CAR and initram.
At this point I need some help. We get into initram but I think that there is a link problem where the first function call to post_code() is past the beginning of the ROM.
I see the following: lar finds normal/initram at 0xFFFC4B20 The call to 0xFFFC4B20 works and we are executing initram. The call to post_code() is to 0xFFF427d4 <--- BAD!
Also, There aren't any map files being generated. I think that they would be helpful in debugging stuff like this. Any volunteers better at makefiles than I am?
Looking at the map file initram knows where post_code() should be but is different from where the code calls. initram.map: 00080000 T main ... ffffdcb4 A post_code ...
I have dumped the code at ffffdcb4 and it is post_code().
I think that the linker knows where the stage0 code is supposed to be but it is linking to it with relative addresses instead of absolute??? It needs to link relative to initram functions and absolute to stage0. Any one else have any thoughts?
Marc
initram is XIP, right?
The LAR files we have run have all been linked at 0x0 base, i.e. where they would be copied to to run. I would bet the ld step is initram is the same.
So, here's a problem. XIP in LAR is problematic, because your location in lar affects the linking step.
now what?
ron
On Thursday 19 July 2007 22:38, ron minnich wrote:
initram is XIP, right?
The LAR files we have run have all been linked at 0x0 base, i.e. where they would be copied to to run. I would bet the ld step is initram is the same.
So, here's a problem. XIP in LAR is problematic, because your location in lar affects the linking step.
now what?
- Is there a way to force the compiler to generate something like the 0x9A opcode (absolute call) instead of the 0xE8 (+/- 2GiB relative call) one? Something like "FAR" in early DOS times? - ELF runtime linking? - initram as a static part of stage0? (=XIP)
Juergen
* ron minnich rminnich@gmail.com [070719 22:38]:
So, here's a problem. XIP in LAR is problematic, because your location in lar affects the linking step.
now what?
In favor of a good design we should have a defined API between stage0 and any other stages and set up a vector table with the addresses of those functions.
When calling from outside of stage0 we have to go through that table instead.
This is very little overhead and helps not blending stage0 and other stages. It also makes us think about what we want to export from stage0. I am sure we do not want/need to allow stageX to call anything in stage0.
Stefan
On Thursday 19 July 2007 21:59, Marc Jones wrote:
Marc Jones wrote:
This patch gets Geode LX into initram. It also cleans up some of the generic stage0 and stage1 code for getting through CAR and initram.
At this point I need some help. We get into initram but I think that there is a link problem where the first function call to post_code() is past the beginning of the ROM.
I see the following: lar finds normal/initram at 0xFFFC4B20 The call to 0xFFFC4B20 works and we are executing initram. The call to post_code() is to 0xFFF427d4 <--- BAD!
Also, There aren't any map files being generated. I think that they would be helpful in debugging stuff like this. Any volunteers better at makefiles than I am?
Looking at the map file initram knows where post_code() should be but is different from where the code calls. initram.map: 00080000 T main ... ffffdcb4 A post_code ...
I have dumped the code at ffffdcb4 and it is post_code().
I think that the linker knows where the stage0 code is supposed to be but it is linking to it with relative addresses instead of absolute???
Using relative addresses is all right, as long ffffdcb4 == runtime address == link address for stage 0 and 00080000 == runtime address == link address for initram.
It needs to link relative to initram functions and absolute to stage0.
The compiler generates the opcodes. The linker only fills in the addresses or offsets. If the Compiler generates a relative jump/call the linker cannot change it (as far as I know).
Any one else have any thoughts?
Initram should run at the address it was linked to.
Juergen
On 7/19/07, Juergen Beisert juergen127@kreuzholzen.de wrote:
Initram should run at the address it was linked to.
A very key point since LAR and linking are not connected, by design.
I think this is why I was so unsure about XIP, then I forgot it.
ron
On Thursday 19 July 2007 23:11, ron minnich wrote:
On 7/19/07, Juergen Beisert juergen127@kreuzholzen.de wrote:
Initram should run at the address it was linked to.
A very key point since LAR and linking are not connected, by design.
I think this is why I was so unsure about XIP, then I forgot it.
XIP is all right as long as you do not refer something outside. For anything outside you need some kind of fixed API or some other ugly tricks (and I'm sure you won't like them ;-).
Juergen
ron minnich wrote:
On 7/19/07, Juergen Beisert juergen127@kreuzholzen.de wrote:
Initram should run at the address it was linked to.
A very key point since LAR and linking are not connected, by design.
I think this is why I was so unsure about XIP, then I forgot it.
ron
I only think that this is a problem with initram because it links to stage0. Maybe we should reconsider that. Maybe it needs to stand alone. Marc
* Marc Jones Marc.Jones@AMD.com [070719 23:52]:
I only think that this is a problem with initram because it links to stage0. Maybe we should reconsider that. Maybe it needs to stand alone. Marc
There are a few functions that we might want to share:
- printk - the lar functions (?? not sure, maybe not even those.) - what else?
One thing we had in v2 was 6 incarnations of print(k), each in 10 incarnations, one for each log level. That made 60 functions just for pushing a few letters of _debug_ to the _developer_.
Maybe we have to duplicate printk in the binary, but we should try to keep it one incarnation in the code.
If it is only for printk, setting up a jump table is maybe not worth it.
Though stage2 will have one, too.
Modular design and it's advantages and disadvantages. I think we should try to go the "defined interface to stage0" way, as Juergen also suggested (I dont think this is a hack)
Stefan Reinauer wrote:
- Marc Jones Marc.Jones@AMD.com [070719 23:52]:
I only think that this is a problem with initram because it links to stage0. Maybe we should reconsider that. Maybe it needs to stand alone. Marc
There are a few functions that we might want to share:
- printk
- the lar functions (?? not sure, maybe not even those.)
- what else?
One thing we had in v2 was 6 incarnations of print(k), each in 10 incarnations, one for each log level. That made 60 functions just for pushing a few letters of _debug_ to the _developer_.
Maybe we have to duplicate printk in the binary, but we should try to keep it one incarnation in the code.
If it is only for printk, setting up a jump table is maybe not worth it.
Though stage2 will have one, too.
Modular design and it's advantages and disadvantages. I think we should try to go the "defined interface to stage0" way, as Juergen also suggested (I dont think this is a hack)
If it is only for printk then I don't think it is worth it. I don't think that initram would need lar functions but stage2 and a payload might. Marc
how about for now, let's just have initram with its own copy of things, and then let the others link against stage 0 as usual.
I've done the 'vector table' approach a fair number of times. It eventually tends to run into trouble as more and more junk gets packed into it.
But, we can argue that out, and, for now, let's just have initram stand alone. We know we can get that to work.
ron
* ron minnich rminnich@gmail.com [070720 00:47]:
I've done the 'vector table' approach a fair number of times. It eventually tends to run into trouble as more and more junk gets packed into it.
This is not a general weakness of the approach. Junk sneaking in is even easier when you link and it will just find all functions. Having to manually add functions to a table at least is a barrier to take and for sure a hook for discussions.
But, we can argue that out, and, for now, let's just have initram stand alone. We know we can get that to work.
I completely agree. We will have to rethink this once we have usb console as that might be worth sharing.
The Qemu target really only uses printk in initram from stage0. Did not check stage2 yet
* Marc Jones Marc.Jones@AMD.com [070720 00:34]:
Modular design and it's advantages and disadvantages. I think we should try to go the "defined interface to stage0" way, as Juergen also suggested (I dont think this is a hack)
If it is only for printk then I don't think it is worth it. I don't think that initram would need lar functions but stage2 and a payload might. Marc
we wont really have the problem for stage2 i think, because we have ram there and know the position stage2 lives at. Though it might be interesting to know and discuss. Qemu was not a good example, since printk is the only thing initram does there ;)
These are the stage0 symbols that stage2 uses on the qemu target:
undefined reference to `die' undefined reference to `gdt_limit' undefined reference to `gdtptr' undefined reference to `get_option_table' undefined reference to `post_code' undefined reference to `printk' undefined reference to `rtc_init' undefined reference to `sprintf'
i think the gdt stuff is for vga bios emulation.
rtc_init should probably not be called in stage2 because it was called in stage0/1 already
we want stage2 printk and other code to use the stage0 support code because stage 0 has done some setup -- there is some state there -- that we'd like stage 2 to inherit. I think.
ron
* ron minnich rminnich@gmail.com [070720 06:45]:
we want stage2 printk and other code to use the stage0 support code because stage 0 has done some setup -- there is some state there -- that we'd like stage 2 to inherit. I think.
Not sure what state you mean.
If it is only about state, we could pass that through memory explicitly after initram. (LBtable)
On 7/19/07, Stefan Reinauer stepan@coresystems.de wrote:
- ron minnich rminnich@gmail.com [070720 06:45]:
we want stage2 printk and other code to use the stage0 support code because stage 0 has done some setup -- there is some state there -- that we'd like stage 2 to inherit. I think.
Not sure what state you mean.
If it is only about state, we could pass that through memory explicitly after initram. (LBtable)
One bit of state is the linuxbios log buffer that I want -- someday -- to appear via linux dmesg commands. Yep, bios startup messages should be seen from Linux. I did this once in 2000 and it was really, really nice.
Other bits are console state, baud rate, and so on. We want to know what those bits are, or just inherit them without changing them. Possibly careful design would make this work.
I think we're working to a solution here, but let's go with 'printk in stage1' for now until we're sure what we're doing will work. Juergen's idea is pretty interesting.
ron
On Friday 20 July 2007 00:02, Stefan Reinauer wrote:
- Marc Jones Marc.Jones@AMD.com [070719 23:52]:
I only think that this is a problem with initram because it links to stage0. Maybe we should reconsider that. Maybe it needs to stand alone. Marc
There are a few functions that we might want to share:
- printk
- the lar functions (?? not sure, maybe not even those.)
- what else?
One thing we had in v2 was 6 incarnations of print(k), each in 10 incarnations, one for each log level. That made 60 functions just for pushing a few letters of _debug_ to the _developer_.
Maybe we have to duplicate printk in the binary, but we should try to keep it one incarnation in the code.
If it is only for printk, setting up a jump table is maybe not worth it.
Though stage2 will have one, too.
Modular design and it's advantages and disadvantages. I think we should try to go the "defined interface to stage0" way, as Juergen also suggested (I dont think this is a hack)
We could add a very thin translation layer between initram and stage0. This will not result into an API. Only the used functions get translated. We could use linker's "--wrap" feature for all functions that tries to relative call functions in stage0. A script could extract all used stage0 symbols from initram.o, create on the fly the required translation code and link both into the final initram. If initram tries to call printf, it calls wrap_printf instead. And the generated wrap_printf functions calls stage0's printf, but calculates its correct entrypoint *at runtime*. This would enlarge initram by a few hundreds bytes, but would avoid to define an API (that grows and grows and will never be finished).
Juergen