memory map driveru
Míla Kuchta
mila.kuchta na atlas.cz
Středa Duben 18 02:45:42 CEST 2001
Michl Ladislav <xmichl03 na stud.fee.vutbr.cz> wrote:
> pekny podvecer,
Vam take,
>
> potreboval bych drobnou radu s timto problemem:
>
> zarizeni ocekava pole deskriptoru (architekrura MIPS, velikost stranky
> 4 kB) a na adresu jimi urcenou sype pres DMA data. funguje to asi tak, ze
> natahne prvni deskriptor a na adresu jim urcenou prenese 4kB dat, pak
> vezme dalsi deskriptor atd. tohle by se dalo zaridit pres get_free_page,
> ale zarizeni musi podporovat mmap a ja nevim jak takto alokovanou pamet
> mapovat ven. dalsi moznost je alokovat linearni pamet, ale tam jednak
> nevim jak ziskat deskriptory na jednotlive stranky a taky se vzhledem
> k fragmentaci alokace nemusi vzdy zdarit - jde o nekolik megabyte. jak z
> toho ven?
Lado, pokud chcete ziskat presnejsi odpoved a usetrit nam trochu casu
za vesteni, neskolilo by, kdyby jste, pokud to neni tajemstvim, lepe
specifikoval Vas zamer. Za prve mi neni uplne jasne, k cemu to ma
slouzit, zda jde o zarizeni blokove ci znakove, I/O mapper atd.
//spolecne
int init_module(void)
{
...
buffer = (char *) __get_free_page(GFP_KERNEL|GFP_DMA);
if (buffer == NULL)
return -ENOMEM;
mem_map_reserve(MAP_NR(buffer));
...
}
void cleanup_module(void)
{
...
mem_map_unreserve(MAP_NR(buffer));
free_page((unsigned long) buffer);
...
}
1) mmap
//tohle zajisti namapovani prostoru ovladace do prostoru aplikace.
//js. implementace mmap(2)u nad souborem zarizeni.
static int zkouska_mmap(struct file *file, struct vm_area_struct *vma)
{
...
if (remap_page_range(vma->vm_start, virt_to_phys(buffer), size,
vma->vm_page_prot))
return -EAGAIN;
...
}
//non-blocking read/write
static ssize_t zkouska_read/write(struct file *file, const char
*bufer2, size_t count, loff_t *offset)
{
if (copy_to/from_user(bufer2/bufer, buffer/buffer2, count))
return -EFAULT;
}
Neuvadim priklady ioctl ani sysctl. Podle konkretnich pozadavku muze
byt vyhodnejsi pouzit kmalloc, pri obavach z nedostatku fyzicky
souvisle pameti vmalloc, kterou zase neni mozne pouzivat pro jine
ucely, nez ucely vnitrojaderne. Alternativa copy_to/from_user(),
get_user() a put_user() (se svyma __bratrickama) je zas vhodna pro mensi
objemy dat. Priklady jsou neuplne, jde jen o nastin moznosti.
Pripadne nepochopeni (a blaboly) z me strany, omlouva znacna unava,
nedostatek casu a pozdni nocni/ranni hodina:-).
S pozdravem
Mila Kuchta
Další informace o konferenci Linux