PCI가 어렵울 거라는 생각을 지금부터 버리도록 합시다.

Slides:



Advertisements
Similar presentations
1. Drive A, Drive B 표준 CMOS 설정 화면에서는 하드디스크 드라이브의 특성 외에 플로피디스크 드라이브도 설정해야 합니다. PC에서 FDD를 2개까지 사용할 수 있다. 표준 CMOS  설정 화면의 Drive A와 Drive B 항목에서는 플로피디스크.
Advertisements

키보드 보안 순천향대학교 정보보호학과 임강빈 교수.
제10장 디바이스 드라이버.
LAN의 구성 요소 장서진 정영환.
제 3 장 변수와 자료형.
KEY 디바이스 드라이버 Lecture #12. 2 차례 GPIO 및 Control Registers KEY 하드웨어 구성 KEY Driver 프로그램 key-driver.c 시험 응용 프로그램 key-app.c.
제5장 산업재해 보상보험 ☞ 목적 : 근로자의 업무와 관련하여 발생한 재해근로자의 재활 및 사회복귀를 촉진시키기 위하여 이에 필요한 보험시설을 설치 운영하며, 피해를 예방하고 근로자의 복지증진을 위한 사업을 행함으로써 근로자의 보호에 이바지함을 목적으로 함. 산재보험은.
리눅스 커널의 이해 중에서 4장. 인터럽트와 예외 이성현 네트워크 실험실.
마이크로프로세서 메모리 및 입출력장치 인터페이스
2014 ITA 8월 강의 C Programming -1주차- C언어 기초 정대진 ( )
아두이노 프로그래밍 1일차 – Part2 아두이노 사양 강사: 김영준 목원대학교 겸임교수.
제7장 버스와 입출력.
Department of Computer Engineering
디바이스 드라이버 이해 Hanbat National University Prof. Lee Jaeheung.
RnA DISPLAY 구동 Clcd 구동 Made by Bonobonobono.
임베디드 하드웨어 Lecture #6.
08. 디바이스 드라이버의 읽기와 쓰기 김진홍
디바이스 드라이버.
이식성과 데이터형 서로 다른 프로세서 상에서의 이식성을 위해 가급적 리눅스 커널이 제공하는 데이터형을 사용하는 것이 좋다.
제3장 추가 실습 3장 관련 C 언어 프로그래밍 실습.
Department of Computer Engineering
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
Network Lab. Seoung Hyeon, Lee
쉽게 풀어쓴 C언어 Express 제16장 파일 입출력 C Express Slide 1 (of 23)
6장. 기 억 장 치 Lecture #6.
Chapter 02 시스템 구조(System Structure)
1 컴퓨터 시스템 소개.
4장. 컴퓨터 시스템의 구성과 기능 다루는 내용 컴퓨터 분해를 통한 본체 살펴보기 컴퓨터 구성요소 컴퓨터의 기능
FND (Flexible Numeric Display)
10장 메모리 관리.
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express.
Department of Computer Engineering
Chapter 10. Interrupt.
Department of Computer Engineering
Step Motor Device Driver
Embeded 기초 다지기 2015년 10월 26일 intern Sally
Input/Output Control.
One-Stop Solution in Device Networking
Socket Address Structure and Byte Ordering Functions
18장. 헤더 파일과 구현 파일 01_ 헤더 파일과 구현 파일의 사용.
Socket Address Structure and Byte Ordering Functions
4족 로봇 삼식이팀 박명대.
(ioctl, mmap, fsync&flush)
Department of Computer Engineering
제 3 장 상수와 변수
모듈 초기화 module_init(hello_init); module_exit(hello_exit);
임베디드 시스템을 위한 C프로그래밍 기법 3.7 ~ 4.5 장 Raphael.
Computer System Architecture
Programmable Logic Device
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
문자 디바이스 드라이버 임베디드 시스템.
[ 포털 사이트 연관검색어/자동완성 등록 서비스 ]
공인인증서 신청 및 발급 제일 먼저 은행에 직접 방문하여 인터넷뱅킹 신청.
중앙대 원격교육원 범용공인인증서 홈페이지 등록 방법 .
8051 IO-PORT 정보통신•컴퓨터 공학부 송명규
리눅스 디바이스 드라이버 (Linux Device Driver)
Windows7 – 글꼴, 시스템, 장치관리자, 전원옵션
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
Stepper Motor 디바이스 드라이버
비밀번호 관련 안내 사용자 매뉴얼 위치 목 차 I II III IE11 및 이전 버전 설정 DIPS 사용자매뉴얼
C89(C++03) 프로그래밍 (Part 2) 7 배열 8 변수 범위 9 포인터 10 유도 자료형.
Department of Computer Engineering
C언어 프로그래밍의 이해 Ch03. 기본 자료형, 변수와 상수.
박성진 컴퓨터 프로그래밍 기초 [03] 변수와 자료형 박성진
27. DMA와 PCI 디바이스 김진홍
C 13장. 입출력 라이브러리 #include <stdio.h> int main(void) { int num;
임베디드 하드웨어 Lecture #6.
Virtual Machine Management
대관시스템 매뉴얼 : 대관회원가입 및 공연장 대관신청
Presentation transcript:

PCI가 어렵울 거라는 생각을 지금부터 버리도록 합시다. 2007.5.13 FA리눅스공개세미나 오 재 경 PCI가 어렵울 거라는 생각을 지금부터 버리도록 합시다.

버스(BUS)란? 32Bit MCU의 메모리 공간의 크기 4GByte 버스의 여러종류 로컬버스, PCI, I2C, AC97, USB, ATA, IEEE1394, etc … 두가지 버스의 구분 (접근방법에 따른, 극히 개인적인) Indirect BUS (USB, SCSI, IEEE1394, I2C) Direct BUS (Local-BUS, PCI) 하드웨어적인 전기적인 연결과 이를 제어하는 소프트웨어의 표준 인터페이스를 제공하여 디바이스의 확장을 용이하게 해주는 것

BUS 의 예 HDD 0xFFFF FFFF 32bit MCU HDD PCI to HDD PCI-BUS 0x8000 0000 PCI to USB USB Device USB Device USB Device AC97 Codec AC97-BUS 각 버스의 특징을 색을 보며 설명한다. 0x4000 0000 LOCAL-BUS Flash 0x0000 0000

PCI 버스의 특징 직접적인 메모리 방식의 제어를 통해 엑세스가 가능하다. 직접 제어방식이라 프로토콜 계층이 없어 소프트웨어적으로 간결하다. 이와는 반대로 USB등과 같이 프로토콜 계층이 존재하는 방식의 장단점을 비교한다.

PCI 버스의 주소할당 PC 보드에서 PCI 슬롯에 카드들을 임의 대로 꽂아도 시스템에서는 잘 인식한다. 어떻게 가능한 것인가? 컨피큐레이션 사이클이라는 특별한 전송이 존재하며 이것은 특정 슬롯을 지정하여 전송할 수 있다. MCU PCI 버스 주소를 할당하는 방법을 설명하며 주소가 할당된 이 후에는 쉽게 접근이 가능하다는 것을 인지시킨다.

PCI Configuration 영역 31 16 15 Device ID Vender ID Status Command Device ID Vender ID Status Command Class ID Rev ID BIST Header Type Latency CacheLineSize Base Address #0 (I/O 전용) Base Address #1 (MEM 전용) Base Address #2 (MEM 전용) Base Address #3 (MEM 전용) Reserved …. 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C 0x20 Configuration 의 기본적인 사항을 설명하며 이 영역을 읽음으로써 하드웨어 결선 상태를 확인할 수 있다.

PCI 디바이스의 Base 주소 MEM Base Address P B IO Base Address 1 IO Base Address 1 P : 메모리 프리패치 가능 메모리일 경우 D0 = 0 IO일 경우 D1:D0 = 01 bit 16 12 8 4 커널이 주소를 어떤 방식으로 할당하며 PCI 디바이스가 점유하는 공간은 어떻게 알아내는지 설명한다. 1 Base Register 에 0xFFFF FFFF 를 쓴 후 다시 읽어 각비트의 값을 보고 필요로 하는 주소의 크기를 판단한다. Read Only

주소할당의 예 할당된 주소를 확인하는 방법과 컨피규레이션 영역의 값들을 살펴본다. lspci 유틸리티의 사용방법을 소개한다.

IO 영역과 MEM 영역의 차이 io 영역은 한번에 하나씩의 데이터를 엑세스하는 곳이며 prefetch가 일어나지 않는다. mem 영역은 prefetch가 가능하며 burst 전송이 가능하다. mem 영역은 할당되는 크기의 제한이 거의 없으며 DMA 전송도 지원하여 고속의 데이타전송이 가능하다.

PCI 버스의 핀(32bit PCI) AD[0..31] : 어드레스/데이터 공통 C/BE[0..3] : Commad/BUS-Enable FRAME# : 사이클 시작신호 DEVSEL# : 사이클 응답신호(주소에 대한) IRDY# : 버스상의 데이터가 유효함을 알림 TRDY# : 데이터를 받을 수 있음을 알림 REQ#, GNT# : 버스점유 요구, 허락 PAR : 짝수패리티 SERR# , PERR# : 어드레스에러, 데이타에러 CLK, RST#, STOP#, INT[A...D]# IDSEL : 환경영역을 엑세스할 때 사용

