Presentation is loading. Please wait.

Presentation is loading. Please wait.

HBE-SMIII-SV210 리눅스 커널과 디바이스 드라이버

Similar presentations


Presentation on theme: "HBE-SMIII-SV210 리눅스 커널과 디바이스 드라이버"— Presentation transcript:

1 HBE-SMIII-SV210 리눅스 커널과 디바이스 드라이버
LIU WEI VLSI design lab Konkuk university

2 리눅스 커널과 디바이스 드라이버 커널과 시스템 구성요소간의 연관 관계 리눅스 커널과 디바이스 드라이버의 관계
리눅스 커널과 디바이스 드라이버의 관계 디바이스 드라이버는 시스템이 지원하는 하드웨어를 응용 프로그램에서 사용할 수 있도록 커널에서 제공하는 라이브러리다. 응용 프로그램이 하드웨어를 제어하려면 커널에 자원을 요청하고, 커널은 이런 요청에 따라 시스템을 관리한다. 시스템 상에서 실행되는 응용 프로그램은 시스템 콜을 통하여 커널과 통신한다. 일반적으로 응용 프로그램에서는 C 라이브러리 같은 함수를 호출하는데, 라이브러리 내부에서는 커널에게 특정 작업을 지시하기 위해 시스템 콜을 사용하게 된다. 일단 커널로 제어가 넘어가게 되면 커널 모드로 실행되어 커널 서브시스템 또는 디바이 스 드라이버를 통해서 하드웨어를 제어하게 된다. 커널과 시스템 구성요소간의 연관 관계

3 디바이스 드라이버 디바이스 드라이버는 시스템이 지원하는 하드웨어를 응용 프로그램에서 사용할 수 있도록 커널에서 제공하는 라이브러리이다. 응용프로그램이 커널에게 자원 사용을 요청하고, 커널은 이런 요청에 따라 시스템을 관리한다. 디바이스 파일 리눅스는 시스템에 있는 모든 자원을 파일 형식으로 표현한다. 램, 키보드, 보조기 억장치인 하드디스크도 파일로 표현한다. 이런 파일들은 /dev/ 디렉토리에 존재하 며, 이들을 디바이스 파일이라고 한다. 이 디바이스 파일 하나 하나는 실질적인 하 드웨어를 표현한다. 예를들어, 마우스 입력 디바이스는 /dev/mouse라는 디바이스 파일로 표현한다. 일반 파일의 목적이 데이터를 저장하는데 있다면 이들은 하드웨 어 정보를 제공하는데 목적이 있다. 이 정보는 세가지로 디바이스 타입정보, 주번 호, 부번호이다. 리눅스에서 동작하는 응용 프로그램은 하드웨어를 다루기 위해 해 당 디바이스 파일에 저수준 입출력 함수를 사용한다.

4 디바이스 파일 생성 디바이스 파일은 일반 파일과 달리 create() 함수를 사용하지 않고, mknod 유틸리 티에 의해서 생성된다. 디바이스 파일은 주로 “/dev/” 디렉토리에 만든다. mknod를 이용하여 디바이스 파일을 만드는 방법은 아래와 같다. 디바이스 파일명은 ttyS1이고, 문자 디바이스 드라이버이고, 주 번호가 4, 부 번호 가 65인 디바이스 파일을 생성한다. mknod /dev/ttyS1 c 4 65

5 주번호와 부번호 주번호 부번호 커널에서 디바이스 드라이버를 구분하고 연결하는데 사용된다.
즉, 주번호는 제어하 려는 디바이스를 구분하기 위한 디바이스의 ID 정도로 생각하면 된다. 부번호 디바이스 드라이버 내에서 장치를 구분하기 위해 사용된다. 즉, 같은 종류의 디바 이스가 여러 개 있을 때 그 중 하나를 선택하기 위해 사용된다. 시리얼 디바이스 파일을 살펴보면 아래와 같다. ~]$ls -al /dev/ttyS* 다음과 같은 메시지가 출력된다 crwxr-xr-x 1 root root 4, 64 Nov /dev/ttyS0 crwxr-xr-x 1 root root 4, 65 Nov /dev/ttyS1 crwxr-xr-x 1 root root 4, 66 Nov /dev/ttyS2 crwxr-xr-x 1 root root 4, 67 Nov /dev/ttyS3 crwxr-xr-x 1 root root 204, 64 Nov /dev/ttySAC0 crwxr-xr-x 1 root root 204, 65 Nov /dev/ttySAC1 crwxr-xr-x 1 root root 204, 66 Nov /dev/ttySAC2 crwxr-xr-x 1 root root 204, 67 Nov /dev/ttySAC3 crw-r--r-- 1 root root 4, 68 Nov /dev/ttyST0 crw-r--r-- 1 root root 4, 69 Nov /dev/ttyST1 crw-r--r-- 1 root root 4, 70 Nov /dev/ttyST2 crw-r--r-- 1 root root 4, 71 Nov /dev/ttyST3

