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