io端口
io端口
- drivers/input/serio/hp_sdc.c
- -------------------------------------
- if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name))
- goto err0;
- 如果request_region 分配端口成功,返回非空指针。
- request_region
- -------------------------------------
- ->./include/linux/ioport.h:
- #define request_region(start,n,name) \
- __request_region(&ioport_resource, (start), (n), (name), 0)
- =====================================
- ioport_resource
- -------------------------------------
- -->kernel/resource.c
- struct resource ioport_resource = {
- .name = "PCI IO",
- .start = 0,
- .end = IO_SPACE_LIMIT,
- .flags = IORESOURCE_IO,
- };
- EXPORT_SYMBOL(ioport_resource);
- __request_region
- -------------------------------------
- -->kernel/resource.c
- struct resource * __request_region(struct resource *parent,
- resource_size_t start, resource_size_t n,
- const char *name, int flags)
- {
- struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
- if (!res)return NULL;
- res->name = name;
- res->start = start;
- res->end = start + n - 1;
- res->flags = IORESOURCE_BUSY;
- res->flags |= flags;
- write_lock(&resource_lock);
- for (;;) {
- struct resource *conflict;
- conflict = __request_resource(parent, res);
- if (!conflict) break; //申请成功
- if (conflict != parent) {
- parent = conflict;
- if (!(conflict->flags & IORESOURCE_BUSY))
- continue;
- }
- /* Uhhuh, that didn't work out.. */
- kfree(res);
- res = NULL;
- break;
- }
- write_unlock(&resource_lock);
- return res;
- }
- EXPORT_SYMBOL(__request_region);
- =====================================
- kzalloc
- -------------------------------------
- --->include/linux/slab.h
- static inline void *kzalloc(size_t size, gfp_t flags)
- {
- return kmalloc(size, flags | __GFP_ZERO);
- }
- __request_resource
- -------------------------------------
- --->kernel/resource.c
- static struct resource *
- __request_resource(struct resource *root,
- struct resource *new)
- {
- resource_size_t start = new->start;
- resource_size_t end = new->end;
- struct resource *tmp, **p;
- if (end < start) return root;
- if (start < root->start) return root;
- if (end > root->end) return root;
- p = &root->child;
- for (;;) {
- tmp = *p;
- if (!tmp || tmp->start > end) {
- new->sibling = tmp;
- *p = new;
- new->parent = root;
- return NULL; //成功
- }
- p = &tmp->sibling;
- if (tmp->end < start) continue;
- return tmp;
- }
- }
- =====================================
- lib/iomap.c
- -------------------------------------
- #define PIO_OFFSET 0x10000UL //64k
- #define PIO_MASK 0x0ffffUL
- #define PIO_RESERVED 0x40000UL //256K
- #endif
- void __iomem *ioport_map(unsigned long port, unsigned int nr)
- {
- if (port > PIO_MASK)
- return NULL;
- return (void __iomem *) (unsigned long) (port + PIO_OFFSET);
- }
- void ioport_unmap(void __iomem *addr)
- {
- /* Nothing to do */
- }
- __iomem
- -------------------------------------
- include/linux/compiler.h
- # define __iomem __attribute__((noderef, address_space(2)))
- //对iomem地址进行检查
- -------------------------------------
- ioport_map ioport_unmap 小结
- -------------------------------------
- 从port的范围(0-0xffff) 可以看到,映射的地址是10000-0x1ffff, 即(64k) -> (128k-1)的空间。
- 还有一个是PIO_RESERVED 40000,是保留的空间。
- 在搜代码的时候,同时也会在include/asm-generic/io.h文件中出现。而其上方有 #ifndef CONFIG_GENERIC_IOMAP,个人理解是这文件处理的是没有iomap的功能情况。里面的函数大都是空。
- ==============================================================================
- ***********************************************************
- ioread8() iowrite8()
- ***********************************************************
- lib/iomap.c
- -------------------------------------
- #define PIO_RESERVED 0x40000UL
- #define PIO_OFFSET 0x10000UL
- unsigned int ioread8(void __iomem *addr)
- {
- IO_COND(addr, return inb(port), return readb(addr));
- return 0xff;
- }
- void iowrite8(u8 val, void __iomem *addr)
- {
- IO_COND(addr, outb(val,port), writeb(val, addr));
- }
- EXPORT_SYMBOL(ioread8);
- EXPORT_SYMBOL(iowrite8);
- #define IO_COND(addr, is_pio, is_mmio) do { \
- unsigned long port = (unsigned long __force)addr; \
- if (port >= PIO_RESERVED) { \
- is_mmio; \
- } else if (port > PIO_OFFSET) { \
- port &= PIO_MASK; \
- is_pio; \
- } else \
- bad_io_access(port, #is_pio ); \
- } while (0)
- static void bad_io_access(unsigned long port, const char *access)
- {
- static int count = 10;
- if (count) {
- count--;
- WARN(1, KERN_ERR "Bad IO access at port %#lx (%s)\n", port, access);
- }
- }
- WARN
- -------------------------------------
- ->include/asm-generic/bug.h
- #define WARN(condition, format...) ({ \
- int __ret_warn_on = !!(condition); \
- unlikely(__ret_warn_on); \
- })
- ioread8(addr)意思就是
- if addr>=256K then readb(addr)
- else if addr >64K then inb(addr - 64K)
- else 打印错误
- 继续追踪 inb 和 readb
- =====================================
- include/asm-generic/io.h
- -------------------------------------
- #define readb __raw_readb
- static inline u8 __raw_readb(const volatile void __iomem *addr)
- {
- return *(const volatile u8 __force *) addr;
- }
- #define writeb __raw_writeb
- static inline void __raw_writeb(u8 b, volatile void __iomem *addr)
- {
- *(volatile u8 __force *) addr = b;
- }
- -------------------------------------
- static inline u8 inb(unsigned long addr)
- {
- return readb((volatile void __iomem *) addr);
- }
- static inline void outb(u8 b, unsigned long addr)
- {
- writeb(b, (volatile void __iomem *) addr);
- }
- arch/x86/boot.c
- -------------------------------------
- static inline u8 inb(u16 port)
- {
- u8 v;
- asm volatile("inb %1,%0" : "=a" (v) : "dN" (port));
- return v;
- }
- static inline void outb(u8 v, u16 port)
- {
- asm volatile("outb %0,%1" : : "a" (v), "dN" (port));
- }
不过应该确认的是,端口和申请的resource地址无关,resource只是用来记录申请的端口
io端口的更多相关文章
- io端口与io内存详解
(一)地址的概念 1)物理地址:CPU地址总线传来的地址,由硬件电路控制其具体含义.物理地址中很大一部分是留给内存条中的内存的,但也常被映射到其他存储器上(如显存.BIOS等).在程序指令中的虚拟地址 ...
- IO端口、IO内存、IO空间、内存空间的含义和联系
1,IO空间:X86一个特有的空间,与内存空间独立的空间,同样利用IO空间可以操作数据,只不过是利用对应的IO端口操作函数,例如inb(), inbw(), inl(); outb(), outw() ...
- IO端口和IO内存的区别及分别使用的函数接口
每个外设都是通过读写其寄存器来控制的.外设寄存器也称为I/O端口,通常包括:控制寄存器.状态寄存器和数据寄存器三大类.根据访问外设寄存器的不同方式,可以把CPU分成两大类.一类CPU(如M68K,Po ...
- IO端口和IO内存
为什么会有IO端口和IO内存 这主要原因是因为处理器的架构不同,这里我们使用arm来代表典型的使用IO内存架构,intel 80x86代表典型的使用IO端口架构.简单来说arm把所有寄存器(包括外部设 ...
- 驱动笔记 - IO端口和IO内存
访问IO端口 (#include <asm/io.h>) 设备资源struct resource{ resource_size_t start; //资源起始物理地址 resource_s ...
- IO端口和IO内存的区别 转
目录(?)[-] Linux系统对IO端口和IO内存的管理 一.I/O端口 二.IO内存 三.IO端口和IO内存的区分及联系 四.外设IO端口物理地址的编址方式 统一编址 独立编址 优缺点 五.L ...
- X86 IO端口和MMIO
X86 IO端口和MMIO I/O作为CPU和外设交流的一个渠道,主要分为两种,一种是Port I/O,一种是MMIO(Memory mapping I/O).前者就是我们常说的I/O端口,它实际上的 ...
- linux中的 IO端口映射和IO内存映射
参考自:http://blog.csdn.net/zyhorse2010/article/details/6590488 CPU地址空间 (一)地址的概念 1)物理地址:CPU地址总线传来的地址,由硬 ...
- Linux系统对IO端口和IO内存的管理
引用:http://blog.csdn.net/ce123_zhouwei/article/details/7204458 一.I/O端口 端口(port)是接口电路中能被CPU直接访问的寄存器的地址 ...
随机推荐
- IOS 获取网络图像尺寸 更改 图像色彩值 什么一套方法灰色
直接在代码 头文件 // 图片处理 0 半灰色 1 灰度 2 深棕色 3 反色 +(UIImage*)imageWithImage:(UIImage*)image grayLevelType:(UII ...
- 隐式意图-activity
Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW);//设置动作 intent.setData(Uri.parse(& ...
- mysql入门记录
mysql -h localhost(or ID) -u root -p show databases; create database <数据库名>: drop database < ...
- 数据交换工具Kettle
网上搜集了一些关于开源数据交换工具Kattle的文章,特收藏例如以下: 文章一:ETL和Kettle简单介绍 ETL即数据抽取(Extract).转换(Transform).装载(Load)的过程.它 ...
- SharePoint 2013 "通知我"简单的功能
简单的功能 "通知我"内部列表或文档库中的主要项目.加入/删除/修改等操作,用户的E- mail通知设定功能:设置列表或文档库通知的能力,有可能设置通知为一个单一的项目.这是Sha ...
- CentOS6.4 安装 Oracle11g
1.硬件要求检查: 1.1 内存要求: 内存大于1G(使用虚拟机安装时内存要稍微大一些,否则安装检查不通过) #cat /proc/meminfo //查看内存大小 1.2 交换分区要求: 交换分区是 ...
- 1.0.1-学习Opencv与MFC混合编程之---播放AVI视频
资源源代码:http://download.csdn.net/detail/nuptboyzhb/3961639 版本1.0.1新增内容 Ø 新建菜单项,Learning OpenCV——> ...
- javascript 回调函数应用
回调函数是什么在学习之前还真不知道js回调函数怎么使用及作用了,下面本文章把我在学习回调函数例子给各位同学介绍一下吧,有需了解的同学不防进入参考. 回调函数原理: 我现在出发,到了通知你”这是一个异步 ...
- TCP/IP笔记 一.综述
1. TCP/IP分层 TCP/IP 是四层的体系结构:应用层.运输层.网际层和网络接口层,如下图: OSI协议是国际标准的网络协议,但是由于OSI的实用性等问题造成OSI没有流行起来.目前国际上广泛 ...
- web端、android端的文件上传
1.web端的文件上传. 这里是利用了第三方的jar包.这里所需要的jar包我已经上传到本博客的资源里了,以下是连接 http://download.csdn.net/detail/caihongsh ...