18
- 1 - 리리리 리리리리 리리리리 리리 Linux Device Driver

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

Embed Size (px)

DESCRIPTION

Linux Device Driver. 리눅스 디바이스 드라이버 개요. Device Driver. 디바이스 드라이버의 정의 정의 디바이스의 정의 LCD, USB, Ethernet, CF, AUDIO 등과 같이 스스템 이외의 주변장치들을 의미 드라이버의 정의 하드웨어 장치를 제어하고 관리하는 방법의 컴퓨터 시스템 디바이스 드라이버의 정의 물리적인 하드웨어 장치를 다루고 관리하는 소프트웨어로 커널의 일부분 리눅스에서는 모든 장치를 파일로 관리하며 해당 장치는 주번호와 부번호로 구분 - PowerPoint PPT Presentation

Citation preview

Page 1: 리눅스  디바이스 드라이버 개요

- 1 -

리눅스 디바이스 드라이버 개요Linux Device Driver

Page 2: 리눅스  디바이스 드라이버 개요

- 2 -Huins. R&D Center

Device Driver

디바이스 드라이버의 정의 정의

디바이스의 정의 LCD, USB, Ethernet, CF, AUDIO 등과 같이 스스템 이외의 주변장치들을 의미 드라이버의 정의 하드웨어 장치를 제어하고 관리하는 방법의 컴퓨터 시스템

디바이스 드라이버의 정의 물리적인 하드웨어 장치를 다루고 관리하는 소프트웨어로 커널의 일부분 리눅스에서는 모든 장치를 파일로 관리하며 해당 장치는 주번호와 부번호로 구분 표준화된 호출 방법을 이용하여 디바이스와 어플리케이션간의 정보를 주고 받을 수 있도록 함 (system call)

디바이스 드라이버와 커널 리눅스는 어플리케이션 영역과 커널영역의 구분이 있다 . 어플리케이션은 어플리케이션 영역에서만 구동됨 제어해야할 디바이스는 커널이 관리하고 있으므로 커널 영역을 통해야 사용이 가능 어플리케이션 영역에서 커널 영역의 드라이버를 이용하려면 시스템 콜을 발생시켜야 함 . 어플리케이션 영역과 커널영역은 독립적인 메모리 공간을 이용 copy_from_user,copy_to_user 등과 같은 시스템 함수를 통해 데이터를 전달

2

Page 3: 리눅스  디바이스 드라이버 개요

- 3 -Huins. R&D Center

Device Driver

디바이스 드라이버의 종류 문자 디바이스 드라이버

일반적인 하드웨어 제어에 이용 작고 빈번한 데이터의 송수신에 이용됨 GPIO, PWM, i2C 와 같은 장치를 이용하는 디바이스

블록 디바이스 드라이버 한번에 많은 데이터를 송수신 하는 디바이스 데이터 통신을 위해서 버퍼를 이용함 HDD, Optical Disc 와 같이 통상적으로 저장 장치들이 해당

네트워크 디바이스 드라이버 네트워크와 관련된 장치들을 제어 일반적인 장치들과는 다르게 네트워크 서브 시스템을 통해서 실제 장치와 연결

어플리케이션에서 하드웨어 제어를 위한 전체 구조

3

Page 4: 리눅스  디바이스 드라이버 개요

- 4 -Huins. R&D Center

Device Driver

커널 모듈 리눅스는 모놀리틱커널 이지만 마이크로 커널의 장점인 모듈 기능을 가지고 있다 모듈은 리눅스 시스템이 부팅 된 이후에 동적으로 load 및 unload 할 수 있는 커널의 요소 모듈을 이용하면 커널 요소의 일부분을 별도의 컴파일 없이 교체할 수 있다 커널은 의존성이라는 특성이 있으며 , 커널의 버전 정보등은 컴파일된 모듈에 삽입된다 . 리눅스 커널 모듈에 대한 정보는 커널소스 /include/linux/module.h 에 정의되어 있다 .

4

Page 5: 리눅스  디바이스 드라이버 개요

- 5 -Huins. R&D Center

Device Driver

커널 링크 해당 모듈을 커널에 등록하려면 insmod 명령을 제거하려면 rmmod 명령을 이용 Insmod 를 이용해서 모듈을 올리면 버전검사를 하게 된다 . 드라이버는 main 함수가 존재하지 않는다 . 거널에 등록하기 위한 별도의 함수가 존재한다 .

int init_module : insmod 를 호출하여 커널에 모듈을 등록할 때 호출 void cleanup_module : 커널에서 모듈을 제거할 때 호출

커널에 모듈이 링크되는 개념도

5

Page 6: 리눅스  디바이스 드라이버 개요

- 6 -Huins. R&D Center

Device Driver

