33
문문 문문문문 문문문문 문문 문문문문 문문문문 임임임임 임임임

문자 디바이스 드라이버

  • Upload
    elaine

  • View
    131

  • Download
    7

Embed Size (px)

DESCRIPTION

문자 디바이스 드라이버. 임베디드 시스템. 목차. 커널 설정 커널 모듈 실습 : 커널 모듈 작성 리눅스 디바이스 드라이버 실습 : Dummy 디바이스 드라이버 작성 및 사용. kernel configuration. 기본 kernel 부팅을 위한 설정들 MTD file system 을 mount 하기 위한 설정들. system type. Serial drivers. Device drivers -> Character devices -> Serial drivers. Boot options. - PowerPoint PPT Presentation

Citation preview

Page 1: 문자 디바이스 드라이버

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

임베디드 시스템

Page 2: 문자 디바이스 드라이버

목차목차

• 커널 설정커널 설정

• 커널 모듈커널 모듈

• 실습 실습 : : 커널 모듈 작성커널 모듈 작성

• 리눅스 디바이스 드라이버리눅스 디바이스 드라이버

• 실습 실습 : Dummy : Dummy 디바이스 드라이버 작성 및 사용디바이스 드라이버 작성 및 사용

문자 디바이스 드라이버 2

Page 3: 문자 디바이스 드라이버

kernel configurationkernel configuration

• 기본 기본 kernel kernel 부팅을 위한 설정들 부팅을 위한 설정들 • MTD file systemMTD file system 을 을 mountmount 하기 위한 설정들하기 위한 설정들

Page 4: 문자 디바이스 드라이버

system typesystem type

Page 5: 문자 디바이스 드라이버

Serial driversSerial drivers

• Device drivers -> Character devices -> Serial driversDevice drivers -> Character devices -> Serial drivers

Page 6: 문자 디바이스 드라이버

Boot optionsBoot options

Page 7: 문자 디바이스 드라이버

MTDMTD

• Device drivers -> Memory Technology Devices (MTD) Device drivers -> Memory Technology Devices (MTD) ->->

Page 8: 문자 디바이스 드라이버

MTDMTD

• Device drivers -> Memory Technology Devices (MTD) Device drivers -> Memory Technology Devices (MTD) ->->Ram/Rom/Flash chip driversRam/Rom/Flash chip drivers

Page 9: 문자 디바이스 드라이버

MTDMTD

• Device drivers -> Memory Technology Devices (MTD) Device drivers -> Memory Technology Devices (MTD) ->->Mapping drivers for chip accessMapping drivers for chip access

Page 10: 문자 디바이스 드라이버

File systemsFile systems

• File systems -> Miscellaneous filesystems ->File systems -> Miscellaneous filesystems ->

Page 11: 문자 디바이스 드라이버

커널 모듈커널 모듈

• 시스템 부팅 후에 동적으로 시스템 부팅 후에 동적으로 loading loading 할 수 있는 커널 구성요소할 수 있는 커널 구성요소– 커널을 다시 컴파일 하거나 시스템 리부팅 할 필요 없이 커널의

일부분을 교체하는 것이 가능– 디바이스 드라이버 , 파일 시스템 , 네트워크 프로토콜 등이 모듈로

제공됨

• 컴파일한 커널 버전 정보가 들어가야 하고컴파일한 커널 버전 정보가 들어가야 하고 , , 현재 실행되고 있는 현재 실행되고 있는 커널 버전과 일치해야 함커널 버전과 일치해야 함– <linux/module.h> 에 정의되어 있음– 모듈 정보는 전체 모듈에서 하나만 존재해야 함

• 일반 응용 프로그램과의 차이점일반 응용 프로그램과의 차이점– main() 함수가 없음– 커널에 로딩 및 제거 될 때 불러지는 함수가 존재

• Loading 시 - int init_module(void) 함수 호출• Unloading 시 - void cleanup_module() 함수 호출

