0

我正在尝试编写一个 ioremap 内核模块 - X86 PC。该模块将从串口读取值。如何在这里找到 SERIAL_ADDR、SERIAL_SIZE?我的驱动程序是否正确读取端口值?我的代码有问题吗?SERIAL_ADDR 和 SERIAL SIZE 是否由硬件制造商固定?

int device_init()
{

    void *sPort;
    int ret;
    ret = register_chrdev(device_major, DEVICE_NAME, &fops);
    if(ret < 0) {
        printk(KERN_ALERT "serial: cannot obtain major number %d.\n", device_major);
        return ret;
    }

    if(request_mem_region (SERIAL_ADDR,SERIAL_SIZE, "SERIAL Driver") == NULL)
    {
        printk("Failed to request memory region!\n");
        device_exit();
        return 1;
    }

    sPort = ioremap(SERIAL_ADDR, SERIAL_SIZE);

    printk("%X\n", ioread32(sPort));

}

*$ cat /proc/ioports 
0000-0cf7 : PCI Bus 0000:00
  0000-001f : dma1
  0020-0021 : pic1
  0040-0043 : timer0
  0050-0053 : timer1
  0060-0060 : keyboard
  0064-0064 : keyboard
  0070-0077 : rtc0
  0080-008f : dma page reg
  00a0-00a1 : pic2
  00c0-00df : dma2
  00f0-00ff : fpu
  03c0-03df : vga+
  03f8-03ff : serial*

proc 文件如何知道串行的地址范围 - 0x3f8 到 0x3ff?那么,串口的大小应该是 - (0x3ff - 0x3f8) + 1 即 8 ?SERIAL_SIZE 是 8 对吗?但是,这里的基地址应该是什么?基地址是 0x3f8 吗?对我来说,它看起来不像基地址?我需要 SERIAL_ADDR 吗?请帮忙。

4

1 回答 1

4

I/O 端口不是内存寻址的。换句话说,x86 I/O 端口有一个完全独立于内存的地址空间。与记忆没有重叠。在 I/O 端口上操作时使用一组不同的 CPU 指令(“IN”、“OUT”)。I/O 端口由设备驱动程序“发现”,然后使用“request_region”在内核中注册/保留;例如,请参见内核源代码中的 serial8250_request_std_resource()。

不要将此与“内存映射 I/O”混淆,其中 I/O 区域映射到处理器的物理内存空间。这些是使用 request_mem_region 注册/保留的。您可以使用 . 查看后者cat /proc/iomem

串行设备可以设计为在 I/O 空间或内存映射 I/O 中工作,因此,对您而言,采用哪种方式将取决于您的特定设备。

于 2014-05-13T13:30:28.150 回答