最新Linux设备驱动程序

合集下载

LINUX设备驱动程序(4)

LINUX设备驱动程序(4)

协议简介
对于网络的正式介绍一般都采用 OSI (Open Systems Interconnection)模型, 但是Linux 中网络栈的介绍一般分为四层的 Internet 模型。
协议栈层次对比
OSI七层网络模型 应用层 表示层 会话层 传输层 网络层
数据链路层 物理层
Linux TCP/IP 四层概念模型
网络协议
网络协议层用于实现各种具体的网络协议, 如: TCP、UDP 等。
设备无关接口
设备无关接口将协议与各种网络设备驱动连接在一起。 这一层提供一组通用函数供底层网络设备驱动程序使用,让 它们可以对高层协议栈进行操作。
首先,设备驱动程序可能会通过调用 register_netdevice 或 unregister_netdevice 在内核中 进行注册或注销。调用者首先填写 net_device 结构,然后 传递这个结构进行注册。内核调用它的 init 函数(如果定义 了这种函数),然后执行一组健全性检查,并将新设备添加 到设备列表中(内核中的活动设备链表)。
驱动程序
网络栈底部是负责 管理物理网络设备 的设备驱动程序。
第二节 网卡驱动程序设计
设备注册
设备描述:
每个网络接口都由一个 net_device结构来描述
注册: 网络接口驱动的注册方式与字符驱动不同之处在于 它没有主次设备号,并使用如下函数注册。
int register_netdev(struct net_device *dev)
Linux网络子系统架构
Linux协议架构
Linux 网络子系统的顶部是系统调用接口。它为用 户空间的应用程序提供了一种访问内核网络子系统 的方法。位于其下面的是一个协议无关层,它提供 了一种通用方法来使用传输层协议。然后是具体协 议的实现,在 Linux 中包括内嵌的协议 TCP、 UDP,当然还有 IP。然后是设备无关层,它提供了 协议与设备驱动通信的通用接口,最下面是设备驱 动程序。

Linux设备驱动程序原理及框架-内核模块入门篇

Linux设备驱动程序原理及框架-内核模块入门篇

Linux设备驱动程序原理及框架-内核模块入门篇内核模块介绍应用层加载模块操作过程内核如何支持可安装模块内核提供的接口及作用模块实例内核模块内核模块介绍Linux采用的是整体式的内核结构,这种结构采用的是整体式的内核结构,采用的是整体式的内核结构的内核一般不能动态的增加新的功能。

为此,的内核一般不能动态的增加新的功能。

为此,Linux提供了一种全新的机制,叫(可安装) 提供了一种全新的机制,可安装) 提供了一种全新的机制模块” )。

利用这个机制“模块”(module)。

利用这个机制,可以)。

利用这个机制,根据需要,根据需要,在不必对内核重新编译链接的条件将可安装模块动态的插入运行中的内核,下,将可安装模块动态的插入运行中的内核,成为内核的一个有机组成部分;成为内核的一个有机组成部分;或者从内核移走已经安装的模块。

正是这种机制,走已经安装的模块。

正是这种机制,使得内核的内存映像保持最小,的内存映像保持最小,但却具有很大的灵活性和可扩充性。

和可扩充性。

内核模块内核模块介绍可安装模块是可以在系统运行时动态地安装和卸载的内核软件。

严格来说,卸载的内核软件。

严格来说,这种软件的作用并不限于设备驱动,并不限于设备驱动,例如有些文件系统就是以可安装模块的形式实现的。

但是,另一方面,可安装模块的形式实现的。

但是,另一方面,它主要用来实现设备驱动程序或者与设备驱动密切相关的部分(如文件系统等)。

密切相关的部分(如文件系统等)。

课程内容内核模块介绍应用层加载模块操作过程内核如何支持可安装模块内核提供的接口及作用模块实例内核模块应用层加载模块操作过程内核引导的过程中,会识别出所有已经安装的硬件设备,内核引导的过程中,会识别出所有已经安装的硬件设备,并且创建好该系统中的硬件设备的列表树:文件系统。

且创建好该系统中的硬件设备的列表树:/sys 文件系统。

(udev 服务就是通过读取该文件系统内容来创建必要的设备文件的。

)。

