리눅스디바이스드라이버개요 http://cafe.naver.com/embeddedcrazyboys http://www.mangoboard.com
디바이스드라이버개요 디바이스 (Device ) 네트워크어댑터, LCD 디스플레이, PCMCIA, Audio, 터미널, 키보드, 하드디스 크, 플로피디스크, 프린터등과같은주변장치들을말함 디바이스의구동에필요한프로그램, 즉디바이스드라이버가필수적으로요구 됨 Device Driver 실제장치부분을추상화시켜사용자프로그램이정형화된인터페이스를통해디바이스를접근할수있도록해주는프로그램 디바이스관리에필요한정형화된인터페이스구현에요구되는함수와자료구조의집합체 표준적으로동일서비스제공을목적으로커널의일부분으로내장 응용프로그램이 H/W 를제어할수있도록인터페이스제공 하드웨어독립적인프로그램을작성을가능하게함 2
디바이스드라이버형태 Application Device Driver Interface Standard Device Driver Interface UNIX compatible I/O system interface : open(), close(), read(), write(), ioctl() IO System osdriver Device Non-standard Device Driver Interface Completely user-defined Custom interface May be more appropriate for some hardware Application mydriver Device 3
리눅스디바이스드라이버 사용자관점에서의디바이스드라이버 사용자는디바이스자체에대한자세한정보를알필요없음 Device 는하나의파일로인식됨 file 에대한접근을통하여 real device 에접근가능 User Program Device file. VFS Device Driver Real Device 4
리눅스디바이스드라이버 (2) 리눅스에서의디바이스 Linux에서 Device는특별한하나의파일처럼취급되고, access가가능함. 사용자는 File operation 을적용할수있음 각디바이스는 Major number 와 Minor number 를갖음 Device Driver 의종류 문자디바이스드라이버 블록디바이스드라이버 네트워크디바이스드라이버 5
Char Device( 문자디바이스 ) 문자디바이스의특징 자료의순차성을지닌장치 버퍼캐쉬를사용하지않음 장치의 raw data 를사용자에게제공 Terminal, Serial/Parallel, Keyboard, Sound Card, Scanner, Printer 리눅에서의문자디바이스 null : black hole tty* : virtual console pt* : pseudo-terminal crw--w--w- 0 root root 5, 1 Oct 1 1998 console crw-rw-rw- 1 root root 1, 3 May 6 1998 null crw------- 1 root root 4, 0 May 6 1998 tty crw-rw---- 1 root disk 96, 0 Dec 10 1998 pt0 crw------- 1 root root 5, 64 May 6 1998 cua0 파일관련정보중첫문자인 C 는 char device 를의미 6
Block Device( 블록디바이스 ) Block device 특징 random access 가능 블록단위의입출력이가능한장치 버퍼캐쉬에의한내부장치표현 파일시스템에의해 mount 되어관리되는장치 디스크, Ram Disk, CD-ROM 등 리눅스에서의 Block device fd* : Floppy disk Hd* : Hard disk sda : SCSI disk brw------- 1 root floppy 2, 0 May 6 1998 fd0 brw-rw---- 1 root disk 3, 0 May 6 1998 hda brw-rw---- 1 root disk 3, 1 May 6 1998 hda1 brw-rw---- 1 root disk 8, 0 May 6 1998 sda brw-rw---- 1 root disk 8, 1 May 6 1998 sda1 파일관련정보중첫문자인 b 는 block device 를의미 7
Network Device( 네트워크디바이 스 ) Network device 특징 대응하는장치파일이없음 네트워크통신을통해패킷을송수신할수있는장치 응용프로그램과의통신은표준파일시스템관련콜대신 socket(), bind() 등의시스템콜사용 Etherent, PPP, ATM, ISDN 등이있음 8
Major & Minor Number Major number( 주번호 ) 커널에서디바이스드라이버를구분 / 연결하는데사용 같은 Device 의종류를지칭, 1Byte (0~255 사이의값 ) Minor number( 부번호 ) 디바이스드라이버내에서장치를구분하기위해사용 각 Device 의부가적인정보를나타냄, 2Byte ( 부번호 ) 하나의디바이스드라이버가여러개의디바이스제어가능 $ ls -al /dev/hda* brw-rw---- 1 root disk 1, 0 May 6 1998 hda brw-rw---- 1 root disk 1, 1 May 6 1998 hda1 brw-rw---- 1 root disk 1, 2 May 6 1998 hda2 brw-rw---- 1 root disk 1, 3 May 6 1998 hda3 주번호 부번호 9
디바이스드라이버구조 리눅스시스템구조상의디바이스드라이버 Application area Application System Call Interface VFS Kernel area Buffer Cache Network Subsystem Char Device Driver Block D/D Network D/D Device Interface Hardware Hardware 10
커널소스트리 11 /usr/src/linux Doc arch include init fs kernel ipc lib mm net scripts driver alpha arm m68k mips ppc sparc i386 boot kernel lib math-emu mm asm-alpha asm-arm asm-i386 linux net scsi video 802 appletalk decnet ethernet ipv4 unix sunrpc x25 block cdrom char net pci pnp sbus scsi sound video coda ext2 hpfs msdos nfs isofs ntfs
커널모듈 (kernel Module) 시스템부팅후에동적으로 loading 할수있는커널구성요소 커널을다시컴파일하거나시스템리부팅할필요없이커널의일부분을교체하는것이가능 디바이스드라이버, 파일시스템, 네트워크프로토콜등이모듈로제공됨 컴파일한커널버전정보가들어가야하고, 현재실행되고있는커널버전과일치해야함 <linux/module.h> 에정의되어있음 모듈정보는전체모듈에서하나만존재해야함 일반응용프로그램과의차이점 main() 함수가없음 커널에로딩및제거될때불러지는함수가존재 Loading 시 - int init_module(void) 함수호출 Unloading 시 - void cleanup_module() 함수호출 12
Linux Device Driver 특성 Linux device driver 의공통적특성 커널코드 디바이스드라이버는커널의한부분이므로, 커널의다른코드와마찬가지로잘못되면시스템에치명적인피해를줄수있다 커널인터페이스 디바이스드라이버는리눅스커널이나자신이속한서브시스템에표준인터페이스를제공해야한다. 커널메커니즘과서비스 디바이스드라이버는메모리할당, 인터럽트전달, wait queue 같은표준커널서비스를사용할수있다. Loadable 대부분의리눅스디바이스드라이버는커널모듈로서, 필요할때로드하고더이상필요하지않을때언로드할수있다. 설정가능 (Configurable) 리눅스디바이스드라이버를커널에포함하여컴파일할수있다. 어떤장치를넣을것인지는커널을 compile 할때설정할수있다 13
커널과모듈의링크개념도 insmod init_module( ) register_capability( ) capabilities[ ] printk( ).. rmmod cleanup_module( ) unregister_capability( ) 14
커널모듈의작성 예제프로그램 커널에모듈이로딩될때 hello mango world 를출력 모듈이제거될때 Good Bye 를출력 Source file : hello.c /* hello.c */ #include <linux/module.h> /* 모든모듈에필요 */ #include <linux/kernel.h> /* printk() 등에필요 */ static int init hello_init(void) { // 모듈이로딩될때호출 printk ( hello mango world\n ); } return 0; // from a text console, not X-terminal. // 0: success, 기타 - fail static void exit hello_exit(void) { } printk ( KERN_ALERT Goodbye world ); module_init(hello_init); Module_exit(hello_exit); MODULE_LICENCE( GPL ); 15
커널모듈의컴파일 ( 커널에포함 ) 커널소스푼디렉토리로이동 #cp hello.c arch/arm/mach-s5pc100/ #vi arch/arm/mach-s5pc100/makefile 수정 #make modules 16
커널모듈의컴파일 (Makefile 작성 ) 커널소스푼디렉토리로이동 #mkdir test-module #cp hello.c test-module #vi Makefile #make 17
module 파일시스템에포함방법 NFS 로 Mount 하는방법 저장장치를이용하는방법 파일시스템에포함하는방법 Etc
module 파일시스템에포함방법 (NFS 로 Mount 하는방법 ) Mango( 타겟 ) board console 창에서입력 #mkdir /mnt/nfs //#echo /sbin/mount t nfs o nolock $(Serverip):$(nfs 디렉토리 ) $(dir) #/sbin/mount -t nfs -o nolock 192.168.0.10:/nfsroot /mnt/nfs #df # cd /mnt/nfs #insmod hello.ko #lsmod #rmmod hello.ko Host linux PC 명령순서 #cp hello.ko /nfsroot #ps aux grep nfs #rpm qa nfs #yum install nfs* #mkdir -p /home/nfsroot #ln s /home/nfsroot /nfsroot #vi /etc/exports 에아래추가 #/etc/init.d/nfs restart #ifconfig eth0 192.168.0.10 up
디바이스드라이버의작성방법 커널모듈의형태로디바이스드라이버함수작성 struct file_operations 정의및함수구현 init_module, module_exit 정의및함수구현 커널에디바이스드라이버등록 register_chrdev(), register_blkdev(), register_netdev() 컴파일 / 로딩 Insmod Make special file Mknod 드라이버를활용하는응용프로그램작성및테스트 20
설정 - 드라이버적재및삭제 노드생성 - 노드 ( 파일 ) 를통해서입출력수행 mknod /dev/ 파일이름드라이버타입주번호부번호 예 ) mknod /dev/keydd c 125 0 생성후속성변경 : chmod ug+w /dev/keydd 디바이스드라이버적재 insmod 드라이버명.ko 예 ) insmod keydd.ko 디바이스드라이버삭제 rmmod 드라이버명.ko 예 )rmmod keydd.ko ( 주의.ko 붙지않아도됨 ) 드라이버의적재여부 lsmod 21
디바이스드라이버 - Etc. Device 의정보를가지는 File 들 /proc/devices 현재 System 에장착되어있는 Device 들의정보./Documentation/devices.txt 현재 Linux System 에서정의되어있는 Device 들의 Major, Minor Number 들에대한정보./include/linux/major.h Major Number 를 define 한 header 22
문자형디바이스드라이버골격 #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) ( ); Header Files Function Prototypes File Operation }; int init_module(void) { } Void module_exit(void) { } 모듈설치시초기화수행 모듈제거시반환작업수행 23