LMA != VMA when compiling a kernel

Guillaume Ballet gballet at gmail.com
Sat May 30 13:34:24 UTC 2009

On Sat, May 23, 2009 at 6:43 PM, Rafal Jaworowski <raj at semihalf.com> wrote:
> On 2009-05-21, at 22:18, Guillaume Ballet wrote:
>> I am still working on a port of FreeBSD to the beagleboard, and am
>> currently working on enabling the VM. So far, I have loaded the kernel
>> at phys_addr = virt_addr = 0x80000000, because that is where the RAM
>> is. However, when enabling the VM, I would like the kernel virtual
>> addresses to start with 0xC0000000 as they do on most other platform.
>> Hence, I have been trying to set the ELF file sections' VMAs to
>> something starting with 0xC and the LMAs to something starting with
>> 0x8. It turns out that just setting KERNPHYSADDR and KERNVIRTADDR is
>> not enough >.< If found a way to do this by chaning the script linker
>> and adding AT after each section declaration, and it works fine. But
>> it's tedious, hacky and lots of hardcoded values only work with my
>> platform.
> What exactly are your problems with getting 0xC0000000 as the KVA base? It
> seems that all our current ARM variations follow this route and they all use
> a single linker script, so there shouldn't be major problems doing likewise
> with yet another port..

The problem is not setting 0xC0000000 as the KVA base, it's that when
KVA != KPA, the ELF header creates a file that has KVA == KLA anyway.
Now, as I found out, most of the problems can be circumvented by
setting up a temporary TLB system so that the startup code can still
access its data segments even though the final VM system has not been
The last remaining problem I face is that the loader (not loader(8) at
the moment) needs to know the physical address at which the kernel
must be loaded. But since KVA==LMA in the ELF header, some information
is lost as far as I know. Now, if the loader for other boards is
indeed able to extract that piece of information from the ELF header
itself, I would love to get some pointers to the solution :)

> The loader(8) entity is separate from how the kernel is linked, so I don't
> think that problems with kernel virtual addresses you mention could be
> worked around at the loader(8) level. Kernel linking/mapping should be
> addressed independently of any booting method involved.

I agree, they should :P I am surely not searching at the right
location, but I haven't found anything like a complete loader + boot
stages in the source tree. Where should I look? I wonder if most
system start in locore.S with the MMU already enabled from the loader,
or most of them use the one that is built from scratch in that file?

More information about the freebsd-arm mailing list