32
Hanbat National University Prof. Lee Jaeheung 디디디디 디디디디 디디

디바이스 드라이버 이해

  • Upload
    gauri

  • View
    171

  • Download
    0

Embed Size (px)

DESCRIPTION

디바이스 드라이버 이해. 목차. 문자 디바이스 드라이버 디바이스 드라이버의 개요 커널 인터페이스 함수 디바이스 드라이버의 종류와 그 특징 문자 디바이스 드라이버의 동작과정 문자 디바이스 제작방법 모듈 프로그래밍 모듈 프로그래밍의 필요성 모듈 프로그래밍 명령어 요약 모듈 프로그램의 동작 설명 커널의 심볼 테이블에 등록 모듈 프로그래밍 예 예제 프로그램. 디바이스 드라이버 개요. 디바이스 드라이버 개요 물리적인 하드웨어 장치를 다루고 관리하는 소프트웨어 커널의 일부분 - PowerPoint PPT Presentation

Citation preview

Page 1: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

디바이스 드라이버 이해

Page 2: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

목차 문자 디바이스 드라이버

– 디바이스 드라이버의 개요

– 커널 인터페이스 함수

– 디바이스 드라이버의 종류와 그 특징

– 문자 디바이스 드라이버의 동작과정

– 문자 디바이스 제작방법

모듈 프로그래밍– 모듈 프로그래밍의 필요성

– 모듈 프로그래밍 명령어 요약

– 모듈 프로그램의 동작 설명

– 커널의 심볼 테이블에 등록

– 모듈 프로그래밍 예

예제 프로그램

Page 3: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

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

– 물리적인 하드웨어 장치를 다루고 관리하는 소프트웨어

– 커널의 일부분

– 주번호 (major number) 와 부번호 (minor number) 를 이용하여 각각의

디바이스들을 구분하여 사용

디바이스 드라이버의 용도

– 응용프로그램에서 하드웨어장치를 이용해서 데이터를 직접 읽고 쓰거나 제어해야

하는 경우에 디바이스 드라이버를 이용

Page 4: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

커널 인터페이스 함수 Port I/O

– inb(unsigned short port),inb_p(unsigned port) port 로부터 1byte 읽음

– outb(char value, unsigned short port)outb_p(char value, unsigned short port)

port 에 1byte 의 value 를 출력함– inb_p(), out_p:inb()/outb() and pause 의 의미– inw(), inw_p(), outw(), outw_p()

port 로부터 short int(2byte) 읽거나 출력함– int(), inl_p(), outl(), outl_p()

port 로부터 long int(4byte) 읽거나 출력함– insb(unsigned int port, void *to, int len)

port 로부터 len bytes 를 읽어 , to 가 가리키는 메모리에 저장 insb_p(), outsb(), outsb_p(), insw(), insw_p(), outsw(),

outsw_p(), insl(), outsl_p()

Page 5: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

커널 인터페이스 함수 Interrupt

– cli()/sti() clear/set interrupt enable

– save_flags(), restore_flags() status register 의 내용을 저장하고 복원

register unsigned long flags;

save_flags(flags);cli();…restore_flags(flags);

– requst_irq(unsigned int irq, void (*handler)(int), unsigned long flags, const char *device)

커널로부터 IRQ 를 요청하여 , IRQ interrupt handler 를 install– free_irq(unsigned int irq)

request_irq() 에서 획득한 irq 를 반납함

Page 6: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

커널 인터페이스 함수 Memory

– kmalloc(unsigned int len, int priority) 커널 메모리 할당 . 128~131056byte 까지 가능 priority:GFP_BUFFER, GFP_ATOMIC, GFP_USER, GFP_KERNEL

– kfree(void *obj) kmalloc() 에서 할당받은 커널 메모리 (obj) 를 반납

– vmalloc(unsigned int len), vmfree(void *addr) 커널 메모리 할당 / 반납 , 크기 제한 없음

– memcpy_xxfs(void *to, const void *from, unsigned long n) 커널주소공간과 사용자주소공간 사이에 memory copy Xx=from/to

– memset(void *s, char c, sizt_t count) 메모리 s 에 c 를 count 만큼 복사

Page 7: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

커널 인터페이스 함수 동기화

– sleep_on(struct wait_queue **q)

q 의 번지를 event 로 sleep 하며 , uninterruptible

– sleep_in_interruptible(struct wait_queue **q)

q 의 번지를 event 로 sleep 하며 , interruptible

– wake_up(struct wait_queue **q)

sleep_on(q) 에 의해 sleep 한 task 를 wakeup

– wake_up_interruptible(struct wait_queuq **q)

sleep_on_interruptible(q) 에 의해 sleep 한 task 를 wakeup

Page 8: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

커널 인터페이스 함수 printk(const char *fmt,….)

