“/ dev”Linux 파일은 어떻게 만들어 집니까?


112

Linux에는 실제로 파일이 아닌 특수 파일이 있습니다.

가장 주목할만한 예는 다음 dev과 같은 "파일"폴더에 있습니다.

  • /dev/null -파일에 쓰는 것을 무시합니다
  • /dev/random -파일 내용 대신 임의의 데이터를 출력
  • /dev/tcp -네트워크를 통해이 파일에 쓰는 모든 데이터를 보냅니다.

우선, 이런 종류의 "파일"의 이름은 실제로 어떤 종류의 스크립트 또는 이진 형태입니까?

둘째, 그것들은 어떻게 만들어 집니까? 이 파일들이 커널 레벨에서 시스템에 내장되어 있습니까, 아니면 "매직 파일"을 직접 만드는 방법이 /dev/rickroll있습니까?


1
나는 내가 찾고있는 것의 이름을 모르기 때문에이 질문에 태그를 붙이는 방법에 대한 단서가 없었습니다. 관련 태그를 자유롭게 편집하십시오.
IQAndreas

15
BTW, 이것은 유닉스 및 유닉스 계열 운영 체제 디자인의 기본 부분입니다. (거의) 모든 것이 파일이거나 파일처럼 보이게 만들 수 있습니다.
cas

5
참조 : mknod (2) man 2 mknod
RobertL

4
이들은 "장치 노드"입니다. 그러나 디스크, 키보드, 마우스, 오디오 카드 및 기타 장치와 관련된 장치와 달리 언급 한 장치는 "실제"장치가 아니며 커널에만 존재하기 때문에 "의사 장치"라고합니다. 적합한 장치 드라이버를 작성하여 새 장치를 만들어 커널에 추가 할 수 있습니다 (예 : 컴퓨터의 일부 활동을 모니터링하기위한 의사 장치). / dev-directory가 디스크에 존재하기 전에 – 요즘은 커널에 의해 만들어진 가상 파일 시스템 (devfs 유형)입니다.
Baard Kopperud

10
"실제"파일까지도 모든 파일은 소프트웨어 아티팩트입니다. 아직 발명되는 모든 장치, 파일, 소켓, 특수 파일, 또는 뭔가 뒤에 소프트웨어를 처리 할 수있는 기능의 테이블을 제공 open(), read(), close()이 소프트웨어에 달려, 그 후 등
waltinator

답변:


101

/dev/zero"특수 파일", 특히 "장치 노드"의 예입니다. 일반적으로 이러한 배포판 설치 과정에 의해 생성 얻을,하지만 당신은 할 수 완전히 당신이 원한다면 그들에게 자신을 만들 수 있습니다.

당신이 요청하는 경우 ls에 대해 /dev/zero:

# ls -l /dev/zero
crw-rw-rw- 1 root root 1, 5  Nov 5 09:34 /dev/zero

시작 부분의 "c"는 이것이 "문자 장치"임을 나타냅니다. 다른 유형은 "블록 장치"( ls"b"로 인쇄 됨 )입니다. 대략적으로 하드 디스크와 같은 임의 액세스 장치는 블록 장치 인 반면 테이프 드라이브 나 사운드 카드와 같은 순차적 장치는 문자 장치 인 경향이 있습니다.

"1, 5"부분은 "주요 장치 번호"및 "부 장치 번호"입니다.

이 정보를 사용하여 mknod명령을 사용하여 자체 장치 노드를 만들 수 있습니다 .

# mknod foobar c 1 5

이것은라는 새 파일을 생성 foobar하지 않습니다 현재 폴더에, 정확히 같은 일을 /dev/zero. (원하는 경우 다른 권한을 설정할 수도 있습니다.)이 "파일"에 실제로 포함 된 모든 항목은 위의 세 가지 항목 (장치 유형, 주 번호, 부 번호)입니다. 당신이 사용할 수있는 ls다른 장치의 코드를보고 너무 사람들을 다시 할 수 있습니다. 지루할 때 rm방금 만든 장치 노드를 제거하는 데 사용 하십시오.

