Linux From Scratch - Version 12.1-systemd
Chapter 9. System Configuration
이전	위로 / 처음으로	다음
개요	장치 및 모듈 처리

9.3. 디바이스 및 모듈 처리 개요

8장에서는 시스템디를 빌드할 때 udev 데몬을 설치했습니다. udev의 작동 방식에 대해 자세히 알아보기 전에 이전 디바이스 처리 방법에 대한 간략한 역사를 살펴볼 필요가 있습니다.

일반적으로 리눅스 시스템에서는 해당 하드웨어 장치가 실제로 존재하는지 여부와 관계없이 /dev 아래에 수많은 장치 노드(때로는 문자 그대로 수천 개의 노드)를 생성하는 정적 장치 생성 방법을 사용했습니다. 이는 일반적으로 세상에 존재할 수 있는 모든 장치에 대한 관련 주 장치 번호와 부 장치 번호가 포함된 mknod 프로그램에 대한 여러 호출이 포함된 MAKEDEV 스크립트를 통해 수행되었습니다.

udev 방법을 사용하면 커널에서 감지된 디바이스에 대해서만 디바이스 노드가 생성됩니다. 이러한 장치 노드는 시스템이 부팅될 때마다 생성되며, devtmpfs 파일 시스템(시스템 메모리에만 있는 가상 파일 시스템)에 저장됩니다. 장치 노드는 많은 공간을 필요로 하지 않으므로 사용되는 메모리는 무시할 수 있는 수준입니다.

9.3.1. 역사

2000년 2월, devfs라는 새로운 파일 시스템이 2.3.46 커널에 병합되어 2.4 시리즈의 안정적인 커널에서 사용할 수 있게 되었습니다. 커널 소스 자체에 존재했지만, 장치를 동적으로 생성하는 이 방법은 핵심 커널 개발자들로부터 압도적인 지지를 받지 못했습니다.

devfs가 채택한 접근 방식의 가장 큰 문제는 디바이스 감지, 생성 및 이름 지정을 처리하는 방식이었습니다. 후자의 문제인 디바이스 노드 이름 지정이 가장 중요한 문제였습니다. 일반적으로 장치 이름을 구성할 수 있는 경우, 장치 이름 지정 정책은 시스템 관리자가 선택해야 하며 개발자가 강요해서는 안 된다는 것이 통념입니다. devfs 파일 시스템은 또한 설계에 내재된 경합 조건으로 인해 커널을 대폭 수정하지 않고는 해결할 수 없는 문제가 있었습니다. devfs는 오랫동안 사용되지 않는 것으로 표시되었고 2006년 6월에 마침내 커널에서 제거되었습니다.

불안정한 2.5 커널 트리가 개발되고 나중에 안정적인 커널인 2.6 시리즈가 출시되면서 sysfs라는 새로운 가상 파일 시스템이 탄생했습니다. sysfs의 역할은 시스템의 하드웨어 구성에 대한 정보를 사용자 공간 프로세스에 제공하는 것입니다. 사용자 공간에서 볼 수 있는 이 표현을 통해 devfs를 대체할 수 있는 사용자 공간을 개발할 수 있게 되었습니다.

9.3.2. Udev 구현

9.3.2.1. Sysfs

sysfs 파일 시스템은 위에서 간략하게 언급했습니다. sysfs가 시스템에 존재하는 장치에 대해 어떻게 알고 어떤 장치 번호를 사용해야 하는지 궁금할 수 있습니다. 커널에 컴파일된 드라이버는 커널에서 감지되는 대로 sysfs(내부적으로는 devtmpfs)에 개체를 등록합니다. 모듈로 컴파일된 드라이버의 경우 모듈이 로드될 때 등록이 이루어집니다. sysfs 파일 시스템이 마운트되면(/sys에) 드라이버가 sysfs에 등록한 데이터를 사용자 공간 프로세스 및 udevd에서 처리(장치 노드에 대한 수정 포함)를 위해 사용할 수 있습니다.

9.3.2.2. 장치 노드 생성

장치 파일은 커널에 의해 devtmpfs 파일 시스템에서 생성됩니다. 장치 노드를 등록하려는 모든 드라이버는 드라이버 코어를 통해 devtmpfs를 사용하여 이를 수행합니다. devtmpfs 인스턴스가 /dev에 마운트되면 장치 노드는 처음에 고정된 이름, 권한 및 소유자와 함께 사용자 공간에 노출됩니다.

