[Linux] SRAM を使う

メモリマップドI/O の SRAM は misc/sram ドライバを使って読み書きすることができます。ここでは kernel module から genpool API で扱う場合と、userland から sysfs で扱う場合を見てみます。

devicetree 定義

devicetree における SRAM は以下のように定義します。

sram@20000000 {
        compatible = "mmio-sram";
        reg = <0x20000000 0x40000>;
        #address-cells = <1>;
        #size-cells = <1>;
        ranges = <0 0x20000000 0x40000>;
        sram-base@0 {
                reg = <0 0x10000>;
        };
        sramdev: sram-dev@10000 {
                reg = <0x10000 0x10000>;
                pool;
        };
        sram-export@20000 {
                reg = <0x20000 0x20000>;
                export;
        };
};

"mmio-sram" で misc/sram ドライバで扱うようになります。ranges は <子ノードの先頭 親ノードの先頭 子ノードのサイズ> を表します。0x20000000...0x2003ffff に対して、子ノードは 0 から記載することで親ノードのアドレスに変換されます。

sram-base は領域の予約だけするため、API で扱う手段はありません。

genpool で SRAM を扱う

sram-dev は "pool" で宣言されていて、genpool API で扱うことができます。使用側の devicetree で例えば以下の宣言を行うと、of_gen_pool_get() で この領域を参照することができます。

hoge,sram = <&sramdev>;

取得した領域は gen_pool_dma_alloc() などで割り当ててメモリを取得します。

struct gen_pool *pool;
void *vaddr;
dma_addr_t dma_addr;

pool = of_gen_pool_get(np, "hoge,sram", 0);
vaddr = gen_pool_dma_alloc(pool, size, &dma_addr);

なお、SRAM 全体のうち子ノードで宣言されていない領域も genpool で取得することができます。特定の用途に制限するようなことがない場合は、敢えて "pool" で宣言しなくても、全体(sram@20000000) を of_gen_pool_get() で参照することで空きメモリを取得することができます。

sysfs で SRAM を扱う

sram-export は userland で扱うことができるようになります。sysfs に以下のようなファイルが現れます。

# ls -l /sys/device/platform/sram@20000000/20020000.sram
-rw-------  root root  131072  20020000.sram

このファイルは直接読み書きできるので、open(), lseek(),write(),read(),close() を使ってアクセスすることで SRAM にアクセスができます。


コメント

タイトルとURLをコピーしました