(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的內存信息不一致,而使程序運行出錯。