27 DMA PCI jhkim 3624etri re kr 2015

  • Slides: 38
Download presentation
27. DMA와 PCI 디바이스 김진홍 jhkim 3624@etri. re. kr 2015. 11. 15.

27. DMA와 PCI 디바이스 김진홍 jhkim 3624@etri. re. kr 2015. 11. 15.

목차 1. DMA 2. PCI

목차 1. DMA 2. PCI

1. DMA

1. DMA

리눅스에서의 DMA 처리 • DMA 전송 시작 • DMA 데이터를 전송 코드의 형태는 정형화

리눅스에서의 DMA 처리 • DMA 전송 시작 • DMA 데이터를 전송 코드의 형태는 정형화 되어 있음 • int xxx_dma_start(int channel, int mode, unsigned char *dma_buff, unsigned int count) { unsigned long flags; : 1. DMA 2. PCI flags=claim_dma_lock( ); disable_dma(channel); clear_dma_ff(channel); set_dma_mode(channel, mode); set_dma_addr(channel, virt_to_bus(dma_buff)); set_dma_count(channel, count); enable_dma(channel); release_dma_lock(flags); : return 0; } • DMA 시작을 위한 I/O 하드웨어에 관련된 처리 • 하드웨어마다 다름 12/36

DMA와 MMAP • DMA와 MMAP 유저 응용 프로그램 1. DMA 가상 메모리 유저 영역

DMA와 MMAP • DMA와 MMAP 유저 응용 프로그램 1. DMA 가상 메모리 유저 영역 mmap (0, 0 x 1000, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 2. PCI 0 x 0 b 0000) 물리 메모리 호출 Device Driver file_operation 내부의 mmap() = xxx_mmap() 0 x 0 b 0000 0 x 0 b 1000 DAM 버퍼 -> mmap을 통해 유저 에게 매핑 DMAC xxx_mmap() I/O 장치 커널 영역 DMA 16/36

2. PCI

2. PCI

Pn. P와 디바이스 환경 설정 공간 • 디바이스 드라이버에서 환경 설정 공간의 접근 •

Pn. P와 디바이스 환경 설정 공간 • 디바이스 드라이버에서 환경 설정 공간의 접근 • PCI 이바이스를 사용하려면 환경 설정 영역에 접근하여 데이터를 처리하는 경우가 생김 • • 접근하기 위해 사용하는 함수 1. DMA • int pci_bus_read_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u 8 *val); • int pci_bus_read_config_word(struct pci_bus *bus, unsigned int devfn, int where, u 16 *val); • int pci_bus_read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u 32 *val); • int pci_bus_write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u 8 *val); • int pci_bus_write_config_word(struct pci_bus *bus, unsigned int devfn, int where, u 16 *val); • int pci_bus_write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u 32 *val); PCI 디바이스 정보가 담겨져 있는 pci_dev 구조체가 있는 경우 • int pci_read_config_byte(struct pci_dev *dev, int where, u 8 *val); • int pci_read_config_word(struct pci_dev *dev, int where, u 8 *val); • int pci_read_config_dword(struct pci_dev *dev, int where, u 8 *val); • int pci_write_config_byte(struct pci_dev *dev, int where, u 8 *val); • int pci_write_config_word(struct pci_dev *dev, int where, u 8 *val); • int pci_write_config_dword(struct pci_dev *dev, int where, u 8 *val); 2. PCI int xxx_read_info(struct pci_dev *dev) { u 8 deviceid; : pci_read_config_byte(dev, PCI_DEVICE_ID, &deviceid); return deviceid; } 26/36

PCI 디바이스의 디바이스 드라이버 • PCI 디바이스 검출 • PCI 디바이스 검색과 등록 요청

