문제

I am trying to write an ioremap kernel module - X86 PC. This module will read the value from the serial port. How to find the SERIAL_ADDR, SERIAL_SIZE here? Is my driver correct to read the port value? Is there any problem with my code? Does SERIAL_ADDR and SERIAL SIZE are fixed by the hardware manufacturer?

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*

How do the proc file got to know the address range of serial - 0x3f8 to 0x3ff? So, the size of serial ports should be - (0x3ff - 0x3f8) + 1 i.e. 8 ? SERIAL_SIZE is 8 right? But, what should be the base address here? Is the base address - 0x3f8? It doesn't look like a base address to me? I need SERIAL_ADDR ? Please help.

도움이 되었습니까?

해결책

I/O ports are not memory-addressed. To put this another way, x86 I/O ports have an entirely separate address space than memory. There is no overlap with memory. A different set of CPU instructions ("IN", "OUT") are used when operating on I/O ports. The I/O ports are "discovered" by device drivers and then registered/reserved within the kernel using "request_region"; see, for example, serial8250_request_std_resource() in the kernel source.

Don't confuse this with "memory-mapped I/O" where I/O regions are mapped into the processor's physical memory space. These are registered/reserved with request_mem_region. You can view the latter with cat /proc/iomem.

Serial devices can be devised to work in either the I/O space or as memory-mapped I/O so, for you, which way to do it will be very dependent on your specific device.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top