メモリマップド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 にアクセスができます。
コメント