기본적으로 주 번호는 Linux 커널에 어떤 장치 드라이버와 통신해야하는지, 부 번호는 장치 드라이버에 어떤 장치에 대해 말하고 있는지 알려줍니다. (예를 들어, 하나의 SATA 컨트롤러가있을 수 있지만 여러 개의 하드 디스크가 연결되어있을 수 있습니다.)

새로운 기능을하는 새로운 장치 를 발명 하려면 Linux 커널의 소스 코드를 편집하고 사용자 정의 커널을 컴파일해야합니다. 그러지 마! :-) 그러나 당신은 이미 잘 얻은 것과 중복되는 장치 파일을 추가 할 수 있습니다. udev와 같은 자동 시스템은 기본적으로 장치 이벤트를보고 자동으로 mknod/ rm를 호출 합니다. 그보다 더 마법은 없습니다.

여전히 다른 종류의 특수 파일이 있습니다.

  • 리눅스는 디렉토리를 특별한 종류의 파일로 간주합니다. (일반적으로 디렉토리를 직접 열 수는 없지만 가능한 경우 특수 형식의 데이터가 들어있는 일반 파일임을 알 수 있으며 커널에게 해당 디렉토리의 모든 파일을 찾을 위치를 알려줍니다.)

  • 심볼릭 링크는 특수 파일입니다. (단, 하드 링크는 없습니다.) ln -s명령을 사용하여 심볼릭 링크를 만들 수 있습니다 . (맨 페이지를 찾으십시오.)

  • "명명 된 파이프"또는 "FIFO"(선입 선출 대기열)라고하는 것도 있습니다. 으로 하나를 만들 수 있습니다 mkfifo. FIFO는 한 번에 하나의 읽기, 하나의 쓰기 로 두 개의 프로그램 으로 열 수있는 마법 파일입니다 . 이런 일이 발생하면 일반 쉘 파이프처럼 작동합니다. 그러나 각 프로그램을 개별적으로 시작할 수 있습니다 ...

어떤 방식 으로든 "특별"하지 않은 파일을 "일반 파일"이라고합니다. 때때로 유닉스 문서에서 이것에 대한 언급을 보게 될 것입니다. 그것이 의미하는 바입니다. 장치 노드 나 심볼릭 링크가 아닌 파일 마법 같은 속성이없는 일상적인 파일 일뿐입니다.


4
파일 시스템에 바인딩 된 Unix 도메인 소켓이라는 특수 파일 유형이 하나 더 있습니다.
Brian Bi

8
당신과 함께 재생하려면 mknod, 실행 cat /proc/devices모든 드라이버의 주 번호를 확인합니다. /proc파일 시스템 의 또 다른 종류의 특수 파일을 제공합니다 ( 이 답변에 대해 이야기합니다).
우고 렌

8
다른 유닉스가 자신의 특수 파일을 발명 한 예를 들어 솔라리스했다 문을 .
케빈

6
마이너 nitpick : 새 문자 / 블록 장치 : 쓰기 커널을 다시 컴파일 할 필요는 없습니다 crashcourse.ca/introduction-linux-kernel-programming/... 그렇지 않으면이 정말 좋은 답변, +1입니다!
사령관 고수 도롱뇽

1
@MathematicalOrchid : 답글이 누락 된 단계 (또는 적어도 암시 적으로 만 언급하는 단계)는 이러한 특수 파일이 셸 스크립트 나 바이너리가 아닌 (질의가 암시하는) 것이 아니라 존재하는 기능에 액세스하기위한 인터페이스라는 사실입니다. OS 커널에서.
Dreamer

34

대부분의 /dev항목은 블록 장치 아이 노드 또는 문자 장치 아이 노드입니다. Wikipedia는 그것에 대해 많은 세부 사항을 가지고 있으며 , 반복하지 않을 것입니다.

그러나 /dev/tcp귀하의 질문에 언급 된 것은 기존 답변 중 어느 것으로도 설명되지 않습니다. 대부분의 다른 항목 /dev/tcp/dev/udp다릅니다 /dev. 블록 및 문자 장치는 커널에 의해 구현되지만, /dev/tcp/dev/udp사용자 모드에서 실행된다.

