디바이스 드라이버에 대한 일반적인 개요를 살펴본다

Slides:



Advertisements
Similar presentations
Format String Attack! 포맷 스트링 공격 경일대학교 사이버보안학과 학년 남주호.
Advertisements

컴퓨터와 인터넷.
Image & Video processing
인공지능실험실 석사 2학기 이희재 TCP/IP Socket Programming… 제 11장 프로세스간 통신 인공지능실험실 석사 2학기 이희재
Network Lab. Young-Chul Hwang
Cross Compiler를이용한 커널 컴파일 및 포팅
제9장 디바이스 드라이버 개요.
Linux/UNIX Programming
08. 디바이스 드라이버의 읽기와 쓰기 김진홍
디바이스 드라이버 (Device Driver)
디바이스 드라이버 기초 디바이스 드라이버의 개요 파일 연산 디바이스 드라이버 등록 디바이스 드라이버 구성
디바이스 드라이버.
이식성과 데이터형 서로 다른 프로세서 상에서의 이식성을 위해 가급적 리눅스 커널이 제공하는 데이터형을 사용하는 것이 좋다.
디바이스 드라이버 개요 가상 디바이스드라이버 실습
Module Programming Linux Kernel 수업 4번째.
Unix Project2 <test character device 생성>
UNIT 06 JTAG Debugger 로봇 SW 교육원 조용수.
커널 프로그래밍과 시스템 콜을 만들어보고, 디바이스 드라이버에 대한 일반적인 개요를 살펴본다.
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express Slide 1 (of 13)
4장. 웹로직 서버상에서의 JDBC와 JTA의 운용
임베디드 시스템 개론 크로스 플랫폼 설치 2일차 강의 자료 Embedded System Lab.
UNIT 07 Memory Map 로봇 SW 교육원 조용수.
FND (Flexible Numeric Display)
Homework #6 (1/3) 다음을 수행한 후, 화면(혹은 파일)을 출력하여 제출한다.
Step Motor Device Driver
제 3장. C보다 나은 C++ II.
07. 디바이스 드라이버의 초기화와 종료 김진홍
CHAPTER 02 OpenCV 개요 PART 01 영상 처리 개요 및 OpenCV 소개.
Root Filesystem Porting
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
Root Filesystem Porting
                              데이터베이스 프로그래밍 (소프트웨어 개발 트랙)                               퍼스널 오라클 9i 인스톨.
파일 기술자 파일 기술자 현재 열려있는 파일을 구분하는 정수값 저수준 파일 입출력에서 열린 파일을 참조하는데 사용
WinCE Device Driver 실습 #3
WinCE Device Driver 실습 #2
커널 모듈 프로그래밍 (Kernel Module Programming)
Cross Compiler 설치.
HBE-SMIII-SV210 리눅스 커널과 디바이스 드라이버
자료구조: CHAP 4 리스트 (3) 순천향대학교 컴퓨터공학과 하 상 호.
프로그래밍 랩 – 7주 리스트.
망고100 보드로 놀아보자 -13 리눅스 디바이스 드라이버 개요
Cross Compiler를이용한 커널 컴파일 및 포팅
사용자 함수 사용하기 함수 함수 정의 프로그램에서 특정한 기능을 수행하도록 만든 하나의 단위 작업
문자 디바이스 드라이버 임베디드 시스템.
UNIT 07 Memory Map 로봇 SW 교육원 조용수.
리눅스 시스템 & 커널 기초 P.46 – P.53 이름: nsh009 학번: 112 1/20.
㈜시스원이 제공하는 시스템 관리 통합 솔루션 SysmanagerOne Agent설치 안내서
27장. 모듈화 프로그래밍.
Homework #6 (1/3) 다음을 수행한 후, 화면(혹은 파일)을 출력하여 제출한다.
Device Driver 임베디드 시스템 I.
Homework #6 (1/3) 다음을 수행한 후, 화면(혹은 파일)을 출력하여 제출한다.
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
리눅스 디바이스 드라이버 (Linux Device Driver)
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
컴퓨터 시스템 하드웨어 컴퓨터 시스템 소프트웨어 C P U Control Unit 입 력 장 치 출 력 장 치 ALU
Stepper Motor 디바이스 드라이버
컴퓨터 프로그래밍 기초 - 8th : 함수와 변수 / 배열 -
네트워크 환경 구축과 이미지 전송 호스트/타겟 통신 직렬 통신을 이용한 이미지 전송 수퍼 데몬 BOOTP 환경 구축
Kernel, Ramdisk, JFFS2 Porting
( Windows Service Application Debugging )
OpenCV 설정 2.21 만든이 딩딩.
DK-128 개발환경 설정 아이티즌 기술연구소
3. 모듈 (5장. 모듈).
01. 분산 파일 시스템의 개요 네트워크에 분산된 파일을 사용자가 쉽게 접근하고 관리할 수 있게 해준다.
구조체(struct)와 공용체(union)
바이트 순서 변환 함수 주소 변환 함수 바이트 조작 함수 원격지 호스트 정보를 얻는 함수
동적메모리와 연결 리스트 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
06. 디바이스의 등록과 해제 김진홍
1장 C 언어의 개요 C 언어의 역사와 기원 C 언어의 특징 프로그램 과정 C 프로그램 구조 C 프로그램 예제.
Homework #7 (1/3) 1. 다음 순서에 따라 수행하고, 그 과정의 화면을 캡쳐한다.
Presentation transcript:

