디바이스 드라이버

● 하드웨어로 가는 통로
● 컴퓨터 시스템은 디바이스가 없으면 의미가 없음
● 사실 디바이스 컨트롤은 어려움
– 디바이스는 굉장히 복잡함

디바이스 드라이버의 핵심은 인터럽트

● 인터럽트
– HW는 SW에게 알려주고 싶어한다.
● 네트워크 패킷 도착, timer expire
– SW는 반드시 현재 하던 작업을 멈춰야 한다!
– 비동기(asynchronous)
● 동작 중인 프로세스에 인터럽트가 걸림
– 인터럽트 핸들러는 프로세스 문맥(유저 레벨)에서 동작하지 않음
– 인터럽트 핸들러는 커널 내부에 있음
● 어디에? 디바이스 드라이버

리눅스 디바이스 드라이버 개요

User-space driver


I2C: i2c-dev
● SPI: spidev
● Memory-mapped: UIO
● USB: /dev/bus/usb, through libusb
● PCI: sysfs entries for PCI
● 조심!!
– framework(subsystem)과 충돌 가능성

User-space interfaces to drivers

● 3가지 인터페이스 접근 가능

/dev 내부의 디바이스 노드를 통해 접근
– open/read/write/close/ioctl
– Character device
– Block device
– 각 디바이스는 3가지 정보를 가짐
● Type (character or block)
● Major (category of device)
● Minor (identifier of the device)
● sysfs filesystem
– 마치 파일처럼 접근(문자열로 쓰고/읽기)
● Network sockets and related APIs
– 소켓처럼 API를 통해

Block devices & character devices

Block devices
– hard disks, SD cards 등 저장장치에 사용
– 고정된 사이즈의 블락을 통해 read/write
– 우리가 개발할 가능성이 거의 없어 보임
●Character devices
– 일반적인 파일 입출력
– Byte 스트림을 통해 read/write
– a serial port, frame buffers
– 대부분의 디바이스의 모양

Everything is a file

● 디바이스는 모두 파일로 처리
● Open, read, write, close
● 응용프로그램은 파일로 보임
● Special type 파일
– type, major, minor

ls -l /dev

Device file 생성

● 2.6.32 이전 버전에서는 mknod로 생성
– mknod /dev/(device) c major minor
● udev
– 데몬이 이벤트를 받아서 디바이스 노드 생성/제거
– rules file

/lib/udev/rules.d , /etc/udev/rules.d
● mdev
– udev의 임베디드 버전

user-space 인터페이스 예

● Serial
– /dev/ttyS , /dev/ttyUSB, /dev/ACM
● GPIO
– /dev/gpiochipX
● Block devices
– /dev/sd
, /dev/mmcblk, /dev/nvme
● Display controllers and GPU
– /dev/dri/
● Audio
– /dev/snd/

● Camera
– /dev/video
● Watchog
– /dev/watchdog

Input
– /dev/input/

sysfs filesystem

● 모든 디바이스는 sysfs에서 보임

/dev
– access the device

/sys
– properties of the devices
– access the device
● LED
– /sys/class/leds
● PWM
– /sys/class/pwm

IIO
– /sys/class/iio

==> insmod로 커널에 적재하면 보임

GPIOs

● GPIO(General Purpose Input Output) 인터페이스
● Legacy interface
– /sys/class/gpios
● 단점 보안
– 프로세스 크래쉬 → gpi export 해제 X 등등
● 새로운 인터페이스 libgpiod

  • /dev/gpiochipx: character devices
    – gpiodetect, gpioset, gpioget 커맨드 지원

커널 모듈

● 커널 사이즈 문제
– 모든 드라이버 코드를 커널에 포함하면 커널 사이즈가 커짐
– 커널 이미지를 줄여야 함
– 실제 하드웨어 연결 시 모듈을 로드
● 디바이스 드라이버 개발 생산성 향상
– 필요한 부분만 빌드/수정/배포 가능
– 부팅 시간 단축
● 실제 필요한 순간 로딩

커널 모듈 위치


/lib/modules/(kernel-version)
● *.ko 파일 이름으로 생성됨
● 기타 메타 정보
– 모듈 로딩 시 사용
– module.dep, module.alias, modules.symbols, modules.builtin
● 특정 모듈은 의존성을 가짐.
– 의존성은 module.dep에 정의되어 있음

모듈 로딩: insmod

● 모듈 로딩
– insmod
● 모듈 언로딩
– rmmod
● 단점
– 모듈 의존성을 처리하지 못한다.

Insmod /lib/modules/5.15.68-v8/kernel/drivers/watchdog/gpio_wdt.ko
● Rmmod
rmmod gpio_wdt.ko

modprobe

● 보다 진보된 툴
● 디바이스 모듈 의존성 해결
● 의존성은 module.dep 파일에 정의됨
● 제거는 modprobe -r
● modprobe bcm2835_v4l2
● modprobe -r bcm2835_v4l2

커널 모듈: 01.hello/kdt_module.c

  • Makefile : 크로스 컴파일

  • test code

EXPORT_SYMBOLE

● 커널 모듈의 함수를 외부 모듈에서 호출할 때 사용
● EXPORT_SYMBOL(symbolname)
● EXPORT_SYMBOL_GPL(symbolname)
– GPL 모듈만 export

파라메터 전송


insmod ./gpio_wdt.ko kdt=1
● modprobe gpio_wdt.ko kdt=1
● modprobe
– /etc/modprobe.conf에 설정 가능
– options kdt=0
● 빌트인 모듈인 경우 커널 command line으로 설정 가능
– gpio_wdt.kdt=1
– Kernel command line: coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0
snd_bcm2835.enable_hdmi=1 smsc95xx.macaddr=E4:5F:01:FF:60:E5
vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000 root=/dev/mmcblk0p2 rootwait
console=tty1 console=ttyAMA0,115200

0개의 댓글

관련 채용 정보