저는 Linux 드라이버 개발이 처음이고 다른 초보자가 커널 개발을 시작하는 데 도움이 될 것이라고 생각하는 개념적인 질문이 있습니다.
나는 "Linux Device Drivers"라는 책을 읽고 있으며 1장을 마쳤습니다. 제 3권. 지금까지 저는 폴더에 있는 파일에 open
, close
및 기타 명령을 실행하여 /dev
사용자 공간이 커널 기능에 액세스할 수 있다는 것을 확인했습니다.
제어를 공유하는 또 다른 방법은 파일을 통하는 것입니다 /sys
. 여기서 파일을 읽거나 쓰는 것은 sys
드라이버에 전달될 수 있습니다.
각 접근 방식의 사용 사례가 무엇인지 알고 싶습니다. 동일한 작업을 수행하는 두 가지 방법입니까? 다른 것과 관련하여 하나에 제한이 있습니까? 누군가가 다른 것보다 더 유용할 수 있는 몇 가지 실제 사례를 공유할 수 있습니까?
나는 여기에서 다른 질문을 읽었으며 설명 dev
합니다 sys
. 이것이 도움이 되지만, 두 가지의 차이점과 용도를 더 깊이 이해하고 싶습니다.
답변1
대략적으로:
/dev
초기 Unix 시스템에서 커널과 상호 작용하는 유일한 방법이었던 장치 노드를 포함합니다. 그 종류는 두 가지가 있는데,막힌장비와특징장비. 해당 API는 블록 기반 I/O(일종의 디스크) 또는 문자 기반 I/O(예: 직렬 포트)를 허용하는 데 적합합니다.
/sys
(및 /proc
)은 나중에 추가되었으며 아마도 다음의 영향을 받았을 것입니다.계획 9운영 체제. 읽을 때 커널 모듈의 내부 상태를 설명하거나 쓸 때 내부 상태를 설정하는 텍스트가 파일 항목에 포함된 완전한 디렉토리 하위 트리를 제공합니다.
따라서 일반적인 응용 프로그램은 다음과 같습니다.
특정 저장 장치용 커널 드라이버를 작성하시겠습니까? 노드를 사용하여 /dev
장치 자체에 액세스하거나 항목을 사용 /sys
하여 /proc
저장소에 액세스하는 방법을 미세 조정합니다.
답변2
/sys
이에 대해서는 14장 "Linux 장치 모델"에서 다룹니다. 사용할 수 있는 더 많은 샘플 코드를 제공합니다. 하지만 나는 이 책이 좀 더 코드 중심적인 접근 방식이라고 생각하며, 디자인 원칙이 어떤 것인지 묻는 것이 유용하다고 생각합니다.
사용자 공간 커널 통신에 /dev 및 /sys는 언제 사용됩니까?
첫 번째 대답은 스스로 선택할 수 없다는 것입니다. 특정 유형의 장치용 드라이버를 작성할 때 커널에는 이미 동일한 유형의 장치에 대한 많은 예가 있습니다. 기존 장치와 동일한 코드 패턴을 사용할 수 있습니다. (가장 최신 문서는 코드 자체입니다. 많은 커널 인터페이스에는 완전하거나 최신 문서가 없습니다. 죄송합니다!)
이것이 장치 드라이버를 작성하는 주된 이유입니다. 각 장치에 대해 서로 다른 세부 정보를 작성할 필요 없이 프로그램에서 사용할 수 있는 일관된 인터페이스를 제공합니다.
이는 일반적인 조언보다 우선합니다. Linux의 하위 시스템(예: 장치 클래스)이 겉보기에 "잘못된" 방법을 사용하지만 일관되게 사용하는 경우 해당 하위 시스템에 대한 드라이버를 작성할 때도 일관되고 "잘못된" 실수여야 합니다.
/개발자
/dev/는 데이터 경로로 사용되어야 합니다. 네트워크 장비는 예외이며 이 책의 여러 부분에서 다루고 있습니다.
/dev/ 특수 파일은 유닉스 작업을 표준화하는 데 사용해야 합니다: read()
, write()
, poll()
/ select()
, s 가 UNIX 또는 Linux에서 효과적으로 표준화된 mmap()
경우 ioctl()
에도 바람직합니다. 이러한 몇 가지 시스템 호출(및 일부 파생 변형)은 거의 모든 상황에서 사용됩니다. 그들과 익숙해지기 시작하세요 :). ioctl()
다음은 운전자가 다양한 추가 조치를 정의하는 데 사용할 수 있는 탈출구입니다.
/체계
sysfs 쓰기는 구성 매개변수에 대해 더 적은 수의 경우에 사용해야 합니다. 일반 텍스트 형식이어야 하며 단일 값만 포함해야 합니다. [*] 서로 다른 sysfs 파일을 너무 많이 갖고 싶지는 않습니다. 당신은 곧 그들의 한계를 보게 될 것입니다.
또한 sysfs 파일은 기본적으로 변수(쓰기 가능 여부)를 읽어야 한다고 말할 수 있습니다. 나는 그것을 읽는 것이 하드웨어 작동을 유발해서는 안된다고 생각합니다. 나는 당신이 이미 이런 맥락에서 생각하고 있다고 생각합니다.
sysfs 파일의 한 가지 장점은 실험에 매우 편리하다는 것입니다. 쉘 명령을 사용하여 쉽게 나열하고 읽고 쓸 수 있습니다. 이는 위험하기도 합니다. 실험적 상태에 있는 sysfs 파일을 게시하지 않도록 주의해야 합니다. 다른 사람들이 sysfs 파일에 의존하기 시작하면 사용자 스크립트를 손상시키는 방식으로 파일을 변경하려는 경우 커널 관리자는 매우 불만스러워할 것입니다.
sysfs(디렉토리 계층 구조 및 기호 링크)를 탐색하는 것도 장치가 어떻게 구성되어 있는지 확인하는 데 유용합니다.
또한 개념적으로 sysfs의 변경 사항을 모니터링하는 것은 프로그램이 새 장치(예: 연결 시)를 감지할 수 있는 방법입니다. 기술적으로 이러한 이벤트는 파일 시스템 자체를 통해 전달되지 않지만 각 이벤트는 특정 sysfs 디렉터리를 가리킵니다.
udev 데몬은 이러한 이벤트를 수신합니다. 일반 프로그램은 필요한 경우 udev/libudev에 의존하는 경향이 있습니다. 예를 들어 udev 규칙은 새로 검색된 장치의 설정 변경과 같은 이벤트가 수신될 때 sysfs 디렉터리의 일부 파일을 읽거나 쓸 수 있습니다.
예시 보기
기존 사례를 살펴보는 것은 매우 좋은 생각입니다. 하나의 예만 보고 다른 곳에서도 동일하게 작동한다고 가정하면 안 되지만 :-).
Dirkt가 말했듯이 블록 저장 장치에 액세스하는 것은 노출된 최대 물리적 IO 크기와 같은 일부 매개변수 /dev/sda
입니다 . 하위 디렉토리를 살펴보십시오 ./dev
/sys/class/block/sda/
queue
많은 sysfs 파일이 커널 트리에 기록됩니다 Documentation/ABI/*/sysfs-*
. 예를 들어:https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-block
"문자 장치"는 그다지 구체적이지 않습니다. 기본적으로 블록 장치도 네트워크 장치도 아닌 모든 장치에 사용됩니다. :-). 완전히 새로운 유형의 장치를 구현해야 한다면 완전히 새로운 유형의 문자 장치를 정의하고 ioctl()
몇 가지 새로운 작업 집합을 정의하는 어려운 작업을 수행해야 할 것입니다.
/sys/class/
자신의 시스템에 정의된 다른 유형의 장치를 살펴보기 시작할 수도 있습니다 .
/sys/
장치 목록도 포함되어 있지만 /dev/
이름이 아닌 장치 번호별로 나열됩니다. ls -l /sys/dev/char/
및 을 참조하십시오 ls -l /sys/dev/block/
. 이는 udev
관리 방법을 설명하는 데 도움이 됩니다 /dev
. 나타나는 모든 장치는 . [**] /dev
에 개체 로 나열됩니다./sys
[*] sysfs uevent
파일에는 여러 값이 포함되어 있으며 실제로 핵심 기능입니다. 하지만 uevent 파일을 사용하여 내부 값을 변경할 수는 없습니다. 그래서 이것은 다음과 같이 말합니다. 그것을 보지 말고 uevent
내 제안이 틀렸다고 생각하지 마십시오. 그러한 파일을 직접 정의해서는 안됩니다. 장치 드라이버는 uevent
파일에 행을 추가할 수 있습니다.생각하다좋은 예는 udev
규칙에서 테스트하려는 매우 유용한 식별 속성이 있는 경우입니다.
[**] 제외 등은 별도의 파일 시스템 "devpts"에 의해 실제로 구현되므로 목록 /dev/pts/0
에 포함되어 있지 않습니다 . 이는 아주 특별한 경우이므로 무시하시기 바랍니다. 나는 답이 있다는 결론에 도달했지만, 그것이 내가 방금 말한 것에 아무것도 추가하지 않는다고 생각합니다. 여기있어:/sys
/dev/pts/0
/dev/pts/0
터미널을 열 때 항상 TTY가 사용됩니까?.