linux内核 端口,Linux内核中IO端口资源管理
读写I/O内存资源
由于在某些平台上,对I/O内存和系统内存有不同的访问处理,因此为了确保跨平台的兼容性,Linux实现了一系列读写I/O内存资源的函数,这些函数在不同的平台上有不同的实现。但在x86平台上,读写I/O内存与读写RAM无任何差别。如下所示(include/asm-i386/io.h):
#define readb(addr) (*(volatile unsigned char *) __io_virt(addr�
#define readw(addr) (*(volatile unsigned short *) __io_virt(addr�
#define readl(addr) (*(volatile unsigned int *) __io_virt(addr�
#define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b�
#define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b�
#define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b�
#define memset_io(a,b,c)memset(__io_virt(a),(b),(c�
#define memcpy_fromio(a,b,c) memcpy
#define memcpy_toio(a,b,c)memcpy(__io_virt(a),(b),(c�
上述定义中的宏__io_virt()仅仅检查虚地址addr是否是核心空间中的虚地址。具体的实现函数在arch/i386/lib/iodebug.c文件。
显然,在x86平台上访问I/O内存资源与访问系统主存RAM是无差别的。但是为了保证驱动程序的跨平台的可移植性,我们应该使用上面的函数来访问I/O内存资源,而不应该通过指向核心虚地址的指针来访问。
大多数平台都区分8位、16位和32位宽度的I/O端口的。Linux在include/asm/io.h头文件(对于i386平台就是include/asm-i386/io.h)中定义了一系列读写不同宽度I/O端口的宏函数。如下所示:
(1)读写8位宽的I/O端口
unsigned char inb(unsigned port);
void outb(unsigned char value,unsigned port);
其中,port参数指定I/O端口空间中的端口地址。在大多数平台上(如x86)它都是unsigned short类型的,其它的一些平台上则是unsigned int类型的。显然,端口地址的类型是由I/O端口空间的大小来决定的。
(2)读写16位宽的I/O端口
unsigned short inw(unsigned port);
void outw(unsigned short value,unsigned port);
(3)读写32位宽的I/O端口
unsigned int inl(unsigned port);
void outl(unsigned int value,unsigned port);
Linux同样在io.h文件中定义了字符串I/O读写函数:
(1)8位宽的字符串I/O操作
void insb(unsigned port,void * addr,unsigned long count);
void outsb(unsigned port ,void * addr,unsigned long count);
(2)16位宽的字符串I/O操作
void insw(unsigned port,void * addr,unsigned long count);
void outsw(unsigned port ,void * addr,unsigned long count);
(3)32位宽的字符串I/O操作
void insl(unsigned port,void * addr,unsigned long count);
void outsl(unsigned port ,void * addr,unsigned long count);
在一些平台上(典型地如X86),对于慢速外设来说,如果CPU读写其I/O端口的速度太快,可能会发生丢失数据。这就要在两次连续的I/O操作之间插入时延。Linux在io.h头文件中定义了带延迟的I/O读写函数,以XXX_p命名,如:inb_p()、outb_p()等。下面以out_p()为例进行分析。
将io.h中的宏定义__OUT(b,"b"char)展开后可得如下定义:
extern inline void outb(unsigned char value, unsigned short port) {
__asm__ __volatile__ ("outb %" "b " "0,%" "w" "1"
: : "a" (value), "Nd" (port));
}
extern inline void outb_p(unsigned char value, unsigned short port) {
__asm__ __volatile__ ("outb %" "b " "0,%" "w" "1"
__FULL_SLOW_DOWN_IO
: : "a" (value), "Nd" (port));
}
可以看出,outb_p()函数的实现中被插入了宏__FULL_SLOWN_DOWN_IO,以实现微小的延时。宏__FULL_SLOWN_DOWN_IO在头文件io.h中一开始就被定义:
#ifdef SLOW_IO_BY_JUMPING
#define __SLOW_DOWN_IO "
jmp 1f
1:jmp 1f
1:"
#else
#define __SLOW_DOWN_IO "
outb %%al,$0x80"
#endif
#ifdef REALLY_SLOW_IO
#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO
__SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO
#else
#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO
#endif
显然,__FULL_SLOW_DOWN_IO就是一个或四个__SLOW_DOWN_IO(根据是否定义了宏REALLY_SLOW_IO来决定),而宏__SLOW_DOWN_IO则被定义成毫无意义的跳转语句或写端口0x80的操作(根据是否定义了宏SLOW_IO_BY_JUMPING来决定)。
linux内核 端口,Linux内核中IO端口资源管理相关推荐
- gulp修改服务器端口,在gulp-nodemon中设置端口有什么用处?
我使用gulp-nodemon,因为它最明显的实用程序.在gulp-nodemon中设置端口有什么用处? Nodemon是一个实用程序,它将监视源中的所有更改 并自动重新启动服务器. 但是我不理解一种 ...
- cmd查看某个服务器端口状态,cmd中检测端口是否处于监听状态 | IT博客
1.查看本地端口监听状态命令:netstat -an Local Address:本地地址 Foreign Address :外地的地址 State:LISTENING该端口在监听外部连接,estab ...
- CC2530学习笔记(2)—— IO端口基本操作实验(按键控制亮灯)
CC2530学习笔记(2)-- IO端口基本操作(按键控制亮灯) 关于CC2530的IO端口基本知识.IO端口有关寄存器的介绍和描述请参照:CC2530学习笔记(1)-- IO端口 电路原理图如图1 ...
- Linux内核网络协议栈7-socket端口管理
一.前情回顾 上一节<socket 地址绑定 >中提到,应用程序传递过来的端口在内核中需要检查端口是否可用: if (sk->sk_prot->get_port(sk, snu ...
- 【linux开发】IO端口和IO内存的区别及分别使用的函数接口
IO端口和IO内存的区别及分别使用的函数接口 每个外设都是通过读写其寄存器来控制的.外设寄存器也称为I/O端口,通常包括:控制寄存器.状态寄存器和数据寄存器三大类.根据访问外设寄存器的不同方式,可以把 ...
- Linux系统IO端口,Linux系统对IO端口和IO内存的管理
五.Linux下访问IO端口 对于某一既定的系统,它要么是独立编址.要么是统一编址,具体采用哪一种则取决于CPU的体系结构. 如,PowerPC.m68k等采用统一编址,而X86等则采用独立编址,存在 ...
- linux mips 时钟中断,Linux内核中地时钟中断.pdf
Linux内核中地时钟中断 Linux 内核中的时钟中断 第七章 Linux 内核的时钟中断 (By 詹荣开,NUDT) Copyright © 2003 by 詹荣开 E-mail:zhanrk@ ...
- Linux中不同进程同一个端口,linux系统实现多个进程监听同一个端口
通过 fork 创建子进程的方式可以实现父子进程监听相同的端口. 方法:在绑定端口号(bind函数)之后,监听端口号之前(listen函数),用fork()函数生成子进程,这样子进程就可以克隆父进程, ...
- linux 内核 虚拟地址,linux内核中的虚拟到物理地址转换
以下用于将Linux内核中的虚拟地址转换为物理地址.但是这是什么意思? 我对装配知识非常有限 163 #define __pv_stub(from,to,instr,type) 164 __asm__ ...
最新文章
- 一致 先验分布 后验分布_浅谈Loki分布式架构中的一致性哈希
- 获取子页面iframe的点击事件及iframe跨域的交互
- How can I generate database tables from C# classes?
- BufferFsStream
- 洛谷 P1136 迎接仪式 解题报告
- [PAT乙级]1036 跟奥巴马一起编程
- 来了!汇总数据库行业最新招聘、热门资讯、精选文章...
- laravel application 容器app
- java 图形化技术 哪个好_纳滤和反渗透技术哪个好?
- specification java_Java Specification类代码示例
- vue m3u8格式 实现监控直播
- 联想一体机计算机桌面不显示,联想一体机关闭屏幕_联想一体机怎么关屏幕
- 漫步微积分二十九——微积分基本定理
- 计算机基础1模拟题,计算机基础模拟题1(有答案)
- 宁波银行金融科技面试
- AAAI2021:面向交通流预测的时空融合图神经网络
- D35 876. Middle of the Linked List
- 第六次:收集分析40个游戏广告(宣传图、落地页等)
- DEBUG 使用RELEASE文件的 DLL
- 哈佛凌晨4点半【收藏】
热门文章
- 使用U盘引导安装CentOS操作系统
- bug in MicrosoftAjax.debug.js
- 滤镜应用——拼图效果
- 用java完成一个模块_Java 9 揭秘(3. 创建你的第一个模块)
- fluent 命令流_FLUENT混合流体中颗粒运动模拟
- mysql更新索引不影响业务_mysql 索引是否能提高UPDATE,DELETE,INSERT 处理速度
- python2.7安装教程win7_win7 64位环境下,为python2.7 安装pip
- php sql 长字符串 查找被包含的短字符串_PHP字符串
- 人工智能导论 王万良教授_FCES2019 panel4:人工智能的第一堂课究竟讲什么?
- wrong elf class: elfclass32_薇娅倾情推荐亿健ELF跑步机,价格优惠大还为粉丝争取福利! - 消费...