[디바이스 파일] /dev Files, sysfs, udevadm, udevd, SCSI, tty

markyang92·2021년 8월 29일
1
post-thumbnail

디바이스 파일

종류

'b': block device

  • 프로그램은 고정된 양을 가진 block device로부터 데이터에 접근한다.
  • sda1과 같은 '디바이스 파일'은 1)디바이스 파일 이며 2)block device에서 3)디스크 장치이다.
    • 디스크 장치는 아주 쉽게 block 단위의 데이터로 분리된다.
    • 블록 장치의 전체 크기고정, idx로 정리하기 쉽기 때문에 프로세스는 커널의 도움으로 장치의 어떤 블록이든지 임의로 접근 할 수 있다.
  • 버퍼 캐시를 사용
  • sda 의 sda1, sda2는 각각 sda의 파티션이다.
    • sda, sda1, sda2는 각각의 Major, Minor 번호를 가진다.
    • 디바이스 파일에 접근할 때, 아래와 같은 Major -> Minor 순으로 접근한다.
      • 이 번호들은 각각 1Byte만 할당되어, 디스크당 파티션 수가 제한되는 것임


'c': character device

  • 데이터 스트림과 함께 작동된다.
  • 문자를 r/w 가능하다.
    • r/w 때 커널이 장치상에서 읽고 쓰는 작업을 수행한다.
  • character device는 크기를 가지고 있지 않다!!!!
  • 컴퓨터에 직접 연결된 프린터는 character device 라고 할 수 있다.
  • character device의 상호 간 작동이 이뤄지는 동안, 커널은 데이터를 장치나 프로세스에 전달한 후에 데이터를 백업하고 재컴토하지 않는다는 점에 유의한다.
  • 버퍼 캐시 사용 안함

pipe device

  • named pipe와 비슷하다.
  • 커널 드라이버 대신 I/O stream의 다른 쪽에 또 다른 프로세스를 가지고 있다.

socket device

  • 소켓은 프로세스 간의 소통을 위해 자주 사용되는 특수 목적의 인터페이스다.

/dev/sd* : SCSI 디스크 디바이스 파일

  • sd가 붙는 디바이스 파일은 스카시(SCSI) 디스크 디바이스 파일이다.
    • 원래는 디스크 같은 장치들과 그 외 주변 장치들 간의 소통을 위한 HW와 프로토콜 표준으로 개발되었다.
    • 전통적인 SCSI HW는 현재 사용되지 않지만, SCSI 프로토콜은 융통성이 뛰어나 현재에도 사용되고 있다.
    • 시스템 상의 SCSI 장치들을 목록으로 정리하려면, sysfs에서 제공하는 장치 경로를 나타내는 유틸리티를 사용해야한다.
      • lsscsi 유틸리티
    • 만약 fstab에서 직접 /dev/sdb 와 같이 명시했을 경우, /dev/sdb가 깨지면 마운트 안됨
      • 이를 방지하기 위해 지속적으 접근할 수 있는 '보편적 고유 식별자'(Universally Unique Identifier, UUID)를 사용한다.

SCSI subsystem 구성

  1. SATA, USB 모두 SCSI 서브시스템에서 다루어진다.

SCSI Generic devfile: sg*

  • 만약 SCSI 디스크 디바이스 파일 하나를 읽고 쓸때를 대비한 Generic Dev file을 둔다.

  • 원래는 더 많은 레이어들이 있지만, 여기 까지만 알아도 사용하는데 지장 없다.