6 저수준 파일 입출력 함수 저수준 파일 입출력 함수는 리눅스 커널에서 제공하는 파일 관련 시스템콜을 라이 브러리 함수로 만든 것이다. 이것은 아주 기본적인 파일을 처리하는 함수로서, 디바이스 파일을 실질적으로 다룰 때 사용한다. 저수준 파일을 이용하여 디바이스 파 일에 연관된 디바이스 드라이버 함수가 동작하게 된다. 저수준 파일 입출력 함수 기 능 open() 파일이나 장치를 연다. 디바이스 노드에 의해 수행되는 첫번째 동작 close() 열린 파일을 닫는다. read() 파일에서 데이터를 읽어온다. write() 파일에 데이터를 쓴다. lseek() 파일의 쓰기나 읽기 위치를 변경한다.

7 디바이스 드라이버의 종류 리눅스에서 사용되는 디바이스 드라이버는 크게 문자, 블록, 네트워크 디바이스 드라이버로 나뉜다.
리눅스에서 사용되는 디바이스 드라이버는 크게 문자, 블록, 네트워크 디바이스 드라이버로 나뉜다. 문자 디바이스 드라이버 문자 디바이스는 임의의 길이를 갖는 문자열이나 자료의 순차성을 지닌 장치를 다 루는 디바이스 드라이버로서 버퍼 캐쉬를 사용하지 않는다. 사용자에게 Raw 데이 터를 제공하며 종류로는 Serial, Console, Keyboard, printer, Mouse 등이 있다. 블록 디바이스 드라이버 블록 디바이스 드라이버는 일정 크기의 버퍼를 통해 데이터를 처리하는 디바이스로, 커널 내부의 파일 시스템에서 관리하고 내부적인 버퍼가 있는 디바이스 드라이버이다. 이것의 종류로는 하드 디스크, 램디스크등이 있다. 네트워크 디바이스 드라이버 네트워크 디바이스 드라이버는 네트워크 계층과 연결되어 네트워크 통신을 통해 네트워크 패킷을 송수신할 수 있는 기능을 제공한다. 이것의 종류로는 이더넷, PPP 등이 있다.

8 커널과 모듈 커널 모듈은 리눅스 커널이 부팅되어 동작중인 상태에서 디바이스 드라이버를 동적 으로 추가하거나 제거할 수 있게 하는 개념이다. 이런 모듈 방식은 리눅스에 포함 된 디바이스 드라이버를 개발할 때 개발 시간을 단축시킬 뿐만 아니라 필요없는 기 능은 커널에 포함시키지 않음으로써 커널 자원을 효율적으로 다루게 한다. 리눅스에서는 다른 운영체제와는 달리 대부분의 기능(파일 시스템, 디바이스 드라 이버, 통신 프로토콜 등)을 모듈로 구현할 수 있는데, 특히 하드웨어를 다루는 기능 을 구현한 것이 바로 디바이스 드라이버이다.

9 모듈 프로그래밍 모듈과 일반 프로그램과의 차이점 모듈관련 유틸리티
커널 모듈 프로그램은 커널 영역에서 동작하며 일반 프로그램은 유저 영역에서 동 작한다. 모듈은 커널에 로딩 및 제거될 때 호출되는 함수가 따로 존재한다. 또한, main() 함수가 존재하지 않으며, 일반적인 라이브러리를 사용하지 못하고 커널이 export 해준 함수만을 사용할 수 있다. 모듈관련 유틸리티 모듈로 만들어진 디바이스 드라이버는 심볼 테이블을 통해 커널에 링크시키도록 도 와주는 유틸리티가 필요하다. 이러한 유틸리티는 아래와 같다. insmod : 모듈을 커널에 적재한다. rmmod : 커널에서 모듈을 제거한다. lsmod : 커널에 적재된 모듈 목록을 출력한다. depmod : 모듈간 의존성 정보를 생성한다.

10 모듈 프로그래밍 간단한 모듈 프로그램 작성 기초적인 디바이스 드라이버를 모듈 형식으로 작성하고 테스트하여 기본으로 알아 야할 내용들을 살펴본다. 작성할 예제는 “Hello world”메시지를 력해주는 간단한 모듈 드라이버이다. 파 일명은 hello.c 이다. 다음과 같이 모듈 드라이버를 작성할 디렉토리를 생성해준다. cd /working mkdir module_driver cd module_driver

