x86 - 如何与连接到并行端口的设备通信?

标签 x86 operating-system hardware parallel-port

假设我的计算机上有一个并行端口,现在并行端口将有一些与之关联的内存,CPU 可以访问它(不确定并行端口是使用内存映射 IO 还是端口映射 IO)。

现在,如果我想向并行端口发送信号或从并行端口接收信号,我将不得不写入或读取与并行端口关联的内存。

现在假设我有一台打印机连接到并行端口,打印机也会有一些内存(例如:它可能有一个缓冲区,用于存储它应该打印的数据)。

我的问题是,CPU是否可以直接访问打印机的内存,例如CPU是否可以直接写入打印机的缓冲区?还是与打印机通信的唯一方式是通过并行端口间接进行?

最佳答案

传统的 PC 并行端口使用带in/out 的端口 I/O,而不是 MMIO。外部信号线直接映射到 I/O 寄存器,因此单个 out 指令将设置所有 8 条信号线。您可以连接 LED + 电阻器并尝试一下。 (有趣的项目。)

This page has Linux 、Windows 和 DOS 程序,它们使用 outb 在并行端口的引脚上放置一个字节。里面还有很多关于并口的介绍,其中很重要的一点就是USB并口对外接口(interface)相同,但内部软件接口(interface)不同。 USB parport 不适用于 in/out 指令。


can the CPU access the memory for the printer directly

没有。我想您是在问是否可以运行从 CPU 寄存器一直存储到打印机内存的 x86 指令。如果打印机恰好正在接收突发数据,那么在并行端口的引脚上放置一个字节将导致打印机将该字节复制到内存中。但要进行设置,您需要以打印机理解的任何通信协议(protocol)发送命令。

想象一下 FTP 或 Web 服务器。您可以读取或写入远程文件,但必须先发送命令以开始传输,然后通信链路(网络套接字)才承载正在传输的数据。您是在与远程计算机上的程序对话,而不是直接读取其磁盘内容或 RAM。


作为Wikipedia's nice parallel port article points out , 计算机 -> 打印机的流量控制是通过打印机解除 BUSY 引脚的断言来实现的。然后计算机可以将下一个字节放在数据引脚上,并将带有 out 的 STROBE 引脚设置到控制寄存器。 (维基百科文章有 pin 到寄存器位映射)。然后在软件中进行轮询,直到看到 BUSY 线变高然后再次变低。

将一个字节一次一个地填充到 I/O 端口称为“编程 I/O”。它很慢,并且会占用您所有的 CPU 时间。

还有其他方法可以对现代(和不太现代的)计算机中的并行端口进行编程。例如,ECP是对同一物理并行端口进行编程的完全独立的方式。它可以使用 DMA,所以你给硬件一个字节缓冲区,它为你做硬件握手,所以 CPU 可以做其他事情而不是轮询 parport。打印机是否将它们存储到内存中是一个单独的问题。


从技术上讲,CPU甚至不能直接访问并口;它必须访问它 via the southbridge .但是当 CPU 核心运行 inout 指令时,硬件会处理这个问题。


顺便说一句,PC 端口是双向的。在以太网广泛使用之前,通过串行或并行端口连接两台计算机来传输文件并不少见。 (或者使用传输 IP 数据包的链接,作为以太网的替代方法。)并行端口(尤其是使用 ECP)比串行端口快得多(2.5MB/s 对典型 PC 硬件上的 115 kbit/s)。并行端口可能比 10Mbit/s 以太网更快。我记得有时在 Linux 上这样做,因为它有很好的内核驱动程序 PLIP .


脚注:

“直接”从本地复制到远程内存(反之亦然)是 called Remote DMA (RDMA) .这主要意味着硬件负责启动复制命令的协议(protocol)内容,并且远程端不会发生访问控制。 (即,您可以通过写入错误的内存地址使远程端崩溃。)InfiniBand 是与 RDMA 相关的一种众所周知的硬件接口(interface),用于高性能计算和/或存储服务器。

Firewire Controller 也支持 RDMA。参见 https://en.wikipedia.org/wiki/DMA_attack有关在不受信任的设备读取/写入主机内存的上下文中的描述,它不应​​该。

关于x86 - 如何与连接到并行端口的设备通信?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46660864/

相关文章:

assembly - 字节、字和双字之间的转换

c++ - 使用 Microsoft Detours 时出现访问冲突

c - 局部变量在栈上的分配顺序

x86 - 为什么 x86 分页没有权限环的概念?

android - wifi硬件是否配备设备

c++ - 组装:JA 和 JB 工作不正确

go - 我应该通过“go build”编译到哪些平台?

c# - 宇宙(C#操作系统): running on Azure?

java - 如何用Java制作最简单的软件控制ON/OFF硬件?

audio - 更改 Flash Player 音频输出设备