배시 쉘의 일 구현이 하나 개의 프로그램 /dev/tcp/dev/udp(복사 ksh93). bash 경로 재 지정 연산자가있는 경로 아래에서 경로를 열려고하면 일반적인 open시스템 호출이 수행되지 않습니다 . 대신 bash는 TCP 소켓을 만들어 지정된 포트에 연결합니다.

즉 사용자 모드 만 분들께 사이의 차이를 보여줍니다 다음 예에서 볼 수 있듯이 일부 프로그램에서 구현 bash하고 cat열려고/dev/tcp/::1/22

$ cat /dev/tcp/::1/22
cat: /dev/tcp/::1/22: No such file or directory
$ cat < /dev/tcp/::1/22
SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.3

와 차이가 ksh93bash뿐만 아니라이 같은 파일을 열 수 있습니다 다른 장소에서, 리디렉션 연산자와 그 TCP 연결을 할 것 source또는 .내장을.


또한 GNU 는 2010 년경 이후로 gawk비슷한 특수 사례를 가지고 있습니다 /inet{,4,6}/{tcp,udp}/$port/$remote/$rport(정확히 기억하지 못하고 릴리스 노트를 찾을 수 없습니다).
dave_thompson_085

6
IMO, 요점을 설명하는 더 좋은 방법 /dev/tcp은 파일이 아니라는 것입니다. 이 파일 은 없습니다 . 소켓을 여는 Bash의 구문 /dev/tcp/address은 파일 이름과 같은 문자열을 사용 하지만 "사용자 공간에서 구현 된 파일"이라고 부르는 것은 이상하게 들립니다. 흥미롭게도 ksh리디렉션뿐만 아니라 모든 파일 이름을 연결합니다. "파일 구현"에 더 가깝습니다.
Peter Cordes

@ PetetCordes UWIN이 실제 파일로 설정한다고 생각합니다. 그리고 3dfs도 똑같이 생각합니다. bash이 동작 만 복사했지만 다른 곳에서 시작된 것임을 기억하십시오 .
mikeserv

19

장치 노드의 추가로 (으로 만든 다른 답변에서 설명 의 mknod (2) 일부 또는 공급 devfs가 ), 리눅스는 특별한 제공하는 다른 "마법"파일이 가상 파일 시스템 에서 특히를, /proc/(참조 (5) proc 디렉토리 에 대해 읽기 procfs의 ) 및 /sys/( sysfs 에 대해 읽어보십시오 ).

이러한 의사 파일 (예 : stat (2)에 나타나는 -파일이 아닌 일반 파일)은 커널에서 제공하는 가상보기입니다. 특히, 프로그램에서 읽 거나 /proc/(예 : 프로그램에서 open (2) -ing 으로 ) 읽을 때는 일반적으로 디스크 나 네트워크의 물리적 I / O가 포함되지 않으므로 매우 빠릅니다.cat /proc/$$/maps/proc/self/status

추가 의사 파일을 만들려면 /proc/일반적으로 자체 커널 모듈을 작성하여 로드해야합니다 (예 : this 참조 ).


3
AFAIK / proc 확장에 대한 정보가 오래되었습니다. 여전히 기술적으로 가능하지만 / proc (또는 오히려 procfs)는 실행중인 프로세스에 대한 정보 만 보유해야합니다. 커널에 대한 런타임 정보 또는 구성 옵션이 포함 된 파일을 포함하여 다른 모든 의사 파일은 / sys (sysfs)로 이동해야합니다. 호환성 이유로 / proc에 프로세스와 관련이없는 일부 의사 파일 (예 : meminfo, cpuinfo)이 여전히 있지만 새 의사 파일은 sysfs로 이동해야합니다.
Dreamer

13

이를 장치 노드라고하며 수동으로 mknod또는 자동 으로 생성합니다 udev. 일반적으로 커널에 드라이버가있는 문자 또는 블록 장치에 대한 파일과 같은 인터페이스입니다. 예를 들어 디스크는 블록 장치, tty 및 직렬 포트 등이 문자 장치입니다.

명명 된 파이프와 fifos 및 소켓을 포함하여 다른 "특별한"파일 형식도 있습니다.


9

다른 사용자가 이미 자세히 설명했듯이 특수 파일을 백업하려면 코드가 필요합니다. 그러나 리눅스가 사용자 공간에 해당 코드를 작성하는 몇 가지 방법을 제공한다고 언급 한 사람은 없습니다.

