1 / 39

리눅스 디바이스 드라이버

리눅스 디바이스 드라이버. 실습 환경 설정 및 준비. 커널 컴파일. 디바이스 파일 (1). 디바이스 파일 (2). mknod 명령 디바이스 파일 생성 mknod [ 디바이스 파일명 ] [ 파일 형 ] [ 주 번호 ] [ 부 번호 ] mknod /dev/devfile c 240 1. 디바이스 드라이버 탐색. 실질적인 디바이스 탐색. 저수준 파일 입출력 함수. 모듈 유틸리티. insmod 모듈을 커널에 적재한다 . rmmod 커널에 등록된 모듈을 제거한다 . lsmod

baba
Download Presentation

리눅스 디바이스 드라이버

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 리눅스 디바이스 드라이버 실습 환경 설정 및 준비

  2. 커널 컴파일

  3. 디바이스 파일(1)

  4. 디바이스 파일(2) • mknod 명령 • 디바이스 파일 생성 • mknod [디바이스 파일명] [파일 형] [주 번호] [부 번호] • mknod /dev/devfile c 240 1 디바이스 드라이버 탐색 실질적인 디바이스 탐색

  5. 저수준 파일 입출력 함수

  6. 모듈 유틸리티 • insmod • 모듈을 커널에 적재한다. • rmmod • 커널에 등록된 모듈을 제거한다. • lsmod • 커널에 등록된 모듈의 상태를 보여준다.

  7. 모듈 소스 형식(1) • 헤더 파일 선언 • 모듈 초기화 함수, 제거 함수

  8. 모듈 컴파일용 Makefile obj-m := test.o // 모듈로 생성할 이름 지정 KDIR := /lib/modules/$(shell uname -r)/build // 커널의소스 위치 지정 PWD := $(shell pwd) // 컴파일 대상의 모듈 소스의 위치 default: // 모듈을컴파일하는 명령 지정 $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules clean: // 컴파일 결과로 생성된 파일을 모 rm -rf *.ko // 두 지운다. rm -rf *.mod.* rm -rf .*.cmd rm -rf *.o

  9. 모듈 프로그램 맛보기(1) • test.c #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> static int hello_init(void) { printk("Hello, world \n"); return 0; } static void hello_exit(void) { printk("Goodbye, world\n"); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("Dual BSD/GPL");

  10. 모듈 프로그램 맛보기(2) • Makefile obj-m := test.o KDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules clean: rm -rf *.ko rm -rf *.mod.* rm -rf .*.cmd rm -rf *.o

  11. 동적 메모리 할당 함수

  12. kmalloc(), kfree()-1 메모리주소 kmalloc(할당 받을 크기, 옵션); kfree(메모리주소); * 할당 가능한 최대 크기는 32 x PAGE_SIZE (일반적으로 128KB) #include <linux/slab.h> char *buf; buf = kmalloc(1024, GFP_KERNEL); if (buf != NULL) { … kfree(buf); }

  13. vmalloc(), vfree() 메모리주소 vmalloc(할당 받을 크기); vfree(메모리주소); #include <linux/vmalloc.h> char *buf; buf = vmalloc(1024); if (buf != NULL) { … vfree(buf); }

  14. vmalloc(), vfree() 특징 • 가상 주소 공간에서 할당받기 때문에 해당주소의 영역이 • 하드디스크에 있을 수도 있어 실패할 수 있다. • 커다란 연속된 공간을 할당하기 위해 가상메모리 관리 루틴이 • 수행되기 때문에 kmalloc() 보다 속도가 매우 느리다. • 할당 시 프로세스가 잠들지 못하게 할 수 없기 때문에 • 인터럽트 서비스 함수 안에서는 사용할 수 없다.

  15. __get_free_pages(), free_pages() 메모리주소 __get_free_pages(옵션, 차수); free_pages(메모리주소); #include <linux/mm.h> //2.4 #include <linux/gfp.h> //2.6 #include <asm/page.h> //get_order char *buf; buf = __get_free_pages(GFP_KERNEL, order); /* order=0이면 1개의 page, order=3이면 3개의 page /* MAX_ORDER은 11, 그러나 5이하의 값만 사용하는 것이 안전 (32*PAGE_SIZE) */ if (buf != NULL) { … free_pages(buf, order); }

  16. 초기화와 종료 처리 • module_init 의 초기화 처리 • 디바이스 드라이버의 등록 • 디바이스 드라이버에 내부 구조체의 메모리 할당 • 여러 프로세스가 하나의 디바이스에 접근하는 경우에 사전처리 • 주 번호에 종속된 부 번호를 관리하기 위한 사전 처리 • 하드웨어 검출 처리 및 에러 처리 • 하드웨어 초기화

  17. 초기화와 종료 처리 • module_exit 의종료 처리 • 초기화 시점에 할당된 메모리 모두 반납 (디바이스 드라이버는 커널의 일부이기 때문에 메모리를 자동 반납하지 않는다.) • 디바이스 드라이버의 해제 • 디바이스 드라이버에 할당된 모든 메모리의 해제 • 하드웨어 제거에 따른 처리

  18. 초기화와 종료 처리 void xxx_exit(void) { kfree(… // 디바이스 드라이버에 할당된 모든 메모리 해제 unregister_chrdev(… // 디바이스 드라이버의 해제 xxx_shutdown(… //하드웨어 제거에 따른 처리 } module_exit 처리순서

  19. 초기화와 종료 처리 int fd; fd = open( DEVICE_FILENAME, O_RDWR|O_NDELAY); //반드시 주번호 정보가 있는 파일 if( fd < 0 ) { printf (“error number %d\n”, error); exit(1); } #include<linux/fs.h> struct file_operations call_fops = { … .open = xxx_open, … } int xxx_open( struct inode *inode, struct file *filp ) { int err = 0; //open() 시 처리내용들…. return err; } *inode – 열린 디바이스 파일에 대한 정보 *filp – 디바이스 드라이버 처리관련 정보 ENODEV : 하드웨어가 존재하지 않는다. ENOMEM : 커널 메모리가 부족하다. EBUSY : 디바이스가 이미 사용중 이다. • 디바이스 드라이버 open( ) 함수[2]

  20. 초기화와 종료 처리 • 디바이스 드라이버 release( ) 함수[1] • release( ) 함수 호출 시 종료 처리 • 프로세스별 할당 메모리 해제 • 모듈 사용 횟수 감소(커널 2.4) • 커널 2.6에서는 사용횟수 관리를 커널에서 한다.

  21. 초기화와 종료 처리 if( fd ) close( fd ); #include<linux/fs.h> struct file_operations call_fops = { … .release = xxx_release, … } int xxx_release( struct inode *inode, struct file *filp ) { //close( ) 시 처리내용들…. return 0; } • 디바이스 드라이버 release( ) 함수[2]

  22. 문자 디바이스 드라이버 동작-3 디바이스 드라이버 하드웨어 인터럽트 insmod xxx_init(); struct file_operations { open : xxx_open write : xxx_write . . . } xxx_exit(); xxx_interupt(); xxx_open(); xxx_write(); 응용 프로그램 open(); write(); rmmod

  23. 커널 2.6의 파일 오퍼레이션 구조체 struct file_operations { struct module *owner; int (*open)(struct inode *, struct file *); . . . } * 디바이스 드라이버의 file_operations에서정의되지 않았거나 NULL로 채워진 필드는 커널에 의해서 default 처리를 한다.

  24. #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/errno.h> #include <linux/types.h> #inlcude <linux/fcntl.h> int xxx_open (struct inode *inode, struct file *filp) { } int xxx_release(struct inode *inode, struct file *filp) { } struct file_operations xxx_fops = { .owner = THIS_MODULE, .open = xxx_open, .release = xxx_release, }; int xxx_init(void) { register_chrdev(240, “char_dev”, &xxx_fops); } void xxx_exit(void) { unreister_chrdev(240, “char_dev”); } module_init(xxx_init); module_exit(xxx_exit);

  25. mknod /dev/calldev c 240 32

  26. make

  27. insmod call_dev.ko

  28. app(call_app) 컴파일

  29. app 실행

  30. dmesg

More Related