/dev/tty*, /dev/pts/* : 가상 콘솔, 의사 터미널

  • 터미널은 사용자 프로세스I/O 장치 간의 문자들을 옮기는 디바이스 파일
  • 의사 터미널(pseudoterminal) 장치는 실제 터미널의 I/O 기능을 이해하는 모조 터미널이라고 할 수 있다.
    • 그러나 이는 실제 H/W와 소통하는 것이 아니라 커널이 소프트웨어 일부분에 I/O 인터페이스를 제공하는 것
  • /dev/tty*: 가상 콘솔
    • /dev/tty*: 현재 프로세스의 제어 터미널. 프로그램이 현재 터미널에서 읽고 쓰고 있는중이라면 이 디바이스는 그 터미널과 같은 것이며 터미널에 연결될 필요가 없다.
    • tty에 관해 linux 디스플레이는 링크 글 참고
  • /dev/pts/*: 의사 터미널

/dev/ttyS* : 직렬 포트

  • RS232 및 직렬 포트
    • baud rate
    • flow contorl 신경 써야함
  • Windows 에서 COMn Port
    • COM1 = /dev/ttys0
  • USB
    • /dev/ttyUSB0, /dev/ttyACM0 ....

/dev/lp0,1 : 병렬 포트

  • 단일 병렬 포트 장치(주로 USB에 의해 대체된 인터페이스 타입)
  • Windows 에서 LPT1:, LPT2:에 해당
    • LPT1:, LPT2: = /dev/lp0, /dev/lp1
  • cat 명령을 통해 파일들을 병렬 포트로 전송할 수 있다.
  • 프린터에 추가로 폼 피드(form feed, 서식 이송)나 리셋을 부여해야할 것이다.
  • CUPS같은 프린터 서버는 프린터와 상호작용을 훨씬 더 잘 조절한다.

/dev/parport0,1: 양방향 병렬 포트


/dev/snd/*, /dev/dsp, /dev/audio

  • 리눅스에서는 두 가지 종류의 오디오 장치를 갖고 있다.
  1. 고급 리눅스 사운트 아키텍쳐(Advanced Linux Sound Architecture, ALSA)
    1.1 ALSA는 /dev/snd 디렉터리에 위치
    1.2 ALSA를 사용하는 리눅스 시스템은 만약 OSS 커널 지원이 현재 로딩된다면 OSS(구 버전) 호환이 가능한 장치를 지원한다.
  2. 오픈 사운드 시스템(Open Sound System, OSS)
  1. 일부 기본적인 기능들은 OSS dsp와 오디오 장치들을 통해 가능하다.
    컴퓨터는 /dev/dsp로 전송한 WAV 파일을 재생한다.
    그러나 HW가 주파수 불일치 때문에 생각대로 실행하지 못할 수도 있다.
    위는 커널 수준의 장치들 이지만 펄스(pulse) 오디오와 같은 전형적인 사용자 공간 서버가 있다. 이는 다양한 소스로부터 오디오를 관리하고, 음향 장치와 그 외 사용자 공간 프로세스 간의 중개인 처럼 작용한다.

custom dev file 만들기

  • 거의 사용하지 않지만(named pipe 사용할 때는 말고) 디바이스 파일을 만드는 법을 알면 도움이 된다.

$ mknod: 디바이스 생성

  • /dev/sda1 디바이스 파일을 b 블록 디바이스로 Major: 8 Minor: 2로 만느는 명령은 아래와같이 한다.
$ sudo mknod /dev/sda1 b 8 2

  • Named pipe의 경우 b(블록 디바이스) 대신, c또는 p를 사용하며, Major와 Minor를 생략한다.

sysfs: 장치 경로

  • /dev는 사용자 프로세스가 커널에서 지원하는 장치들을 참조하고 접속하기에 아주 편리하다.
  • 하지만, 장치들이 발견되는 순서에 따라 커널이 장치들을 배정
    • 재부팅하면 device file이 바뀔수 있음
  • 따라서 커널은 파일과 디렉터리의 시스템을 통해 sysfs 인터페이스를 제공한다.

/dev/sda의 예

  1. /dev/sda

    /dev/sda, 8:0
    /dev/sda1, 8:1
    /dev/sda2, 8:2

  1. /sys

    /sys/block

  1. /sys/block/

    /dev/sdasysfs: /sys/devices/platform/214000.ahci/ata1/host0/target0:0:0/0:0:0:0/block/sda

  1. /sys/block/sda

    $ cat dev를 해보면 major:minor 번호 나온다.
    실제로 프로그램은 /dev/sda를 사용할 때, 이 곳을 사용한다.

$ udevadm: 디바이스장치의 sysfs를 알려줌

  • device file의 sysfs를 노가다로 찾기는 힘들다.
  • 리눅스에서는 udevadm이라는 명령을 통해 쉽게 device file의 sysfs를 찾을 수 있다.
$ udevadm info --query=all --name=/dev/sda


  • udevadmudevd의 관리자 툴이다.
    • udevd rules를 리-로드 하고 이벤트가 동작하도록 할 수 있다.
  • N: 장치 노드(Node, 즉 /dev 파일에 주어지는 이름)
  • S: udevd가 그 rule에 따라 /dev에 생성한 장치 노드로 이어지는 심볼릭 링크
  • E: udevd가 rules에서 발췌한 장치의 추가 정보

$ udevadm monitor

$ sudo udevadm monitor [Options]
OptionsDescriptione.g.
--kernel오직 커널 이벤트만 봄
--udev외부로 나가는 이벤트만 봄
--property유입되는 전체 uevent
--subsystem-match='type'매치되는 서브시스템만 봄--subsystem-match=scsi
  • USB를 뺐다 꽂았을 때의 udevadm monitor 내용

devtmpfs

  • devtmpfs 파일 시스템은 부팅 시에 장치 활용에 관한 문제에 대응하면서 발전된 시스템이다.
  • 커널은 필요에 따라 디바이스 파일들을 생성하고 새로운 디바이스를 사용할 수 있다는 것을 udevd에게 통지한다.
    • 이 신호를 받은 udevd는 디바이스 파일을 생성하지는 않지만, 장치 초기 설정을 수행하고 프로세스에 통지한다.
    • udevd는 장치를 식별하도록 /dev에 많은 심볼릭 링크들을 생성한다.
      • /dev/disk/by-id 디렉토리에 이런 예를 발견할 수 있다.
      • udevd는 인터페이스 타입, 제조사와 모델정보, 시리얼번호, 파티션으로 링크의 이름을 만들고 디바이스 파일과 연결한다.
  • /dev/disk/
  • /dev/disk/by-id

udevd

  • udevd 데몬은 다음과 같이 동작한다.
  1. 커널은 udevd로 내부 네트워크 링크를 통해 uevent라는 알림 이벤트 전송
  2. udevduevent내 모든 속성 로딩
  3. udevd는 그 규칙들을 분석하고 조치를 취하거나 그 규칙들을 기반으로 더 많은 속성들을 설정한다.

  • udevd가 커널로부터 받아서 유입되는 uevent는 다음과 같다.
ACTION=change
DEVNAME=sde
DEVPATH=/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.0/host4/target4:0:0/4:0:0:3/block/sde
DEVTYPE=disk
DISK_MEDIA_CHANGE=1
MAJOR=8
MINOR=64
SEQNUM=2752
SUBSYSTEM=block
UDEV_LOG=3
  • uevent를 받은 다음, udevdsysfs 장치 경로를 알게 된 상태이고, 그 속성들과 연관있는 다른 많은 attributes도 인지한다.
  • rules file은 /lib/udev/rules.d/etc/udev/rules.d 디렉터리에 있다.
    • /lib 내 rule은 디폴트다.
    • /etc 내 rule은 디폴트 규칙을 무시할 수 있다.

udevd는 아래 rule을 참고한다.


/lib/udev/rules.d/60-persistent-storage.rules

  • 위 규칙은 커널의 SCSI 서브시스템이 제시한 ATA 디스크와 부합한다. (위 SCSI subsystem 구성 참고)
  1. udevd(KERNEL=="sd*[!0-9]|sr*"...로 인해 'sd*+숫자'(/dev/sdb1 같은 파티션)가 포함되지 않고 SUBSYSTEMS=="scsi"를 만족하는 장치를 찾도록할 것이다.
  2. IMPORT{program}="ata_id --export $devnode
    2-1. /lib/udev/ata_id 명령으로부터 변수를 불러오는 import 지시어를 사용한다.
$ sudo /lib/udev/ata_id --export /dev/sda
ID_ATA=1
ID_TYPE=disk
ID_BUS=ata
ID_MODEL=TAMMUZ_SSD
ID_MODEL_ENC=TAMMUZ\x20SSD\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
ID_REVISION=S0130B0
ID_SERIAL=TAMMUZ_SSD_TM550X19335120331N
ID_SERIAL_SHORT=TM550X19335120331N
ID_ATA_WRITE_CACHE=1
ID_ATA_WRITE_CACHE_ENABLED=1
ID_ATA_FEATURE_SET_HPA=1
ID_ATA_FEATURE_SET_HPA_ENABLED=1
ID_ATA_FEATURE_SET_PM=1
ID_ATA_FEATURE_SET_PM_ENABLED=1
ID_ATA_FEATURE_SET_SECURITY=1
ID_ATA_FEATURE_SET_SECURITY_ENABLED=0
ID_ATA_FEATURE_SET_SECURITY_ERASE_UNIT_MIN=2
ID_ATA_FEATURE_SET_SECURITY_ENHANCED_ERASE_UNIT_MIN=2
ID_ATA_FEATURE_SET_SECURITY_FROZEN=1
ID_ATA_FEATURE_SET_SMART=1
ID_ATA_FEATURE_SET_SMART_ENABLED=1
ID_ATA_FEATURE_SET_APM=1
ID_ATA_FEATURE_SET_APM_ENABLED=1
ID_ATA_FEATURE_SET_APM_CURRENT_VALUE=254
ID_ATA_DOWNLOAD_MICROCODE=1
ID_ATA_SATA=1
ID_ATA_SATA_SIGNAL_RATE_GEN2=1
ID_ATA_SATA_SIGNAL_RATE_GEN1=1
ID_ATA_ROTATION_RATE_RPM=0
  • import는 출력에 있는 모든 변수 이름이 위와 같은 값들로 설정되도록 환경을 설정한다.
  1. 이제 부터 예를 들면 ENV{ID_BUS}ata로 인식할 것이다.
  2. ENV{ID_SERIAL}!="?*"ID_SERIAL이 설정이 되어 있지 않으면 참이란 말이다.
    4-1. 만약 설정이 되어 있다면, 조건은 false. 현재 전체 규칙은 false이다. 그리고 udevd는 다음으로 넘어간다.

    4-2. ENV{ID_SERIAL}이 설정되도록 요구한다.
  3. SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}"을 적용한다.
    5-1. 이 지시어를 udev가 만나면, 유입(incoming)되는 장치를 심볼릭 링크로 추가한다.
profile
pllpokko@alumni.kaist.ac.kr

0개의 댓글