Date: Thu, 12 Jan 2012 09:18:43 -0600 From: Alan Cox <alc@rice.edu> To: Juli Mallett <jmallett@FreeBSD.org> Cc: Oleksandr Tymoshenko <gonzo@freebsd.org>, "freebsd-mips@freebsd.org" <freebsd-mips@freebsd.org> Subject: Re: MIPS64 modules Message-ID: <4F0EF9D3.5030907@rice.edu> In-Reply-To: <CACVs6=8d76EbqErdGjrsb2wqP_OydXK%2BU6PmXD=-CNQeeAXRjA@mail.gmail.com> References: <4F0E1965.6060808@freebsd.org> <CACVs6=8d76EbqErdGjrsb2wqP_OydXK%2BU6PmXD=-CNQeeAXRjA@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On 01/11/2012 17:57, Juli Mallett wrote: > On Wed, Jan 11, 2012 at 15:21, Oleksandr Tymoshenko<gonzo@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4F0EF9D3.5030907>