문자 디바이스 드라이버 11

Page 12: 문자 디바이스 드라이버

실습 실습 : : 커널 모듈 작성커널 모듈 작성

• Hello World Hello World 프로그램프로그램– 모듈이 로딩될 때

• Hello world 출력– 모듈이 제거될 때

• Goodbye world 출력

/* /* hello.c */hello.c */

##include <linux/module.h> /* include <linux/module.h> /* 모든 모듈에 필요모든 모듈에 필요 */*/

#include <linux/kernel.h> /* printk() #include <linux/kernel.h> /* printk() 등에 등에 필요 필요 */*/

int int hello_inithello_init(void) { // (void) { // 모듈이 로딩될 때 호출모듈이 로딩될 때 호출printk (“Hello world\n”); printk (“Hello world\n”); return 0;return 0;

}}

void void hello_exithello_exit(void) { // (void) { // 제거 될 때 호출제거 될 때 호출printk (“Goodbye world”);printk (“Goodbye world”);

}}

module_init(hello_init);module_init(hello_init);module_exit(hello_exit);module_exit(hello_exit);

MODULE_LICENSE(“GPL”);MODULE_LICENSE(“GPL”);

문자 디바이스 드라이버 12

Page 13: 문자 디바이스 드라이버

실습 실습 : : 커널 모듈 컴파일커널 모듈 컴파일

• arm-linux-gcc arm-linux-gcc 컴파일러를 컴파일러를 이용이용

• 오른쪽과 같이 오른쪽과 같이 Makefile Makefile 작성작성

#Makefile#Makefile

obj-m := hello.oobj-m := hello.o KDIR :=$(KDIR :=$( 커널 소스가 설치된 절대 경로커널 소스가 설치된 절대 경로 ))PWD :=$(shell pwd)PWD :=$(shell pwd) all:all: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) $(MAKE) -C $(KDIR) SUBDIRS=$(PWD)

modulesmodules clean:clean: rm -rf *.korm -rf *.ko rm -rf *.mod.*rm -rf *.mod.* rm -rf .*.cmdrm -rf .*.cmd rm -rf *.orm -rf *.o

문자 디바이스 드라이버 13

Page 14: 문자 디바이스 드라이버

실습 실습 : : 커널 모듈 적재 커널 모듈 적재 & & 제거제거

• 생성된 모듈을 로딩생성된 모듈을 로딩– rx hello.ko– 시리얼 통신 (x 모뎀 ) 을 통해

타겟으로 컴파일한 ko 파일 전송– insmod hello.ko

• 커널에 적재된 모듈 목록 보기커널에 적재된 모듈 목록 보기– lsmod

• 모듈 제거모듈 제거– rmmod hello

• 모듈 적재와 제거 시에 원래 의도했던 메시지들이 출력되는 지 확인모듈 적재와 제거 시에 원래 의도했던 메시지들이 출력되는 지 확인

문자 디바이스 드라이버 14

Page 15: 문자 디바이스 드라이버

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

• 실제 장치 부분을 추상화 시켜 사용자 프로그램이 정형화된 실제 장치 부분을 추상화 시켜 사용자 프로그램이 정형화된 인터페이스를 통해 디바이스를 접근할 수 있도록 해주는 프로그램인터페이스를 통해 디바이스를 접근할 수 있도록 해주는 프로그램

• 디바이스 관리에 필요한 정형화된 인터페이스 구현에 요구되는 디바이스 관리에 필요한 정형화된 인터페이스 구현에 요구되는 함수와 자료구조의 집합체함수와 자료구조의 집합체

• 표준적으로 동일 서비스 제공을 목적으로 커널의 일부분으로 내장표준적으로 동일 서비스 제공을 목적으로 커널의 일부분으로 내장

• 하드웨어 독립적인 프로그램을 작성을 가능하게 함하드웨어 독립적인 프로그램을 작성을 가능하게 함