모듈 관련 명령

6

명령어 용 도

insmod module 을 커널에 등록 (load)

rmmod 실행중인 modules을 커널에서 제거 (unload)

lsmod Load된 module 들의 정보를 표시

depmod 커널 내부에 적재된 모듈간의 의존성을 검사

modprobe 모듈간 의존성을 검사하여 그 결과 누락된 다른 모듈을 찾아서 적재

modinfo 목적 파일을 검사해서 관련된 정보를 표시

Page 7: 리눅스  디바이스 드라이버 개요

- 7 -Huins. R&D Center

Device Driver

Character Device Driver 문자 디바이스는 바이트 스트림 형태로 참조 open, close, read, write 시스템 호출을 구현 ex) /dev/console, /dev/ttySn 문자디바이스와 일반파일의 사용상 차이점

파일 : 파일의 시작과 끝 사이의 위치에 임으로 접근이 가능 디바이스 : 일반적으로 순차적으로 참조함 ( 메모리를 참조하는 드라이버의 경우 파일과 유사한 조작이 가능 ex, framebuffer)

7

Page 8: 리눅스  디바이스 드라이버 개요

- 8 -Huins. R&D Center

Device Driver

문자디바이스의 노드를 만드는 방법

디바이스를 커널에 등록 및 해제 하는 함수 ( 커널 소스 /include/linux/fs.h) extern int register_chrdev(unsigned int, const char *, struct file_operations *)

extern int unregister_chrdev(unsigned int, const char *)

파일의 연산과 관련된 함수 loff_t (*llseek) (struct file *, loff_t, int) 장치에서 데이터를 읽거나 쓰는 경우 이용 ssize_t (*read, *write) (struct file *, char *, size_t, loff_t *); 장치에서 데이터를 읽는 경우에 이용

8

mknod /dev/ttySAC0 c 204

첫 번째 인수 ○ : Major 번호로 만약 ‘ 0’ 값을 주면 Major 번호 중 사용하지 않는 번호로 동적 할당한다 .

두 번째 인수 ○ : 디바이스 name 즉 장치 이름이며 , /proc/devices 에 나타난다 .

세 번째 인수 ○ : 파일연산 함수 ( 다음에 자세히 설명할 것이다 .)

리턴하는 값 ○ : 0 이나 양수이면 정상 , 음수이면 실패 .

첫 번째 인자 ○ : 해제하고자 하는 장치 주 번호 (Major nuber)

두 번째 인자 ○ : 해제하고자 하는 장치 이름 (Device name)

Page 9: 리눅스  디바이스 드라이버 개요

- 9 -Huins. R&D Center

Device Driver

unsigned int (*poll) (struct file *, struct poll_table_struct *); 현재 실행중인 프로세스를 대기 queue 에 넣음 int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); 디바이스에 종속적인 함수나 프로그래머의 임의의 커맨드를 만듦 . int (*mmap) (struct file *, struct vm_area_struct *); 디바이스의 메모리를 응용 프로세스의 메모리에 매핑 int (*open) (struct inode *, struct file *); 디바이스를 열고자 할때 이용 int (*release) (struct inode *, struct file *); 디바이스를 닫을 때 이용

Block Device Driver 문자 디바이스와 마찬가지로 /dev/ 디렉터리의 노드를 통해 접근 파일 시스템을 수용할 수 있는 디바이스 드라이버 응용 프로그램이 블록 디바이스를 문자 디바이스 처럼 사용할 수 있음 한번에 전송할 데이터의 크기의 제한이 없음 버퍼 캐시를 통하여 랜덤 액세스가 가능 문자디바이스와의 차이는 드라이버 소프트웨어 인터페이스에서만 차이가 남 문자디바이스와 별개로 관리되므로 문자디바이스와 동일한 주번호 및 부번호 이용가능 문자 디바이스 드라이버의 등록과 해제에 이용되는 함수

9

Page 10: 리눅스  디바이스 드라이버 개요

- 10 -Huins. R&D Center

Device Driver

extern int register_blkdev(unsigned int, const char *, struct block_device_operations *);

extern int unregister_blkdev(unsigned int, const char *);

블록 디바이스의 파일 연산 Read, write, fsync 함수는 별도로 구현하지 않고 제공되는 함수를 이용 Open 과 release 는 문자 디바이스 드라이버 처럼 구현 Ioctl 은 많은 장치들이 사용할 것이라 예상하는 공통적인 커맨드를 지원

10

첫 번째 인자 ○ : Major 번호 , 0 이면 동적 할당

두 번째 인자 ○ : 블록 디바이스 이름

세 번째 인자 ○ : 블록 디바이스 장치에 대한 파일 연산 함수

리턴 값 ○ : 0 이나 양수이면 정상 , 음수이면 에러

