Devices

froajnzd·2024년 11월 19일
0

how linux works

목록 보기
2/8
post-thumbnail

기본 장치 파일 시스템을 살펴보도록 하겠다.
몇 가지 기본 작업을 이해하기 위해 시스템의 device에 대한 정보를 추출하겠다.

new device가 생겼을 때 kernel이 user space와 어떻게 상호작용하는지 이해하는 것이 중요하다.
udev system을 이용하면 user-space program이 새 장치를 자동으로 구성하고 사용할 수 있다.

1. Device Files

/dev 디렉토리에 존재한다
ex) /dev/sda (디스크), /dev/tty (터미널), /dev/null (특수 파일)
Kernel과 HW간의 인터페이스 역할을 한다.

장치 파일의 종류

  • b : Block device
    보통 하드디스크나 CD/DVD, 플로피디스크 등의 장치. 블록이나 섹터 등의 정해진 단위로 데이터 전송
    (ex. sda1)

  • c : Character device
    키보드, 마우스, 모니터, 프린터 등의 장치. Byte 단위로 데이터 전송.

  • p : Pipe device
    파일 시스템에서 이름을 가진 특별한 종류의 파일로, 데이터를 한 프로세스에서 다른 프로세스로 전달하는 데 사용

  • s : socket device
    프로세스 간 통신에서 자주 사용

2. The sysfs Device Path

이전의 /dev 디렉토리의 한계

  • 단순히 장치를 표현
  • 장치에 대한 정보 제한적
  • 재부팅 할 때마다 장치 이름이 바뀔 수 있음

새로운 방식 : sysfs (/sys)

장치의 실제 하드웨어 특성을 기반으로 정보 제공

ex) SATA 하드디스크의 경우

  • /dev에서는 => /dev/sda

  • /sys에서는 => /sys/devices/pci0000:00/0000:00:17.0/ata3/host0/target0:0:0/0:0:0:0/block/sda

  • /sys/block 기능 : 모든 블록 장치의 심볼릭 링크 제공

  • udevadm 기능 : 장치 정보 쉬운 확인

/dev와 /sys의 용도 차이

  • /dev : 장치를 사용하기 위한 인터페이스
  • /sys : 장치 정보 확인/관리를 위한 인터페이스

3. dd and Devices

파일이나 장치의 데이터를 읽고 쓰는 매우 강력한 도구
특히 블록 단위로 데이터를 다룰 때 유용
⚠️ 주의: 매우 강력해서 실수하면 데이터를 손상시킬 수 있음

사용 예시

dd if=/dev/zero of=new_file bs=1024 count=1

  • if=파일명: 입력 파일 (input file) 어디서 데이터를 읽을지
  • of=파일명: 출력 파일 (output file) 어디에 데이터를 쓸지
  • bs=크기: 블록 크기 (block size) 한 번에 얼마나 많은 데이터를 처리할지
  • count=숫자: 복사할 블록 수
  • skip=숫자: 입력에서 몇 블록을 건너뛸지

용도

  • 디스크나 파티션 백업
  • 특정 크기의 테스트 파일 생성
  • 디스크 성능 테스트
  • 파일의 특정 부분만 추출

4. Device Name Summary

4.1. Hard Disks : /dev/sd*

4.2. Virtual Disk : /dev/xvd, /dev/vd

4.3. Non-Volatile Memory Devices : /dev/nvme*

4.4. Device Mapper : /dev/dm-*, /dev/mapper

4.5. CD and DVD Drivers : /dev/sr*

4.6. PATA Hard Disks : /dev/hd*

4.7. Terminals : /dev/tty, /dev/pts/, /dev/tty

터미널은 user process와 I/O 장치 사이에서 문자를 움직이기 위한 장치로, 일반적으로 터미널 화면에 텍스트를 출력하기 위한 장치이다.
터미널 장치 인터페이스는 터미널이 타자기 기반 장치였던, 단일 기계에 연결했던 시절로 가야한다.

많은 터미널들은 pseudoterminal 장치로, 실제 터미널의 I/O 기능을 이해하는 에뮬레이트된 터미널이다. 실제 하드웨어와 통신하는 대신, kernel은 I/O 인터페이스를 셸 터미널 창 같은 SW 일부에 제공한다.

일반적으로 터미널 장치는 /dev/tty1(첫 번째 가상 콘솔), /dev/pts/0(첫 번째 의사 터미널 장치) 두 개가 있다.

/dev/pts 폴더는 전용 파일 시스템이다.

/dev/tty 장치는 "현재 프로세스"를 control하는 터미널이다. 현재 실행 중인 프로세스가 연결된 터미널을 자동으로 참조한다. 예로, 네가 /dev/pts/0에서 프로그램을 실행한다면, /dev/tty는 내부적으로 /dev/pts/0을 가르킨다.
모든 프로세스가 터미널과 연결된 것은 아니다. 백그라운드 프로세스나 데몬같은 경우는 터미널과 연결되지 않으므로 이 경우 /dev/tty는 의미가 없다.(터미널과 연결된 프로세스인 경우에만 /dev/tty로 입출력을 처리할 수 있다)

