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