[OpenBIOS] Q: How to "squeeze" C functions in between two symbols?

Andreas Färber andreas.faerber at web.de
Fri Oct 8 19:11:59 CEST 2010


Am 08.10.2010 um 15:30 schrieb Alexander Graf:

> On 08.10.2010, at 15:23, Andreas Färber wrote:
>
>> Am 08.10.2010 um 14:54 schrieb Alexander Graf:
>>
>>> On 08.10.2010, at 14:44, Andreas Färber wrote:
>>>
>>>> The RTAS code in arch/ppc/qemu/start.S currently looks like this:
>>>>
>>>> GLOBL(of_rtas_start):
>>>> 	blr
>>>> GLOBL(of_rtas_end):
>>>>
>>>> ...and I would like to branch to C code from there.
>>>>
>>>> Is there a way to have code from, say, rtas.c go between the blr  
>>>> and of_rtas_end symbol?
>>>> Or do I need to move the symbols to the ldscript and place the  
>>>> code in a special section? If yes, how?
>>>
>>> Why do you want to have the code in between? You can just branch  
>>> to the C code:
>>>
>>> b c_rtas_function
>>>
>>> The only thing you need to make sure is that you follow the  
>>> ABI :). Input parameters go in r3-rsomething, output is in r3,  
>>> stack pointer (r1) has to be valid.
>>>
>>> Also by only doing the b instead of blr you jump to the C function  
>>> directly, so a return from there actually returns from the rtas  
>>> function.
>>
>>> If the rtas function follows a different ABI, better set up a  
>>> stack frame and blr into the C function.
>>
>> I assumed the latter is what I should do, following the CIF example.
>>
>>>> Those symbols are being used for code size calculation and  
>>>> relocation in arch/ppc/qemu/methods.c.
>>>
>>> Maybe I don't really understand the question though.
>>
>> Thanks for promptly trying!
>>
>> The code in methods.c basically does a memcpy() of  
>> of_rtas_start..of_rtas_end to memory that AIX allocates for us. The  
>> code is never called at its original location so needs to be PIC.  
>> Thus, if the C functions are not copied along, any relative  
>> addressing wouldn't work and absolute addressing would break as  
>> soon as the functions get unmapped. You might think of it as a  
>> "separate" executable that OpenBIOS loads and sets up.
>> Therefore I need a way to get one piece of memory containing the  
>> entry point, data storage and all helper functions called.
>
> Oh. That's not exactly easy. So the rtas space stays intact while  
> all the openbios functions it wants to call don't? Hrm.

At least that's what [1] and [2] suggested. CHRP System Architecture  
spec 1.0 chapter 7.1 (hrpa_103.ps) specifically says:

"The role of RTAS versus Open Firmware is very important to understand.
Open Firmware and RTAS are both vendor-provided software, and both are  
tailored
by the hardware vendor to manipulate the specific platform hardware.
However, RTAS is intended to be present during the execution of the  
OS, and
to be called by the OS to access platform hardware features on behalf  
of the
OS, whereas Open Firmware need not be present when an OS is running.  
This
frees Open Firmware’s memory to be used by applications. RTAS is small
enough to painlessly coexist with OSs and applications."

I'd be happy to continue in some way that plays nicely with the  
relocation only for now though.

[1] http://www.scribd.com/doc/23367157/Concept-Design-and-Implementation-of-a-Slimline-Boot-Firmware-for-Linux-on-Power-Architecture 
  pp. 8 f.
[2] http://www.slideshare.net/schihei/agnostic-device-drivers slides  
16 f.

> I guess you'll have to copy them down too, which can become very  
> hairy very quick.

> Why don't you just create a separate binary for RTAS which can then  
> use relative branching inside of itself? You could then copy the  
> whole blob somewhere and be sure that everything's there.

How? :) Assuming I managed to fork arch/ppc/qemu/{start.S,ldscript}  
for a separate ELF binary, what would we do with it? Would QEMU need  
to load it separately as a ROM with known location, like openbios-ppc?  
Or would you embed such a binary into OpenBIOS somehow?

In theory we need support for both bitnesses and both endiannesses,  
i.e. up to four executables...

And how would the interaction between OpenBIOS and RTAS work then?  
Would we have to duplicate all info into the RTAS private memory using  
an init function called during initialize-rtas?
PCI for instance is supposed to be handled by RTAS (e.g., read-pci- 
config and write-pci-config), and the OS is supposed to call restart- 
rtas after reconfiguring PCI, which sort of implies probing  
capabilities inside RTAS...

Andreas


More information about the OpenBIOS mailing list