天天看點

IO記憶體

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      

# 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”,

[email protected]:/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

[email protected]:/proc#

其中70000000-77ffffff : System RAM為記憶體空間大小為128Mb,我們用是用了兩片DDR2SDRAM,64M,8位寬的Micron的MT47H64M8CF并聯,組合成總共128M,16位寬的記憶體。

其他的這些位址範圍都是基于實體位址的

3)/proc/meminfo檔案中記錄了記憶體情況。

/proc/meminfo内容如下:

[email protected]:/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指令檢視記憶體情況:

[email protected]:/proc# free

             total         used         free       shared      buffers

Mem:        125556        22680       102876            0            0

-/+ buffers:              22680       102876

Swap:            0            0            0

[email protected]:/proc#

從這裡看到的記憶體大小為122M左右,比從iomem中檢視到的要小點,是原因不是很清楚了。