답변:
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
라이브러리를 사용하여 사용자 공간에서 통신합니다 .
이 ioctl
기능은 장치의 구성을 설정하기 위해 장치 드라이버를 구현하는 데 유용합니다. 예를 들어 글꼴 군, 글꼴 크기 등을 확인하고 설정하는 구성 옵션이있는 프린터를 ioctl
사용하여 현재 글꼴을 가져 오고 글꼴을 새 글꼴로 설정할 수 있습니다. 사용자 응용 프로그램은 ioctl
프린터에 코드를 보내 현재 글꼴을 반환하거나 글꼴을 새 글꼴로 설정하도록 지시합니다.
int ioctl(int fd, int request, ...)
fd
파일 디스크립터이며 open
;request
요청 코드입니다. 예를 들어 GETFONT
프린터에서 현재 글꼴을 가져오고 프린터 SETFONT
에서 글꼴을 설정합니다.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);
드라이버 모듈의 해당 시스템 호출은 코드를 수신하고 프린터를 일시 중지합니다.
__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)
데이터 흐름 사용자 공간과 각각 두 가지로 커널 공간에서있을 곳.
이것이 도움이된다면 알려주십시오!