2016-11-03 28 views
4

Freescale MPC8308 프로세서 (PowerPC 아키텍처 기반)에서 PCI-e 포트를 사용하고 있으며 사용하려고 할 때 몇 가지 문제가 있습니다. 엔드 포인트 PCI-e 디바이스의 메모리 공간은 256MB입니다. "pciutils"패키지를 사용하여 엔드 포인트 장치의 구성 공간을 쉽게 읽고 쓸 수 있습니다.mmap을 사용한 PCI-e 메모리 공간 액세스

구성 레지스터에 올바른 값을 쓰고 메모리 공간을 액세스 할 수있는 권한을 얻은 후; I는 "mmap에()"C 함수를 사용하여 메모리 공간에 액세스하는 시도에있는 파일 디스크립터 사용했을

"/sys/devices/pci0000:00/0000:00:00.0/resource0"

정확히 256MB (엔드 포인트 장치의 메모리 공간과 동일)이므로 파일 설명자에 올바른 경로를 사용하고있는 것처럼 보입니다. 여기 당신은 https://github.com/billfarrow/pcimem에 언급 된 "의 mmap()"를 사용하여 내 코드를 찾을 수 있습니다

https://github.com/billfarrow/pcimem/blob/master/pcimem.c

그러나 불행하게도을 내가 "의 mmap()"함수의 반환 주소를 사용하여 메모리 공간을 사용하려고하면, 엔드 포인트 장치의 읽기 전용 레지스터를 올바르게 읽을 수 없습니다. 또한 "0x7FFFFFC"보다 큰 주소를 읽을 때 MPC8308이 재부팅됩니다. 위의 상황을 고려해 볼 때 PCI-e 인터페이스를 초기화하기위한 모든 단계를 놓치고 있습니까? Linux 커널 이미지 또는 U-Boot 코드에서 무엇을 변경해야합니까? mmap()과 함께 PowerPC PCI-e를 사용하는 것과 다른 점이 있습니까? PCI-e 메모리 공간을 읽는 데 도움이되는 예제 코드가 있습니까?

감사합니다.

+0

엔드 포인트의 메모리 공간이 너무 큰 것 같습니다. 내 프로세서 (i.MX6)에서는 16MB보다 큰 엔드 포인트를 가질 수 없습니다. PCIe 용 Linux 부팅에서 초기화 오류가 있습니까? PCI-e 메모리 장치 란 무엇입니까? FPGA입니까? – FabienM

+0

예, 나에게는 너무 많은 것처럼 보였지만 리눅스 부팅에는 오류가 없었으며/proc/iomem에서 볼 수있는 것처럼 디바이스 용 메모리에 256MB를 사용했습니다. 엔드 포인트 디바이스는 FPGA가 아닙니다. PCI-e 인터페이스가있는 ASIC. –

+1

다른 경로는 장치의 기본 물리적 주소와 한계를 찾아서/dev/mem에 매핑하는 것입니다. (정직하게 작동하는 것은 보장 할 수 없지만, 그래도 궁금하다.) – ruthafjord

답변

1

mmap()은 사용자 공간에서 PCIe 장치에 액세스하는 매우 유용하지만 임시적인 방법입니다.

mmap의 첫 번째 인수로 0을 전달합니다. x86 컴퓨터에 연결된 FPGA 카드의 경우 필자는 lspci를 호출하여 pcie 슬롯에있는 카드의 실제 주소를 얻습니다. 그런 다음 그 실제 주소를 mmap의 첫 번째 인수로 사용합니다. 나는 장치의 설정 공간에 BAR을 쓰고 있지만 lspci로 이중 체크를 한 것 같습니다.

$ sudo lspci -s 02:00 -v 
02:00.0 Memory controller: Xilinx Corporation Device 8028 
    Subsystem: Xilinx Corporation Device 0007 
    Flags: bus master, fast devsel, latency 0, IRQ 11 
    Memory at f7e00000 (32-bit, non-prefetchable) [size=1M] 
    Capabilities: [80] Power Management version 3 
    Capabilities: [90] MSI: Enable- Count=1/1 Maskable- 64bit+ 
    Capabilities: [c0] Express Endpoint, MSI 00 
    Capabilities: [100] Advanced Error Reporting 
0

전어 : 비 응답을 준비하십시오. 사용자 공간에서이 작업을 수행하는 것처럼 들립니다. 장치를 사용자 공간으로 MMAPing하는 것은 일반적인 관행이 아닙니다 (아키텍처에 대해 매우 염두에 두지 않는 한 끔찍한 보안상의 영향을 미칩니다). 솔직히, 나는 이것이 가능해야만하는지조차 확신하지 못한다. 나는이 일이 일어나는 경우를 생각하기 위해 애 쓰고 있습니다. 일반적으로 장치는 커널에서만 사용되므로 사용자 공간에서 재생하는 대신 드라이버 나 커널 모듈을 작성하는 것이 좋습니다.

+1

의견을 보내 주셔서 감사합니다. mmap()을 PCI-e를 사용할 때 특별히 장치에 액세스하기 위해 도입 된 일반적인 솔루션으로 사용할 수 있습니다. 예를 들어, "Linux device driver"장의 15 장에서 mmap()을 사용하여 PCI-e 메모리 공간을 액세스 할 수 있다고 언급했습니다.그러나 나는이 목적을 위해 커널 모듈을 작성하는 것이보다 전략적인 해결책이라는 것에 동의한다. 또한 장치가 커널에 의해 알려지고 해당 메모리 공간 영역이 엔드 포인트 장치에만 사용될 때 특별히 mmap 사용법과 비교할 때 어려움이 있습니다. –

+0

당신이 의도 한대로 혼란스러워합니다. mmap 호출을 중개하는 장치 드라이버가있는 경우 (일부 빠른 스키밍에서이 책이 권장하는 것처럼 보임) 합리적 일 수 있습니다 (예 : 모든 Nvidia 그래픽 카드는 바운스 버퍼를 피하기 위해). 나를 신경 쓰게하는 부분은 장치의 전체 MMIO 영역을 매핑하는 것입니다 (아마도 사용자 공간에 장치의 완전한 제어권을 부여하고 사용자 - 커널 분리의 전체 지점을 파괴합니다). – ruthafjord