首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >装配键盘IO端口

装配键盘IO端口
EN

Stack Overflow用户
提问于 2010-08-08 23:21:06
回答 1查看 6.4K关注 0票数 5

我看过下面的topic

我对通过输入/输出指令接触键盘和设置各种模式感兴趣,例如打开caps lock led。到目前为止,我在这样做时遇到了问题。下面的link可能会有所帮助。

我尝试过各种组合,例如

代码语言:javascript
复制
mov al,0EDh           ;ED command - Send LED bits. The next byte written to port 60h updates the LEDs on the keyboard.
out 60h,al            ;out on port 60h
mov al,00000111b      ;led status - all leds on. bits 3-7 = reserved(zero)
out 60h,al            ;out on port 60h

如果有任何帮助,我将不胜感激。谢谢。

编辑:正如我所说的,使用端口60h不起作用,我已经在网上搜索了0040:0017的用法。其中一个网络表示位5、6、7包含关于leds状态的数据

我尝试使用以下代码:

代码语言:javascript
复制
mov al,es:[0017h]
or al,11100000b
mov es:[0017h],al

而且它也不起作用。

我可能做错了,所以谁能帮助我或给我一个工作代码,打开所有3个leds?

EDIT2:我在安装在VM上的MS-DOS上运行了我的应用程序,代码运行得很好。

我的问题是:我如何让它在MS-DOS之外工作?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-08-13 00:46:51

要从在VM86模式或保护模式下运行的任务访问I/O端口,您需要特殊权限。此权限可通过以下方式获得:

  • IOPL (仅适用于保护模式任务):如果任务的当前权限级别是任务的<= IOPL,则允许访问。
  • I/O权限位图(用于VM86任务和CPL不足的受保护模式任务):TSS可能包含用于允许/拒绝I/O端口访问的位图。

当访问被拒绝时,会生成GPF。

Linux具有iopl()和ioperm()系统调用,允许使用CAP_SYS_RAWIO的进程获得这些特权。因此,在Linux上访问键盘LED可以如下所示:

代码语言:javascript
复制
#include <stdio.h>
#include <sys/io.h>

int main()
{
    int ret;

    ret = ioperm(0x60, 0xf, 1);
    if (ret < 0) {
            perror("ioperm");
            return 1;
    }
    while (inb(0x64) & 0x2);
    outb(0xed, 0x60);
    while (inb(0x64) & 0x2);
    outb(0x07, 0x60);
    ioperm(0x60, 0xf, 0);

    return 0;
}

Windows NTVDM和Linux dosemu使用VM86模式来运行实模式的DOS程序。当尝试不允许的I/O端口访问时,会生成GPF,并且这些系统可以模拟(或不模拟) I/O端口访问。dosemu有一个-k开关,可以绕过通常的tty层,直接访问键盘。使用此开关,您的第一个示例可以正常工作。

现在,在Windows上做同样的事情可能需要在环0上运行的驱动程序来做。一种替代方案可能是使用允许环3进程访问I/O端口的驱动程序(非常不安全):例如,参见ioperm for cygwin

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3434827

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档