임베디드기사 실기 20부작 8편
mknod와 Major/Minor Number, /dev Device Node 완전 이해
앞선 연재에서 Kernel Module이 로드되고 register_chrdev()를 통해 Character Device Driver가 Kernel에 등록되는 흐름을 살펴보았습니다. 그런데 여기서 한 가지 중요한 질문이 남습니다.
“Kernel에 Driver를 등록했다고 해서 User Application이 곧바로 그 Driver를 사용할 수 있을까?”
정답은 그렇지 않습니다. User Space의 Application은 Kernel 내부 함수에 직접 접근할 수 없기 때문에, 양쪽을 연결해 주는 장치 파일(Device Node)이 필요합니다. 이때 전통적으로 사용되는 명령이 바로 mknod입니다.
mknod는 Make Node의 약자로, Linux/Unix에서 Device File이나 특수 파일을 만드는 명령입니다. 임베디드 Linux에서는 특히 Kernel Driver와 User Application을 이어 주는 /dev 아래의 Device Node를 만드는 용도로 자주 다뤄집니다.
시험 답안에서는 다음 문장 정도로 정리하면 좋습니다.
mknod는 Kernel에 등록된 Device Driver를 User Space에서 접근할 수 있도록 /dev 디렉터리에 Device Node를 생성하는 명령이다.
Linux는 User Space와 Kernel Space를 분리합니다. 일반 Application은 Hardware Register나 Kernel Memory를 마음대로 읽고 쓸 수 없습니다. 대신 Kernel이 제공하는 Driver Interface를 통해 접근해야 합니다.
[ User Application ]
|
open/read/write/ioctl
|
[ /dev/mydevice ]
|
Major / Minor Number
|
[ Kernel Device Driver ]
|
MMIO / I/O Register
|
[ Physical Hardware ]
따라서 /dev/mydevice는 단순한 일반 파일이 아니라, User Application이 Kernel Driver를 호출할 수 있도록 해 주는 입구라고 이해하면 쉽습니다.
mknod [장치파일명] [타입] [Major Number] [Minor Number]
예를 들어 Major Number가 240인 Character Driver를 User Space에서 /dev/fpga_ctrl이라는 이름으로 사용하고 싶다면 다음과 같이 만들 수 있습니다.
sudo mknod /dev/fpga_ctrl c 240 0
여기서 c는 Character Device, 240은 Major Number, 0은 Minor Number입니다.
| 구분 | 기호 | 특징 | 예 |
|---|---|---|---|
| Character Device | c | Byte/Stream 중심 접근 | UART, Sensor, GPIO 계열 |
| Block Device | b | Block 단위 접근, Buffer/Cache 활용 | Disk, eMMC, USB Storage |
| Named Pipe | p | IPC용 FIFO | Process 간 통신 |
실기 문제에서는 “Character Device를 나타내는 기호” 또는 “Block Device의 예”처럼 짧은 형태로 출제될 수 있습니다.
Major Number는 “이 Device Node가 어느 Driver와 연결되는가?”를 식별하는 번호입니다. Kernel이 Character Driver를 등록할 때 Major Number를 부여하거나 할당하고, User Space의 Device Node는 같은 Major Number를 사용해 해당 Driver와 연결됩니다.
쉽게 비유하면 Major Number는 회사 대표번호와 비슷합니다. 어느 Driver 그룹에 연결할지를 결정합니다.
Major Number = Driver 식별 번호
Minor Number는 같은 Driver가 여러 Device를 관리할 때 개별 장치를 구분하기 위한 번호입니다.
예를 들어 하나의 Driver가 여러 Motor Controller를 관리한다고 가정하면 다음처럼 구성할 수 있습니다.
/dev/motor0 → Major 240, Minor 0 /dev/motor1 → Major 240, Minor 1 /dev/motor2 → Major 240, Minor 2
세 Device Node 모두 같은 Driver를 사용하지만 Minor Number를 통해 어떤 장치인지 구분할 수 있습니다.
Minor Number = 동일 Driver 아래의 개별 Device 식별 번호
이 부분은 실기에서 매우 중요합니다. 두 기능을 따로 외우지 말고 한 쌍으로 이해해야 합니다.
| Kernel Space | User Space |
|---|---|
register_chrdev()Character Driver를 Kernel에 등록 |
mknod/dev Device Node 생성 |
즉, Kernel에 Driver가 존재하더라도 User Space에서 접근할 Device Node가 없다면 Application 입장에서는 접근 경로가 없습니다. 반대로 Device Node만 있고 Driver가 Kernel에 제대로 등록되어 있지 않다면 역시 정상 동작하지 않습니다.
register_chrdev() + mknod + open()의 세 단계를 연결해서 기억하면 좋습니다.
Device Node가 만들어지면 User Application은 일반 파일과 비슷한 방식으로 접근합니다.
int fd = open("/dev/fpga_ctrl", O_RDWR);
read(fd, buf, size);
write(fd, data, size);
ioctl(fd, CMD_SET_MODE, &value);
close(fd);
여기서 중요한 점은 open(), read(), write(), ioctl()가 Driver 안의 file_operations와 연결된다는 것입니다. 따라서 Linux가 “모든 것을 파일처럼 다룬다”는 표현의 실제 의미를 Device Driver에서 확인할 수 있습니다.
ls -l /dev를 실행하면 일반 파일과는 조금 다른 정보가 보입니다.
crw-rw---- 1 root dialout 188, 0 ... ttyUSB0
맨 앞의 c는 Character Device라는 뜻이며, 파일 크기 대신 188, 0처럼 Major Number와 Minor Number가 표시됩니다. 이 형식을 이해하면 실제 시스템에서도 어느 Device가 어떤 Driver 계열에 연결되는지 추적하는 데 도움이 됩니다.
예전에는 Boot Script에서 직접 mknod를 호출해 Device Node를 만드는 경우가 많았습니다. 하지만 현대 Linux에서는 udev, 임베디드 환경에서는 mdev 같은 Device Manager가 Kernel Event를 받아 자동으로 /dev 아래의 Node를 생성하는 경우가 일반적입니다.
그렇다고 mknod가 시험에서 중요하지 않은 것은 아닙니다. 오히려 mknod를 이해하면 Kernel Driver와 User Application의 연결 구조를 가장 명확하게 이해할 수 있기 때문에 자격증 문제에서 계속 의미가 있습니다.
Application이 Device를 열지 못할 때는 무조건 Driver Code부터 의심하는 것보다 아래 순서로 확인하는 것이 효율적입니다.
- Kernel Module이 실제로 로드되었는가?
- Driver가 정상 등록되었는가?
- Major Number가 맞는가?
- /dev Device Node가 존재하는가?
- Minor Number가 올바른가?
- Device Node 권한이 적절한가?
- open()이 어떤 errno로 실패하는가?
이 순서대로 보면 Kernel 문제인지, Device Node 문제인지, Permission 문제인지 빠르게 분리할 수 있습니다.
문제: Linux에서 Kernel에 등록된 Character Device Driver를 User Application이 접근할 수 있도록 /dev 아래에 특수 파일을 만드는 명령어는 무엇인가?
정답: mknod
문제: Device Node의 Major Number와 Minor Number의 의미를 각각 설명하시오.
모범답안: Major Number는 Device Node가 연결될 Kernel Device Driver를 식별하는 번호이다. Minor Number는 동일한 Driver가 관리하는 여러 Device 중 특정 Device를 구분하는 번호이다.
문제: 다음 명령어의 의미를 설명하시오.
mknod /dev/mydev c 240 1
모범답안: /dev/mydev라는 Character Device Node를 생성하며, Major Number는 240, Minor Number는 1로 설정한다.
c = Character Device
b = Block Device
Major = Driver 식별
Minor = 개별 Device 식별
register_chrdev() = Kernel 쪽 등록
mknod = User Space 접근 경로 생성
/dev/device → open/read/write/ioctl → Driver
mknod는 명령어 하나를 외우는 문제가 아닙니다. 이 개념 속에는 Linux Device Driver 구조의 핵심이 들어 있습니다. Kernel에는 Driver가 존재하고, User Space에는 Application이 존재합니다. 그리고 그 둘 사이를 Device Node와 System Call Interface가 연결합니다.
이 구조를 확실하게 이해하면 이후에 ioctl(), file_operations, Character Driver, udev, sysfs를 공부할 때도 훨씬 수월해집니다.
9편에서는 「Linux System Call과 ioctl() - User Space에서 Hardware까지 가는 길」을 다룰 예정입니다. open(), read(), write(), ioctl()이 Driver 내부 함수와 어떻게 연결되는지 시험과 실무 관점에서 정리하겠습니다.
#임베디드기사 #임베디드기사실기 #임베디드시스템 #리눅스 #Linux #디바이스드라이버 #DeviceDriver #mknod #MajorNumber #MinorNumber #DeviceNode #CharacterDevice #BlockDevice #register_chrdev #리눅스커널 #KernelDriver #시스템콜 #ioctl #임베디드리눅스 #자격증공부