linux驅動編程--內存與I/O訪問

(still a problem)

一.

        1.1 MMU

                MMU(Memory Manage Unit)是一種輔助內存管理的硬件機制。由一組硬件設備共同協從硬件上爲CPU提供訪問安全檢查,地址映射等功能。

                地址映射(物理地址和虛擬地址的映射)

                linux利用MMU建立了一個三級頁表。

二.linux的內存管理

       內存空間指0~4GB的邏輯地址範圍,實際物理來源可能包括: 物理內存, IO內存,IO端口等部分。其中0~3GB爲用戶空間,其每個進程有獨立的邏輯映射關係。3~4GB爲內核空間,其邏輯映射關係始終不變。其中內核空間又詳細的分爲:物理內存映射區--//--vmalloc映射區-- //--高端內存映射區--...--保留區;其中物理內存映射區包含896MB的範圍,映射關係是簡單的線性映射,超出896MB的範圍非線性映射到高端內存映射區。一般用kmalloc__get_free_page申請的內存就是在這個區域。

       2.1 用戶空間內存的動態申請

                malloc();

                free();

        2.2 內核空間內存的動態申請

                kmalloc();       //較適合小內存申請

                  kfree();

                __get_free_pages();   //頁申請

                  release_pages();

                vmalloc();       //大內存申請,至少超過一頁

                  vfree();

三.IO端口和IO內存

                 IO端口和IO內存的最大區別在於地址的編碼方式,IO內存與普通內存是統一編址,IO端口是單獨編制。

        3.1 訪問IO端口

                              對IO端口的訪問可以直接訪問,也可以將其映射到內存空間中間接訪問。

                             3.1.1 直接訪問

	request_region( unsigned long first, unsigned long n, const char *name);	//申請IO端口
	inb();			//直接訪問
	outb();
	release_region( unsigned long start, unsigned long n);


                             3.1.2  間接訪問

	request_region( unsigned long first, unsigned long n, const char *name);	//申請IO端口
	ioport_map(port,nr);		//地址映射到內存區

	ioread8(X);
	ioread8_rep(p,dst,count);

	ioport_unmap(addr);
	release_region( unsigned long start, unsigned long n);

        3.2 訪問IO內存

                             3.2.1 動態映射

	//在需要時再將物理地址動態映射到內核空間中
	request_mem_region(start,n,name);	//申請IO內存
	ioremap(cookie,size);
		/*io操作*/
	iounmap(cookie);
	release_mem_region(start,n);

            

                             3.2.2 靜態映射

                                                    由系統自動將物理地址動態映射進內存。在板級文件中有一個記錄內存映射信息的數組,通常如下

	static struct map_desc io_desc[] = {
		{
			.virtual 	= IO_ADDRESS(x),
			.pfn 		= __phys_to_pfn(paddr),
			.length 	= SZ_4K,
			.type 	= MT_DEVICE,
		},
		{},
		{},
	};

                                                   然後系統會調用iotable_init(map,num)將該段地址映射進內存。

        3.3 設備地址到用戶空間的映射                     

	//將設備地址空間映射到用戶空間
	mmap(struct file * file,struct vm_area_struct * vma);
	munmap(void *,int);

        3.4 (*)slab               

	kmem_cache_create(const char * name,size_t size,size_t align,unsigned long flags,void(* ctor)(void *));
	kmem_cache_alloc(struct kmem_cache * cachep,gfp_t flags);
	kmem_cache_free(struct kmem_cache * cachep,void * objp);
	kmem_cache_destroy(struct kmem_cache * cachep);

        3.5 (*)內存池

	mempool_create(int min_nr,mempool_alloc_t * alloc_fn,mempool_free_t * free_fn,void * pool_data);
	mempool_alloc(mempool_t * pool,gfp_t gfp_mask);
	mempool_free(void * element,mempool_t * pool);
	mempool_destroy(mempool_t * pool);

 四.DMA

                DMA是一種設備與內存進行高速數據交換的方式,並不需要驅動。常見的問題是有可能導致內存與cache的內存信息不一致,而使程序運行出錯。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章