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中檢視到的要小點,是原因不是很清楚了。