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.