IO内存

来源:互联网 发布:java io nio 面试 编辑:程序博客网 时间:2024/06/04 19:57

 

1)cat /proc/iomem看到的内容:
IO memory空间的地址资源分配情况,以树状结构显示。
request_mem_region
ioremap
 
2)cat /proc/ioports看到的内容
IO port空间的地址资源分配情况,以树状结构显示。[源于x86平台的设计思想,目前基本不用了]
request_region
ioremap
 
 
# define __iomem __attribute__((noderef, address_space(2)))
void __iomem *fpga_vbase;
 
__iomem是linux2.6.9内核中加入的特性。是用来个表示指针是指向一个I/O的内存空间。主要是为了驱动程序的通用性考虑。由于不同的CPU体系结构对I/O空间的表示可能不同。当使用__iomem时,编译器会忽略对变量的检查(因为用的是void __iomem)。若要对它进行检查,当__iomem的指针和正常的指针混用时,就会发出一些警告。
 
include/linux/compiler.h , make C=1 时会有检查,C=0
则无任何作用。 
$ grep -RIn 'define __iomem' include/linux
#ifdef __CHECKER__
# define __user         __attribute__((noderef, address_space(1)))
# define __kernel       /* default address space */
# define __safe         __attribute__((safe))
# define __force        __attribute__((force))
# define __nocast       __attribute__((nocast))
# define __iomem        __attribute__((noderef, address_space(2)))
# define __acquires(x)  __attribute__((context(0,1)))
# define __releases(x)  __attribute__((context(1,0)))
# define __acquire(x)   __context__(1)
# define __release(x)   __context__(-1)
# define __cond_lock(x) ((x) ? ({ __context__(1); 1; }) : 0)
extern void __chk_user_ptr(void __user *);
extern void __chk_io_ptr(void __iomem *);

#else
# define __user
# define __kernel
# define __safe
# define __force
# define __nocast
# define __iomem
# define __chk_user_ptr(x) (void)0
# define __chk_io_ptr(x) (void)0
# define __builtin_warning(x, y...) (1)
# define __acquires(x)
# define __releases(x)
# define __acquire(x) (void)0
# define __release(x) (void)0
# define __cond_lock(x) (x)

#endif
 
概念性的东西:

几乎每一种外设都是通过读写设备上的寄存器来进行的。外设寄存器也称为“I/O端口”,通常包括:控制寄存器、状态寄存器和数据寄存器三大类,而且一个外设的寄存器通常被连续地编址。CPU对外设IO端口物理地址的编址方式有两种:一种是I/O映射方式(I/O-mapped),另一种是内存映射方式(Memory-mapped)。而具体采用哪一种则取决于CPU的体系结构。

有些体系结构的CPU(如,PowerPC、m68k等)通常只实现一个物理地址空间(RAM)。在这种情况下,外设I/O端口的物理地址就被映射到CPU的单一物理地址空间中,而成为内存的一部分。此时,CPU可象访问一个内存单元那样访问外设I/O端口,而无需设立专门的外设I/O指令。这就是所谓的“内存映射方式”(Memory-mapped)。

而另外一些体系结构的CPU(典型地如X86)则为外设专门实现了一个单独地地址空间,称为“I/O地址空间”或“I/O端口空间”。这是个和CPU地RAM物理地址空间不同的地址空间,任何外设的I/O端口均在这一空间中进行编址。CPU通过设立专门的I/O指令(如X86的IN和OUT指令)来访问这一空间中的地址单元(也即I/O端口)。这就是所谓的“I/O映射方式”(I/O-mapped)。和RAM物理地址空间相比,I/O地址空间通常都比较小,如x86 CPU的I/O空间就只有64KB(0-0xffff)。这是“I/O映射方式”的一个主要缺点。
 
Linux设计了一个通用的数据结构resource来描述各种I/O资源(如:I/O端口、外设内存、DMA和IRQ等)。该结构定义在include/linux/ioport.h头文件中。
Linux是以一种倒置的树形结构来管理每一类I/O资源(如:I/O端口、外设内存、DMA和IRQ)的。每一类I/O资源都对应有一颗倒置的资源树,树中的每一个节点都是个resource结构,而树的根结点root则描述了该类资源的整个资源空间。
基于上述这个思想,Linux将基于I/O映射方式的I/O端口和基于内存映射方式的I/O端口资源统称为“I/O区域”(I/O Region)。
参考:
linux/kernel/resource.c
include/linux/Ioport.h

 

4)/proc/iomem:

/proc/iomem这个文件记录的是物理地址的分配情况,内存只占用4G(32位CPU)物理地址的一部分,一般从地址0开始,每一行都代表一个资源(地址范围和资源名), 可用物理内存的资源名为“System RAM”,

root@project:/proc# cat iomem
00500000-00500fff : atmel_lcdfb.0
  00500000-00500fff : atmel_lcdfb
00700000-007fffff : at91_ohci
  00700000-007fffff : ohci_hcd
00800000-008fffff : atmel-ehci
  00800000-008fffff : ehci_hcd
10000000-101fffff : fpga_slave.0
40000000-4fffffff : atmel_nand
70000000-77ffffff : System RAM
  700e7000-704affff : Kernel text
  704ce000-7052589f : Kernel data
feffee00-feffefff : atmel_usart.0
  feffee00-feffefff : atmel_serial
fff7c000-fff7ffff : atmel_tcb.0
fff80000-fff83fff : atmel_mci.0
fff8c000-fff8ffff : atmel_usart.1
  fff8c000-fff8ffff : atmel_serial
fffbc000-fffbffff : macb
fffd4000-fffd7fff : atmel_tcb.1
ffffe200-ffffe3ff : atmel_nand
ffffec00-ffffedff : at_hdmac
  ffffec00-ffffedff : at_hdmac
fffffd20-fffffd2f : at91_rtt.0
root@project:/proc#

其中70000000-77ffffff : System RAM为内存空间大小为128Mb,我们用是用了两片DDR2SDRAM,64M,8位宽的MicronMT47H64M8CF并联,组合成总共128M16位宽的内存。

其他的这些地址范围都是基于物理地址的

 

3)/proc/meminfo文件中记录了内存情况。

/proc/meminfo内容如下:

root@project:/proc# cat meminfo
MemTotal:         125556 kB
MemFree:          102848 kB
Buffers:               0 kB
Cached:            12804 kB
SwapCached:            0 kB
Active:             6292 kB
Inactive:          11008 kB
Active(anon):       4572 kB
Inactive(anon):        0 kB
Active(file):       1720 kB
Inactive(file):    11008 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:          4536 kB
Mapped:             2600 kB
Slab:               2000 kB
SReclaimable:        636 kB
SUnreclaim:         1364 kB
PageTables:           96 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:       62776 kB
Committed_AS:       9952 kB
VmallocTotal:     890880 kB
VmallocUsed:      268700 kB
VmallocChunk:     610300 kB
VmallocChunk:     610300 kB

 

用free命令查看内存情况:

root@project:/proc# free
             total         used         free       shared      buffers
Mem:        125556        22680       102876            0            0
-/+ buffers:              22680       102876
Swap:            0            0            0
root@project:/proc#

 

从这里看到的内存大小为122M左右,比从iomem中查看到的要小点,是原因不是很清楚了。

原创粉丝点击