11 모듈 프로그래밍 다음과 같이 hello 모듈 드라이버를 작성한다.
vi hello.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(“Daul BSD/GPL”); 저장 하고 종료한다 ① 모듈 소스에서는 커널 소스의 헤더 파일 디렉토리를 참조한다. 포함된 헤더 파일들은 기본으로 포함시켜야 하는 파일들이며, 필요에 따라 다른 헤더파 일을 포함시킨다. ② 모듈을 커널에 적재할 때 호출될 함수이다. ③ 모듈을 커널에서 제거할 때 호출될 함수이다. ④ 커널에 모듈을 적재할 때 커널이 호출하는 함수를 지정하는 매크로와 커널 에서 모듈을 제거할 때 커널이 호출하는 함수를 지정하는 매크로이다. ⑤ 모듈의 라이센스를 표기하는 부분이다.

12 모듈 프로그래밍 다음과 같이 작성된 모듈을 컴파일하기 위한 Makefile을 작성한다
① 컴파일러를 크로스 컴파일러인 arm-linux-gcc로 설정한다. ② 모듈로 생성할 모듈 이름을 정의한다. ③ 커널의 소스 위치를 지정한다. ④ 컴파일 대상이 되는 모듈 소스가 위치한 현재 디렉토리를 지정한다. ⑤ 모듈을 컴파일하는 명령을 지정한다. ⑥ 컴파일 결과로 생생된 파일들을 모두 지운다. (1) (2) (3) (4) (5) (6) :/working/module_driver# vi Makefile 다음과 같이 수정한다 # Hello Device Driver Makefile CC = arm-linux-gcc-gneubi obj-m := hello.o KDIR := /working/linux hanback/ PWD := $(shell pwd) default: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules clean: rm -f *.ko rm -f *.o rm -f *.mod.* rm -f .*.cmd 저장하고 종료한다

13 모듈 프로그램 컴파일 다음과 같이 모듈을 컴파일한다.
다음과 같이 생성된 파일 리스트를 확인한다. 생성된 파일 중에 커널에 로딩하는 모듈 파일은 hello.ko이다. ls 다음과 같은 메시지가 출력된다 Makefile hello.c make 다음과 같은 메시지가 출력된다 make -C /working/linux hanback/ SUBDIRS=/working/module_driver modules make[1]: Entering directory `/working/linux hanback' CC [M] /working/module_driver/hello.o Building modules, stage 2. MODPOST 1 modules CC /working/module_driver/hello.mod.o LD [M] /working/module_driver/hello.ko make[1]: Leaving directory `/working/linux hanback' ls 다음과 같은 메시지가 출력된다 Makefile hello.c hello.mod.c hello.o Module.symvers hello.ko hello.mod.o modules.order

14 디바이스 드라이버의 등록과 해제 모듈 초기화와 종료
디바이스 드라이버는 하드웨어를 다루고 커널 내에서 디바이스 드라이버로서 동작 하기 위한 소프트웨어적인 처리를 수반한다. 이것은 디바이스 드라이버가 동작하기 위한 초기화와 종료에 대한 처리이며, 이것을 처리하기 위한 두가지 시점이 존재한다. 모듈 초기화와 종료 모듈 초기화 함수에서는 디바이스 드라이버가 처리해야 할 하드웨어 검출 및 검출 된 하드웨어를 응용 프로그램에서 사용할 수 있도록 초기화 작업을 한다. 또한 모 듈 초기화나 종류 시점에는 응용 프로그램이 디바이스 드라이버를 사용하는 전후의 처리를 구현한다.

15 디바이스 드라이버의 등록과 해제 module_init의 초기화 처리
디바이스 드라이버에 내부 구조체의 메모리 할당 하드웨어 초기화 module_exit의 종료 처리 module_exit 매크로에 정의된 함수는 디바이스 드라이버 모듈이 제거될 때 수행되며, 모듈 초기화 함수에서 수행한 항목을 반대로 처리한다. 디바이스 드라이버의 해제 디바이스 드라이버에 할당된 메모리의 해제

16 디바이스 드라이버의 등록과 해제 open()함수와 release() 함수의 초기화와 종료
디바이스 드라이버의 open()과 close()에 대응하는 함수들은 파일이 열리는 시점과 닫히는 시점에 호출되며, 디바이스가 사용되면서 필요한 처리와 디바이스가 더 이 상 사용되지 않을 때의 처리를 주로 구현한다.

