LDD3学习笔记(12):与硬件通讯

本文深入探讨了Linux内核中的内存屏障指令及其作用,以及如何进行有效的I/O端口读写操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<linux/kernel.h>

voidbarrier(void)

这个"软件"内存屏蔽要求编译器对待所有内存是跨这个指令而非易失的.

#include<asm/system.h>

voidrmb(void);

voidread_barrier_depends(void);

voidwmb(void);

voidmb(void);

硬件内存屏障.它们请求CPU(和编译器)来检查所有的跨这个指令的内存读,,或都有.

#include<asm/io.h>

unsignedinb(unsignedport);

voidoutb(unsignedcharbyte,unsignedport);

unsignedinw(unsignedport);

voidoutw(unsignedshortword,unsignedport);

unsignedinl(unsignedport);

voidoutl(unsigneddoubleword,unsignedport);

用来读和写I/O端口的函数.它们还可以被用户空间程序调用,如果它们有正当的权限来存

取端口.

unsignedinb_p(unsignedport);

如果在一次I/O操作后需要一个小延时,你可以使用在前一项中介绍的这些函数的6个暂停

对应部分;这些暂停函数有以_p结尾的名子.

voidinsb(unsignedport,void*addr,unsignedlongcount);

voidoutsb(unsignedport,void*addr,unsignedlongcount);

voidinsw(unsignedport,void*addr,unsignedlongcount);

voidoutsw(unsignedport,void*addr,unsignedlongcount);

voidinsl(unsignedport,void*addr,unsignedlongcount);

voidoutsl(unsignedport,void*addr,unsignedlongcount);

这些"字串函数"被优化为传送数据从一个输入端口到一个内存区,或者其他的方式.这些传送通过读或写到同一端口count次来完成.

#include<linux/ioport.h>

structresource*request_region(unsignedlongstart,unsignedlonglen,char*name);

voidrelease_region(unsignedlongstart,unsignedlonglen);

intcheck_region(unsignedlongstart,unsignedlonglen);

I/O端口的资源分配器.这个检查函数成功返回0并且在错误时小于0.

structresource*request_mem_region(unsignedlongstart,unsignedlonglen,char*name);

voidrelease_mem_region(unsignedlongstart,unsignedlonglen);

intcheck_mem_region(unsignedlongstart,unsignedlonglen);

为内存区处理资源分配的函数

#include<asm/io.h>

void*ioremap(unsignedlongphys_addr,unsignedlongsize);

void*ioremap_nocache(unsignedlongphys_addr,unsignedlongsize);

voidiounmap(void*virt_addr);

ioremap重映射一个物理地址范围到处理器的虚拟地址空间,使它对内核可用.iounmap释放

映射当不再需要它时.

#include<asm/io.h>

unsignedintioread8(void*addr);

unsignedintioread16(void*addr);

unsignedintioread32(void*addr);

voidiowrite8(u8value,void*addr);

voidiowrite16(u16value,void*addr);

voidiowrite32(u32value,void*addr);

用来使用I/O内存的存取者函数.

voidioread8_rep(void*addr,void*buf,unsignedlongcount);

voidioread16_rep(void*addr,void*buf,unsignedlongcount);

voidioread32_rep(void*addr,void*buf,unsignedlongcount);

voidiowrite8_rep(void*addr,constvoid*buf,unsignedlongcount);

voidiowrite16_rep(void*addr,constvoid*buf,unsignedlongcount);

voidiowrite32_rep(void*addr,constvoid*buf,unsignedlongcount);

I/O内存原语的"重复"版本.

unsignedreadb(address);

unsignedreadw(address);

unsignedreadl(address);

voidwriteb(unsignedvalue,address);

voidwritew(unsignedvalue,address);

voidwritel(unsignedvalue,address);

memset_io(address,value,count);

memcpy_fromio(dest,source,nbytes);

memcpy_toio(dest,source,nbytes);

旧的,类型不安全的存取I/O内存的函数.

void*ioport_map(unsignedlongport,unsignedintcount);

voidioport_unmap(void*addr);

一个想对待I/O端口如同它们是I/O内存的驱动作者,可以传递它们的端口给ioport_map.

这个映射应当在不需要的时候恢复(使用ioport_unmap)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值