– printf 의 커널 버전– printk(LOG_LEVEL_ message)

LOG_LEVEL:KERN_EMERG, KERN_ALERT, KERN_ERR, KERN_WARNING, KER_INFO, KERN_DEBUG

– 예 printk(“<1>Hello, World”); printk(KERN_WARNING”warning…\n”);

– sprintf(char *str, const char *fmt, …) print to string

Page 9: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

커널 인터페이스 함수 driver register

– register_xxxdev(unsigned int major, const char *name,

struct file_operations *fops)

character/block driver 를 xxxdev[major] 에 등록

xxx:blk/chr

– unregister_xxxdev(unsigned int major, const char *name)

xxxdevs[major] 에 등록되 있는 device driver 를 제거

– major(a)/minor(a)

장치번호 a 로부터 major/minor 번호를 구함

Page 10: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

디바이스 드라이버 종류 및 특징

디바이스 드라이버의 종류와 특징드라이버종류 설 명

문자 드라이버

디바이스를 파일처럼 취급하고 접근하여 직접 읽기 /쓰기를 수행 , 데이터 형태는 스트림 방식으로 전송EX) 콘솔 , 키보드 , 시리얼 포트 드라이버등

블록 드라이버

디스크와 같이 파일 시스템을 기반으로 일정한 블록 단위로 데이터 읽기 / 쓰기를 수행EX) 플로피 디스크 , 하드 디스크 , CDROM 드라이버 등

네트워크 드라이버

네트워크의 물리 계층과 프레임 단위의 데이터를 송수신EX) 이더넷 디바이스 드라이버 (eth0)

등록함수명

register_chrdev()

register_blkdev()

register_netdev()

디바이스 드라이버의 종류 및 특징

Page 11: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

디바이스 드라이버 종류 및 특징사용자 프로그램과 응용 프로그램

사용자 프로그램과 응용 프로그램

프로세스 관리프로세스 관리 메모리 관리메모리 관리 파일 시스템파일 시스템 디바이스 제어디바이스 제어 네트워크네트워크

아키텍처의존적 코드아키텍처

의존적 코드 메모리관리자

메모리관리자

FS 타입FS 타입

문자 디바이스문자 디바이스

블록 디바이스블록 디바이스

네트워크서브 시스템네트워크

서브 시스템

If 드라이버If 드라이버

동시 멀티 테스킹 가상 메모리 파일과 디렉토리 TTY 와디바이스 제어 연결

CPUCPU

RAMRAM

디스크와 CD디스크와 CD

콘솔 ,시리얼 포트 ,

특수 보드콘솔 ,

시리얼 포트 ,특수 보드

네트워크인터페이스네트워크

인터페이스

시스템 콜응용프로그램 레벨

커널 레벨

하드웨어 레벨

하드웨어

커널 부분

기능 구현

소프트웨어지원

하드웨어제어

모듈

Page 12: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

디바이스 드라이버 동작

System CallSystem Call

HardwareHardware

File SystemFile System

Buffer CacheBuffer Cache

Disk Device DriverDisk Device Driver

Process ManagementProcess Management

Memory ManagerMemory Manager

processread()

processread()

processfork ()

processfork ()

sys_read()

bread()

hd_request()

hd_io()

sys_fork()

copy_mm()

copy_thread()

CPU

시스템 콜 흐름도

Page 13: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

디바이스 드라이버 동작 System call processing

user task

msin(){ … fork();}

msin(){ … fork();}

libc.a

…fork(){ … swi 0x900002 …}…

…fork(){ … swi 0x900002 …}…

IDT

swiSYS_ERROR

swiSYS_ERROR

……

Jump toVector_swi…

Jump toVector_swi…

0x0

0x8