A. FUSE (USErspace의 파일 시스템)를 사용하면 /proc커널 충돌의 위험없이 무언가를 작성할 수 있으며 Go , Node.js , Perl , PHP , Python , Ruby , Rust , 등등 .

또한 FUSE 파일 시스템은 sudo사용자가 마운트를 수행 할 때 실행되기 때문에 마운트 할 수 없다는 이점이 있습니다 .

사람들이 FUSE를 사용하여 작성한 것들의 예는 다음과 같습니다.

  • mp3fs (FLAC 파일을 MP3 플레이어로 복사 / 클릭-드래그 할 때 즉석에서 생성되는 MP3 파일로 봅니다 )
  • PyTagsFS (메타 데이터 태그로 작성된 가상 폴더 트리에서 미디어보기)
  • fuse-zip (Zip 파일을 폴더로 마운트)
  • FuseISO (루트 권한이없는 ISO 마운트)
  • iFUSE ( iDevice 마운트)
  • FuseDAV (WebDAV 공유 마운트)
  • fuse-exfat (exFAT 형식의 파일 시스템 마운트)
  • NTFS-3g ( 리눅스 NTFS 드라이버)

B. 키보드, 마우스, 조이스틱 등과 같은 가상 입력 장치를 만들려면 (예 : 사용하려는 USB 장치의 사용자 공간 드라이버 작성 libusb) uinput이 있습니다.

바인딩은 찾기가 어렵지만 Go (키보드 전용), PythonRuby (2)에 존재한다는 것을 알고 있습니다 .

실제 uinput 사용의 예는 다음과 같습니다.

  • G15Daemon (Logitech G15 게임 키보드의 LCD 및 게임 키용 Linux 드라이버)
  • ds4drv (Sony DualShock 4 컨트롤러 용 드라이버)
  • xboxdrv ( Runner2 : Future Legend of Rhythm Alien 과 같이 잘못 설계된 게임 인 x360ce에 해당하는 대체 XBox 360 컨트롤러 드라이버 및 Linux 는 실제 XBox 컨트롤러와 대화하지 않을 때이를 생각할 수 있습니다)
  • 같은 오래된 Wiimote의 드라이버 cwiid 지원은 기본적으로 사용할 것, 그래서 누군가가 전에 요구되었다 마지막으로 커널 Wiimote의 드라이버를 썼다.

C. 일반 문자 장치에는 CUSE ( USErspace의 문자 장치)가 있습니다. 그래도 덜 인기가 있습니다.

: 나는 개인적으로 알고 해요 CUSE API의 유일한 사용자는 생성하라는 메시지가 같은 프로그램입니다 osspd , 구현 /dev/dsp, /dev/adsp그리고 /dev/mixer그들이 펄스 오디오 또는 DMIX를 통해 라우팅 할 수 있도록 사용자 공간에서합니다 (OSS 오디오 API).

내가 찾을 수있는 유일한 CUSE 바인딩은 cusepy 이며 2010 년 이후 업데이트되지 않았습니다.

D. 새로운 특수 파일이 전혀 필요하지 않을 수도 있습니다.

예를 들어 libusb (페이지의 바인딩 목록)를 사용하여 USB 장치와의 원시 통신을 연 다음 다른 메커니즘 (TCP / UDP 소켓, stdin / stdout 읽기 / 쓰기 또는 디스크의 일반 파일)을 통해 다른 프로그램과 통신 할 수 있습니다. 등).


1
cusepy는 한동안 업데이트되지 않았을 수도 있지만 (사실 업데이트되지 않았습니다. 커밋이 하나뿐입니다!) 몇 주 전에 cusepy를 사용하여 문자 장치를 작성한 후에도 여전히 제대로 작동하는지 확인할 수 있습니다. 구현과 관련된 몇 가지 함수가 누락 poll되었지만 cusepy는 ctypes를 사용하고 바인딩은 C 헤더 파일을 기반으로 자동 생성되므로 누락 된 함수를 수정하면 원하는 함수 이름을에서 내 보낸 함수 목록에 추가하면 setup.py됩니다.
Aleksi Torhamo

