디바이스 드라이버

2025. 8. 1. 10:51·Linux

종류

  • 문자 디바이스 드라이버: 대부분의 디바이스 드라이버, 구현 간편
  • 블록 디바이스 드라이버
  • 네트워크 디바이스 드라이버
  • 버스 디바이스 드라이버

디바이스 노드

mknod [옵션] <파일이름> <타입> <주번호> <부번호>

  • 타입
    • c : 문자형
    • b : 블록형
  • 주번호 : 드라이버마다 고유의 번호, 커널이 할당해주기도
  • 부번호 : 드라이버마다 고유의 번호, 드라이버가 할당을 관리

문자 디바이스 드라이버

  • 드라이버는 리눅스에서 1바이트 단위로 데이터를 읽고 쓰는 장치를 제어하는 드라이버
    • read(), write()와 같이 바이트 단위로 입출력을 처리하는 드라이버
  • file_operations를 구현하는 드라이버
    • open, read, write, lseek, close 같은 일반적으로 사용하는 파일 함수
    • 별도의 시스템콜 없이 새로운 기능 추가 가능 -> 가상 파일 시스템
file_operations를 구현한다?

만약 유저가 write 시스템콜을 호출하면,
커널은 "이 fd에 연결된 파일에 데이터를 쓰라" 라는 요청을 받음.

커널은 이 요청을 처리하기위해서 file_operations.write()를 호출
즉, 정확히 어떤 동작을 할지 정해줘야함
여기서의 write을 구현한다는 말이다

드라이버 등록

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/spinlock.h>

#define BUF_SIZE 16

static DEFINE_RWLOCK(lock);
static char comento_buf[BUF_SIZE] = {0, };

static ssize_t comento_device_read(struct file *file, char __user *buf, size_t len, loff_t *ppos)
{
	ssize_t ret;
	read_lock(&lock);

	if(BUF_SIZE <= len + *ppos)
	{
		len = BUF_SIZE - *ppos;
	}

	ret = len - copy_to_user(buf, comento_buf + *ppos, len);
	*ppos += ret;

	read_unlock(&lock);

	return ret;
}

static ssize_t comento_device_write(struct file *file, const char __user *buf, size_t len, loff_t *ppos)
{
	ssize_t ret;
	write_lock(&lock);

	if(BUF_SIZE <= len + *ppos)
	{
		len = BUF_SIZE - *ppos;
	}

	ret = len - copy_from_user(comento_buf + *ppos, buf, len);
	*ppos += ret;

	write_unlock(&lock);

	return ret;
}

static int comento_device_open(struct inode *inode, struct file *file)
{
	int minor = iminor(inode);
	printk(KERN_DEBUG "%s - minor : %d\n", __func__, minor);

	return 0;
}

static struct file_operations fops = 
{
	.open = comento_device_open,
	.read = comento_device_read,
	.write = comento_device_write,
};

static int __init comento_module_init(void)
{
	printk(KERN_DEBUG "%s\n", __func__);
	int ret = register_chrdev(177, "comento", &fops);
	return ret;
}

static void __exit comento_module_exit(void)
{
	unregister_chrdev(177, "comento");
	printk(KERN_DEBUG "%s\n", __func__);
}

module_init(comento_module_init);
module_exit(comento_module_exit);

MODULE_AUTHOR("Jin Minu");
MODULE_DESCRIPTION("Example driver");
MODULE_LICENSE("GPL v2");

 

  • 열기 (open)
  • 읽기 (read) / 쓰기 구현 (write)
  • ----------------테스트과정-----------------
  • 커널 재빌드
  • rootfs에 마운트
  • comento.ko를 rootfs에 이동 (모듈 복사)
  • unmount
  • qemu실행 후, insmod로 comento.ko 모듈 삽입
  • mknod (장치 파일 생성)
  • 테스트
이 코드에서는 file_operations에 있는 open, read, write를 구현한다.
또한 spinlock을 사용하여, 특정 파일 사용중에 접근하지 못하도록 함
echo "wow" > /dev/comento 로 쓰기
cat /dev/comento 로 읽기 테스트

파일 특수 제어 (ioctl)

  • 사용자 공간에서 커널 공간으로 특정 드라이버에 명령 전달
  • 일반적인 read, write로는 부족할 때

udev

  • 사용자 공간에서의 장치 파일 자동 생성 및 관리 시스템
  • /dev 디렉토리 장치파일을 자동 생성 및 관리

 

원래 코드는 많이 적지 않으려 했는데..

아무튼, 몇가지 코드는 그냥 생략한다.

종합 정리하면,

 

드라이버가 하드웨어, 커널사이 연결을 해준다. 드라이버만으로는 유저가 장치를 직접 다루기 어렵다.

그래서 udev라는 시스템이 필요하다.

udev는 드라이버가 인식한 하드웨어를 위한 장치 파일을 /dev에 자동으로 생성하고,

이 파일은 유저 프로그램과 드라이버를 이어주는 역할을 한다.

'Linux' 카테고리의 다른 글

linux/drivers/char/mem.c 드라이버 분석  (0) 2025.09.20
objdump활용 vmlinux 분석시 start address의미  (0) 2025.09.11
커널 모듈 (insmod, lsmod, rmmod) 커널 API  (5) 2025.07.30
ls 명령어 분석 with strace  (1) 2025.07.29
Kernel 및 System call 디버그 with GDB  (0) 2025.07.28
'Linux' 카테고리의 다른 글
  • linux/drivers/char/mem.c 드라이버 분석
  • objdump활용 vmlinux 분석시 start address의미
  • 커널 모듈 (insmod, lsmod, rmmod) 커널 API
  • ls 명령어 분석 with strace
Jminu
Jminu
  • Jminu
    뇌 구조가 바이너리
    Jminu
  • 전체
    오늘
    어제
    • 분류 전체보기
      • C프로그래밍
        • 오류해결
        • 개인 공부
        • Programming Lab(학교수업)
        • MemoryTracker
      • C++
        • 개인 공부
      • 자료구조(Data Structure)
      • ARM arch
        • Cortex-M
        • FreeRTOS
      • 컴퓨터 공학(Computer Science)
        • OS
        • 컴퓨터 구조
      • Qualcomm 기업과제
      • Linux
      • Web
      • 똥글
      • 백준
      • Git 학습
        • 오류해결
        • 학습중
      • Python
        • 오류해결
        • 개인 공부
  • 블로그 메뉴

    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    파이썬
    C++
    Git
    토발즈
    Qualcomm
    rubikpi3
    백준
    커널
    포인터
    스택
    arm
    INIT
    드라이버 분석
    동적메모리
    리눅스
    commit
    시스템콜
    버퍼
    소수
    yolo
    파일 입출력
    Branch
    순환
    이진 트리
    앤드류모튼
    자료구조
    피보나치
    c언어
    rubik pi
    커널 기여
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Jminu
디바이스 드라이버
상단으로

티스토리툴바