8. Hardware Management
Download
Report
Transcript 8. Hardware Management
Chapter 8. Hardware Management
I/O 포트와 I/O 메모리
I/O 포트 사용하기
병렬포트 사용 short 예
I/O 메모리 사용하기
순천향대학교 정보기술공학부
이상정
1
LINUX Device Drivers
단원 소개
드라이버는 추상화된 계층으로 소프트웨어 개념과 하드웨어
회로를 연결
지금까지는 소프트웨어 개념을 살펴보았고, 이 장에서는 리
눅스 플랫폼 상에서 드라이버가 I/O 포트와 I/O 메모리를 어
떻게 접근하는지를 소개
순천향대학교 정보기술공학부
이상정
2
Ch.8 Hardware Management
I/O 포트와 I/O 메모리
순천향대학교 정보기술공학부
이상정
3
LINUX Device Drivers
주소영역
모든 주변장치는 내부 레지스터를 읽고 쓰기하여 제어
• 레지스터의 주소는 메모리영역과 분리된 격리형(isolated I/O)이나
메모리와 같은 주소공간을 사용하는 메모리 맵형(memory-mapped
I/O)으로 구현
• 격리형 I/O는 I/O 포트 주소 사용
• 메모리 맵형 I/O는 I/O 메모리 주소 사용
순천향대학교 정보기술공학부
이상정
4
Ch.8 Hardware Management
LINUX Device Drivers
메모리 배리어 (1)
최근의 컴파일러와 프로세서는 최적화된 성능을 위해 원래 프로그램의
순서를 벗어나서 비순차(out-of-order) 이슈되어 실행
• 원래의 소스 프로그램의 순서대로 메모리가 참조되지 않을 수도 있어 오동작
유발
• 컴파일러나 하드웨어가 원래 프로그램 순서대로 순차적으로 실행하도록 강
제하도록 메모리 배리어(hardware barrier)를 해당 코드 위치에 삽입
리눅스는 다음과 같은 매크로를 제공
#include <linux/kernel.h>
void barrier(void)
• 컴파일러에게 메모리 배리어를 삽입하게 한다.
• 컴파일러가 현재 레지스터에 저장되고 수정된 모든 값들을 메모리에 저장하
는 코드를 삽입
#include <asm/system.h>
void rmb(void);
void wmb(void);
void mb(void);
• 하드웨어 메모리 배리어를 삽입하는 매크로로 플랫폼에 종속적
• rmb(read memory barrier)는 배리어 이전의 모든 읽기가 완료되도록 보장하
고, wmb(write memory barrier)는 쓰기 완료를 보장하고, mb는 읽기,쓰기
모두 보장한다.
순천향대학교 정보기술공학부
이상정
5
Ch.8 Hardware Management
LINUX Device Drivers
메모리 배리어 (2)
메모리 배리어는 성능에 크게 영향을 미치므로 꼭 필요한 곳
에서만 사용
• 플랫폼마다 그 영향이 다른데, 예를들면 x86 아키텍처에서는 쓰기 동
작은 순차이슈되어 wmb()는 아무 동작도 하지 않는다. 그러나 읽기
동작은 비순차 이슈되어 mb()를 사용하면 wmb()보다도 더 느리게
수행될 것이다.
커널 2.4에서는 값의 대입과 메모리 배리어를 결합한 다음과
같은 매크로를 제공
#define set_mb(var, value) do {var = value; mb();} while 0
#define set_wmb(var, value) do {var = value; wmb();} while 0
#define set_rmb(var, value) do {var = value; rmb();} while 0
순천향대학교 정보기술공학부
이상정
6
Ch.8 Hardware Management
I/O 포트 사용
순천향대학교 정보기술공학부
이상정
7
LINUX Device Drivers
I/O 포트 할당
2장에서 소개한 바와 같이 사용하기 전에 I/O포트를 할당
#include <linux/ioport.h>
int check_region(unsigned long start, unsigned long len);
struct resource *request_region(unsigned long start,
unsigned long len, char *name);
void release_region(unsigned long start, unsigned long len);
메모리맵형 I/O 레지스터만을 지원하는 아키텍처에서는 포
트 주소와 메모리 주소를 매핑함으로써 가상의 포트 I/O를
지원
• 커널은 호환을 위해 이러한 상세한 내용들을 드라이버에게 감춤
순천향대학교 정보기술공학부
이상정
8
Ch.8 Hardware Management
LINUX Device Drivers
I/O 포트 읽기, 쓰기
드라이버는 I/O 포트 영역을 할당 한 후에 포트로부터 읽기,쓰기를 수행
• 하드웨어가 8 비트,16 비트, 32 비트 포트를 구분하기 때문에 각 크기의 포트에 따라
서로 다른 함수를 제공
<asm/io.h>에서 다음과 같이 I/O 포트를 접근하는 인라인 함수가 정의
• 타입의 지정없는 unsigned 표시는 아키텍처에 따라 다르고 컴파일러가 알아서 형 지
정
• unsigned inb(unsigned port);
void outb(unsigned char byte, unsigned port);
•
바이트 포트의 읽기,쓰기를 수행
• 플랫폼에 따라 unsigned는 unsigned long 또는 unsigned short로 정의
•
unsigned inw(unsigned port);
void outw(unsigned short word, unsigned port);
• 16비트 포트를 접근하는 함수
• 바이트 I/O만 지원하는 M68k, S390에서는유용하지 않음
•
unsigned inl(unsigned port);
void outl(unsigned longword, unsigned port);
• 32비트 포트를 접근하는 함수
• longword는 플랫폼에 따라 unsigned long 또는 unsigned int로 선언
• 워드 I/O와 마찬가지로 지원하는 M68k, S390에서는유용하지 않음
순천향대학교 정보기술공학부
이상정
9
Ch.8 Hardware Management
LINUX Device Drivers
사용자 영역 I/O 포트 접근
I/O 포트 함수들은 기본적으로 디바이스 드라이버에서 사용
을 위한 것이지만 사용자 영역에서도 사용
GNU C 라이브러리는 <sys/io.h>에서 정의되고, 사용자 영
역에서 사용 시 다음과 같이 수행
• 인라인 함수의 확장을 위해 -O 옵션으로 컴파일
• 포트 상에서 I/O 동작을 수행할 수 있는 허가를 얻기 위해 ioperm 이
나 iopl 시스템 콜을 호출
• ioperm은 개별 포트들에 대한 허가를 얻고, iopl은 전체 I/O 영역에 대한
허가 획득
• 프로그램은 ioperm 또는 iopl을 호출하기 위해 루트 권한에서 실행되어
야함
순천향대학교 정보기술공학부
이상정
10
Ch.8 Hardware Management
LINUX Device Drivers
inp/outp 코드 예
사용자 영역의 커맨드 라인에서 포트 읽기,쓰기하는 간단한
도구로 misc-progs/inp.c, misc-progs/outp.c 의 샘플 소
스에서 구현
inp.c
# cc inp.c –o inpb
# ./inpb 3f8
=> 시리얼 포트 번호 3f8 입력
03f8: 22
outp.c
# cc outp.c –o outpb
# ./outpb 378 ff
=> 병렬포트(0x378)에 ff 출력
순천향대학교 정보기술공학부
이상정
11
Ch.8 Hardware Management
LINUX Device Drivers
문자열 오퍼레이션들(string operations)
문자열 오퍼레이션들(string operations)
• void insb(unsigned port, void *addr, unsigned long count);
void outsb(unsigned port, void *addr, unsigned long count);
메모리 주소 addr 시작하여 count 크기의 바이트를 port의 포트에 읽기,쓰
• void insw(unsigned port, void *addr, unsigned long count);
void outsw(unsigned port, void *addr, unsigned long count);
16 비트 값의 읽기, 쓰기를 수행
• void insl(unsigned port, void *addr, unsigned long count);
void outsl(unsigned port, void *addr, unsigned long count);
32 비트 값의 읽기, 쓰기를 수행
지연 I/O (pausing I/O)
• i386과 같은 플랫폼에서 ISA 버스 사용 시 프로세서가 버스에 비해 너무 빠르
게 수행되어 I/O 동작이 처리되어 완료하기 전에 다음 I/O 명령 실행하여 하
여 데이터 손실
• 이를 방지하기 위해 inb_p, outb_p 함수는 각 I/O 명령 수행 후 지연 루틴 삽
입
순천향대학교 정보기술공학부
이상정
12
Ch.8 Hardware Management
병렬포트 사용 short 예
순천향대학교 정보기술공학부
이상정
13
LINUX Device Drivers
병렬포트 소개
병렬포트 상에서 동작하는 short(Simple Hardware
Operations and Raw Tests) 샘플 드라이버 소개
• source/short/short.c
병렬포트 소개
• 25개의 PIN으로 구성
• 3개 포트가 있고 각 포트 당 양방향 데이터 레지스터, 읽기 전용 상태
레지스터, 출력 전용 출력 레지스터로 구성
Port
1
2
3
순천향대학교 정보기술공학부
Data
0x0378
0x0278
0x03bc
이상정
14
Status
0x0379
0x0279
0x03bd
Control
0x037a
0x027a
0x03be
Ch.8 Hardware Management
LINUX Device Drivers
병렬포트 핀 구성 (1)
순천향대학교 정보기술공학부
이상정
15
Ch.8 Hardware Management
LINUX Device Drivers
프린트 병렬포트 핀 구성 (2)
순천향대학교 정보기술공학부
이상정
16
Ch.8 Hardware Management
LINUX Device Drivers
short 샘플 드라이버
short(Simple Hardware Operations and Raw Tests) 샘플
드라이버
• short가 동작하기 위해서는 해당 하드웨어 디바이스(디폴트로 병렬
인터페이스)에 자유롭게 접근 가능해야 함
• /proc/ioports를 통해 포트를 사용 중에 있는지 체크
• 결과를 확인하기 위해 출력 핀에 LED(1-K ohm 저항과 함께)를 연결
• 핀 9,10은 9장에 사용되기 때문에 연결하지 말 것
• /dev/short0 ~ /dev/short7
• I/O 주소 base에 위치한 8 비트 포트(디폴트 0x378)에 쓰기, 읽기를 수
행
• /dev/short1은 base+1에 위치한 8 비트 포트에서 수행되고 /dev/short7
은 base+7에서 수행
• 비록 PC 병렬 인터페이스가 3개의 포트만을 갖지만 다른 I/O 디바이스를
사용하면 더 필요할 수도 있기 때문에 8개를 제공
• /dev/short0p는 빠른 함수대신 outb_p와 inb_p를 사용하고,
/dev/short0s는 문자열 함수를 사용
순천향대학교 정보기술공학부
이상정
17
Ch.8 Hardware Management
LINUX Device Drivers
short 입출력 동작
출력 동작
• outb() 함수를 반복 수행하고 최적화하지 않기 위해 메모리 배리어
명령이 삽입
while (count--) {
outb(*(ptr++), address);
wmb();
}
• LED를 켜기 위해 다음과 같은 명령을 실행
echo –n 6 > /dev/short0
echo -n "any string" > /dev/short0
입력 동작
• inb() 함수를 사용하여 유사하게 수행
• 병렬포트로부터 읽기 위해서는 커넥터의 입력 핀에 신호를 생성하는
하드웨어를 연결
순천향대학교 정보기술공학부
이상정
18
Ch.8 Hardware Management
LINUX Device Drivers
short 이용 사용자 프로그램
#include <unistd.h> // sleep()
#include <fcntl.h>
#define ON 7; // pin 2,3,4 LSB 3 bit
#define OFF 0;
int main(int argc, char *argv[])
{
int fd, n, delay = 1;
char data;
if (argc > 1)
delay = atoi(argv[1]);
fd = open("/dev/short0", O_WRONLY, 0); // or shortp0
while (1) {
data = ON;
write(fd, &data, 1);
sleep(delay);
data = OFF;
write(fd, &data, 1);
sleep(delay);
}
return 0;
}
순천향대학교 정보기술공학부
이상정
19
Ch.8 Hardware Management
I/O 메모리 사용하기
순천향대학교 정보기술공학부
이상정
20
LINUX Device Drivers
I/O 메모리 소개
I/O 메모리 소개
• 메모리맵형 레지스터나 디바이스 메모리에 접근하여 입출력
• 프로세서가 메모리오 같이 버스를 통해 디바이스에 접근
• 이장에서는 주로 ISA나 PCI 메모리를 소개
I/O 메모리의 접근은 컴퓨터 아키텍처,버스,디바이스에 따라 다소 차이
• 컴퓨터 플랫폼이나 사용되는 버스에 따라 I/O 메모리는 페이지 테이블을 거
치지 않고 물리주소로 직접 접근하거나,
• 페이지 테이블을 경유하여 가상주소로 참조할 수도 있음
• 물리주소로 지정된 I/O 메모리 주소를 가상주소로 변환 시 ioremap() 함수 사용
• 포인터를 직접 사용하여 I/O 메모리 접근은 바람직하지 않음
• 디바이스 접근 시 속도의 차이, 배리어 등 문제점
• I/O 메모리를 사용하는 랩퍼함수(wrapper function)을 사용하는 것이 안전하
고 효율적
순천향대학교 정보기술공학부
이상정
21
Ch.8 Hardware Management
LINUX Device Drivers
I/O 메모리 할당 및 함수
I/O 메모리 할당 및 해제 함수 (2장에서 소개)
• int check_mem_region(unsigned long start, unsigned long len);
• void request_mem_region(unsigned long start, unsigned long len, char
*name);
• void release_mem_region(unsigned long start, unsigned long len);
사용 예
if (check_mem_region(mem_addr, mem_size)) {
printk("drivername: memory already in use\n");
return -EBUSY;
}
request_mem_region(mem_addr, mem_size, "drivername");
...
release_mem_region(mem_addr, mem_size);
순천향대학교 정보기술공학부
이상정
22
Ch.8 Hardware Management
LINUX Device Drivers
소프트웨어 매핑 I/O 메모리
(Software-Mapped I/O Memory)
메모리맵형 디바이스들은 주로 주변장치 버스에 연결되어 사
용가 사용
• 디바이스들의 주소는 하드와이어드(ISA 디바이스) 되거나 부팅 시 시
스템 펌웨어(PCI 디바이스)에 의해 지정
• 이들은 가상주소가 아닌 물리주소가 지정
• CPU가 I/O 메모리에 접근하기 위해서는 디바이스에 가상주소가 지
정되어야 함
ioremap() 함수가 I/O 메모리 영역에 가상주소를 할당
• ioremap(그리고 iounmap)을 사용하면 디바이스 드라이버는 어떤
I/O 메모리 주소도 접근 가능
• 가상주소로 변환한 후에는 readb()와 같은 함수를 사용하여 입출력
순천향대학교 정보기술공학부
이상정
23
Ch.8 Hardware Management
LINUX Device Drivers
과제
실행, 결과 및 코드 분석
• short 소스 예 분석
• short0 ~ short7
• short0p ~ short7p
• short0s ~ short7s
• 실행 및 테스트
• LED(1-K ohm 저항과 함께)를 땜질로 연결
순천향대학교 정보기술공학부
이상정
24
Ch.8 Hardware Management