PCI 버스의 기본적인 동작 버스의 타이밍을 설명하며 하드웨어 디버깅시 필요한 테스트 포인터를 알려준다.

PCI 하드웨어 설계 시 주의점 회로 설계시 아트웍 시 문제점 버스의 드라이빙 능력 버스 아비터의 개수 클럭버퍼의 사용 OC 핀의 풀업저항 아트웍 시 클럭신호는 한 디바이스 까지의 버스들의 평균거리로 설정 버스내 각 신호선간의 길이는 가급적 동일하게 설정(20% 오차까지(?)) 문제점 보드가 너무 작을 경우 동일한 버스 길이를 설정하기 힘들다. PCI 디바이스가 너무 많을 경우 외부 아비터나 버스 브릿지를 고려해본다. (버스 브릿지는 비추천.. 하지만 달아야 한다면 ㅜ.ㅜ) 클럭신호가 왜 평균거리가 필요한지 설명한다. 통신하는 칩들간의 평균거리임을 주지시킨다.

PCI 디바이스 회로도 Idsel 핀과 인터럽트선을 어떤 규칙에 의해 배치하는지 설명한다. 풀업저항은 3.3V 일때 8.2K, 5V 일때 4.7K 임을 말하고 10K 저항을 사용한 이유를 설명한다.

PCI 하드웨어 디버깅 디바이스의 전원이 정상인지 확인한다. 디바이스의 클럭이 공급되는지 확인한다. 디바이스의 RESET 신호가 정상인지 확인한다. 회로도가 이상이 없는지 넷트의 이름과 칩의 핀배치가 일치하는지 확인한다. 주변 저항등 칩들이 모두 정상으로 붙어있는지 확인한다. 디바이스의 configuraion 레지스터를 읽는다. (lspci 유틸리티) Frame# 신호화 함게 디바이스의 IDSEL 핀이 High 로 선택되는지 확인한다. Devsel# 신호가 동기 되는지 확인한다. PERR#, SERR# 가 발생하는지 확인한다. 버스의 신호가 전혀나오지 않는다면 MCU 레지스터 설정과 커널의 PCI 관련 동작이 활성화 되어있느지 또는 나의 보드에 맞게 포팅되어 있는지 확인한다. 하드웨어 디버깅의 왕도는 없다. 1~5 번까지의 내용은 일반 하드웨어 디버깅도 동일하다. 6번까지의 내용은 소프트웨어 엔지니어도 충분히 가능한 내용임을 설명한다.

PCI 버스를 지원하는 MCU 구조 MCU PCI/MEM PCI/IO PCI Device 0x4100 0000 + PCI MEM-Base + PCI MEM-Base 0x4100 0000 0x4000 0000 + PCI IO-Base 0x4000 0000 PCI IO-Base 일반적인 MCU 들이 PCI 버스로 주소를 어떻게 사상(표출)하는지 설명한다.

리눅스커널이 부팅시 하는 일 Configuration 싸이클을 이용하여 주소 할당 BUS, SLOT, FUNC 번호를 이용한 IRQ 등록 커널의 하는일이 많지 않음을 설명한다.

디바이스 드라이버의 최초 실행 static int __init spci_init( void ) { return pci_module_init(&spci_driver); } static void __exit spci_exit( void ) pci_unregister_driver(&spci_driver); module_init(spci_init); module_exit(spci_exit); insmod 유틸리티를 이용하여 드라이버를 커널에 적재할때 호출되는 함수 init_module() rmmod 유틸리티를 실행하면 호출되는 함수 cleanup_module() __init, __exit 를 설명한다.

PCI 디바이스 드라이버 등록 PCI 드라이버 등록 구조체 인자 struct pci_driver spci_driver = { .name = DEV_NAME, .id_table = spci_tbl, .probe = spci_probe, .remove = spci_remove, }; PCI 드라이버 초기화 함수 pci_module_init(&spci_driver); // #define pci_module_init pci_register_driver PCI 드라이버 해제 함수 pci_unregister_driver(&spci_driver); pci_register_driver  probe pci_unregister_driver  remove

