Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9472064
  • 博文数量: 1751
  • 博客积分: 12961
  • 博客等级: 上将
  • 技术积分: 20101
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-09 11:25
个人简介

偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.

文章分类

全部博文(1751)

文章存档

2024年(27)

2023年(26)

2022年(112)

2021年(217)

2020年(157)

2019年(192)

2018年(81)

2017年(78)

2016年(70)

2015年(52)

2014年(40)

2013年(51)

2012年(85)

2011年(45)

2010年(231)

2009年(287)

分类: LINUX

2010-11-24 17:08:16

  1. I/O 内存可以或者不可以通过页表来存取.
    当通过页表存取, 内核必须首先安排物理地址, 并且这常常意味着在做任何 I/O 之前你必须调用 ioremap .
    如果不需要页表, I/O 内存位置看来很象 I/O 端口, 并且你只可以使用对应函数读写.
  2. I/O 内存分配和映射

    I/O 内存区必须在使用前分配. 分配内存区的接口是( 在 定义):
    struct resource *request_mem_region(unsigned long start, unsigned long len, char *name);
    这个函数分配一个 len 字节的内存区, 从 start 开始. 如果一切顺利, 一个 非NULL 指针返回; 否则返回值是 NULL. 所有的 I/O 内存分配来 /proc/iomem 中列出.

    内存区在不再需要时应当释放:
    void release_mem_region(unsigned long start, unsigned long len);

    IO内存分配完后,如果要直接进行存取还一定要经过一个映射. 这是 ioremap 函数的功能。这个函数设计来特别的安排虚拟地址给 I/O 内存区.

#include <asm/io.h>
void *ioremap(unsigned long phys_addr, unsigned long size);
void *ioremap_nocache(unsigned long phys_addr, unsigned long size);
void iounmap(void * addr);


一旦装备了 ioremap (和iounmap), 一个设备驱动可以存取任何 I/O 内存地址, 不管是否它是直接映射到虚拟地址空间. 但是, 从 ioremap 返回的地址不应当直接引用; 相反, 应当使用内核提供的存取函数.

存取 I/O 内存




从 I/O 内存读, 使用下列之一:

unsigned int ioread8(void *addr);
unsigned int ioread16(void *addr);
unsigned int ioread32(void *addr);

这里, addr 应当是从 ioremap 获得的地址(也许与一个整型偏移); 返回值是从给定 I/O 内存读取的.

有类似的一系列函数来写 I/O 内存:

void iowrite8(u8 value, void *addr);
void iowrite16(u16 value, void *addr);
void iowrite32(u32 value, void *addr);


如果你必须读和写一系列值到一个给定的 I/O 内存地址, 你可以使用这些函数的重复版本:

void ioread8_rep(void *addr, void *buf, unsigned long count);
void ioread16_rep(void *addr, void *buf, unsigned long count);

void ioread32_rep(void *addr, void *buf, unsigned long count);
void iowrite8_rep(void *addr, const void *buf, unsigned long count);
void iowrite16_rep(void *addr, const void *buf, unsigned long count);
void iowrite32_rep(void *addr, const void *buf, unsigned long count);

这些函数读或写 count 值从给定的 buf 到 给定的 addr. 注意 count 表达为在被写入的数据大小; ioread32_rep 读取 count 32-位值从 buf 开始.

上面描述的函数进行所有的 I/O 到给定的 addr. 如果, 相反, 你需要操作一块 I/O 地址, 你可使用下列之一:

void memset_io(void *addr, u8 value, unsigned int count);
void memcpy_fromio(void *dest, void *source, unsigned int count);
void memcpy_toio(void *dest, void *source, unsigned int count);


当前不鼓励使用旧的代码方式  readb/w/l 和 writeb/w/l 等IO内存读写函数。

阅读(3539) | 评论(0) | 转发(0) |
0

上一篇:9.2. 使用 I/O 端口

下一篇:第10章 中断处理

给主人留下些什么吧!~~