GENERIC kernel issues

Warner Losh imp at bsdimp.com
Wed Mar 6 17:51:50 UTC 2013


On Mar 6, 2013, at 10:36 AM, Tim Kientzle wrote:

>>>>> 
>>>>> On the other hand, I haven't got anything to offer on the PROBLEM OF
>>>>> THE LOADER needing to be linked differently for each board or SoC, since
>>>>> they all have physical memory in differing address ranges.
>>>> 
>>>> Well, the Phyiscal memory load address is just a hint after all. Any way to leave it blank and have ubldr cope by putting it in the first available phyiscal memory slot from the FDT?
>>>> 
>>>> Warner
>>>> 
>>> 
>>> It's not just a hint, the executable is linked to run at that address
>>> and no other.  There is no relocation info in the file at all.  That's
>>> true of both the kernel and ubldr.  It's also true of any old
>>> static-linked executable, but in that case the object is just mapped at
>>> the virtual address it's linked for by the kern/imgact_elf.c code.
>> 
>> It is just a hint, since we can load it at any physical address.  Well, almost any. But we can get the almost from the virtual part.
>> 
>>> We essentially pull off the same mapping trick with the kernel, except
>>> that very early in locore.s the code is carefully crafted to work right
>>> whether on physical or virtual addressing, just long enough to get the
>>> MMU turned off.  Then it sets up page tables to map the physical pages
>>> the kernel has been loaded into to match the virtual addresses it was
>>> linked for.  All of that only works if the low-order bits of the virtual
>>> address it was linked for match the physical address it was loaded at.
>>> That is, if linked for 0xC0001000 it must be loaded at 0xNNNN1000
>>> physical, where the N bits can be anything.
>> 
>> Right, but can't we get that from the virtual address.
>> 
>>> Unfortunately, I don't think we can pull the same kind of trick with
>>> UBLDR.  In locore.s for the kernel we build simple page tables which are
>>> just enough to get us to the code in initarm() that builds them for
>>> real.  No SoC-specific stuff has to happen along the way (or if it does,
>>> SoC-specific code is invoked via various hooks to board support
>>> routines).  In UBLDR we mess with the hardware (via the u-boot drivers),
>>> so if we turn on the MMU to map the memory UBLDR is running from, we
>>> also have to map the hardware va=pa for those drivers to work.  I don't
>>> know that there's any way to get the needed info for that from u-boot.
>> 
>> So long as the code is PIC up until the time we turn on the MMU, then we're fine. We can and should still do this in locore.S.
>> 
>> I guess I'm being dense this morning.. I'm not sure I understand what the big deal is…
> 
> Ian is NOT talking about the kernel here.
> 
> He's talking about UBLDR, which is an ELF image
> loaded by U-Boot.
> 
> The techniques used for the kernel (which we
> all agree on and which Ian has partly implemented
> already) don't seem to be applicable here.  (I don't want
> to change U-Boot's ELF loader, nor should UBLDR
> be messing with the MMU.)
> 
> So we're stuck for now with linking UBLDR separately
> for each memory address at which UBLDR gets run.
> The obvious answer is to have UBLDR be a static PIC
> binary and not ELF.  If you see another approach, I'm
> interested.

OK. I'm back with you now, and I agree. ubldr does run in PA, and what I've said don't apply...  Unless we make ubldr PIC, so I think we're on the same page here...

We could create our own mapping, but we'd have to totally trash that just before jumping to the kernel, which I'm at best luke warm to since that kind of code has to be in assembler...  I think that static PIC binary would be easier...

Warner


More information about the freebsd-arm mailing list