Mapping Physical Memory without a Device?
Bruce M Simpson
bms at spc.org
Fri Jun 13 13:31:54 PDT 2003
On Fri, Jun 06, 2003 at 01:30:28PM -0400, cd_freebsd wrote:
> I would like to be able to map memory before I have a device to work with (to read system BIOS information or mess with the video buffer). Is this possible? In linux, I would just call ioremap_nocache or request region. Is there a way to use bus_alloc_resource or something similar to accomplish this?
I assume you wish to do this from within the kernel.
The key ingredient here is pmap_kenter().
You would want to do something like this:
...
struct pcmem_softc {
int sc_unit;
device_t sc_dev;
dev_t sc_cdev;
...
/* common memory mapping descriptors */
u_int32_t sc_cm_base;
int sc_cm_size;
vm_offset_t sc_cm_kva_base;
u_int32_t sc_cm_kva_size;
...
};
static vm_offset_t
pcmem_phys_map(struct pcmem_softc *sc)
{
int i;
u_int32_t off;
u_int32_t pa;
vm_offset_t va;
vm_offset_t size;
/*
* ensure the range to be mapped fits within page boundaries.
*/
pa = round_page((u_int32_t) sc->sc_cm_base);
sc->sc_cm_kva_size = size = round_page((u_int32_t) sc->sc_cm_size);
off = (u_int32_t) sc->sc_cm_base - pa;
/*
* reserve a pageable memory range within the kva.
*/
va = kmem_alloc_pageable(kernel_map, size);
if (va == (vm_offset_t) 0)
return (va);
/*
* wire each page into kva.
*/
for (i = 0; i < size; i += PAGE_SIZE) {
pmap_kenter(va + i, pa + i);
}
#ifdef __i386__
invltlb();
#endif
return (va + off);
}
I wrote the above segment knowing much less about vm than I do now, so
it's probably too pmap and arch specific and could be done better.
Anything more elaborate (e.g. exporting pages to userland) would require
you to use a pager of type OBJT_PHYS.
BMS
More information about the freebsd-hackers
mailing list