vector_swi/* arch/arm/kernel/entry-common.S */ 1. 시스템 콜 번호 추출 2. Idreq pc, [tbl, scno, lsl #2] @ call sys routine …. 3. Ret_from_sys_call (schedule, signal, bh_active, interrupt handling)

vector_swi/* arch/arm/kernel/entry-common.S */ 1. 시스템 콜 번호 추출 2. Idreq pc, [tbl, scno, lsl #2] @ call sys routine …. 3. Ret_from_sys_call (schedule, signal, bh_active, interrupt handling)

sys_exit()sys_exit()

sys_fork()sys_fork()

sys_read()sys_read()

sys_write()sys_write()

….….

1234

Sys_fork()/* arch/arm/kernel/sys_arm.c */

Sys_fork()/* arch/arm/kernel/sys_arm.c */

Kernel

Page 14: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

문자 디바이스 드라이버 동작 디바이스 드라이버의 동작과정

실패 시 종료

Page 15: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

문자 디바이스 제작방법 문자 디바이스 드라이버 제작법

– 외부와 디바이스 드라이버는 파일 인터페이스를 통해서 연결

– 디바이스 드라이버는 file_operations 를 제공함으로써 구현

– 디바이스 드라이버는 자신을 구별하기 위해 고유의 major number 를 사용

장치의 등록과 해제– 등록 : int register_chrdev(unsigned int major, const char *name, struct file_o

perations *fops)

major : 등록할 major number. 0 이면 사용하지 않는 번호 중 동적으로 할당

name : 장치의 이름

fops : 장치에 대한 파일 연산 함수들

– 해제 : int unregister_chrdev(unsigned int major, const char *name)

Page 16: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

문자 디바이스 제작방법

userprogram

openclosereadwrite

kernel

device driver

file operations dev_open dev_close dev_read dev_write

isr rx_isr tx_isr

device

systemcall

interrupt

Page 17: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

문자 디바이스 제작방법 major number 와 minor number

– 장치를 구분하는 방법으로 둘을 이용하여 특정 장치를 구별

– major number : 커널에서 디바이스 드라이버를 구분하는데 사용

– minor number : 디바이스 드라이버 내에서 필요한 경우 장치를 구분하기 위해 사용

– 새로운 디바이스는 새로운 major number 를 가져야 함

– documentation/devices.txt 에 모든 장치의 major number 정의

– register_chrdev() 로 장치를 등록할 때 major number 를 지정

– 같은 major number 가 등록되어 있으면 등록 실패

Page 18: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

문자 디바이스 제작방법 mknod 명령으로 디바이스 드라이버에 접근할 수 있는 장치 파일

생성

– mknod [device file name] [type] [major] [minor]

mdev_t : 장치의 major, minor number 를 표현하는 자료구조

– MAJOR() : kdev_t 에서 major number 를 얻어내는 매크로

– MINOR() : kdev_t 에서 minor number 를 얻어내는 매크로

– MKDEV(ma, mi) : major number, minor number 를 가지고

kdev_t 를 만듬

– cat /proc/devices 명령으로 현재 로드된 디바이스 드라이버 확인

Page 19: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

문자 디바이스 제작방법 struct file_operatons() 함수의 내용

Page 20: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

문자 디바이스 제작방법 module owner : 모듈 사용자 이름 llseek : 파일에서 현재 읽고 쓰는 위치 이동 read : 장치에서 데이터를 읽어 들임 write : 장치에 데이터를 기록 readdir : 장치에서 사용하지 않고 디렉토리에서 사용하는 함수 poll : 장치에 읽고 쓸 수 있는지 예외 상황이 발생했는지 확인하는 함수 ioctl : 읽기 / 쓰기가 아닌 장치마다 필요한 명령을 내리는데 사용하는 함수 mmap : 장치의 메모리와 프로세서의 메모리를 mapping 함 open : 장치 열기 flush : 장치를 해제 release : 장치를 닫음 fsync : 장치를 flush 함 rock : readv : 파일 기술자 fd 에서 데이터를 읽고 그 결과를 vector 가 가리키는 버퍼에 삽입 writev : vector 가 가리키고 있는 버퍼에서 파일 기술자 fd 에 데이터를 씀

Page 21: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

문자 디바이스 제작방법 Open 에서 할 일 :

– 처음으로 장치를 연 경우 장치 초기화

– Minor 번호를 확인하고 필요한 경우 f_op 포인터 수정

– 필요한 경우 메모리를 할당받아 filp-private_data삽입

– 참조 횟수 (usage count) 를 증가

Release 에서 할 일 :– 참조 횟수를 감소

– Filp-private_data 에 할당된 데이터가 있으면 삭제

– Close 하는 경우 장치 종료

Page 22: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

문자 디바이스 제작방법 Read 의 return value

– 요구한 만큼 읽은 경우 count 와 같은 값을 리턴

– 요구한 값보다 작을 경우 count 보다 작은 양수 리턴

– EOP(end of file) 인 경우 0 을 리턴

– 에러가 발생하면 음수 리턴

Write– 요구한 만큼 기록한 경우 count 와 같은 값을 리턴

– 요구한 크기보다 적게 쓴 경우 count 보다 작은 양수 리턴

– 하나도 쓰지 못한 경우 0 리턴 , write() 함수 재시도

– 에러가 발생한 경우 음수 리턴

Page 23: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

모듈 프로그래밍 모듈 프로그래밍의 필요성

– 리눅스 커널은 모노리딕 커널 , 마이크로 커널 방식이 아님

– monolithic Kernel 모든 기능이 커널 내부에 구현 사소한 커널 변경에도 커널 컴파일과 리부팅 필요 커널의 크기가 너무 큼 일부 사용되지 않는 기능이 메모리 상주

– micro Kernel 높은 확장성과 동적 재구성이 용이 VxWorks, pSOS, VRTX, QNX, SROS

Page 24: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

모듈 프로그래밍 모듈 프로그래밍의 역할

– 모듈 프로그래밍으로 모노리딕의 단점을 해결

커널의 일부 기능을 빼고 모듈로 구현

필요할 때만 적재시키므로 효과적인 메모리 사용

– 커널 영역에서 프로그래밍 방법 제공

Page 25: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

모듈 프로그래밍 모듈 프로그래밍 명령어 요약

이 름 용 도

insmod module 을 설치 (install)

rmmod 실행중인 modules 을 제거 (unload)

lsmod Load 된 module 들의 정보를 표시

depmod Module 들의 symbol 들을 이용하여 Makefile 과 유사한 dependency file 을 생성

modprobe depmod 명령으로 생성된 dependency 를 이용하여 지정된 디렉토리의 module 들과 연관된 module 들을 자동으로 load

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

Page 26: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

모듈 프로그래밍 모듈 프로그램의 동작 설명

init_module()init_module() register_capability()register_capability()

cleanup_module()cleanup_module() unregister_capability()unregister_capability()

printk()……

printk()……

rmmod

insmod

capabilities()

모듈 핵심 커널하나의 함수

다른 함수들

데이터

펑션 포인터

데이터로 할당

펑션 콜

데이터 포인터

Page 27: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

모듈 프로그래밍 커널의 심볼 테이블에 등록

– 커널 내부에서 별도로 관리– [ 커널 소스 디렉토리 ]/kernel/ksyms.c 에 등록– #cat /proc/ksyms 명령으로 등록된 심볼의 목록을 확인

심볼 추가 등록에 사용되는 매크로 명령

심볼 등록 매크로 설 명

EXPORT_SYMTAB심볼 테이블을 등록하기 위해 소스코드에서 ‘ linux/module.h’ 전에 정의

EXPORT_SYMBOL심볼을 등록하는 매크로로써 커널 소스의 kernel/ksyms.c 파일을 통해 정의

EXPORT_NO_SYMBOL모듈 프로그램에서 아무런 심볼 등록을 원하지 않을 경우 이 매크로를 삽입

Page 28: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

모듈 프로그래밍 현재 설치되어 있는 모듈을 확인

– /sbin/lsmod 모듈 제작 -> 오브젝트 파일 생성

– /sbin/insmod my_driver.o – 재확인 : /sbin/lsmod

모듈제거– /sbin/rmmod my_driver

my_driver.c 파일 예문

int init_module(void) extern char kernel_version[]; printk("module test\n");

return 0;

Page 29: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

NFS(Network File System) 설치 NFS RPM 설치후

– rpm –ivh xxxx.i386.rpm setup

– system service선택 후 nfs[*]체크 vi /etc/exports

– /[ 공유폴더명 ] [ 보드의 IP](rw)– /etc/rc.d/init.d/.nfs stop– /etc/rc.d/init.d/.nfs start

보드상에서 접근– mount –t nfs –o nolock [ 호스트 PC 의 IP]:/[PC폴더명 ]

/[ 보드폴더명 ]

Page 30: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

예제 프로그램 소스 작성

– vi Hello.c #include <linux/kernel.h> #include <linux/kernel.h> #ifdef CONFIG_MODVERSIONS #define MODVERSIONS #endif

int init_module(void){

printk(“<1>Hello, World\n”);return 0;

}void cleanup_module(viod){

printk(“<1>Goodbye\n”);}

Page 31: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

예제 프로그램 compile

– arm-linux-gcc –c –D__KERNEL__ -DMODULE –Wall –o2 –o hello.o hello.c

mount (soc 보드상에서 작업 )– nfs

mount –t nfs –o nolock (pc 의 IP):/( 원본폴더명 ) /( 다운받을 폴더명 )– minicom

Ctrl + a, z 누른 후 파일 선텍

테스트 (soc 보드상에서 작업 )– 모듈 설치

insmod hello.o * 만약 모듈 버전이 다를 시 insmod –f 옵션 추가– 로드된 모듈 리스트 보기

lsmod– 모듈 제거

rmmod hello

Page 32: 디바이스 드라이버 이해

Hanbat National University Prof. Lee Jaeheung

예제 프로그램 읽기 가능한 간단한 문자 디바이스 드라이버 제작

– arm-linux-gcc –c –D__KERNEL__ -DMODULE –Wall –O2 –o sample.o sample.c– arm-linux-gcc –o test test.c– minicom 이나 nfs 를 이용해서 soc 보드로 다운로드– insmod sample.o– mknod /dev/sample_buf c 254 0– ./test

sample_buf 의 major number확인 방법cat /proc/device (major number 는 출력 결과에서 확인 )cat /dev/sample_buf