17 문자 디바이스 드라이버의 구성 문자 디바이스 드라이버를 제작하려면 최소한 저 수준 파일 입출력에 대응하는 file_operations 구조체에 등록할 함수들과 문자 디바이스 드라이버 등록 및 제거함 수 그리고 인터럽트를 사용하는 하드웨어라면 인터럽트 처리 함수가 구현이 되어야 한다. 문자 디바이스 드라이버의 구조에 대해서 알아보기 위해서 아래의 led 문자 디바이 스 드라이버 소스 구성을 살펴본다.

18 디바이스 드라이버의 구현: LED 디바이스 드라이버
HBE-SMIII-SV210에는 총 8개의 LED가 데이터버스와 연결되어 있으며, 정해진 물리주소에 값을 출력하면 해당 비트가 1인 경우 LED가 켜진다. LED Controller는 16bit로 구성된 LED_Ctrl_Reg (LED Control Register)에 의해 제 어된다. 이 LED Control Register는 Read와 Write 모두 가능하도록 설계되어 있으며 LED_Ctrl_Reg 0~7bit에 ‘0’ 또는 ‘1’을 써 넣음으로써 On/Off 할 LED를 선택할 수 있다. 다음 표는 LED Control Register의 데이터 비트 구조를 나타낸 것이다. LED Control Register (read/write)

19 LED 디바이스 드라이버 소스파일 작성 이제 LED 디바이스 드라이버를 작성해 본다. 디바이스 드라이버의 기본 작업 디렉 토리는 /working/device_driver이다. 작업 디렉토리 : /working/device_driver/241.bus-led_driver 다음과 같이 LED 디바이스 드라이버 작업 디렉토리를 생성하고, 해당 디렉토리로 이동한 후에 ledioport.c 소스 파일을 작성한다. :~# cd /working :~# mkdir –p /working/device_driver/241.busled_driver :~# cd /working/device_driver/241.bus-led_driver :/working/device_driver/241.bus-led_driver# vi ledioport.c

20 컴파일 다음과 같이 make clean하면 먼저 컴파일된 드라이버와 실행예제 파일이 지워진다.
:/working/device_driver/241.bus-led_driver# ls Makefile led_test.c ledioport.c :/working/device_driver/241.bus-led_driver# make clean; make 다음과 같은 메시지가 출력된다 rm -f *.ko rm -f *.o rm -f *.mod.* rm -r .*.cmd rm -rf led_test Module.* module* .tmp_versions arm-linux-gcc led_test.c -o led_test make -C /working/linux hanback SUBDIRS=/working/device_driver/241.busled_ driver modules make[1]: Entering directory `/working/linux hanback' CC [M] /working/device_driver/241.bus-led_driver/ledioport.o Building modules, stage 2. MODPOST 1 modules CC /working/device_driver/241.bus-led_driver/ledioport.mod.o LD [M] /working/device_driver/241.bus-led_driver/ledioport.ko make[1]: Leaving directory `/working/linux hanback' rm -f default ls Makefile led_test ledioport.ko ledioport.o Module.markers led_test.c ledioport.mod.c modules.order Module.symvers ledioport.c ledioport.mod.o

21 타겟보드에 다운받기 및 실행 타겟 보드에 다운로드 받는 방법으로 tftp를 사용한다.
Copy using lrz, zmodem. 다음으로는 모듈을 커널에 삽입하여야 한다. 삽입 명령은 insmod이며, mknod로 디바이스 드라이버를 적재시킨다. mknod 사용시 사용되는 주번호는 insmod 명령 어 사용시 나오는 번호로 사용하면 된다. 디바이스 드라이버 포팅이 완료되면 led_test 프로그램을 실행하여 LED를 제어한다. 지금까지의 과정을 요약하면 다음과 같다. ① 디바이스 드라이버 / 응용 프로그램을 작성한다. ② 작성한 프로그램을 컴파일 한다. ③ 호스트에서 타겟보드로 오브젝트화일(.ko), 실행화일을 복사한다. ④ insmod / mknod 를 사용하여 등록시킨다. ⑤ 응용 프로그램을 실행시킨다. device_driver]$ insmod ledioport.ko Init Module, ledioport Major Number : 241 device_driver]$ lsmod Module Size Used by Not tainted ledioport device_driver]$ mknod /dev/ledioport c 241 0 device_driver]$./led_test please input the parameter! ex)./test 0xff device_driver]$./led_test 0x11


Download ppt "HBE-SMIII-SV210 리눅스 커널과 디바이스 드라이버"

Similar presentations


Ads by Google