4.8. Serial Ports : /dev/ttyS, /dev/ttyUSB, /dev/ttyACM*

RS-232 타입 및 이와 비슷한 시리얼(직렬) 포트는 실제 터미널 장치로 인식된다.
전송 속도, 흐름 제어와 같이 신경써야 할 세팅이 너무 많기에, 시리얼 포트 장치를 사용하는 명령줄에서 많은 작업을 수행할 수는 없지만, screen 명령으로 장치 경로를 인수로 추가해 터미널에 연결할 수 있다.
장치에 대한 읽기/쓰기 권한이 필요할 수 있다.
때로 dialout같이 특정 그룹에 자신을 추가해 이 작업을 수행한다.
윈도우의 COMI port는 /dev/ttyS0 이고, COM2는 /dev/ttyS1, ....이다.
플러그인 USB 직렬 어댑터는 USB, ACM과 함께 /dev/ttyUSB0, /dev/ttyACM0, /dev/ttyUSB1, /dev/ttyACM1 등으로 표시된다.

4.9. Parallel Ports : /dev/lp0, /dev/lp1

USB 및 네트워크로 대체된 인터페이스 유형을 나타내는 단방향 병령 포트 장치 /dev/lp0, /dev/lp1은 윈도우의 LPT1, LPT2에 해당된다.
cat 명령을 이용해서 파일을 병렬 포트로 직접 보낼 수 있지만, 프린터에 추가 양식 피드를 제공하거나 추후에 재설정해야할 수 있다.
CUPS와 같은 프린트 서버는 프린터와의 상호작용성이 좋다.

양방향 병렬 포트는 /dev/parport0, /dev/parport1 이다.