디바이스 드라이버에 대한 일반적인 개요를 살펴본다

목 차 (1) Linux Kernel Module Programming (2) Device Driver 정의 목 차 (1) Linux Kernel Module Programming (2) Device Driver 정의 (3) Device Driver 종류 (4) Device Driver 작성 (5) 제작한 Device Driver 검증 파일 만들기 (6) Makefile 만들기 (7) Driver를 커널에 모듈로 등록 및 해제하기

Kernel Module 정의 (1) 리눅스 커널(Linux Kernel) 커널 모듈(Kernel Module) 모노리스 커널(Monolithic Kernel) cf) 마이크로 커널(Micro-kernel) 커널의 기능을 확장하기 위해서는 커널 재컴파일이 필요 커널 모듈(Kernel Module) 실행시간에 커널을 확장하기 위해 사용하는 오브젝트 모듈 커널이 실행중인 동안에 동적으로 로딩하여 커널과 링크함으로써 커널의 기능을 확장하여 사용할 수 있으며, 불필요 시에 커널과의 링크를 풀고 메모리에서 제거할 수 있다  커널 재컴파일이 필요없이 커널 기능 확장이 가능 명시적인 커널 모듈 설치 및 제거 과정이 필요 Insmod / rmmod 명령어 디바이스 드라이버, 파일시스템, 네트워크 프로토콜 스택 등에 적용 커널 경량화를 위해 반드시 필요 임베디드 시스템의 경우, 제한적인 자원으로 인해 커널 등 시스템 소프트웨어의 최소화가 필요

Kernel Module 정의 (2) 커널 모듈 프로그래밍 커널 모듈은 커널 모드에서 실행됨으로 커널 프로그래밍에 준하여 작성되어야 한다 모듈 프로그래밍의 주의 사항 무제한적인 메모리 접근  메모리 접근 오류는 시스템에 치명적인 손상을 줄 수 있음 커널 함수 호출에 따른 에러 코드 검사 실수 연산 및 MMX 연산 사용 불가 제한적인 커널 스택 크기 크기가 큰 배열 사용 회피  동적 할당 방법을 이용 재귀 호출 회피 상이 플랫폼 고려 32 bit 및 64 bit 환경 바이트 순서 – big-endian 또는 little-endian 프로세서에 특화된 명령어 사용 회피 버전 종속성 커널 버전에 따라 모듈 버전이 다름

Kernel Module 정의 (3) 커널 모듈 버전 종속성(Version Dependency) 커널 버전에 따라 지원되는 커널 함수의 종류나 프로토 타입이 다르기 때문에 다른 버전의 커널에 모듈을 링크하려면 모듈 재컴파일이 필요 모듈을 커널에 설치할 때에 버전 검사 수행 커널 버전과 모듈 버전이 일치하지 않는 경우에 모듈을 설치할 수 없음 커널 모듈 프로그램의 버전 정의 커널 ver.2.0 이상에서는 <linux/module.h> 헤드 파일에서 char kernel_version[ ] 변수에 커널 버전을 정의 커널 모듈 프로그램에서 위의 헤드 파일을 including #include <linux/module.h> 커널 버전 정의는 전체 모듈에서 한번만 정의되어야 함 커널 버전에 따른 종속적인 동작 정의 <linux/version.h>에서 정의된 매크로 LINUX_VERSION_CODE 사용 #ifdef LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) // 리눅스 ver.2.4.0 이상일 때의 코드 #else // 리눅스 ver.2.4.0 미만일 때의 코드 #endif