• 파일 연산을 통해 장치를 제어파일 연산을 통해 장치를 제어

문자 디바이스 드라이버 15

Page 16: 문자 디바이스 드라이버

리눅스 디바이스 드라이버의 종류리눅스 디바이스 드라이버의 종류

• 문자 디바이스 드라이버문자 디바이스 드라이버– 자료의 순차성을 지닌 장치– 입출력연산 한번으로 임의의 데이터 전송– 예 ) 키보드 , 시리얼 포트 등

• 블록 디바이스 드라이버블록 디바이스 드라이버– 블록 단위로 데이터 입출력– 파일시스템에 마운트 되어 관리되는 장치– 입출력연산 한번으로 고정된 크기의 데이터 전송– 예 ) 하드 디스크 , CD 롬 , 플로피 디스크 등

• 네트워크 디바이스 드라이버네트워크 디바이스 드라이버– 대응하는 장치파일이 없음– 응용프로그램과의 통신은 표준 파일 시스템관련 콜 대신 socket(),

bind() 등의 시스템 콜 사용

문자 디바이스 드라이버 16

Page 17: 문자 디바이스 드라이버

리눅스 디바이스 드라이버의 종류리눅스 디바이스 드라이버의 종류 (2)(2)

문자 디바이스 드라이버 17

Application

System Call Interface

VFS

Network SubsystemBuffer Cache

Network D/DBlock D/DCharacter D/D

Device Interface

Hardware

Applicationarea

Kernelarea

Hardware

Page 18: 문자 디바이스 드라이버

디바이스 장치 파일디바이스 장치 파일

• 리눅스에서 장치는 파일로 인식됨리눅스에서 장치는 파일로 인식됨– ls –l /dev 명령을 이용하여 확인 가능

문자 디바이스 드라이버 18

디바이스 종류 주번호 부번호

Page 19: 문자 디바이스 드라이버

디바이스 장치 파일디바이스 장치 파일 (2)(2)• 주 번호주 번호 (Major Number)(Major Number)

– 커널에서 디바이스 드라이버를 구분 /연결하는데 사용– 같은 Device 의 종류를 지칭 , 1Byte (0~255 사이의 값 )

• 부 번호부 번호 (Minor Number)(Minor Number)– 디바이스 드라이버 내에서 장치를 구분하기 위해 사용– 각 Device 의 부가적인 정보를 나타냄 , 2Byte ( 부번호 )– 하나의 디바이스 드라이버가 여러 개의 디바이스 제어 가능

문자 디바이스 드라이버 19

주번호 부번호

Page 20: 문자 디바이스 드라이버

문자 디바이스 드라이버 기본 골격문자 디바이스 드라이버 기본 골격

#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h> int device_open( … ) { … }int device_release( … ) { … }ssize_t device_write( … ) { … }ssize_t device_read( … ) { … } static struct file_operations device_fops = { …ssize_t (*read) (…);ssize_t (*write) (…); …int (*open) (…);int (*release) (…);…};

int init_module(void) { … } void cleanup_module(void) { … } module_init(hello_init);module_exit(hello_exit);

문자 디바이스 드라이버 20

헤더 파일

파일 연산 함수 정의

파일 연산 구조체

Page 21: 문자 디바이스 드라이버

디바이스 드라이버 작성 방법디바이스 드라이버 작성 방법

• 디바이스 드라이버 등록디바이스 드라이버 등록– 드라이버를 커널에 등록하고 , 파일 연산을 정의하는 등의 초기화 작업

수행이 필요– insmod 를 이용하여 모듈이 커널에 로딩될 시 init 함수에서 초기화

수행

– 문자 드라이버 등록 함수

• 커널에 지정되어 있는 chrdevs 구조에 새로운 문자 드라이버 등록– major number : 주번호 , 0 을 주면 사용하지 않는 값을 반환– name : 디바이스 이름으로 /proc/devices 에 나타남– fops: 디바이스와 연관된 파일 연산 구조체 포인터