첫 번째 인자 ○ : Major 번호

두번째 인자 ○ : 블록 디바이스 이름

- BLKGETSIZE : 장치의 크기를 섹터의 개수로 환산해 리턴

- BLKFLSBUF : 버퍼 캐시를 flush

- BLKRAGET : 미리 읽어올 데이터 크기

- BLKRASET : 미리 읽어올 데이터 셋팅

- BLKROGET : flag 얻어오기

- HDIO_GETGEO : 하드 디스크의 구조 읽어오기 등이 바로 그것이다 .

Page 11: 리눅스  디바이스 드라이버 개요

- 11 -Huins. R&D Center

Device Driver

Floppy 드라이버의 예시

버퍼 캐시의 상태 블록 디바이스는 버퍼 캐시를 이용하여 데이터를 주고 받는다

11

- BH_Uptodate 현재 버퍼는 유효한 데이터를 가지고 있다 .

- BH_Dirty 디스크에 있는 데이터와 버퍼의 데이터는 다르다 .

- BH_Lock 현재 버퍼가 Lock 되어 있다 . ( 처리 중에 있다 )

- BH_Req 해당하는 블록이 데이터를 요청 .

- BH_Mapped 버퍼가 현재 디스크에 mapping 되어 있다 .

- BH_New 버퍼가 새로운 것이며 아직 write 되지 않았다 .

- BH_Protected 버퍼가 보호되고 있는 상태 . 이 버퍼는 free 되지

않는다 .

Page 12: 리눅스  디바이스 드라이버 개요

- 12 -Huins. R&D Center

Device Driver

네트워크 디바이스 모든 네트워크 트랜잭션은 다른 호스트와 데이터를 교환해주는 디바이스를 거침 네트워크 디바이스의 데이터 패킷 전송은 커널에 포함된 네트워크 서브시스템에 의한다 . 네트워크 인터페이스는 스트림 형태의 디바이스가 아니라 스페셜 파일이 생성되지 않는다 ( lo, eth, wlan0 등과 같은 고유한 이름을 할당 받아 참조하지만 , 파일 시스템에 포함되진 않음 ) 어플리케이션에서 read 나 write 함수를 이용하는 경우 드라이버 상의 fos 의 read,write 가

아닌 패킷 전송에 관련된 함수를 호출하여 처리한다

Achro4210 에서 이용되는 문자 드라이버 소개 Framebuffer

Linux 시스템에서 그래픽을 표현할 수 있는 하드웨어 Framebuffer 는 LCD 에 표시할 정보를 저장해놓는 버퍼 LCD 컨트롤러는 DMA 를 이용하여 Framebuffer 의 내용을 주기적으로 LCD 로 보냄

12

Page 13: 리눅스  디바이스 드라이버 개요

- 13 -Huins. R&D Center

Device Driver

리눅스에서 연결하는 디바이스 노드

SD/MMC (rivers/mmc/core/, drivers/mmc/host) SD Host controller

Achro-4210 에서 SD interface 를 제공함 WiFi 등과 같은 SD 인터페이스를 이용하는 다양한 장비를 사용할 수 있음 일반적으로 MMC 등과 같은 메모리를 연결하여 사용

리눅스에서 연결하는 디바이스 노드 ( 일반적인 상황 )

Audio Audio Subsystem 을 포함 오디오 하드웨어 코덱에 따라 다 채널의 I2S 인터페이스를 지원 칩 컨트롤은 I2C 통신을 통하고 , 데이터는 I2S 로 처리

13

[root@uclibc /dev]# ls -al fb0

crw-rw-rw- 1 root root 29, 0 Jan 1 09:00 fb0

/dev/ mmcblk0

/dev/ mmcblk0p1

/dev/ mmcblk0p2

/dev/ mmcblk1

/dev/ mmcblk1p1

Page 14: 리눅스  디바이스 드라이버 개요

- 14 -Huins. R&D Center

Device Driver

오디오 관련 소스 arch/arm/plat-s5p/dev-audio.c, Driver/sound 관련 전체에 전반적으로 존재 코덱은 ound/soc/codecs 에 위치

오디오와 관련된 디바이스 노드 ( 기본적인 노드 )

터치 스크린 인터페이스 터치 스크린은 임베디드 디바이스에서 주로 사용되는 입력 장치이다 . 일반적으로 감압식과 정전식으로 크게 나눌 수 있다 . 감압식은 터치 위의 패널을 눌러서 발생되는 저항값을 통해 포인팅 함 정전식은 화면에 누른 사람이나 물체에 흐르는 미세한 전류를 이용하여 포인팅 함 Achro-4210 의 경우 I2C 를 이용하여 장치와 통신을 함 .