잠시 후 커널은 udevd로 이벤트를 전송합니다. udevd는 /etc/udev/rules.d, /usr/lib/udev/rules.d 및 /run/udev/rules.d 디렉토리 내의 파일에 지정된 규칙에 따라 장치 노드에 대한 추가 심볼릭 링크를 생성하거나 해당 개체의 권한, 소유자 또는 그룹을 변경하거나 내부 udevd 데이터베이스 항목(이름)을 수정합니다.

이 세 디렉터리의 규칙에는 번호가 매겨지며 세 디렉터리는 모두 병합됩니다. udevd가 생성 중인 장치에 대한 규칙을 찾을 수 없는 경우 처음에 사용된 devtmpfs에 권한 및 소유권이 그대로 남습니다.

9.3.2.3. 모듈 로드

모듈로 컴파일된 장치 드라이버에는 별칭이 내장되어 있을 수 있습니다. 별칭은 modinfo 프로그램의 출력에서 볼 수 있으며 일반적으로 모듈에서 지원하는 장치의 버스별 식별자와 관련이 있습니다. 예를 들어, snd-fm801 드라이버는 공급업체 ID 0x1319 및 장치 ID 0x0801의 PCI 장치를 지원하며, 별칭은 pci:v00001319d00000801sv*sd*bc04sc01i*입니다. 대부분의 디바이스에서 버스 드라이버는 sysfs를 통해 디바이스를 처리할 드라이버의 별칭을 내보냅니다. 예를 들어, /sys/bus/pci/devices/0000:00:0d.0/modalias 파일에는 pci:v00001319d00000801sv00001319sd00001319bc04sc01i00 문자열이 포함될 수 있습니다. udev와 함께 제공되는 기본 규칙에 따라 udevd는 MODALIAS 이벤트 환경 변수의 내용(sysfs의 modalias 파일 내용과 동일해야 함)을 사용하여 /sbin/modprobe로 호출하여 와일드카드 확장 후 이 문자열과 별칭이 일치하는 모든 모듈을 로드합니다.

이 예에서는 snd-fm801 외에도 더 이상 사용되지 않는(그리고 원치 않는) forte 드라이버가 있으면 로드된다는 의미입니다. 원치 않는 드라이버의 로딩을 방지할 수 있는 방법은 아래를 참조하세요.

커널 자체는 네트워크 프로토콜, 파일 시스템 및 NLS 지원을 위한 모듈도 필요에 따라 로드할 수 있습니다.

9.3.2.4. 핫플러깅 가능/동적 장치 처리

USB(범용 직렬 버스) MP3 플레이어와 같은 장치를 연결하면 커널은 이제 장치가 연결되었음을 인식하고 이벤트를 생성합니다. 이 이벤트는 위에서 설명한 대로 udevd에 의해 처리됩니다.

9.3.3. 모듈 로드 및 장치 생성 관련 문제

장치 노드를 자동으로 만들 때 몇 가지 문제가 발생할 수 있습니다.

9.3.3.1. 커널 모듈이 자동으로 로드되지 않음

Udev는 모듈에 버스별 별칭이 있고 버스 드라이버가 필요한 별칭을 sysfs로 올바르게 내보내는 경우에만 모듈을 로드합니다. 다른 경우에는 다른 방법으로 모듈 로드를 준비해야 합니다. Linux-6.7.4에서는 udev가 INPUT, IDE, PCI, USB, SCSI, SERIO 및 FireWire 장치에 대해 올바르게 작성된 드라이버를 로드하는 것으로 알려져 있습니다.

필요한 장치 드라이버가 udev에 필요한 지원을 제공하는지 확인하려면 모듈 이름을 인수로 modinfo를 실행하세요. 이제 /sys/bus에서 장치 디렉터리를 찾아 modalias 파일이 있는지 확인합니다.

modalias 파일이 sysfs에 있으면 드라이버가 장치를 지원하며 직접 연결할 수 있지만 별칭이 없는 경우 드라이버에 버그가 있는 것입니다. udev의 도움 없이 드라이버를 로드하고 나중에 문제가 해결될 것으로 기대하세요.

관련 디렉터리인 /sys/bus에 modalias 파일이 없다면 커널 개발자가 아직 이 버스 유형에 modalias 지원을 추가하지 않았다는 뜻입니다. Linux-6.7.4에서는 ISA 버스가 이에 해당합니다. 이 문제는 이후 커널 버전에서 수정될 것으로 예상됩니다.

Udev는 snd-pcm-oss와 같은 “wrapper” 드라이버 및 loop와 같은 비하드웨어 드라이버를 전혀 로드하지 않습니다.

