IOCTL Linux 장치 드라이버 [닫기]


126

누구든지 나를 설명 할 수 있습니까?

  1. 무엇입니까 IOCTL?
  2. 무엇을 위해 사용됩니까?
  3. 어떻게 사용하나요?
  4. 왜 같은 기능을하는 새로운 기능을 정의 할 수 IOCTL없습니까?

답변:


99

ioctl장치 특정 시스템 호출의 일종 인 수단 "입출력 제어". Linux (300-400)에는 시스템 호출이 거의 없으며 장치가 가질 수있는 모든 고유 기능을 표현하기에는 충분하지 않습니다. 따라서 드라이버는 사용자 공간 애플리케이션이 주문을 보낼 수있는 ioctl을 정의 할 수 있습니다. 그러나 ioctl은 매우 유연하지 않으며 약간 혼란스러워하는 경향이 있습니다 (수십 개의 "매직 숫자"는 작동합니다 ...) 쉽게 할 수 있습니다.

대안은 sysfs인터페이스입니다. 여기서 인터페이스에서 파일을 설정 /sys/하고 드라이버에서 정보를 얻기 위해 파일을 읽고 쓸 수 있습니다. 이것을 설정하는 방법의 예 :

static ssize_t mydrvr_version_show(struct device *dev,
        struct device_attribute *attr, char *buf)
{
    return sprintf(buf, "%s\n", DRIVER_RELEASE);
}

static DEVICE_ATTR(version, S_IRUGO, mydrvr_version_show, NULL);

그리고 드라이버 설정 중 :

device_create_file(dev, &dev_attr_version);

그러면 /sys/예를 들어 /sys/block/myblk/version블록 드라이버 와 같은 장치 파일이 있습니다 .

더 많이 사용하는 또 다른 방법은 netlink인데, 이는 BSD 소켓 인터페이스를 통해 드라이버와 통신하는 IPC (프로세스 간 통신) 방법입니다. 이것은 예를 들어 WiFi 드라이버에서 사용됩니다. 그런 다음 libnl또는 libnl3라이브러리를 사용하여 사용자 공간에서 통신합니다 .


3
이 답변은 질문에 부분적으로 '답변합니다'.
Vishal Sahu

163

ioctl기능은 장치의 구성을 설정하기 위해 장치 드라이버를 구현하는 데 유용합니다. 예를 들어 글꼴 군, 글꼴 크기 등을 확인하고 설정하는 구성 옵션이있는 프린터를 ioctl사용하여 현재 글꼴을 가져 오고 글꼴을 새 글꼴로 설정할 수 있습니다. 사용자 응용 프로그램은 ioctl프린터에 코드를 보내 현재 글꼴을 반환하거나 글꼴을 새 글꼴로 설정하도록 지시합니다.

int ioctl(int fd, int request, ...)
  1. fd파일 디스크립터이며 open;
  2. request요청 코드입니다. 예를 들어 GETFONT프린터에서 현재 글꼴을 가져오고 프린터 SETFONT에서 글꼴을 설정합니다.
  3. 세 번째 주장은 void *입니다. 두 번째 인수에 따라 세 번째 인수가있을 수도 있고 없을 수도 있습니다. 예를 들어 두 번째 인수가이면 SETFONT세 번째 인수는 다음과 같은 글꼴 이름 일 수 있습니다 "Arial".

int request매크로가 아닙니다. 장치에서 재생할 구성을 결정하려면 요청 코드 및 장치 드라이버 모듈을 생성하는 사용자 응용 프로그램이 필요합니다. 애플리케이션은 ioctl을 사용하여 요청 코드를 전송 한 후 디바이스 드라이버 모듈의 요청 코드를 사용하여 수행 할 조치를 결정합니다.

요청 코드에는 4 가지 주요 부분이 있습니다.

    1. A Magic number - 8 bits
    2. A sequence number - 8 bits
    3. Argument type (typically 14 bits), if any.
    4. Direction of data transfer (2 bits).  

요청 코드가 SETFONT프린터에서 글꼴을 설정하는 경우 데이터 전송 방향은 사용자 응용 프로그램에서 장치 드라이버 모듈로 전달됩니다 (사용자 응용 프로그램은 글꼴 이름 "Arial"을 프린터로 보냅니다 ). 요청 코드가 인 GETFONT경우 방향은 프린터에서 사용자 응용 프로그램으로 향합니다.

요청 코드를 생성하기 위해 Linux는 미리 정의 된 함수형 매크로를 제공합니다.

1. _IO(MAGIC, SEQ_NO)둘 다 0에서 255까지의 8 비트입니다. 예를 들어 프린터를 일시 중지한다고 가정하겠습니다. 데이터 전송이 필요하지 않습니다. 따라서 아래와 같이 요청 코드를 생성합니다

#define PRIN_MAGIC 'P'
#define NUM 0
#define PAUSE_PRIN __IO(PRIN_MAGIC, NUM) 

지금 사용 ioctl으로

ret_val = ioctl(fd, PAUSE_PRIN);

드라이버 모듈의 해당 시스템 호출은 코드를 수신하고 프린터를 일시 중지합니다.

  1. __IOW(MAGIC, SEQ_NO, TYPE) MAGIC그리고 SEQ_NO상기와 동일하고, TYPE다음의 인자의 종류를 부여 제의 인수 회수 ioctl이다 void *. W in __IOW은 데이터 흐름이 사용자 응용 프로그램에서 드라이버 모듈 로 있음을 나타냅니다. 예를 들어 프린터 글꼴을로 설정한다고 가정합니다 "Arial".
#define PRIN_MAGIC 'S'
#define SEQ_NO 1
#define SETFONT __IOW(PRIN_MAGIC, SEQ_NO, unsigned long)

더욱이,

char *font = "Arial";
ret_val = ioctl(fd, SETFONT, font); 

이제 font포인터입니다. 이는 주소로 가장 잘 표현 된 주소 unsigned long이므로 _IOW멘션 유형 의 세 번째 부분은 그대로입니다. 또한이 글꼴 주소는 장치 드라이버 모듈에 구현 된 해당 시스템 호출로 전달 unsigned long 되므로 사용하기 전에 올바른 유형으로 캐스트해야합니다. 커널 공간은 사용자 공간에 액세스 할 수 있으므로 작동합니다. 다른 두 함수와 같은 매크로가 __IOR(MAGIC, SEQ_NO, TYPE)__IORW(MAGIC, SEQ_NO, TYPE)데이터 흐름 사용자 공간과 각각 두 가지로 커널 공간에서있을 곳.

이것이 도움이된다면 알려주십시오!


위의 __IOW, __IOR 및 __IORW 함수가 올바른지 궁금합니다 (일부 경우 이중 밑줄을 의미합니다. 경우에 따라 이중 밑줄을 사용하지 않았습니다). 명확한 설명을 주셔서 감사합니다!
jcoppens

잘 설명했습니다. 감사합니다! 이 ioctl을 사용하는 드라이버 측의 작은 코드 스 니펫을 제공 할 수 있습니까?
Aadishri

예를 들어 opensourceforu.com/2011/08/io-control-in-linux 를 참조하십시오
chandola

잘 설명했다. 감사합니다. _IORW가 아닌 _IOWR 인 것 같습니다
Mohamed Samy

블로그 게시물처럼 답변하십시오.
프레드릭 가우스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.