4.10. Audio Devices : /dev/snd/*, /dev/dsp, /dev/audio, and more...

리눅스는 2개의 오디오 장치 그룹이 있다.
ALSA(Advanced Linux Sound Architecture) 시스템 인터페이스와 이전의 OSS(Open Sound System)를 위한 별도의 장치가 있다.
ALSA 장치는 /dev/snd 폴더에 있으나, 직접 작업하는 것은 어렵다
ALSA를 사용하는 리눅스 시스템은 OSS 커널 지원이 로드된 경우, OSS 이전 버전과 호환하는 장치를 지원한다.

OSS dsp, 오디오 장치를 사용해 일부 기본 작업을 할 수 있다. 예로, /dev/dsp로 보내는 모든 WAV 파일을 컴퓨터에서 재생할 수 있다. 그러나 하드웨어는 주파수 불일치로 인해 예상대로 작동하지 않을 수 있다. 또한, 대부분의 시스템에서는 로그인하자마자 장치가 사용 중인 경우가 많다.

4.11. Device File Creation

최근의 리눅스 시스템은 사용자가 직접 장치 파일을 만들 필요가 없다. devtmpfs, udev 시스템이 자동으로 관리한다.

mknod 명령어 : 하나의 장치를 작성하는 전통적인 방법

mknod /dev/sda1 b 8 1

b 8 1에서

  • b : 블록 장치
  • 8 : 주 번호(major number)
  • 1 : 부 번호(minor number)

b 대신 c(character)나 p(pipe device: named pipes의 경우 major, minor 번호 생략)를 사용할 수 있다.

  • 과거의 문제점
    • 커널이 업그레이드될 때마다 새로운 장치들이 추가됨
    • 각 장치마다 새로운 번호를 할당해야 함
    • MAKEDEV 프로그램으로 장치 파일들을 생성/관리함
    • 시스템 업그레이드 시마다 MAKEDEV도 업데이트해야 함
  • 해결 방안
    • 첫 변화: devfs (커널 내부에서 /dev 관리)
    • 현재 : udev, devtmpfs (개선됨)

5. udev

  • udevd : 리눅스의 user space daemon으로, 새로운 장치가 연결되었을 때, 이를 감지하고 적절한 장치
  1. 리눅스에서는 udevd 프로그램(user space)이 장치 파일을 만드는 역할을 한다.(컴퓨터에 USB를 꽂으면 kernel이 새 장치가 연결되었음을 udevd에 알려줌)
  2. 장치를 만드는 일을 kernel이 안하는 이유는 kernel은 시스템의 핵심이며 많은 일을 하면 복잡해지기에 시스템이 불안정해질 수 있다. 그래서 이런 일은 user space 프로그램에게 맡긴다.(즉, 커널은 하드웨어를 감지하는 역할까지만 한다)
  3. 문제는? 부팅 초기에 문제가 생길 수 있다. 컴퓨터를 부팅할 때, 디스크나 다른 장치에 접근하려면 장치 파일이 이미 존재해야하지만, 이 장치 파일을 만드는 udevd는 부팅 중간에 시작된다. 그리하여 udevd는 최대한 빨리 실행되어야 하며, 다른 장치/파일에 의존하지 않고 작동되어야 함

즉, 부팅 초기에 장치 파일이 필요하기에 udev가 빨리 시작해야 하는 부팅 속도 및 의존성 문제가 생긴다.
이를 해결하기 위하여 필수 장치 파일은 부팅 시 미리 만들어두거나, udevd가 매우 빠르게 작동하도록 최적화한다.

5.1. devtmpfs

부팅 중 장치 가용성 문제에 대응하기 위해 개발
devfs와 유사하지만 조금 더 단순화되었다.

$ ls -l /dev/disk/by-id
 lrwxrwxrwx 1 root root  9 Jul 26 10:23 scsi-SATA_WDC_WD3200AAJS-_WD-WMAV2FU80671 -> ../../sda
 lrwxrwxrwx 1 root root 10 Jul 26 10:23 scsi-SATA_WDC_WD3200AAJS-_WD-WMAV2FU80671-part1 ->
 ../../sda1
 lrwxrwxrwx 1 root root 10 Jul 26 10:23 scsi-SATA_WDC_WD3200AAJS-_WD-WMAV2FU80671-part2 ->
 ../../sda2
 lrwxrwxrwx 1 root root 10 Jul 26 10:23 scsi-SATA_WDC_WD3200AAJS-_WD-WMAV2FU80671-part5 ->
 ../../sda5

5.2. udevd Operation and Configuration

udevd daemon 동작 방식

  1. kernel은 내부 네트워크 링크를 통해 uevent 알림 이벤트를 udevd에 보낸다.
  2. udevd는 uevent의 모든 속성을 로드한다
  3. udevd는 규칙을 파싱하고, 해당 규칙에 따라 uEvent를 필터링/업데이트하고, 그에 따라 작업을 수행하거나 더 많은 속성을 설정한다

5.3. udevadm

udevadm 프로그램은 udevd의 관리 도구이다
udevd 규칙을 다시 로드하고, event를 트리거할 수 있지만, udevadm의 가장 강력한 기능은 시스템 장치를 검색/탐색하는 기능과 udevd가 kernel에서 uevents를 수신할 때 uevents를 모니터링하는 기능일 것이다.

5.4. Device Monitoring

6. In-Depth : SCSI and the Linux Kernel

SCSI와 리눅스 커널의 관계: 이 내용은 디스크 사용에 꼭 필요한 것은 아니며, 리눅스 커널 구조를 이해하는 데 도움이 되는 심화 내용이다

SCSI: 하드웨어 장치(ex: 하드디스크, CD/DVD 드라이브)를 컴퓨터와 연결하고, 이들과 데이터를 주고받을 수 있게 해주는 통신 표준

  • 전통적인 SCSI 구성
    • host adapter : 컴퓨터에 연결된 장치를 관리하는 장치. 컴퓨터는 장치와 직접 소통하지 않고, 이 호스트 어댑터를 통해 명령을 전달한다.
    • SCSI device : 하드 디스크나 CD/DVD 드라이브 같은 하드웨어 장치. 이 장치들은 각자 SCSI ID라는 고유 번호를 가진다.

리눅스에서 SCSI를 관리하는 방법.
리눅스 커널에는 SCSI 서브시스템이라는 계층 구조가 있으며 이 구조는 3개의 층으로 나뉜다.

  1. Top Layer
    장치의 종류에 따라 필요한 명령을 처리
    예로, sd 드라이버는 커널의 요청을 디스크가 이해할 수 있는 명령으로 변환한다.
  2. Middle Layer
    SCSI 메세지를 상위 계층과 하위 계층 사이에서 전달하고, 시스템에 연결된 모든 SCSI 장치를 관리한다. (메세지 교환소)
  3. Bottom Layer
    실제 하드웨어와 소통
    Host Adapter가 장치에 명령을 보내고, 응답을 받아오는 구체적인 과정을 처리한다.

예로, 디스크 파일 /dev/sda가 있다고 하자.

  • Top Layer Driver : sd 드라이버가 명령을 처리
  • Bottom Layer Driver : ATA bridge 드라이버가 디스크와 실제 통신
  • kernel은 이 두 드라이버를 사용해 디스크를 제어

전통적인 SCSI 장치는 요즘엔 잘 쓰지 않지만, USB 저장장치나 CD/DVD 드라이브는 여전히 SCSI 명령 세트를 사용.

SATA 디스크(일반적인 하드 디스크나 SSD)도 리눅스에서는 SCSI 장치로 나타낼 수 있음

  • 대부분 libata 번역 계층을 통해 SCSI 명령 사용
  • 고급 RAID 컨트롤러는 번역을 하드웨어에서 처리하기도 함

SCSI 같이 복잡한 구조를 쓰는 이유

  • SCSI 장치와 kernel 간의 명령 통신을 효율적이고 일관성있게 관리하기 위해
  • 계층 구조를 도입함으로써, 각 드라이버가 자신의 역할만 신경 쓰면 되기 때문에 유지보수와 확장이 쉬워짐

6.1. USB Storage and SCSI

6.2. SCSI and ATA

6.3. Generic SCSI Devices

6.4. Multiple Access Methods for a Single Device

profile
Hi I'm 열쯔엉

0개의 댓글