Kernel Module 작성 (1) 커널 모듈 구성 커널 기능을 확장한 함수와 자료 구조로 구성 main() 함수는 없는 독립된 프로그램 모듈 init_module()/cleanup_module() 함수 존재 init_module() 함수 모듈이 설치될 때에 자동적으로 호출 모듈 초기화 등의 기능 수행 cleanup_module() 함수 모듈을 삭제할 때에 자동적으로 호출 모듈 제거에 따른 cleanup 작업을 수행 기본적인 구성  #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> /* global variables */ … int init_module(void) { } void cleanup_module(void) { }

Kernel Module 작성 (2) 커널 모듈 구성 (계속) 커널 ver.2.4 이상에서는 module_init() / module_exit() 매크로 지원 함수 이름에 의한 종속 관계를 해결 module_init() 매크로 : startup 함수 등록 module_exit() 매크로 : cleanup 함수 등록 #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> /* global variables */ … int module_start() { /* 모듈이 설치될 때에 초기화를 수행하는 코드 */ } int module_end() { /* 모듈이 제거될 때에 반환작업을 수행하는 코드 */ } module_init(module_start); module_exit(module_end);

Linux 플랫폼에서 동작하는 모듈임을 정의하는 매크로 Kernel Module 작성 (3) 커널 모듈 구성 (계속) 모듈 프로그램의 Makefile -c : 링커를 호출하지 않고 오브젝트 모듈만 생성 -O : 최적화 옵션 지정 (최대 O2) 컴파일 매크로 : __KERNEL__ , MODULE, LINUX CC = arm_linux_gcc INCLUDEDIR = /kernel_source_dir/include CFLAGS := -c -O –Wall –D__KERNEL__ –DMODULE –DLINUX -I$(INCLUDEDIR) OBJS = hello.o all : $(OBJS) clean : rm –f *.o *.~ 커널 프로그램임을 명시하는 매크로 모듈 프로그램임을 명시하는 매크로 Linux 플랫폼에서 동작하는 모듈임을 정의하는 매크로

Kernel Module 설치 및 제거 (1) 커널 모듈 설치 및 제거 관련 쉘 명령어 이 름 용 도 insmod 용 도 insmod module을 설치(install) rmmod 실행중인 modules을 제거(unload) lsmod Load된 module들의 정보를 표시 depmod Module들의 symbol들을 이용하여 Makefile과 유사한 dependency file을 생성 modprobe depmod명령으로 생성된 dependency를 이용하여 지정된 디렉토리의 module들과 연관된 module들을 자동으로 load modinfo 목적화일을 검사해서 관련된 정보를 표시

Kernel Module 설치 및 제거 (2) 커널 모듈 설치 및 제거 (계속) 설치된 모듈은 ‘/proc/modules’ 파일에 기록된다 ‘/proc/modules’ 파일을 이용한 현재 설치된 모듈을 확인 가능 #cat /proc/modules

Kernel Module 프로그래밍 (1) 커널 모듈 프로그램 작성 모듈 적재 및 제거 시에 간단한 메시지를 출력하는 모듈 작성 구현 방법 모듈 적재 시에 호출되는 init_module() 함수에서 printk() 함수를 이용하여 “Hello, World!” 메시지를 출력한다 모듈 제거 시에 호출되는 cleanup_module() 함수에서 같은 방법으로 “Good bye!!!” 메시지를 출력한다 모듈 작성 및 테스트 모듈 프로그램 소스 파일 hello_world.c을 작성한다 /* hello_world.c */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> static int module_begin(void) { printk(“Hello, World!\n”); return 0; } static void module_end(void) { printk(“Good bye!!!\n”); } EXPORT_NO_SYMBOLS; module_init(module_begin); module_exit(module_end);