struct pci_device_id struct pci_device_id { // linux/mod_devicetable.h __u32 vendor, device; __u32 subvendor, subdevice; __u32 class, class_mask; kernel_ulong_t driver_data; }; static struct pci_device_id spci_tbl[] = { {0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SPCI_PRIVATE_NUMBER }, {0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SPCI_PRIVATE_NUMBER }, {0,} }; Vendor, Product ID 설명

struct pci_driver member 함수 int spci_probe ( struct pci_dev *pdev, const struct pci_device_id *ent ) { // 디바이스가 정상인지 확인 // 디바이스가 점유하는 베이스주소 얻기 // 사용할 메모리 할당 // 인터럽트 함수 등록 // 클래스에 맞는 드라이버 등록 ex) register_chrdev() // 디바이스 초기화 실행 } void spci_remove ( struct pci_dev *pdev ) // 점유한 리소스 반환 각 함수에서 해야하는 일 설명

주소 (Resource) 얻기 struct pci_dev *pdev; // 함수의 인자 int win_nr = 0; // PCI configuration base-address index // 0번은 IO 베이스 주소 // 1~5 번은 메모리 베이스 주소 unsigned long base = pci_resource_start (pdev, win_nr); unsigned long end = pci_resource_end (pdev, win_nr); unsigned long flags = pci_resource_flags (pdev, win_nr); unsigned long len = pci_resource_len (pdev, win_nr); unsigned int irq = pdev->irq; PCI 디바이스에 할당된 주소를 얻어온다.

struct pci_dev struct pci_dev { struct pci_bus *bus; unsigned int devfn; unsigned short vendor; unsigned short device; unsigned int class; u8 pin; struct pci_driver *driver; struct device dev; int cfg_size; unsigned int irq; struct resource resource[DEVICE_COUNT_RESOURCE];

주소 맵핑(mapping) Configuration Base-Address 에 등록(할당)된 주소는 물리주소이다. 리눅스 커널에서는 물리주소를 바로 사용할 수 없다. 이를 사용하기 위해서는 가상주소로 변환하여 사용하여야 한다. vir_addr = ioremap( phy_address, len ); iounmap( vir_addr ); ioremap_nocache(), ioremap_cache(); PCI 영역중 mem 영역은 가상영역으로 변환하여야 한다. PCI 영역중 IO 영역은 변환하지 않고 사용한다. 인텔의 CPU i386 Core 에 대해 설명한 후 mem, io 영역이 다른이유를 설명한다. 드라이버 포팅시 이분에 주의 해야 함을 말한다.

버스접근 함수 PCI-IO 영역 접근함수 inb(), outb(), inw(), outw(), inl(), outl() PCI-MEM 영역 접근함수 readb(), writeb(), readw(), writew(), readl(), writel() inclue/asm/io.h 참고(중요소스)

인터럽트 처리 request_irq( irq, spci_callback, SA_INTERRUPT | SA_SHIRQ, “sample”, NULL ); irqreturn_t spci_interrupt( int irq, void *dev_id, struct pt_regs *regs ) { if ( 내가 다루는 디바이스가 인터럽트를 발생시켰는가 ) // 인터럽트 라인이 해제될 수 있도록 처리한다. return IRQ_HANDLED; } else return IRQ_NONE; 인터럽트가 공유된다는 것을 숙지 시킨다.

PCI 버스의 DMA 전송 PCI 버스가 빠른것은 DMA 전송을 지원하기 때문이다. 이 기능을 사용하지 않고는 PCI 디바이스를 사용할 이유가 반감된다. DMA 전송을 위해서는 물리적으로 연속된 메모리를 획득한다. 연속된 물리메모리를 획득하였다면 PCI 디바이스의 특정 영역에 호스트측의 물리 메모리 주소와 PCI 디바이스의 물리주소 그리고 전송할 데이터의 크기를 넣은 후 DMA 전송 명령을 내린다. DMA 전송명령을 위해서는 PCI 디바이스 레지스터를 접근하여 특정값을 넣어야 한다. 커널에 따로 이를 위한 함수는 준비되어 있지 않다. PCI 버스에서 DMA 전송의 버스 마스터는 PCI 디바이스에 있다.

DMA 메모리 획득(K2.6.10 이상) 1-page 이하의 크기 (4KByte) 1-page 이상의 크기 kmalloc( b-size, GFP_KERNEL ), kfree( virt ) 1-page 이상의 크기 kmalloc( b-size, GFP_DMA ); void *dma_alloc_coherent( struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp ); dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle ); 예제 dma_addr_t dma; // DMA 용 물리주소 void *virt = dma_alloc_coherent( pdev->dev, 1M, &dma, GFP_KERNEL );

PCI 디바이스 드라이버 소스 소스를 봅시다. ^^

예제 드라이버 실행 결과

끝 이페이지를인쇄한분들은인쇄하기전에내용을살피지않고오셨거나공짜로사용할수있는회사나학교의용지를사용하셨거나한페이지에여러페이지인쇄를하신분들입니다아니면종이가많은부자이거나어찌됬든이번강의를위해이페이지까지아낌없어투자하신분들은꼭성공하실겁니다부족한강의를끝까지들어주셔서감사합니다나가는문이어느쪽이든남은강의열심히들으신후경품도타가시는행운을누리시기바랍니다