일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
- Debugging
- 리눅스
- Raspberry
- QEMU
- GPIO
- 디버깅
- Visual Studio
- yocto
- UART
- raspberrypi
- avr-gcc
- esp32
- USART
- platformio
- 라즈베리파이
- nucleo
- Linux
- C++
- Arduino
- BeagleBone
- Debug
- buildroot
- AVR
- STM32
- AArch64
- Visual Studio Code
- atmel
- vscode
- bare metal
- 아두이노
- Today
- Total
임베디드를 좋아하는 조금 특이한 개발자?
[Linux Kernel Module] Character Device(문자 장치) 초기화 및 생성 본문
- 개발 환경
개발 보드 : Raspberrypi 4
OS : Linux raspberrypi 6.12.25
1. 서론
먼저 리눅스에서는 Device(장치)또한 파일로 취급하여 관리하고 있습니다. 실제 /dev 폴더를 확인해보면 PC에 연결된 장치들을 확인 할 수 있습니다. 그리고 장치에 접근 방법에 따라 그리고 Character Device(이하 문자 장치)와 Block Device(이하 블록 장치)로 구분할 수 있습니다. 그 중 이번 포스트에서는 일반적으로 많이 사용되는 문자 장치을 초기화 및 생성하는 방법에 대해서 확인해보도록 하겠습니다.
2. 관련 함수 및 구조체 확인
2.1. register_chrdev() 함수
int register_chrdev(unsigned int major, const char *name, const struct file_operations *fops)
https://elixir.bootlin.com/linux/v6.12.34/source/include/linux/fs.h#L2822
매개변수 확인)
- unsigned int major
생성하고자 하는 문자 장치에 할당하고자 하는 major 번호를 설정합니다. 자동으로 할당하고자 할 때 0으로 설정합니다.
- const char *name
생성하고자 하는 문자 장치의 이름을 설정합니다.
- const struct file_operations *fops
문자 장치에 접근하는 방법을 설정합니다.
반환 값)
실제 할당한 major 번호를 반환합니다.
만약, 에러가 발생한 음수를 반환합니다.
2.1. unregister_chrdev() 함수
static inline void unregister_chrdev(unsigned int major, const char *name)
https://elixir.bootlin.com/linux/v6.12.34/source/include/linux/fs.h#L2828
매개변수 확인)
- unsigned int major
반납하고자 하는 문자 장치의 major의 번호를 전달합니다.
- const char *name
반납하고자 하는 문자 장치의 이름을 설정합니다.
2.3. struct file_operations 구조체
struct file_operations
https://elixir.bootlin.com/linux/v6.12.34/source/include/linux/fs.h#L2062
파일에 접근하기 위한 Callback 함수를 설정하기 위한 구조체입니다. 해당 구조체는 다른 포스트에서 자세히 다루도록 하겠습니다.
3. 모듈 프로그래밍
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
// 문자 장치의 이름
#define CHAR_DEV_NAME ("testDevice")
// 생성한 문자 장치의 Major 번호
static int major;
// 생성한 문자 장치을 제어하기 위한 함수를 관리하는 구조체
static struct file_operations fops ={
.owner = THIS_MODULE,
};
static int __init initModule(void){
// 문자 장치 생성
major = register_chrdev(0, CHAR_DEV_NAME, &fops);
// 문자 장치 생성시 에러가 발생한 경우
if(major < 0){
printk("[testDevice] Error : register_chrdev()\n");
// 에러 반환
return major;
}
// 정상적으로 문자 장치 생성됨을 알림 및 major 번호 확인
printk("[testDevice] Success to init char device module\n");
printk("[testDevice] Major : %d\n",major);
return 0;
}
static void __exit exitModule(void){
// 생성된 문자 장치를 해제
unregister_chrdev(major, CHAR_DEV_NAME);
printk("[testDevice] Error : exit module\n");
}
module_init(initModule);
module_exit(exitModule);
MODULE_LICENSE("GPL");
|
cs |
4. 문자 장치와 노드 연결
# 모듈 빌드
make
# 모듈 등록
sudo insmod testDevice
dmesg를 통해 문자 장치가 정상적으로 생성됐음을 확인하였습니다. 또한 major 번호가 236임을 확인하였습니다. 이제 해당 문자 장치에 접근 하기 위한 파일을 생성하기 위해 노드를 연결하도록 하겠습니다.
# major 번호가 236, minor 번호가 0인 문자장치에 연결하기 위한 /dev/testDevice 노드를 생성
sudo mknod /dev/testDevice c 236 0
5. 후기
문자 장치를 생성하고 노드를 연결하여 /dev 폴더 내 노드 파일을 생성하는 것 까지 완료 하였습니다. 하지만, 지금 상태로는 아무 것도 할 수 없습니다. fops를 통해 해당 문자 장치을 접근 하기 위한 함수를 등록하지 않았기 때문입니다. 다음 포스트에서는 fops에 함수를 등록하여 문자 장치에 접근 할 수 있는 방법을 알아보도록 하겠습니다.
'Embedded > Linux' 카테고리의 다른 글
[Linux Kernel Module] 개발 프로젝트 구성 (2) | 2025.08.09 |
---|---|
[Linux Debugging] VScode로 간편히 Linux 디버깅하기 (3) | 2025.08.05 |
[Linux Debugging] QEMU로 실행한 Linux를 GDB로 디버깅 (1) | 2025.08.05 |
[Linux Debugging] Buildroot를 통해 디버깅할 리눅스 빌드 (3) | 2025.08.03 |