14

/dev/dsp

/dev/dsp0

/dev/dsp1

/dev/mixer

/dev/mixer0

/dev/mixer1

Page 15: 리눅스  디바이스 드라이버 개요

- 15 -Huins. R&D Center

Device Driver

터치 관련된 디바이스 노드 ( 일반적인 노드 )

터치와 관련된 노드는 해당 드라이버를 설정할 때의 위치에 따라 이름과 장치가 변경됨

UART 일반적으로 시리얼 통신을 할 수 있는 포트를 의미한다 . Achro-4210 에서 외부와 통신할 수 있는 UART 는 2 개이며 , 한 포트는 디버그 포트로 이용 UART 로 설정하여 사용할 때에는 /dev/ttyS 로 시작하는 노드를 갖게 된다 . UART 관련된 디바이스 노드

15

/dev/ts

/dev/ts0

/dev/input/event0

/dev/input/event1

/dev/ttySAC0 UART 0

/dev/ttySAC1 UART 1

/dev/ttySAC2 UART 2

/dev/ttySAC3 UART 3

Page 16: 리눅스  디바이스 드라이버 개요

- 16 -Huins. R&D Center

Device Driver

Ioremap 과 mmap() Mmap() 은 응용프로그램의 가상 주소에 커널의 해당 디바이스의 메모리 영역을 매핑

장점 : 매핑된 이후로 시스템 콜을 사용하지 않고 해당 장치의 메모리 영역을 이용 ( 커널 영역에서 발생하는 많은 시간적 비용이 줄어들어 빠른 처리가 가능 ) 단점 : 매핑할 메모리 공간이 많이 필요한 다수의 장치를 모두 이용하는데 여러 고려사항 필요

Ioremap() 커널의 가상 주소에 디바이스의 메모리 영역을 매핑 장점 : 크지 않은 메모리 크기에 대해서 할당 받아 사용이 가능 ( 메모리를 할당 받기 위해서 전 처리 해야 되는 부분이 쉬움 ) 단점 : 프로그램이 지속적인 참조를 할 경우 반복되는 시간만큼 커널 내 처리시간이 늘어남

16

Page 17: 리눅스  디바이스 드라이버 개요

- 17 -Huins. R&D Center

Device Driver

Iormap 과 mmap 의 동일 하드웨어 제어 코드 비교 예시

17

// mmap.c – linux application… 생략 …#include <sys/mman.h>

/* 페이지 크기 (4096) 의 정수배 */#define MAP_SIZE 0x1000 /* led 의 physical address */

#define MAP_PHYS 0xA8000000 #define LED (*((volatile unsigned short *)(map_base + 0)))

void *map_base;

int main (int argc, char *argv[]) { int fd = open( "/dev/led_driver", O_RDWR | O_SYNC );

map_base = mmap( NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, MAP_PHYS );if (map_base == MAP_FAILED) {

perror("mmap()");exit(2);

} …

/* 할당받았던 매핑 영역을 해제한다 . */ if (munmap(map_base, MAP_SIZE) == -1) {

perror("munmap()");exit(3);

} close(fd); return 0;}

// ioremap – kernel module… 생략 … #include <linux/ioport.h> #define IOM_LED_MAJOR 246 // led device major number #define IOM_LED_NAME “led_driver” // led device name #define IOM_LED_ADDRESS 0xA8000000 // physical address

struct file_operations iom_led_fops = { open: iom_led_open, write: iom_led_write, release: iom_led_release, };

ssize_t iom_led_write(struct file *inode, const char *gdata, size_t length, loff_t *off_what) { unsigned short value; const char *tmp = gdata; if (copy_from_user(&value, tmp, 2)) return -EFAULT; outw(value,(unsigned int)iom_led_addr); return length; }

int __init iom_led_init(void) { int result = register_chrdev(IOM_LED_MAJOR, IOM_LED_NAME, &iom_led_fops); … iom_led_addr = ioremap(IOM_LED_ADDRESS, 0x2); return 0; } void __exit iom_led_exit(void) { iounmap(iom_led_addr); unregister_chrdev(IOM_LED_MAJOR, IOM_LED_NAME); }

module_init(iom_led_init); module_exit(iom_led_exit);

Page 18: 리눅스  디바이스 드라이버 개요

- 18 -Huins. R&D Center

Device Driver

전체 수행 구조 비교 ioremap 은 커널에 모듈로 등록이 되므로 해당 모듈을 참조하여 값을 전송하는 어플리케이션이 필요

mmap 으로 애플리케이션에서 매핑한 경우 시스템 콜 없이 디바이슬 제어할 수 있다 . ioremap 으로 드라이버를 만든후 하드웨어를 제어할 경우 시스템 콜을 이용한다 .

18