Kernel Module 프로그래밍 (2) 커널 모듈 프로그램 작성 (계속) 모듈 작성 및 테스트 Makefile을 작성하고 컴파일을 수행한다 Hello_world.o 모듈을 임베디드 시스템에 다운로드한다 임베디드 시스템에서 모듈 설치 및 제거를 수행 # insmod hello_world.o # lsmod … # rmmod hello_world # Makefile CROSS_COMPILE=arm_linux_gcc INCLUDEDIR = /kernel_source_dir/include MODCFLAGS = -c -O –Wall –D__KERNEL__ -DMODULE –DLINUX -I$(INCLUDEDIR) SRC = hello_world.c hello_world.o: $(SRC) $(CROSS_COMPILE) $(MODCFLAGS) $(SRC)

Device Driver 정의 (1) 물리적인 hardware 장치를 다루고 관리하는 software user application이 driver에게 요청을 하면, driver는 hardware를 구동시켜서 목적을 달성 major number와 minor number를 이용하여 각각의 devices을 구분하여 사용 device와 system memory 간에 data의 전달을 담당하는 kernel 내부 기능 - Driver는 해석 그대로 사물을 구동하는 주체. - 응용프로그램에서 하드웨어 장치를 이용해서 데이터를 직접 읽고 쓰거나 제어해야 하는 경우에 디바이스 드라이버를 이용 - 일반적으로 위쪽으로는 파일 시스템과 인터페이스를 가지며, 아래쪽으로는 실제 디바이스 하드웨어와 인터페이스를 갖는다.

DDI (device driver interface) User application level Kernel task System call interface File system Block Driver Char Driver DDI (device driver interface) Network Driver terminal keyboard Hard disk CD-ROM ethernet User application level Kernel level Hardware level Application의 일반 함수는 kernel level로 접근하는게 제한되어 있다. 그래서 hardware를 제어하기 위해서 driver를 파일로 작성하고 커널에 모듈로 적재한다. 리눅스에서는 모든 장치는 파일로 다루어진다. 모듈 또한 /dev에 파일로 적재되고, Application에서 그 file을 불려서 hardware를 제어하낟.

Device Driver 종류 Driver 종류 설 명 Char Driver 설 명 Char Driver device를 file처럼 취급하고 접근하여 직접 read/write를 수행, data 형태는 stream 방식으로 전송 EX) console, keyboard, serial port driver등 Block Driver disk와 같이 file system을 기반으로 일정한 blcok 단위로 data read/write를 수행 EX) floppy disk , hard disk, CD-ROM driver 등 Network Driver network의 physical layer와 frame 단위의 데이터를 송수신 EX) Ethernet device driver(eth0) 등록함수명 register_chrdev() register_blkdev() register_netdev() - 문자 드라이버는 저속, 순차적, 사용자 응용프로그램과 byte 단위로 데이터를 송/수신. 이것은 오디오, UART, keyboard 같은 장치가 해당 - 블록 드라이버는 고속, 랜덤, 사용자 응용 프로그램과 블록 단위로 데이터를 송/수신. 이것은, 하드디스크 같은 고속 저장장치에 사용. - 네트웍 드라이버가 있는데 앞에서 설명했던 문자와 블록 드라이버는 사용자 프로그램과 데이터를 주고 받을 때, 파일 형태의 노드를 통해서 주고 받지만, 네트웍 드라이버는 메모리에 있는 구조체 형식을 통하여 데이터를 송/수신 함

Device Driver 작성 (1) 기본적인 device driver의 형태 Device Opertations static struct file_operations device_fops={ open : device_open, release : device_release, read : device_read, write : device_write,}; Function Prototypes static int device_open(); static int device_release(); ssize_t device_read(); static ssize_t device_write(); int init_function(); void cleanup_function(); Module 제거 시 반환작업 수행 module_exit(cleanup_function) Module 설치 시 초기화 수행 module_init(init_function) Header Files #include <linux/kernel.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/init.h> Printf와 같은 기능의 커널 코드를 위한 함수 필요한 header. 모듈소스가 include해야함 insmod로 모듈을 적재하면 이 함수가 불려진다. 이 함수 안에서 regiseter_chrdev() 커널 함수를 뷸러서 모둘을 적재한다. rmmod로 적재된 모듈을 삭제할 경우 이 함수가 불려진다. unregister_chrdev() 커널 함수를 불려서 모듈을 삭제한다. “파일시스템”헤더는 디바이스 드라이버를 쓰는데 필요한 헤더파일 application에서 쓰는 함수와 driver에서 쓰는 함수를 mapping Module_init()과 module_exit() 정의됨 Header file은 상대경로로 표시되는데 위의 상대 경로는 /usr/src/리눅스 소스가 있는 디렉토리/include/ 밑에 있다. Device_open 함수는 이 드라이버를 MOD_INC_USE_COUNT라는 매크로를 사용하여 사용횟수를 증가시킨다. Divece_release 함수는 이 드라이버를 MOD_DEC_USE_COUNT라는 매크로를 사용하여 사용횟수를 감소시킨다. 사용수가 0일때에야만 모듈 삭제 가능.

