PHYSADDR

Warner Losh imp at bsdimp.com
Sat Mar 2 23:15:12 UTC 2013


On Mar 2, 2013, at 10:50 AM, Ian Lepore wrote:
> I'm not sure its safe to assume that (entry-pc & 0xfffff000) is the
> beginning of the kernel; it's true now but need not be so.  But that's
> no big deal, we can tweak the linker script to give us the offset of the
> _start symbol so it'll work no matter what.

We have total control over this, since we control the linker script that puts locore.S at the front.

> The more I ponder the fixed offset concept for a generic kernel the more
> it seems that it might be viable, providing that we require the use of
> ubldr.  Then we can make sure that ubldr is always linked at an offset
> that doesn't overlap the kernel load offset.  An offset number like 1mb
> or 4mb might work well for the kernel; it leaves lots of space for ubldr
> to be loaded down low in memory.  I think putting the loader at a lower
> address than the kernel is required, because there's no upper bound on
> the kernel size (I did a 27MB kernel last month -- it contains a huge
> embedded md filesystem image).
> 
> This just pushes the real problem into ubldr, though, and that becomes
> the non-generic component that has to be linked at a different physical
> address for each SoC.  A kernel could still be loaded without ubldr, but
> it may need to be built in a non-generic way for some platforms.

Why not compile ubldr -pic? Then it wouldn't matter where we get loaded, we'll work...

> So if we declare that this scheme is for generic kernels loaded by a
> loader (ubldr or other) that is aware of the generic kernel scheme,
> there's no need for the physical address fields in the elf headers to be
> interpretted as a real physical address that would work for a standard
> elf loader.  You can build kernels that work with a standard elf loader,
> but the generic kernel is not such a thing.  

Correct.  BTW, what do latter-day universal-boot linux kernels do?

> In that case, the physical address and entry address fields in the
> headers are all offsets.  If physical ram on a given chip starts at
> zero, then the headers would accidentally be right for a standard elf
> loader.  Otherwise the generic-aware loader is responsible for filling
> in some high-order bits when interpretting the headers.
> 
> The PHYSADDR symbol (and its several name variations) at build time now
> becomes zero for a generic kernel or non-zero to generate a SoC-specific
> kernel that can be loaded by a standard elf loader.  The symbol doesn't
> exist at all in the compilation, it's used only by the build system and
> is passed as a parameter to the linker.
> 
> There's another problem constant we haven't talked about yet:
> STARTUP_PAGETABLE_ADDR, used by locore to build the early page tables.
> It's the absolute physical address of an area of memory that doesn't
> have any other important data in it, and won't get overwritten by
> something before initarm() builds the real page tables.  I think most
> SoCs now put it way up high in memory "safely out of the way", but that
> won't work generically.  We need 16K aligned to a 16K boundary, and
> maybe it would work to use the area immediately preceeding the start of
> the kernel.  We could require the kernel to be linked on a 16k boundary
> so that we can just blindly subtract 16K from the starting physaddr we
> calculate; nice and easy.

Maybe have ubldr responsible for this? And if you aren't booting with ubldr using a custom loader, you're already into the land of unique kernel build anyway, and can wire it there...

Warner


More information about the freebsd-arm mailing list