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