x86 IO port分配

本文详细介绍了 Red Hat 5 操作系统中 IO 设备的独立编址配置,包括 DMA、定时器、键盘、RTC、DMA 页面寄存器等设备的地址范围。

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

Redhat 5 /proc/ioports 独立编址的IO
0000-001f : dma1
0020-0021 : pic1
0040-0043 : timer0
0050-0053 : timer1
0060-0060 : keyboard
0064-0064 : keyboard
0070-0077 : rtc
0080-008f : dma page reg
00a0-00a1 : pic2
00c0-00df : dma2
00f0-00ff : fpu
0170-0177 : ide1
02f8-02ff : serial
0376-0376 : ide1
0378-037a : parport0
03c0-03df : vga+
03f2-03f5 : floppy
03f7-03f7 : floppy DIR
03f8-03ff : serial
1000-103f : 0000:00:07.3
1000-103f : motherboard
1000-1003 : ACPI PM1a_EVT_BLK
1004-1005 : ACPI PM1a_CNT_BLK
1008-100b : ACPI PM_TMR
100c-100f : ACPI GPE0_BLK
1010-1015 : ACPI CPU throttle
1040-104f : 0000:00:07.3
1040-104f : motherboard
1060-107f : pnp 00:0d
1080-10bf : 0000:00:07.7
10c0-10cf : 0000:00:07.1
10c0-10c7 : ide0
10c8-10cf : ide1
10d0-10df : 0000:00:0f.0
1400-14ff : 0000:00:10.0
2000-3fff : PCI Bus #02
2000-207f : 0000:02:00.0
2000-201f : pcnet32_probe_pci
4000-4fff : PCI Bus #03
5000-5fff : PCI Bus #0b
6000-6fff : PCI Bus #13
7000-7fff : PCI Bus #1b
8000-8fff : PCI Bus #04
9000-9fff : PCI Bus #0c
a000-afff : PCI Bus #14
b000-bfff : PCI Bus #1c
c000-cfff : PCI Bus #05
d000-dfff : PCI Bus #0d
e000-efff : PCI Bus #15
f000-ffff : PCI Bus #1d
<think>嗯,用户想了解在UEFI环境下读取I/O端口的方法。这个问题很专业啊,用户应该是做固件开发或系统底层编程的工程师。 从用户的问题来看,ta需要的是具体的技术实现方案。我注意到用户引用了几个UEFI相关的技术文档,特别是关于EFI_SERIAL_IO_PROTOCOL和PCI配置空间访问的内容,说明用户对UEFI环境有一定了解基础。 让我整理下UEFI下I/O访问的几种主要方式: 第一种是直接使用IoLib库函数,这是最基础的方法。UEFI的MdePkg提供了IoRead/Write系列函数,可以直接操作I/O端口。比如用IoRead8()读取8位端口这种简单直接的方式。 第二种是通过PCI协议访问。当需要访问PCI设备的配置空间时,EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL会更规范和安全。用户引用的PCI配置空间访问文档[^2]就提到了0xCF8/0xCFC这两个标准端口。 第三种是特定设备的专用协议,比如用户提到的串口[^1]和键盘[^3]的例子。不过这些是针对特定设备的,不如前两种方法通用。 用户还提到读取CMOS的例子[^4],那个其实也是用IoLib实现的。看来IoLib是最常用的方案。 考虑到用户可能需要实际操作,我得提醒几个重要注意事项: 首先是权限问题,DXE阶段后I/O访问会被限制,需要申请权限。其次是轮询模式下的时序处理,UEFI没有中断机制,这点很关键。最后是不同架构的区别,x86和ARM的I/O映射方式不同。 用户可能还想知道如何写入端口,其实和读取是对应的,用IoWrite系列函数即可。不过要特别注意安全性和稳定性,错误的I/O操作可能导致系统崩溃。 对了,用户没提具体要访问什么设备,如果是标准设备,最好查查UEFI规范看是否有现成的协议可用。直接操作I/O应该是最后的选择。</think>在UEFI环境下读取I/O端口,主要通过**UEFI提供的标准库函数**实现,核心是`MdePkg`中的**IoLib库**。以下是具体方法和注意事项: --- ### 一、使用`IoLib`库直接读取I/O端口 UEFI的`MdePkg.dec`提供了`IoLib.h`头文件,包含以下关键函数: ```c #include <Library/IoLib.h> UINT8 IoRead8 (UINTN Port); // 读取8位端口 UINT16 IoRead16 (UINTN Port); // 读取16位端口 UINT32 IoRead32 (UINTN Port); // 读取32位端口 UINT64 IoRead64 (UINTN Port); // 读取64位端口 ``` **示例:读取CMOS时间(端口0x70/0x71)** ```c UINT8 GetCmosTime(UINT8 Offset) { IoWrite8(0x70, Offset); // 向0x70端口写入寄存器偏移量 return IoRead8(0x71); // 从0x71端口读取数据 } ``` --- ### 二、通过PCI协议访问配置空间 对于PCI设备配置空间(如端口`0xCF8/0xCFC`),需使用**PCI Root Bridge I/O Protocol**: ```c EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootIo; // 1. 定位协议(通常在DXE阶段可用) gBS->LocateProtocol(&gEfiPciRootBridgeIoProtocolGuid, NULL, (VOID**)&PciRootIo); // 2. 读取PCI配置空间 UINT32 PciValue; PciRootIo->Pci.Read( PciRootIo, // 协议实例 EfiPciWidthUint32, // 读取32位 PCI_LIB_ADDRESS(Bus, Dev, Func, RegOffset), // PCI地址 1, // 数据数量 &PciValue // 输出结果 ); ``` > **注**:PCI地址计算宏`PCI_LIB_ADDRESS`定义在`IndustryStandard/Pci.h`中[^2]。 --- ### 三、关键注意事项 1. **权限与阶段限制** - I/O操作仅在**DXE阶段及之后**可用(PEI阶段需通过PPI)。 - 某些平台可能限制对敏感端口(如`0x70/0x71`)的访问。 2. **轮询模式要求** - UEFI驱动为**轮询模式**,读取高速设备时需频繁检查数据,避免丢失[^1]。 3. **硬件差异** - x86架构直接支持`IN/OUT`指令,ARM需通过MMIO映射。 4. **替代方案** - 若设备有专用协议(如串口使用`EFI_SERIAL_IO_PROTOCOL`[^1]),应优先使用协议接口而非直接I/O。 --- ### 四、完整示例(读取键盘控制器状态) ```c #include <Uefi.h> #include <Library/IoLib.h> #include <Library/UefiLib.h> EFI_STATUS ReadKeyboardStatus() { UINT8 status = IoRead8(0x64); // 读取键盘控制器状态端口 Print(L"Keyboard Status: 0x%02x\n", status); return EFI_SUCCESS; } ``` --- ### 相关问题 1. UEFI中如何安全地写入I/O端口? 2. 在ARM架构的UEFI固件上访问I/O端口有何不同? 3. 如何通过UEFI协议获取PCI设备的I/O资源范围? 4. 为什么直接操作I/O端口在UEFI应用中需谨慎? [^1]: EFI_SERIAL_IO_PROTOCOL 要求轮询模式操作,避免数据丢失。 [^2]: PCI配置空间访问需注意端口地址计算(0xCF8/0xCFC)。 [^3]: 专用设备(如USB键盘)建议使用协议接口而非直接I/O。 [^4]: CMOS访问示例展示基础I/O操作,但需注意平台限制。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值