Linuxを実行しているシングルボードコンピューターでlspci -vv -s 00:00
を実行すると、次の出力が得られます。
07:05.0 RAID bus controller: Adaptec AAC-RAID (Rocket) (rev 03)
Subsystem: Adaptec ASR-2230S + ASR-2230SLP PCI-X (Lancer)
Control: I/O- Mem+ BusMaster+ SpecCycle+ MemWINV+ VGASnoop-
ParErr- Stepping- SERR+ FastB2B-
Status: Cap+ 66MHz+ UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- SERR-
Latency: 64 (250ns min, 250ns max), Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 74
Region 0: Memory at f7a00000 (64-bit, non-prefetchable) [size=2M]
Region 2: Memory at f79ff000 (64-bit, non-prefetchable)
[Remaining output truncated]
上記は出力例であり、私が得ているものとは異なりますが、関心のある項目が含まれています。
lspci
コマンドからの出力のほとんどは理解していますが、Regionで始まる行を誰かに説明してもらいたいです...ここで見ているメモリの種類は、リージョンライン?どのようにアクセスすればよいですか?それを聞いて、PCIバスを介して接続された2台のシングルボードコンピューター間の通信を実現しようとしています。直接話すことができるはずです。バスを実行しているPCIアービターがすべてあります。これは私がこれまでに達成したことです...
アウトバウンドPCIトラフィック用のLinuxカーネルモジュールを作成しました。基本的には、ドライバーmmap実装を使用して、ユーザースペースから(ユーザースペースアプリケーションを使用して)完全にマッピングします。 mmapから返された場所に書き込み、実際にバスアナライザーでトラフィックを確認します。もう一方のシングルボードコンピューターで、PCIデバイスのsysfsリソースを読み取ろうとしましたが、すべてのFFのみが表示され、変更は表示されません。
PCIを含む、このすべてのメモリマッピングがどのように発生するかについてのアドバイスや説明をいただければ幸いです。ありがとう!
PCI/PCI-X/PCI-Eデバイスでは、PCI構成スペースにBARレジスタがあります。また、Linuxカーネルの起動中に、PCIバスをスキャンし、PCI-to-PCIブリッジおよびPCIデバイスを含むすべてのPCIデバイスを検出します。また、カーネルは、PCIデバイスの構成スペースにあるBARの数をチェックします。また、BARレジスタに0xFFFFFFFFを書き込んで、各BARに必要なメモリ容量とメモリ空間の種類を確認してください。次に、カーネルはメモリスペースリソースをPCIデバイスに割り当てます。
あなたの場合、RegionlionはBARレジスタを表示しています。
対応する各デバイスドライバーで、pci_resource_start()を呼び出し、pci_iomap()を呼び出して基本物理アドレスをカーネル仮想アドレスにマップするか、remap_pfn_range()を使用して実装することにより、Linuxカーネルが各BARに割り当てる基本物理アドレスを取得できます。物理アドレスをユーザースペースプロセスの仮想アドレスにマップするためのユーザースペースプロセスのmmapメソッド。
デバイス上のレジスタは、IOマップまたはメモリマップのいずれかです。(x86の場合はtrue)リージョンは、これらのレジスタがマップされているカーネル仮想アドレスを示します。この場合、それらはivenカーネル仮想アドレス空間にマップされたメモリです。