linux设备驱动之8250串口驱动

linux设备驱动之8250串口驱动

linux设备驱动之8250串口驱动一:前言前一段时间自己实践了一下8250芯片串口驱动的编写。

今天就在此基础上分析一下linux kernel自带的串口驱动。

毕竟只有对比专业的驱动代码才能更好的进步,同以往一样,基于linix kernel2.6.25.相应驱动代码位于:linux-2.6.25/drivers/serial/8250.c。

二:8250串口驱动初始化相应的初始化函数为serial8250_init().代码如下:static int __init serial8250_init(void){int ret, i;if (nr_uarts > UART_NR)nr_uarts = UART_NR;printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ ""%d ports, IRQ sharing %sabled\n", nr_uarts,share_irqs ? "en" : "dis");for (i = 0; i < NR_IRQS; i++)spin_lock_init(&irq_lists[i].lock);ret = uart_register_driver(&serial8250_reg);if (ret)goto out;serial8250_isa_devs = platform_device_alloc("serial8250",PLA T8250_DEV_LEGACY);if (!serial8250_isa_devs) {ret = -ENOMEM;goto unreg_uart_drv;}ret = platform_device_add(serial8250_isa_devs);if (ret)goto put_dev;serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);ret = platform_driver_register(&serial8250_isa_driver);if (ret == 0)goto out;platform_device_del(serial8250_isa_devs);put_dev:platform_device_put(serial8250_isa_devs);unreg_uart_drv:uart_unregister_driver(&serial8250_reg);out:return ret;}这段代码涉及到的知识要求,如platform ,uart等我们在之前都已经做过详细的分析。

如何在Linux系统中安装驱动程序

如何在Linux系统中安装驱动程序

如何在Linux系统中安装驱动程序Linux系统作为一个开源的操作系统,广泛应用于各种设备和领域。

而安装驱动程序是在Linux系统中使用外部硬件设备的关键步骤之一。

在本文中,我们将学习如何在Linux系统中安装驱动程序的方法和步骤。

1. 检查硬件设备在安装驱动程序之前,首先需要确定硬件设备的型号和制造商。

可以通过查询设备的型号或者查看设备的相关文档来获取这些信息。

这是非常重要的,因为不同的设备可能需要不同的驱动程序来正确地工作。

2. 更新系统在安装驱动程序之前,确保你的Linux系统已经是最新的状态。

可以通过在终端中运行以下命令来更新系统:```sudo apt-get updatesudo apt-get upgrade```更新系统可以确保你拥有最新的软件包和驱动程序,以获得更好的兼容性和性能。

3. 查找合适的驱动程序一般来说,大部分硬件设备的驱动程序都可以在Linux系统的软件仓库中找到。

可以通过使用包管理器(如apt、yum等)来查找并安装合适的驱动程序。

运行以下命令来搜索并安装特定的驱动程序:```sudo apt-cache search 驱动程序名称sudo apt-get install 驱动程序名称```注意替换“驱动程序名称”为具体的驱动程序名称。

安装驱动程序可能需要输入管理员密码和确认安装。

如果你无法在软件仓库中找到合适的驱动程序,可以转向设备的制造商网站或者开源社区来获取。

下载驱动程序后,根据驱动程序提供的文档和说明来安装。

4. 编译和安装驱动程序有些驱动程序可能需要手动编译和安装。

在这种情况下,你需要确保你的系统已经安装了编译工具(如GCC、make等)。

在终端中切换到驱动程序所在的目录,并按照以下步骤进行编译和安装:```./configuremakesudo make install```以上命令将分别进行配置、编译和安装驱动程序。

在进行安装之前,可能需要输入一些配置选项或者确认安装。

一、如何编写LinuxPCI驱动程序

一、如何编写LinuxPCI驱动程序

⼀、如何编写LinuxPCI驱动程序PCI的世界是⼴阔的,充满了(⼤部分令⼈不快的)惊喜。

由于每个CPU体系结构实现不同的芯⽚集,并且PCI设备有不同的需求(“特性”),因此Linux内核中的PCI⽀持并不像⼈们希望的那么简单。

这篇简短的⽂章介绍⽤于PCI设备驱动程序的Linux APIs。

1.1 PCI驱动程序结构PCI驱动程序通过pci_register_driver()在系统中"发现"PCI设备。

事实上,恰恰相反。

当PCI通⽤代码发现⼀个新设备时,具有匹配“描述”的驱动程序将被通知。

详情如下。

pci_register_driver()将设备的⼤部分探测留给PCI层,并⽀持在线插⼊/删除设备[因此在单个驱动程序中⽀持热插拔PCI、CardBus和Express-Card]。

pci_register_driver()调⽤需要传⼊⼀个函数指针表,从⽽指⽰驱动程序的更⾼⼀级结构体。

⼀旦驱动程序知道了⼀个PCI设备并获得了所有权,驱动程序通常需要执⾏以下初始化:启⽤设备请求MMIO / IOP资源设置DMA掩码⼤⼩(⽤于⼀致性DMA和流式DMA)分配和初始化共享控制数据(pci_allocate_coherent())访问设备配置空间(如果需要)注册IRQ处理程序(request_irq())初始化non-PCI(即LAN/SCSI/等芯⽚部分)启⽤DMA /处理引擎当使⽤设备完成时,可能需要卸载模块,驱动程序需要采取以下步骤:禁⽌设备产⽣irq释放IRQ (free_irq())停⽌所有DMA活动释放DMA缓冲区(包括流式DMA和⼀致性DMA)从其他⼦系统注销(例如scsi或netdev)释放MMIO / IOP资源禁⽤该设备下⾯⼏节将介绍这些主题中的⼤部分。

其余部分请查看LDD3或<linux/pci.h>。

如果PCI⼦系统没有配置(没有设置CONFIG_PCI),下⾯描述的⼤多数PCI函数都被定义为内联函数,要么完全空,要么只是返回⼀个适当的错误代码,以避免在驱动程序中出现⼤量ifdefs。

Linux下PCI设备驱动开发详解

Linux下PCI设备驱动开发详解

一、设备驱动程序概述自Linux在中国发展以来,得到了许多公司的青睐。

在国内的玩家也越来越多了,但目前还是停留在玩的水平上,很少有玩家对Linux的系统进行研究。

因为它的开放,我们可以随时拿来“把玩”。

这也是Linux一个无可比拟的优势,这样我们可以修改后再加入到里面。

但很少有专门的书籍讲到Linux驱动程序的开发,像上海这样的大城市也很少有讲Linux驱动开发的资料,唉,谁让这个是人家的东西呢,我们还是得跟着人家跑。

我现在讲的这些驱动开发的细节,并不特定哪个版本的内核,这只是大体的思路与步骤。

因为大家都知道Linux 2.6.x 与Linux 2.4.x是有不少改动的。

所以,具体的大家可以去参考Linux Device Driver 2.4 和Linux Device Driver 2.6这几本书。

这是我们学习开发驱动必不可少的东西。

好了,下面就开始学习吧。

根据设备的行为,我们可以把设备分为字符设备和块设备,还有网络设备。

字符设备是以字节为单位进行顺序读写,数据缓冲系统对它们的访问不提供缓存。

而块设备则是允许随机访问与读写,每次读写的数据量都是数据块长度的整数倍,并且访问还会经过缓冲区缓存系统才能实现。

与Unix版本不同的是:Linux的内核允许不是数据块长度整数倍的数据量被读取,用官方的语言就是:但这种不同只是纯粹学术方面的东西。

大多数设备驱动程序都要通过文件系统来进行访问的,但网络设备是不同的。

/dev子目录里都是关于设备的特殊文件,但看起来它们与普通的目录没有什么两样。

如下:$ ls -l /dev...brw-rw--- 1 root disk 22, 1 May 5 1998 hdc1crw-rw--- 1 root daemon 6 0 May 5 1998 lp0与普通文件有所不同是开头的“C” 和“B”,即char 和block的意思,即字符设备和块设备。

再后面的“22,1” 和“6,0”即设备的主设备号和次设备号,主设备号表明它是哪一种设备,这与你在Windows里添加硬件时看到的那些是一个意思。

Linux设备驱动程序加载卸载方法insmod和modprobe命令

Linux设备驱动程序加载卸载方法insmod和modprobe命令

Linux设备驱动程序加载卸载⽅法insmod和modprobe命令linux加载/卸载驱动有两种⽅法。

1.modprobe注:在使⽤这个命令加载模块前先使⽤depmod -a命令⽣成modules.dep⽂件,该⽂件位于/lib/modules/$(uname -r)⽬录下;modprobe命令智能地向内核中加载模块或者从内核中移除模块,可载⼊指定的个别模块,或是载⼊⼀组相依的模块。

modprobe会根据depmod所产⽣的依赖关系,决定要载⼊哪些模块。

若在载⼊过程中出错,modprobe会卸载整组的模块。

载⼊模块的命令:(1) 载⼊指定的模块:modprobe drv.ko(2) 载⼊全部模块:modprobe -a卸载模块的命令:modprobe -r drv.komodprobe命令⽤于智能地向内核中加载模块或者从内核中移除模块。

modprobe可载⼊指定的个别模块,或是载⼊⼀组相依的模块。

modprobe会根据depmod所产⽣的相依关系,决定要载⼊哪些模块。

若在载⼊过程中发⽣错误,在modprobe会卸载整组的模块。

选项-a或--all:载⼊全部的模块;-c或--show-conf:显⽰所有模块的设置信息;-d或--debug:使⽤排错模式;-l或--list:显⽰可⽤的模块;-r或--remove:模块闲置不⽤时,即⾃动卸载模块;-t或--type:指定模块类型;-v或--verbose:执⾏时显⽰详细的信息;-V或--version:显⽰版本信息;-help:显⽰帮助。

参数模块名:要加载或移除的模块名称。

实例查看modules的配置⽂件:modprobe -c这⾥,可以查看modules的配置⽂件,⽐如模块的alias别名是什么等。

会打印许多⾏信息,例如其中的⼀⾏会类似如下:alias symbol:ip_conntrack_unregister_notifier ip_conntrack列出内核中所有已经或者未挂载的所有模块:modprobe -l这⾥,我们能查看到我们所需要的模块,然后根据我们的需要来挂载;其实modprobe -l读取的模块列表就位于/lib/modules/`uname -r`⽬录中;其中uname -r是内核的版本,例如输出结果的其中⼀⾏是:/lib/modules/2.6.18-348.6.1.el5/kernel/net/netfilter/xt_statistic.ko挂载vfat模块:modprobe vfat这⾥,使⽤格式modprobe 模块名来挂载⼀个模块。

基于Linux的USB设备驱动程序实现

基于Linux的USB设备驱动程序实现

!+ 123 设备驱动程序设计
123 设备开发包括硬件电路设计和 软件设计两部分 内容, 其中软件设计部分又包括 123 芯片驱动 程序设计 和应 用程 序设 计; 123 设 备在 硬件 上 通过 123 芯 片实 现。 123 芯片负责管理和实现 123 物理层 差分信 号, 通 过配置和管理寄存器来初始化设 备, 提供连接的端点, 管 理电源和通过寄存器管理端点。 123 芯片提供多个 标准的端 点, 每个端 点都 支持单 一的总线传输方式。 端点 " 支 持控制 传输, 其它 端点支 持同步传输、 批量传输 或者中断 传输中 的一种。 管理和 使用这些端点, 实际上是通过操作相应的控制寄存器、 状 态寄存器、 中断寄存器和数据寄存器来实现的。其中, 控 制寄存器用 于设 置端 点的 工作 模式 和启 用端 点的 功能 等; 状态寄存器用于查询端点的当前状态; 中 断寄存器用 于设置 端点的中 断触发和响 应功能; 数据寄 存器则是设 备与主机交换 用的缓冲区。
收稿日期: !""#$"%$&# 作者简介: 刘 永祥 (&’() * + ) , 男, 湖北钟祥人, 昆明理工大学信自学院 硕士研究生。
!4
Байду номын сангаас
第 \ 卷$
! " # $ 电路设计原理
无 锡 职 业 技 术 学 院 学 报 引脚连接 +,-//20> 外部中断引脚 %>?3@0 , 对应的中断 向量为 0 。初始化 1+2 中 断的步 骤如 下: 初 始化 中断控 制器的 ?3@-93 及 中 断 方式 寄 存器 ?3@79:, 使 %?3@0 中断使能; 安装 1+2 中断程 序入 口到 中断 向量 中; 初始 化 ? A 9 端口 Q 组控制器 <-93Q, <1<Q 指 明 %>?@0 是作 为中断输入引脚 使用; 设置外 部中断 寄存器 %>@?3@, 指 明触发中断方式。 初始化 1+2 需要 使用 1+2 读 A 写 函 数对 1+2 控制 器内部的控制寄存器进行设置, 步骤如下: 设置主控制寄 存器 7-3@RS 的软 件复 位位 ( +R+@) , 以复 位 1+2 控制 器; 设置主控制器 7-3@RS 的 ; 电 压调 整位 ( .Q% ) 及中 断输出 ( ?3@9- ) 位, 以 禁 止 中 断 输 出; 写时钟寄存器 --93T , 设置 1+2 控制 器的 工作 频率; 初 始化 功能 地址 寄存器 ( T;R) , 及 %<-0 寄存器。端点号 0 为双向 端点, 用作控制使用; 设置中断屏蔽寄存器, 包括 主屏蔽寄存器 7;7+=、 无应答事件 寄存器 3;=7+=、 发送时 间寄 存器 @>7+=、 接收事 件寄 存器 R>7+= 和 ;O*(FIM*( 事 件寄存 器 ;S@7+=; 允许 1+2 控制 器中 信 号输 出, 使 控制 器附 加到 1+2 总线上。 1+2 中断服务例程: 中断服务例程 处理 1+2 控制器 产生的中断, 它将数据从 1+2 内部 T?T9 读出, 并建立正 确的事件标志, 以通知主循环程序进行处理, 其基本步骤 如下: 从 主事件 寄存 器 7;%. 中 读出 产生中 断的 事件; 根据 主事件寄存 器某位的状 态判别事 件, 接 着读取相应 的事件寄存器, 接收事件寄存器 R>%., 或发 送事件寄存 器 @>%., 或无 应答 事件 寄存 器 3;=%., 或 ;O*(FIM*( 事 件寄存器 ;S@%.; 进一 步判 别事 件寄 存器 某位 的状 态, 根据具体事件分别作出相应的 操作。 中断初始化, 安装 1+2 中断服务函数: NBCD ?)FG?IC* ( NBCD) { $ F?3@-93 U P 0V# ; $ A A 中断控制寄存器设置 $ F?3@79:W P X 0V# ; A A ?RY 模式 $ ( " ( NBOM*CO( $ ( " ( NBOM*CO( HI)CJI(D HI)CJI(D KLMF KLMF ") ") 引脚 $ F<1<Q P F<1<QW0V[(; $ A A Q<Q9 上拉电阻有 效 $ F%>@?3@ P 0V00 ; $ A A 低电平触发 $ F?3@7+= P F?3@7+= U 2?@G%?3@0 ;A A 关外部中断 } 通道 0 用 于控 制传 输, 在驱 动程 序中 调 用 FV(N(I*0 () 和 *V(N(I*0 () 处理端点 0 的事件, 通道 # 中 由 *V(N(I*# () 处理端点 # ( 单向 发送) 的 事件, 由 FV(N(I*# () 处理端 点! ( 单向接收) 的事件, 通道 ! 中由 *V(N(I*! () 处理端点 $ F(*HFI ( "( NBOM*CO( HI)CJI(D KLMF " ) ( 单向发送) , 的事 件, 由 FV(N(I*! () 处理 端点 / ( 单 向接 收) 的事件。通道 , 中由 *V(N(I*, () 处理 端点 \ 的 事件, 由 FV(N(I*, () 处理端点 5 的事件。 $ Z?+RG%?3@0 P ( CI* ) GG%CI*0?)F; $ F<-93Q P F<-93Q U 0V000, ; $ A A Q<Q0 设 为 中断
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
中断服务程序
LED设备驱动程序的例子
CPU
struct file_operations LED_fops =
{ read:
LED_read,
write: open: release:
LED_write,
程序列表 (1) LED_open,
LED_release,
};
int LED_init_module(void) { SET_MODULE_OWNER(&LED_fops);
module_init(LED_init_module); module_exit(LED_cleanup_module);
程序列表 (2)
int LED_open(struct inode *inode, struct file *filp) { printk("LED_open()\n");
MOD_INC_USE_COUNT; return 0; }
Linux设备驱动程序
内容
• 设备分类 • 设备驱动程序的框架 • 字符型设备 • 网络设备 • 文件系统
– User Space File System
• USB设备 • FrameBuffer例子和使用 • Debug原理和Debug方法 • 常用设备/fb/ram/loopback/zero
字符设备 vs 块设备
字符设备
块设备
• 字符设备发出读/写请 求时,对应的硬件I/O 一般立即发生。
• 数据缓冲可有可无
• 利用一块系统内存作 缓冲区,一般读写由 缓冲区直接提供,尽 量减少IO操作
• 针对磁盘等慢速设备
• ADC/DAC、按钮、LED、 传感器等
可装卸的设备驱动程序和 静态连接到内核的设备驱动程序
int LED_release(struct inode *inode, struct file *filp) { printk(“LED_release()\n“);
MOD_DEC_USE_COUNT; return 0; }
程序列表 (3)
ssize_t LED_read (struct file *filp, char *buf, size_t count, loff_t *f_pos) { int i;
ioperm(BASEPORT, 3, 0)); // give up
exit(0); • ioperm(from,num,turn_on)
}
• 用ioperm申请的操作端口地址在0x000~0x3FF,利用iopl()
可以申请所有的端口地址
• 必须以root运行
• 用 “gcc -02 –o xxx.elf xxx.c” 编译
for (i=0; i<count; i++) *((char*)(buf+i)) = LED_Status;
return count; } ssize_t LED_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos) { int i;
直接访问IO端口(/dev/port)
port_fd = open("/dev/port", O_RDWR); lseek(port_fd, port_addr, SEEK_SET); read(port_fd, …); write(port_fd, …); close(port_fd);
用open/read/write/close 等命令访问
设备 文件
用mknod 命令创建
用户程序
通过主设备号 找到设备驱动
设备驱动程序
用insmod命令安装, 或直接编译到内核中
驱动程序 代码结构
驱动程序注册与注销
设备文件的操作函数 (*open)() (*write)() (*flush)()
(*llseek)() …
#include <asm/io.h>
#define BASEPORT 0x378 // printer
int main()
{
ioperm(BASEPORT, 3, 1)); // get access permission
outb(0, BASEPORT);
usleep(100000);
printf("status: %d\n", inb(BASEPORT + 1));
设备驱动程序内访问设备地址
• 设备驱动程序可以通过指针访问设备地址
• 设备驱动程序接触到的还是虚拟地址,但 对于外界设备有固定的设备地址映射(设 备的地址在移植Linux时候确定)
设备驱动程序
设备驱动程序
虚拟地址映射 设备地址映射
虚拟地址映射 设备地址映射
物理内存地址空间 设备地址空间直接访问IO端口 vs 设备驱动程序
LED_major = register_chrdev(0, "LED", &LED_fops); LED_off(); LED_status=0; return 0; }
void LED_cleanup_module(void) { unregister_chrdev(LED_major, "LED"); }
• 静态连接到内核的设备驱动程序
–修改配置文件、重新编译和安装内核
• 可装卸的设备驱动程序
– insmod 装载
– rmmod
卸载
– lsmod
查询
Linux对硬件设备的抽象
设备文件
• Open/Close/Read/Write • 例子
–/dev/mouse –/dev/lp0
驱动程序与设备文件
IO直接访问 • 用户态 • 程序编写/调试简单 • 查询模式,响应慢 • 设备共享管理困难
设备驱动访问
• 核心态 • 编程调试困难 • 可用中断模式访问、

• 设备共享管理简单 (由内核帮助完成)
设备分类
• 字符设备
–鼠标、串口、游戏杆
• 块设备
–磁盘、打印机
• 网络设备
–由BSD Socket访问
• 注意:不能用fopen/fread/fwrite/fclose因 为它们有数据缓冲,对读写操作不是立即 完成的
outb()/outw()/inb()/inw()函数
#include <stdio.h> #include <unistd.h>
• outb(value, port); inb(port); // 8-bit • outw(value, port); inw(port); // 16-bit • 访问时间大约1us
相关文档
最新文档