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

Slides:



Advertisements
Similar presentations
SPARCS 10 이 가 영 기본 UNIX 명령어. 일단 로그인 ! Linux login 시 계정을 입력하거나 root 를 입력 Root -> # 일반 사용자 -> $ 패스워드 : echo 기능을 꺼서 볼 수 없다. 대소문자 구분 패스워드 처음 설정 시 : ~$ passwd.
Advertisements

2013 년 2 학기 임베디드 프로그래밍. 권장사양  HOST PC 권장사항  리눅스 배포판이 설치된 PC - 권장 배포판 : Asianux open edition3 ( 라곤 하지만 Ubuntu, Fedora, CentOS 등 다양한 리눅스 프랫폼이 가능 )  PC.
제10장 디바이스 드라이버.
KEY 디바이스 드라이버 Lecture #12. 2 차례 GPIO 및 Control Registers KEY 하드웨어 구성 KEY Driver 프로그램 key-driver.c 시험 응용 프로그램 key-app.c.
FND 디바이스 드라이버 Lecture #13.
TextLCD 디바이스.
임베디드 시스템 개발 환경 (1) Lecture #3.
시작부터 끝까지 진지한 궁서체로 진행하는 완벽한 주입식의 하드코어한 리눅스/장난감 세미나
임베디드 시스템 개발을 위한 리눅스 환경설정.
6 레이스 컨디션.
공유메모리 int shmget(key_t key, size_t size, int permflags);
1장. 이것이 C 언어다.. 1장. 이것이 C 언어다. 1-1 C 언어의 개론적 이야기 프로그래밍 언어란 무엇인가? 컴파일이란 무엇인가? 사람과 컴파일러가 이해할 수 있는 약속된 형태의 언어 C 언어도 프로그래밍 언어 중 하나이다. 컴파일이란 무엇인가? 프로그래밍.
2013 스마트 컨트롤러 중간 프로젝트 김성엽 진종영 조유진
리눅스 실습 정성훈.
컴퓨터 네트워크 실습.
PXA270 개발환경 설정 Ubuntu 실습용.
개발 환경 개발 환경 개요 PXA270과 타겟 시스템 툴체인 환경 구축 JTAG 유틸리티 미니컴 Make 유틸리티
크로스 컴파일 환경 구축.
Kernel Programming Kernel
2006년 3월 20일 황의권, 지용인, 최종윤 서울대학교 컴퓨터공학부
디렉토리 다루기 ㅎㅎ 유닉스 파일 시스템 현재 디렉토리 확인 : pwd 디렉토리 이동 : cd
Makefile의 이해 ㈜FALinux 박진호.
디바이스 드라이버 이해 Hanbat National University Prof. Lee Jaeheung.
Kernel Porting Lecture #7.
제4장 Cross Compiler 설치.
임베디드 프로그래밍 Lecture #
디바이스 드라이버 (Device Driver)
디바이스 드라이버 기초 디바이스 드라이버의 개요 파일 연산 디바이스 드라이버 등록 디바이스 드라이버 구성
디바이스 드라이버.
이식성과 데이터형 서로 다른 프로세서 상에서의 이식성을 위해 가급적 리눅스 커널이 제공하는 데이터형을 사용하는 것이 좋다.
디바이스 드라이버 개요 가상 디바이스드라이버 실습
[beginning] Linux & vi editor
목차 커널의 개념 및 기능 커널 포팅 램디스크.
Unix Project-Final <test character device 생성>
MicroC/OS-II Lab. 경희대학교 컴퓨터공학과 조 진 성.
Linux/UNIX Programming
컴퓨터 네트워크 실습.
FND (Flexible Numeric Display)
Embedded System Porting (2)
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 02. 프로그램의 기본구성.
Step Motor Device Driver
리눅스 커널과 디바이스드라이버.
Internet Protocol and Programming
개발 환경.
1장. 프로그래밍 언어, C 프로그래밍.
4족 로봇 삼식이팀 박명대.
운영체제 (Operating Systems)
커널 모듈 프로그래밍 (Kernel Module Programming)
모듈 초기화 module_init(hello_init); module_exit(hello_exit);
1주차: 프로그래밍언어란 무엇인가? C 언어란? C 프로그래밍을 위한 준비
망고100 보드로 놀아보자 -13 리눅스 디바이스 드라이버 개요
Linux/UNIX Programming
Mips cross compile OS LAB.
문자 디바이스 드라이버 임베디드 시스템.
리눅스 디바이스 드라이버 (Linux Device Driver)
Internet Protocol and Programming
쉽게 풀어쓴 C언어 Express 제2장 프로그램 작성 과정 C Express.
운영체제 RaspberryPi Sejin Oh.
Stepper Motor 디바이스 드라이버
시스템 인터페이스 Lab2 X-window 및 명령어 사용.
Telnet 을 활용한 Linux 메뉴얼 오두환.
제 6 강 Getting started.
8. 리눅스의 내부 군자삼락 [君子三樂] 청출어람이청어람 [ 靑出於藍而靑於藍 ] Why Linux ?
Kernel Programming Kernel
Internet Protocol and Programming
Makefile
C.
Eclipse를 이용한 Embedded Linux 응용 프로그램 개발
한국 휴렛팩커드/고객지원사업본부/IT 기술사업부 박기영
C프로그래밍 도구 컴퓨터공학과 강성인.
Presentation transcript:

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

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

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

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

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

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

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

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

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

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

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

모듈 프로그래밍 다음과 같이 작성된 모듈을 컴파일하기 위한 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-2.6.32-hanback/ PWD := $(shell pwd) default: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules clean: rm -f *.ko rm -f *.o rm -f *.mod.* rm -f .*.cmd ------- 저장하고 종료한다 -----------------

모듈 프로그램 컴파일 다음과 같이 모듈을 컴파일한다. 다음과 같이 생성된 파일 리스트를 확인한다. 생성된 파일 중에 커널에 로딩하는 모듈 파일은 hello.ko이다. root@ubvm-desktop:/working/module_driver# ls ---------다음과 같은 메시지가 출력된다 ----------------- Makefile hello.c root@ubvm-desktop:/working/module_driver# make --------다음과 같은 메시지가 출력된다 ----------------- make -C /working/linux-2.6.32-hanback/ SUBDIRS=/working/module_driver modules make[1]: Entering directory `/working/linux-2.6.32-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-2.6.32-hanback' root@ubvm-desktop:/working/module_driver# ls ------------------다음과 같은 메시지가 출력된다 ----------------- Makefile hello.c hello.mod.c hello.o Module.symvers hello.ko hello.mod.o modules.order

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

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

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

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

디바이스 드라이버의 구현: 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)

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

컴파일 다음과 같이 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-2.6.32-hanback SUBDIRS=/working/device_driver/241.busled_ driver modules make[1]: Entering directory `/working/linux-2.6.32-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-2.6.32-hanback' rm -f default root@hanback-desktop:/working/device_driver/241.bus-led_driver# 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

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