Device Driver 작성(2) #include <linux/module.h> #include <linux/fs.h> #include <linux/kernel.h> #include <linux/init.h> #define DEV_NAME "test_dd" int test_major = 0; int result; ///////////// 함 수 정 의 ////////////// int device_open (struct inode *inode, struct file *filp); int device_release (struct inode *inode, struct file *filp); ssize_t device_read (struct file *filp, unsigned int *buf, size_t count, loff_t *f_pos); ssize_t device_write (struct file *filp, unsigned int *buf, size_t count, loff_t *f_pos); int device_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned int arg); int sample_init(); void sample_cleanup(); 모듈을 커널에 적재하는 함수 register_chrdev()의 parameter로써 0으로 설정하면 major값을 뒤에서부터 자동으로 빈자리로 등록시킨다 register_chrdev()함수가 return하는 값을 넘겨받음. 0보다 적으면 모듇 등록 실패 application에서 open()함수로 driver를 호출할때 실행되는 함수 application에서 close()함수로 driver를 닫을때 실행되는 함수 ioctl() 대신 get_user() 또는 copy_to_user() 함수를 사용 가능 ioclt()과 copy_to_user()는 한번에 최대 4byte만 전송가능하나, put_user()는 4 byte 이상 보낼 수 있음. application에서 kernel로부터 넘어온 값을 처리하는 함수

Device Driver 작성 (3) 이 함수가 호출될때마다 count가 증가한다. int device_open (struct inode *inode, struct file *filp) { printk("test_open start!!!\n"); MOD_INC_USE_COUNT; return 0; } int device_release (struct inode *inode, struct file *filp) MOD_DEC_USE_COUNT; ssize_t device_read (struct file *filp, unsigned int *buf, size_t count, loff_t *f_pos) printk("read() ^^\n"); ssize_t device_write (struct file *filp, unsigned int *buf, size_t count, loff_t *f_pos) 이 함수가 호출될때마다 count가 증가한다. 이 함수가 호출될때마다 count가 감소한다. ssize_t는 long로 정의 됨… - /asm-arm/posix_types.h에서 typedef int __kernel_ssize_t로 정의됨 - /linux/types.h에서 typedef __kernel_ssize_t ssize_t로 정의됨. MOD_INC_USE_COUNT와 MOD_DEC_USE_COUNT는 module.h에서 define되어 있음. # define MOD_INC_USE_COUNT __MOD_INC_USE_COUNT(mod) __MOD_INC_USE_COUNT(mod)는 linux/mtd/compatmac.h에서 define 되어 있다 #define __MOD_INC_USE_COUNT(mod) (atomic_inc(&(mod)->uc.usecount), (mod)->flags |=MOD_VISITED|MOD_USED_ONCE) Application에서 read함수를 호출하면 terminal에 문자 출력

Device Driver 작성 (4) module_exit(sample_cleanup); int device_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned int arg) { printk("ioctl() ^^\n"); return 0; } struct file_operations test_fops = { open: device_open, read: device_read, write: device_write, ioctl: device_ioctl, release: device_release, }; module_init(sample_init); module_exit(sample_cleanup); Ioctl()호출이 성공하면 문자 출력 파일연산구조체는 char device driver에 대한 모든 연산을 포함한다. 즉 여기에 정의된 함수를 통해서 커널이 접근하게 된다. 즉 application에서 open함수를 호출하면 이는 driver의 test_open()과 mapping되어있어 이를 실행하게 된다. insmod로 불려지는 함수 rmmod로 불려지는 함수