PCI 디바이스의 디바이스 드라이버 • PCI 디바이스 검출 • PCI 디바이스 검색과 등록 요청 • 1. DMA static struct pci_driver xxx_pci_driver = {. name = XXX_DRIVER_NAME, . id_table = xxx_pci_tbl, 2. PCI . probe = xxx_probe, . remove = __devexit_p(xxx_remove), #ifdef CONFIG_PM. suspend = xxx_suspend, . resume = xxx_resume, #endif }; • static int __init xxx_init_module(void) { • return pci_register_driver(&xxx_pci_driver); } static void __exit xxx_cleanup_module(void) { pci_unregister_driver(&xxx_pci_driver); } 30/36

PCI 디바이스의 디바이스 드라이버 • PCI 디바이스 검출 • int probe(struct pci_dev *dev, const

PCI 디바이스의 디바이스 드라이버 • PCI 디바이스 검출 • int probe(struct pci_dev *dev, const struct pci_device_id *id); 1. PCI 디바이스를 활성화 • 1. DMA PCI 디바이스에 접근하기 위해 디바이스 활성화 • int pci_enable_device(struct pci_dev *dev); • void pci_disable_device(struct pci_dev *dev); 2. PCI 디바이스의 하드웨어 제어 주소 정보 • 주소정보는 커널 내의 데이터 구조에 존재함 • 다음 함수를 이용하여 획득 • unsigned long pci_resource_start(struct pci_dev *dev, int bar); • • unsigned long pci_resource_end(struct pci_dev *dev, int bar); • • BAR(Base Address Register)에 해당하는 메모리의 끝주소를 얻어옴 unsigned long pci_resource_len(struct pci_dev *dev, int bar); • • BAR(Base Address Register)에 해당하는 메모리의 시작주소를 얻어옴 BAR(Base Address Register)에 해당하는 메모리의 크기를 얻어옴 unsigned long pci_resource_flags(struct pci_dev *dev, int bar); • BAR(Base Address Register)에 해당하는 메모리의 속성값을 가져옴 • IORESOURCE_IO, IORESOURCE_MEM 32/36

PCI 디바이스의 디바이스 드라이버 • PCI 디바이스 검출 • probe 함수의 예 • 1.

PCI 디바이스의 디바이스 드라이버 • PCI 디바이스 검출 • probe 함수의 예 • 1. DMA int xxx_probe(struct pci_dev *dev, const struct pci_device_id *id) { : //PCI 디바이스 활성화 //디바이스 드라이버 등록 register_chrdev(XX_DEV_MAJOR, XXX_DEV_NAME, &xxx_fops); 2. PCI pci_enable_device(dev); // 메모리 주소 획득 및 등록과 매핑 //하드웨어 초기화 xxx_hardware_init(); xxx_hw_addr = pci_resource_start(dev, 0); : xxx_addr_size = pci_reousrce_len(dev, 0); } pci_request_regions(dev, XXX_DEV_NAME); xxx_vaddr = ioremap(xxx_hw_addr, xxx_addr_size); //인터럽트 등록 xxx_irq = dev->irq; request_irq(xxx_irq, xxx_interrupt, SA_INTERRUPT | SA_SHIRQ, XXX_DEV_NAME, &xxx_info); //버스 마스터링 모드 설정 pci_set_master(dev); 34/36

PCI 디바이스의 디바이스 드라이버 • PCI 디바이스 검출(수동) • struct pci_dev *pci_find_device(unsigned int vendor,

PCI 디바이스의 디바이스 드라이버 • PCI 디바이스 검출(수동) • struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *from); struct pci_dev *pci_find_subsys (unsigned int vendor, unsigned int device, unsigned int ss_vendor, unsigned int ss_device const struct pci_dev *from); 1. DMA struct pci_dev *pci_find_class(unsigned int class, const struct pci_dev *from); struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn); • • 2. PCI 각 함수는 다음과 같은 조건과 일치하는 대상을 찾음 • pci_find_device : 벤더ID, 디바이스 ID • pci_find_subsys : 벤더ID, 디바이스 ID, 하부 벤더 ID, 하부 디바이스 ID • pci_find_class : 클래스 코드 • pci_find_slot : 버스번호, 슬롯, function 번호 예제 • struct pci_dev *dev = NULL; while(dev = pci_find_device(VENDOR_ID, DEVICE_ID, dev)){ //찾은 PCI 디바이스 정보가 dev에 넘어온다. : } 35/36

Q&A 37/40

Q&A 37/40