• 음수가 반환되면 오류가 발생했음을 나타냄

문자 디바이스 드라이버 21

int register_chrdev( unsigned int major, const * name,

struct file_operations * fops);

Page 22: 문자 디바이스 드라이버

디바이스 드라이버 작성 방법디바이스 드라이버 작성 방법 (2)(2)

• 디바이스 드라이버 제거디바이스 드라이버 제거– rmmod 명령으로 드라이버가 제거될 때 cleanup 함수에서 호출

– 문자 드라이버 제거 함수

문자 디바이스 드라이버 22

int unregister_chrdev( unsigned int major, const * name);

Page 23: 문자 디바이스 드라이버

디바이스 드라이버 작성 방법디바이스 드라이버 작성 방법 (3)(3)• 파일 연산 구조체 정의파일 연산 구조체 정의

– 디바이스 드라이버를 일반적인 파일과 유사한 인터페이스를 이용하여 관리• 각 디바이스는 파일 형태로 존재하고 , 커널은 파일 연산을 이용하여 I/O

연산을 수행하도록 인터페이스 구성• 디바이스 드라이버를 구현한다는 것은 상당부분 파일연산 구조체에서

요구되는 기능들을 프로그래밍 한다는 것을 의미

문자 디바이스 드라이버 23

struct file_operations dummy_fops = { .owner = THIS_MODULE, .open = dummy_open,     .read = dummy_read,        .write = dummy_write,        .ioctl = dummy_ioctl    .release = dummy_release,  };

Page 24: 문자 디바이스 드라이버

디바이스 드라이버 작성 방법디바이스 드라이버 작성 방법 (4)(4)• 파일 연산의파일 연산의 종류종류

– read• 디바이스에서 데이터를 가져오기 위해서 사용

– write• 디바이스에 데이터를 쓰기 위해서 사용

– ioctl• 디비아스에 종속적인 명령을 만들기 위해 사용

– mmap• 디바이스 메모리를 프로세스 메모리에 매핑

– open• 디바이스를 열 때 수행

– release• 디바이스를 닫을 때 수행

문자 디바이스 드라이버 24

Page 25: 문자 디바이스 드라이버

실습 실습 : Dummy : Dummy 디바이스 드라이버 작성디바이스 드라이버 작성

• 헤더 파일 및 매크로 정의헤더 파일 및 매크로 정의

문자 디바이스 드라이버 25

#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/errno.h>#include <linux/types.h>#include <linux/fcntl.h>

#define DUMMY_NAME “dummy”#define DUMMY_MAJOR_NUMBER 240

Page 26: 문자 디바이스 드라이버

실습 실습 : Dummy : Dummy 디바이스 드라이버 작성디바이스 드라이버 작성(2)(2)

• 드라이버 등록드라이버 등록

문자 디바이스 드라이버 26

static int dummy_init(void){        int ret;

        printk(“dummy init\n”);

     ret = register_chrdev(DUMMY_MAJOR_NUMBER,              DUMMY_NAME, &dummy_fops);

        if (res < 0)                return ret;        return 0;}

module_init(dummy_init);

Page 27: 문자 디바이스 드라이버

실습 실습 : Dummy : Dummy 디바이스 드라이버 작성디바이스 드라이버 작성(3)(3)

• 드라이버 제거드라이버 제거

문자 디바이스 드라이버 27

static void dummy_exit(void) {         printk(“dummy exit\n”);

        unregister_chrdev( DUMMY_MAJOR_NUMBER,              DUMMY_NAME); }

module_exit(dummy_exit);

MODULE_LICENSE(“GPL”);

Page 28: 문자 디바이스 드라이버

실습 실습 : Dummy : Dummy 디바이스 드라이버 작성디바이스 드라이버 작성(4)(4)

• 파일 연산 구조체 정의파일 연산 구조체 정의