driver를 커널에 모듈로 등록하는 함수, result에 major 값이 넘어옴 Device Driver 작성 (5) int sample_init(void) { result = register_chrdev(test_major, DEV_NAME, &test_fops); if (result < 0) { printk(KERN_WARNING "%s: can't get major %d\n", DEV_NAME, test_major); return result; } printk("<1> init module success!!.. %s major number : %d\n", DEV_NAME, result); return 0; void sample_cleanup(void) if( !unregister_chrdev(result, DEV_NAME) ) printk("%s cleanup_module success...\n", DEV_NAME); else printk("%s cleanup_module fail...\n", DEV_NAME); driver를 커널에 모듈로 등록하는 함수, result에 major 값이 넘어옴 driver를 커널에서 삭제하는 함수

Device Driver 검증 프로그램 만들기(1) #include <stdio.h> #include <fcntl.h> #include <string.h> #include <errno.h> int fd; int main(int argc, char **argv) { if( (fd = open("/dev/testdd", O_RDWR)) < 3) { fprintf(stderr, "/dev/testdd device file open error!! .. %s\n",strerror(errno)); return 0; } read(fd, 0, 0); ioctl(fd, NULL,0); close(fd); File에 대한 제어와 설정 Error에 관한 header file mknod를 통하여 /dev에 만들어진 node(file)을 open한다. open()과 fopen()의 차이점 - fopen()은 stdio.h를 include 해야하고, 함수의 return값은 FILE이라는 structure의 포인터이다. -open()은 fcntl.h를 include 해야하고, 함수의 returnr값은 integer인 현재 사용되지 않는 가장 작은 파일 지시자이다. -파일을 열어 그 파일을 세세하게 제어해야 하고 읽고 쓰는 속도가 크게 중요하지 않다면 fopen()이 낫다. 그렇지않고 연 파일을 세세하게 제어해야할 필요는 없지만 읽고 쓰는 속도가 중요하다면 open()함수를 권유 Open()의 마지막 parameter - O_RDONLY :파일을 읽기전용으로 연다 - O_WRONLY : 파일을 쓰기 전용으로 연다 - O_RDWR : 파일을 읽고 쓰는 용으로 연다 - O_APPEND : 파일은 연 후 쓰려고 하면 파일의 끝에 덧 붙인다.

Device Driver 검증 프로그램 만들기(2) 경고를 다 출력해준다는 의미 Compile Options %arm-linux-gcc –c –D__KERNEL__ -DMODULE –Wall –o2 –o test_dd.o test_dd.c test_dd는 커널에서 동작하고 모듈에 사용된다는 뜻 Compile과정에서 inlne 함수를 확장할 때 최적화함 모듈은 test_dd.o로 컴파일 되어야 하므로 –c 옵션 사용 옵션 O 옵션 01 과 동일 옵션 O0 최적화 하지 않음(기본값): 정확한 동작 및 컴파일 시간 적음 옵션 O1 코드 크기와 실행 시간을 줄여 줌 옵션 O2 더 많은 최적화를 수행함  -Wall 은 컴파일시 발생하는 모든 경고 메세지를 표현하라는 의미 인데 컴파일시 발생하는 경고를 무시하게        되면 모듈 삽입을 위하여 insmod 명량을 사용할때 심볼릭 에러를 발생하거나 모듈이 동작할때 이상하게      동작할 수 있으므로 필히 없애는 것이 정석입니다.

Device Driver 검증 프로그램 만들기(3) CC =arm-linux-gcc INCLUDEDIR = /usr/local/pza255/linux-2.4.19-huins/include CFLAGS = -D__KERNEL__ -DMODULE -Wall -O2 CFLAGS2 = -I.. -I$(INCLUDEDIR) All: test_dd test_app test_dd : test_dd.c $(CC) $(CFLAGS) $(CFLAGS2) -c -o test_dd.o test_dd.c test_app : test_app.c $(CC) -o test_app test_app.c clean : rm -rf test_dd.o test_app Macro 부분 C에서 define 역할 target command 위와 같이 Makefile을 만든 후 프롬프트에서 make 를 치면 컴파일 됨. 또한 object 파일을 지우려면 make clean을 치면 지워짐. Command 부분 파일들의 dependency를 설정 주의할 점은 이 공백은 반드시 Tab 공백

Device Driver 등록 및 해제 (1) Char Device Driver 등록 방법 장치의 등록과 해제 외부와 device driver는 file interface (node를 의미)를 통해 연결 Device driver는 자신을 구별하기 위해 고유의 major number를 사용 장치의 등록과 해제 등록 : int register_chrdev(unsigned int major, const char *name, stuct file_operations *fops) Major : 등록할 major number. 0이면 사용하지 않는 번호 중 자동으로 할당 Name : device의 이름 Fops : device에 대한 file 연산 함수들 해제 : int unregister_chrdev(unsigned int major, const char *name) register_chrdev()가 성공하면 major 번호를 return unregister_chrdev()가 실패하면 0을 return

Device Driver 등록 및 해제 (2) kernel user program device driver open close read write kernel device driver file operations device_open device_close device_read device_write system call device

Device Driver 등록 및 해제 (3) Major number와 minor number 장치를 구분하는 방법으로 둘을 이용하여 특정 장치를 구별 Major number : 커널에서 디바이스 드라이버를 구분하는데 사용 Minor number : 디바이스 드라이버 내에서 필요한 경우 장치를 구분하기 위해 사용 새로운 디바이스는 새로운 major number를 가져야 함 register_chrdev()로 장치를 등록할 때 major number를 지정 같은 major number가 등록되어 있으면 등록 실패 Major와 minor 번호는 파일의 정보를 담고 있는 inode의 i_rdev에 16bit로 저장된다. 상위 8bit는 major, 하위 8bit는 minor이다.

C는 char device drive의미, block device drive는 b를 사용 Device Driver 등록 및 해제 (4) mknod 명령으로 디바이스 드라이버에 접근할 수 있는 장치 파일 생성 mknod [device file name] [type] [major] [minor] Ex] %mknod testdd c 252 0 mdev_t : 장치의 major, minor number를 표현하는 자료구조 MAJOR() : kdev_t에서 major number를 얻어내는 매크로 Ex] MAJOR(inode->i_rdev); MINOR() : kdev_t에서 minor number를 얻어내는 매크로 cat /proc/devices 명령으로 현재 로드된 디바이스 드라이버 확인 C는 char device drive의미, block device drive는 b를 사용 참고로 major와 minor 번호는 inode의 i_rdev에 16bit로 저장이 된다. 상위 8bit는 major번호로 maximm 255까지 지정할 수 있다.

