MIPS64 modules
Alan Cox
alc at rice.edu
Thu Jan 12 15:18:47 UTC 2012
On 01/11/2012 17:57, Juli Mallett wrote:
> On Wed, Jan 11, 2012 at 15:21, Oleksandr Tymoshenko<gonzo at freebsd.org> wrote:
>> Modules on MIPS use the same interface as AMD64 modules:
>> sys/kern/link_elf_obj.c. It works for MIPS32 but there is a problem
>> with MIPS64. sys/kern/link_elf_obj.c calls vm_map_find that uses
>> KERNBASE as a map base. As I told - it works for mips32 because
>> KERNBASE for mips32 is located before actual virtual memory area
>> (KERNBASE points to directly-mapped KSEG0 segment). But for MIPS64
>> it's not the case - KERNBASE points to the very end of address space
>> and vm_map_find fails.
> It seems like the problem here must be because on 32-bit MIPS the
> direct-mapped region is less than kernel virtual mapped address space,
> and either some macro we provide or the VM code makes a wrong
> assumption about that relationship, since in 64-bit addressing, the
> direct-mapped region is much, much higher, and so we're not looking up
> something in the direct map when we ought to be? Or some other
> conditional is wrong? Is that right?
>
On amd64, the direct map is also beneath the kernel map (or kernel
virtual address space). The difference with respect to mips is that the
kernel is not executed through the direct map. The kernel code and data
segments are also mapped into the upper region of the kernel map, and
the kernel is executed via this mapping.
On both amd64 and mips, KERNBASE is roughly the starting virtual address
of the kernel code segment. The essential difference is whether or not
this address falls within the kernel map (between VM_MIN_KERNEL_ADDRESS
and VM_MAX_KERNEL_ADDRESS). On 32-bit mips, KERNBASE winds up below the
kernel map, and on 64-bit mips, it winds up above the kernel map. This
explains why link_elf_obj.c works on 32-bit mips and fails on 64-bit
mips. The value passed to vm_map_find() defines the starting point for
finding a free virtual address within the kernel map. If that starting
point is above the entire kernel map, then no satisfying address can be
found.
On amd64, link_elf_obj.c must specify KERNBASE rather than
VM_MIN_KERNEL_ADDRESS to vm_map_find() because kernel loadable modules
must be mapped for execution in the same upper region of the kernel map
as the kernel code and data segments. In other words, specifying
KERNBASE in link_elf_obj.c reflects (1) an architectural peculiarity of
amd64 and (2) the fact that this code was previously only used by
amd64. In the general case, which would include mips, any address
within the kernel map can be used to map a kernel loadable module.
amd64 is really the exception. So, it makes sense for link_elf_obj.c to
use the same #ifdef as kmem_init() and pass VM_MIN_KERNEL_ADDRESS to
vm_map_find() when we are not compiling for amd64.
Alan
More information about the freebsd-mips
mailing list