组装键盘IO端口 [英] Assembly Keyboard IO Port

查看:128
本文介绍了组装键盘IO端口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看过以下主题.

我有兴趣通过IN/OUT指令联系键盘并设置各种模式,例如打开大写锁定指示灯.到目前为止,我在执行此操作时遇到了问题. 以下链接可能会有所帮助.

I am interested in contacting the keyboard via the IN / OUT instructions and setting various modes, such as turning on the caps lock led. So far I have encountered problems doing so. The following link may help.

我尝试了各种组合,例如

I have tried various combinations such as

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

我将不胜感激. 谢谢.

I would appreciate any help. Thanks.

如我所说,使用端口60h无效 我已经在网上搜索了0040:0017的用法. 其中一个网站指出,第5、6、7位包含有关LED状态的数据

As I said, using port 60h didn't work I have searched around the net for the usage of 0040:0017. One of the webs stated that bits 5,6,7 contain data about the leds' status

我尝试使用此代码:

mov al,es:[0017h]
or al,11100000b
mov es:[0017h],al

它也不起作用.

我可能做错了,所以有人可以帮助我或给我发送所有3个LED亮起的工作代码吗?

I might be doing that wrong, so could anyone please help me or send me a working code for turning all 3 leds on?

我在VM上安装的MS-DOS上运行了我的应用程序,并且代码运行正常.

I ran my application on MS-DOS installed on a VM, and the code worked perfectly.

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

My question is: how can I make it work outside MS-DOS??

推荐答案

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

To access I/O ports from a task running on VM86 mode or protected mode you need special privileges. This privileges can be obtained via:

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

如果拒绝访问,则会生成GPF.

When access is rejected, a GPF is generated.

Linux具有iopl()和ioperm()系统调用,它们允许使用CAP_SYS_RAWIO的进程获取这些特权.因此,可以通过以下方式访问Linux上的键盘LED:

Linux has the iopl() and ioperm() syscalls which allow processes with CAP_SYS_RAWIO to get these privileges. So, accessing keyboard LEDs on Linux can be done like this:

#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剂量使用VM86模式运行实模式DOS程序.当尝试不允许的I/O端口访问时,会生成GPF,并且这些系统可以模拟(或不模拟)I/O端口访问. dosemu具有-k开关,可绕过常规的tty层并直接访问键盘.使用此开关,第一个示例有效.

Windows NTVDM and Linux dosemu use VM86 mode to run real mode DOS programs. When a not allowed I/O port access is attempted, a GPF is generated, and these systems may emulate (or not) the I/O port access. dosemu has a -k switch that bypasses the usual tty layer and accesses directly the keyboard. Using this switch your first example works.

现在,要在Windows上执行相同的操作,可能需要在环0上运行的驱动程序执行此操作.另一种选择是使用允许环3进程访问I/O端口的驱动程序(非常不安全):请参阅例如 cygwin的ioperm .

Now, to do the same thing on Windows will probably require doing it from a driver running on ring 0. An alternative may be using a driver that allows ring 3 processes access to the I/O ports (very insecure): see for instance ioperm for cygwin.

这篇关于组装键盘IO端口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