9.3.3.2. 커널 모듈은 자동으로 로드되지 않으며 Udev는 이를 로드하지 않습니다.

“wrapper” 모듈이 다른 모듈이 제공하는 기능만 향상시키는 경우(예: snd-pcm-oss는 사운드 카드를 OSS 응용 프로그램에서 사용할 수 있게 함으로써 snd-pcm의 기능을 향상시킵니다), udev가 래핑된 모듈을 로드한 후에 래퍼를 로드하도록 modprobe를 구성합니다. 이렇게 하려면 해당 /etc/modprobe.d/<파일 이름>.conf 파일에 “softdep” 줄을 추가합니다. 예를 들어

“softdep” 명령은 pre: 종속성 또는 pre: 종속성과 post: 종속성을 혼합하여 사용할 수도 있습니다. “softdep” 구문 및 기능에 대한 자세한 내용은 modprobe.d(5) man 페이지를 참조하세요.

9.3.3.3. Udev가 원치 않는 모듈을 로드하는 경우

모듈을 빌드하지 않거나 아래 예제의 forte 모듈에서와 같이 /etc/modprobe.d/blacklist.conf 파일에 블랙리스트에 추가합니다.

블랙리스트에 추가된 모듈은 명시적인 modprobe 명령을 사용하여 수동으로 로드할 수 있습니다.

9.3.3.4. Udev가 디바이스를 잘못 만들거나 잘못된 심볼릭 링크를 만듭니다.

일반적으로 규칙이 예기치 않게 디바이스와 일치하는 경우 이런 문제가 발생합니다. 예를 들어, 잘못 작성된 규칙은 공급업체에 따라 SCSI 디스크(원하는)와 해당 SCSI 일반 장치(잘못된)를 모두 일치시킬 수 있습니다. 문제가 있는 규칙을 찾아서 udevadm info 명령을 사용하여 보다 구체적으로 작성하세요.

9.3.3.5. Udev 규칙이 불안정하게 작동함

이것은 이전 문제의 또 다른 징후일 수 있습니다. 그렇지 않고 규칙이 sysfs 속성을 사용하는 경우 커널 타이밍 문제일 수 있으며, 이는 이후 커널에서 수정될 수 있습니다. 현재로서는 사용된 sysfs 속성을 기다리는 규칙을 만들어 /etc/udev/rules.d/10-wait_for_sysfs.rules 파일에 추가하여 이 문제를 해결할 수 있습니다(이 파일이 없는 경우 생성). 이 작업을 수행하면 LFS 개발 목록에 알려 주시면 도움이 됩니다.

9.3.3.6. Udev가 장치를 생성하지 않음

먼저 드라이버가 커널에 빌드되어 있거나 이미 모듈로 로드되어 있는지, udev가 잘못된 이름의 장치를 생성하지 않는지 확인합니다.

커널 드라이버가 데이터를 sysfs로 내보내지 않으면 장치 노드를 만드는 데 필요한 정보가 udev에 부족합니다. 이는 커널 트리 외부의 타사 드라이버에서 발생할 가능성이 높습니다. 적절한 주/부 번호를 사용하여 /usr/lib/udev/devices에 정적 장치 노드를 만듭니다(커널 설명서 또는 타사 드라이버 공급업체가 제공한 설명서 내의 devices.txt 파일 참조). 정적 장치 노드는 udev에 의해 /dev에 복사됩니다.

9.3.3.7. 재부팅 후 장치 이름 지정 순서가 임의로 변경됨

이는 udev가 설계상 이벤트를 처리하고 모듈을 병렬로 로드하므로 예측할 수 없는 순서로 로드하기 때문입니다. 이 문제는 결코 “고쳐”지지 않습니다. 커널 디바이스 이름이 안정적이라는 것에 의존해서는 안 됩니다. 대신 일련 번호 또는 udev에서 설치한 다양한 *_id 유틸리티의 출력과 같은 장치의 안정적인 속성을 기반으로 안정적인 이름으로 심볼릭 링크를 만드는 자체 규칙을 만드세요. 예는 9.4장 “디바이스 관리하기” 및 9.2장 “일반 네트워크 구성”을 참조하세요.

9.3.4. 유용한 참고 자료

다음 사이트에서 유용한 추가 문서를 확인할 수 있습니다.

devfs의 사용자 공간 구현
http://www.kroah.com/linux/talks/ols_2003_udev_paper/Reprint-Kroah-Hartman-OLS2003.pdf

sysfs 파일 시스템
https://www.kernel.org/pub/linux/kernel/people/mochel/doc/papers/ols-2005/mochel.pdf