1
FUSE 사용법의 또 다른 흥미로운 예는 sshfs 입니다. 마치 SSH 연결을 사용하여 마치 로컬 인 것처럼 원격 파일 시스템을 찾아 볼 수 있습니다.
Mr. Deathless 2018

@ Mr.Deathless 그래. 나는 실제로 그것을 사용하고 언급하려고했지만 잊어 버렸습니다.
ssokolow

6

Linux 장치 드라이버 (권장) 책 에이 내용이 자세히 설명되어 있으며이를 설명하는 커널 모듈을 만들었더라도 간단히 말해 각 장치 드라이버에는 파일을 열거 나 닫을 때 호출되는 특정 기능이 있습니다 "특수"파일은 디스크의 스토리지 하드웨어에 액세스하는 대신 해당 기능 내에서 특별한 작업을 수행합니다.

예를 들어, write 함수 /dev/null는 바이트를 무시하고 아무것도하지 않습니다. 의 read 함수 /dev/random는 난수 를 반환합니다.


1

mount -t devtmpfs

현대 시스템에서는 /dev일반적으로 원하는 곳에 마운트 할 수있는 파일 시스템 유형이라는 것도 흥미 롭습니다 . 우분투 16.04 :

mkdir d
sudo mount -t devtmpfs none d
head -c 10 d/random
sudo umount d

이것은에 의해 활성화되며 CONFIG_DEVTMPFS=y커널 자체가 필요에 따라 장치 파일을 생성하고 파괴 할 수 있도록합니다.

CONFIG_DEVTMPFS_MOUNT=y

이 옵션은 커널을 devtmpfs에 자동 마운트합니다 /dev.

drivers/base/Kconfig 서류:

config DEVTMPFS_MOUNT
    bool "Automount devtmpfs at /dev, after the kernel mounted the rootfs"
    depends on DEVTMPFS
    help
      This will instruct the kernel to automatically mount the
      devtmpfs filesystem at /dev, directly after the kernel has
      mounted the root filesystem. The behavior can be overridden
      with the commandline parameter: devtmpfs.mount=0|1.
      This option does not affect initramfs based booting, here
      the devtmpfs filesystem always needs to be mounted manually
      after the rootfs is mounted.
      With this option enabled, it allows to bring up a system in
      rescue mode with init=/bin/sh, even when the /dev directory
      on the rootfs is completely empty.

file_operations

마지막으로, 자신의 캐릭터 장치 커널 모듈을 만들어서 무슨 일이 일어나고 있는지 정확하게 확인해야합니다.

실행 가능한 최소 예는 다음과 같습니다. 문자 장치 (또는 문자 특수) 파일 이해

가장 중요한 단계는 다음과 같이 file_operations구조체를 설정하는 것입니다 .

static const struct file_operations fops = {
    .owner = THIS_MODULE,
    .read = read,
    .open = open,
};

static int myinit(void)
{
    major = register_chrdev(0, NAME, &fops);
    return 0;
}

여기에는 각 파일 관련 시스템 호출에 대해 호출되는 함수 포인터가 포함됩니다.

그런 다음 파일 관련 시스템 호출을 재정 의하여 원하는 모든 작업을 수행한다는 것이 분명해 지므로 커널은 다음과 같은 장치를 구현합니다 /dev/zero.

/dev없이 자동으로 항목 만들기mknod

마지막 미스터리는 커널이 자동으로 /dev엔트리를 생성하는 방법 입니다.

이 메커니즘은 https://stackoverflow.com/questions/5970595/how-to-create-a-device-node-from-the-init-module-에 표시된대로 직접 커널 모듈을 만들어 관찰 할 수 있습니다. code-of-a-linux-kernel-module / 45531867 # 45531867device_create호출로 연결됩니다.


OpenBSD에는 MAKEDEV 스크립트가 있습니다. man.openbsd.org/MAKEDEV를 참조하십시오. Linux가 더 복잡한 이유를 제외하고 왜 Linux에 없는지 잘 모르겠습니다. 부품을 개조 할 수도 있습니다. 예를 들어 MKNOD tty라고 말하면 세부 정보를 처리합니다.
Alan Corey
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.