Linux内存管理机制没有用过,以前在vxworks系统下做过内存管理的模块,这里就先介绍些重点学习内容,以后需要查找一些实例,结合来学习!
1、分页机制等等
2、内存分配函数
3、slab
4、内存池
5、I/O端口及I/O内存
1、 访问I/O内存的流程是:
request_mem_region()-> ioremap() -> ioread8()/iowrite8() -> iounmap()->release_mem_region() 。
前面说过,IO内存是统一编址下的概念,对于统一编址,IO地址空间是物理主存的一部分,对于编程而言,我们只能操作虚拟内存,所以,访问的第一步就是要把设备所处的物理地址映射到虚拟地址,Linux2.6下用ioremap():
void *ioremap(unsigned long offset, unsigned long size);
然后,我们可以直接通过指针来访问这些地址,但是也可以用Linux内核的一组函数来读写:
ioread8(),iowrite16(), ioread8_rep(), iowrite8_rep()......
2、 访问I/O端口
访问IO端口有2种途径:I/O映射方式(I/O-mapped)、内存映射方式(Memory-mapped)。前一种途径不映射到内存空间,直接使用 intb()/outb()之类的函数来读写IO端口;后一种MMIO是先把IO端口映射到IO内存(“内存空间”),再使用访问IO内存的函数来访问 IO端口。
void ioport_map(unsigned long port, unsigned int count);
通过这个函数,可以把port开始的count个连续的IO端口映射为一段“内存空间”,然后就可以在其返回的地址是像访问IO内存一样访问这些IO端口。
request_region()函数用于申请IO端口,
request_mem_region用于申请IO内存(一般为控制寄存器)。
这两个函数申请之后还要通过ioremap函数去映射到内核虚拟地址。
voidrequest_region(unsigned long from, unsigned long num, const char *name)
这个函数用来申请一块输入输出区域。
如果这段I/O端口没有被占用,在我们的驱动程序中就可以使用它。在使用之前,必须向系统登记,以防止被其他程序占用。登记后,在/proc/ioports文件中可以看到你登记的io口。
参数1:io端口的基地址。
参数2:io端口占用的范围。
参数3:使用这段io地址的设备名。
在对I/O口登记后,就可以放心地用inb(), outb()之类的函来访问了。********************************************************************************************
request_region()用于内核为驱动“分配”端口,这里分配的意思是,记录该端口已经被某个进程使用,要是其它进程试图访问它,就会产生“忙”错误。所以目的在于实现资源的互斥访问。
反之, 如果一个资源只被一个进程访问,不会导致资源的争用,这时request_region()是可选的。
Linux下的IO端口和IO内存
CPU对外设端口物理地址的编址方式有两种:一种是IO映射方式,另一种是内存映射方式。
Linux将基于IO映射方式的和内存映射方式的IO端口统称为IO区域(IO region)。
IO region仍然是一种IO资源,因此它仍然可以用resource结构类型来描述。
Linux管理IO region:
1) request_region()
把一个给定区间的IO端口分配给一个IO设备。
2) check_region()
检查一个给定区间的IO端口是否空闲,或者其中一些是否已经分配给某个IO设备。
3) release_region()
释放以前分配给一个IO设备的给定区间的IO端口。