앞에서 작성했던 driver에 사용된 파일연산 함수 Device Driver 등록 및 해제 (5) /usr/lcoal/pxa255/linux-2.4.19-cd/include/linux/fs.h 앞에서 작성했던 driver에 사용된 파일연산 함수 /usr/lcoal/pxa255/linux-2.4.19-cd/include/linux/fs.h

Device Driver 등록 및 해제 (6) 이 름 용 도 insmod module을 설치(install) rmmod 용 도 insmod module을 설치(install) rmmod 실행중인 modules을 제거(unload) lsmod Load된 module들의 정보를 표시 depmod Module들의 symbol들을 이용하여 Makefile과 유사한 dependency file을 생성 modprobe depmod명령으로 생성된 dependency를 이용하여 지정된 디렉토리의 module들과 연관된 module들을 자동으로 load modinfo 목적화일을 검사해서 관련된 정보를 표시 target에서 depmod를 실행시키면 /lib/modules/2.4.19-huins/modules.dep 라는 파일이 생성

Device Driver 등록 및 해제 (7) Device Driver의 동작 과정

Device Driver 등록 및 해제 (8) 앞에서 만든 드라이버 소스를 test_dd.c, test application은 test_app.c, 그리고 makefile은 Makefile로 작성 후 저장한다. make 명령어를 이용하여 위의 2 files을 컴파일한다. % make 생성된 test_dd.o 와 test_app를 target으로 전송한다. 전송방식은 앞에서 배웠던 minicom 또는 nfs방식을 이용한다. 밑에서는 nfs 방식을 통하여 파일을 전송하였다.

Device Driver 등록 및 해제 (9) Module을 kernel에 적재 major number는 253 Test application에서 open()로 이 nod를 연다. 이 nod로 application과 hardware가 만남 ls 명령으로 nod가 잘 만들어졌는지 확인. 253은 major 번호 결과 화면