3

最初に、私が取り組んでいるマシンについて少し説明します (これは、FPGA と 2 つの CPU を含む SoC を備えた SOM であり、そのうちの 1 つで Linux OS が実行されています)。

特徴:

  • ボード : Microzed
  • SoC: Zynq 7020
  • OS : ペタリナックス 2019.2
  • カーネル バージョン: 4.19.0-xilinx-v2019.2
  • プロセッサの種類: ARMv7 プロセッサ rev 0 v7l (armv7l)

BRAM メモリへの標準 AXI4 インターフェイスを提供する FPGA に実装されたカスタム ペリフェラルがあります (このコンポーネントのおかげです)。この周辺機器は私のデバイス ツリーに登録されており、カーネルの汎用 uio ドライバーを介してアクセスできます (これに関する詳細なドキュメント)。

BRAM メモリのサイズは 32kB です。に表示されるマッピング特性は次の/sys/class/uio/uioX/maps/map0/とおりです。

  • アドレス = 0x40000000
  • オフセット = 0x0
  • サイズ = 0x00008000

この BRAM メモリを読み取り、内部の内容をテキスト ファイルに記録するだけの C コードを作成しています。そうするために、mmap(ここにそのマニュアルページ/dev/uioXがあります)を使用して、 (私のデバイスに対応する)にあるファイルのいくつかのメモリプロジェクションを作成します。

必要なファイル ページのみを使用し、ページごとにファイル ページをより正確にマッピングしたい。1 つのページのマッピングを作成するために使用する関数を次に示します。

/**
 * @brief Get a pointer to the corresponding file page
 * 
 * @param filePage file page number
 * @param fd pointer where the file descriptor will be stored
 * @return int* 
 */
int *getFilePagePointer(int *fd, unsigned int filePage)
{
    // open driver file
    *fd = open("/dev/uio1", O_RDWR);
    if (*fd == -1)
    {
        int errsv = errno;
        fprintf(stderr, "Error while opening /dev/uio1 : errno %d (%s).\n", errsv, strerror(errsv));
        exit(EXIT_FAILURE);
    }

    // choose projection parameters
    int length = sysconf(_SC_PAGE_SIZE);
    int offset = filePage * sysconf(_SC_PAGE_SIZE);

    // create mapping
    void *filePagePointer = mmap((void *)NULL, (size_t)length, PROT_READ, MAP_PRIVATE, *fd, (off_t)offset);
    if (filePagePointer == MAP_FAILED)
    {
        int errsv = errno;
        fprintf(stderr, "Error while mapping file page : errno %d (%s).\n", errsv, strerror(errsv));
        exit(EXIT_FAILURE);
    }

    return (int *)filePagePointer;
}

そして問題: filePage(オフセット)0が の場合は完全に機能しますが、厳密に正の場合は で失敗しerrno = 22ます。

マニュアルページで何かを見逃していない限り、すべてのパラメーターは有効です (offsetは の倍数でありsysconf(_SC_PAGE_SIZE)addrisは厳密に正でありNULLlength大きすぎず、フラグは正しいです)。では、なぜ EINVAL なのか?...

4

1 に答える 1