ubuntu下ioport和iomem有什么不同

ubuntu下ioport和iomem有什么不同,第1张

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

__user表示是一个用户空间的指针,所以kernel不可能直接使用。

#ifdef __CHECKER__

# define __user __attribute__((noderef, address_space(1)))

# define __kernel /* default address space */

#else

# define __user

# define __kernel

#endif

noderef告诉编译器,不应该解除该指针的引用,因为在当前地址空间中它是没有意义的。

这里的CHECKER表示是否使用了Sprase(就是一种静态分析工具,用来分析内核源码中的BUG)。是不是想研究一下了?呵呵。可以参见http://sparse.wiki.kernel.org/index.php/Main_Page

所以对于这种变量,在kernel中使用要用到copy_to_user和copy_from_user。

__iomem是2.6.9中加入的特性。是用来个表示指会指向一个I/O的内存空间。主要

是为了driver的通用性考虑。由于不同的CPU体系结构对I/O空间的表示可能不同。当使用__iomem时,compiler会忽略对变量的检查

(因为用的是void __iomem)。但sparse会对它进行检查,当__iomem的指针和正常的指针混用时,就会发出一些warnings。

下面还有一些为个变量新加入的函数:

unsigned int ioread8(void __iomem *addr)

unsigned int ioread16(void __iomem *addr)

unsigned int ioread32(void __iomem *addr)

void iowrite8(u8 value, void __iomem *addr)

void iowrite16(u16 value, void __iomem *addr)

void iowrite32(u32 value, void __iomem *addr)

Writeln是输出语句,输出语句有三种格式:

① Write (输出项1,输出项2) ; {执行输出后光标不换行}

② Writeln (输出项1,输出项2) ; {执行输出后光标换到下一行}

③ Writeln {仅输出空白且光标换到喊贺下一行}

Writeln语句后面的圆括号以内部分均为输出项,可以是多项,各项间用逗号分隔; 对单引号里的内容按照引号内的原样(字符)输出显示。如果输出项是表达式,则只输出表达式的值,而不是表达式本身。

Readln是一个特殊的输入语句,要求输入一个回车(换行)才能往下执行。

Readln是输入语句,它的一般格式为:

① Read (变量1,变量2);

② Readln (变量1,变量2);

③ Readln

前两种格式均要从键盘给变量输入数据,输入时,所键入的数据之间以空格为分隔,以回车为输入结束。若多输入了数据(即数据个数超过变量个数),Read语句读完数据之后,能让后续的读语句接着读取多下来的数据;而Readln 语句对本行多输入的数据不能让后续语句接着读取多下来的数据。为了防止多输入的数据影响下一个输入语句读取数据,建议尽孙皮量使用Readln语句输则渗差入数据。第三种格式不需输入数据,只需按入一个回车键。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12297319.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存