문자 디바이스 드라이버 28

struct file_operations dummy_fops = { .owner = THIS_MODULE, .open = dummy_open,   .read = dummy_read,        .write = dummy_write,       .ioctl = dummy_ioctl,    .release = dummy_release,  };

Page 29: 문자 디바이스 드라이버

실습 실습 : Dummy : Dummy 디바이스 드라이버 작성디바이스 드라이버 작성(5)(5)

• open & releaseopen & release

문자 디바이스 드라이버 29

int dummy_open(struct inode *inode, struct file *filep){         int num = MINOR(inode->i_rdev);

        printk(“dummy dev open -> minor %d\n”, num);

        return 0; }

int dummy_release(struct inode *inode, struct file *filep){         printk(“dummy dev close\n”);

        return 0; }

Page 30: 문자 디바이스 드라이버

실습 실습 : Dummy : Dummy 디바이스 드라이버 작성디바이스 드라이버 작성(6)(6)

• read & writeread & write

문자 디바이스 드라이버 30

size_t dummy_read(struct file *filep, char *buf, size_t count, loff_t *f_pos){         printk(“dummy dev read -> buf 0x%08x, count 0x%08x\n”, buf, count);

        return 0x33; }

size_t dummy_write(struct file *filep, const char *buf, size_t count,         loff_t *f_pos){         printk(“dummy dev write -> buf 0x%08x, count 0x%08x\n”, buf, count);

        return 0x43; }

Page 31: 문자 디바이스 드라이버

실습 실습 : Dummy : Dummy 디바이스 드라이버 작성디바이스 드라이버 작성(7)(7)

• ioctlioctl

문자 디바이스 드라이버 31

int dummy_ioctl(struct inode *inode, struct file *filep,         unsigned int cmd, unsigned long arg){         printk(“dummy dev ioctl -> cmd 0x%08x, arg 0x%08x\n”, cmd, arg);

        return 0x53; }

Page 32: 문자 디바이스 드라이버

실습 실습 : Dummy : Dummy 드라이버를 제어하기 위한 드라이버를 제어하기 위한 어플리케이션 작성어플리케이션 작성

• app.capp.c

문자 디바이스 드라이버 32

#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <fcntl.h>#include <unistd.h>

#define DEV_NAME “/dev/dummy_device”

int main(){        int dev;        char buf[128];        int ret;

        printf(“1> device open\n”);

        dev = open(DEV_NAME,                O_RDWR|O_NDELAY);

        printf(“dev %d\n”, dev);        if (dev >= 0)        {

                printf(“2> read function\n”);

                ret = read(dev, 0x30, 0x31);                printf(“ret = 0x%x08x\n”, ret);

                printf(“3> write function\n”);

                ret = write(dev, 0x40, 0x41);                printf(“ret = 0x%x08x\n”, ret);

                printf(“4> ioctl function\n”);

                ret = ioctl(dev, 0x51, 0x52);                printf(“ret = 0x%x08x\n”,

                printf(“5> device close\n”);

                ret = close(dev);                printf(“ret = 0x%x08x\n”, ret);        }

        return 0; }

Page 33: 문자 디바이스 드라이버

실습 실습 : : 디바이스 드라이버 적재 및 디바이스 드라이버 적재 및 삭제삭제

• 디바이스 드라이버 컴파일디바이스 드라이버 컴파일– 커널 모듈 실습과 동일

• 디바이스 드라이버 적재디바이스 드라이버 적재– insmod dummy.ko

• 노드 생성노드 생성– 디바이스를 사용하기 위해서는 노드

( 파일 ) 을 생성해야 함– 노드 ( 파일 ) 를 통해서 입출력 수행– mknod /dev/dummy_device c 240 0

• 디바이스 드라이버 삭제디바이스 드라이버 삭제– rmmod dummy

• 드라이버의 적재 여부드라이버의 적재 여부– lsmod

문자 디바이스 드라이버 33