2014-05-13 6 views
0

ioremap 커널 모듈 (X86 PC)을 쓰려고합니다. 이 모듈은 직렬 포트에서 값을 읽습니다. 여기 SERIAL_ADDR, SERIAL_SIZE를 찾는 방법은 무엇입니까? 포트 값을 읽으려면 드라이버가 올바 릅니까? 내 코드에 문제가 있습니까? SERIAL_ADDR 및 SERIAL SIZE는 하드웨어 제조업체가 고정합니까? 는 0x3ff하는 0x3f8 - proc 디렉토리 파일은 일련의 주소 범위를 알고있어 어떻게X86 - 0x2f8에서 직렬 포트를 초기화하는 방법은 무엇입니까?

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* 

? 그래서 직렬 포트의 크기는 - (0x3ff - 0x3f8) + 1, 즉 8이어야합니다. SERIAL_SIZE이 (가) 8입니다. 하지만 여기에 기본 주소는 무엇입니까? 기본 주소가 0x3f8입니까? 나에게 기본 주소처럼 보이지 않습니까? SERIAL_ADDR이 필요합니까? 도와주세요.

답변

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로 작동하도록 고안 될 수 있으므로 어떤 방식으로 작업 할 것인지는 특정 장치에 따라 크게 달라질 수 있습니다.

+0

저는 이것을 iomem으로 처리하고 싶습니다. –

+0

@SHREYASJOSHI 이것은 불가능합니다. 당신은 1981 년에 IBM에게 말 했어야했다. –