[Linux] 物理 RAM 上の固定領域に ramdisk を作る

Linux で ramdisk を作る方法はいくつかあります。root filesystem であれば initramfs、それ以外なら tmpfs を使ったり、BLK_DEV_RAM を有効にすれば /dev/ramN に ramdisk が現れるので使うことができます。ここでは、物理メモリ上の固定領域に ramdisk を作成してみることを考えます。

通常、必要なバイナリがあれば initramfs にインストールしておけば用は済みますし、後から USB や SD をマウントして使うこともできます。物理領域に依らないテンポラリデバイスとして ramdisk を使うのであれば、tmpfs や /dev/ramN が使えます。そのため、物理メモリ上の固定領域を使うのはかなり特殊な状況が考えられますが、手段として持っておくに越したことはありません。

kernel への準備

正確には ramdisk ではなく、RAM 上に MTD (Memory Technology Device) を作成します。

物理メモリをMTDとして扱うには slramphram があります。slram は kernel が使用するメモリを uncacheable に再定義して利用するため、kernel 管理メモリに限られます。phram は kernel が map しないメモリ領域ならどこでも利用でき、reserved-memory にて kernel 管理メモリも再定義して利用できます。本稿では phram を扱います。

phram を扱うには以下の defconfig を有効にして kernel をビルドします。

CONFIG_MTD=y
CONFIG_MTD_PHRAM=y

物理メモリ上に Linux で扱わない領域を devicetree にて定義します。kernel で map しないように no-map を付与します。

reserved-memory {
        #address-cells = <2>;
        #size-cells = <2>;
        ranges;
        memory@e0000000 {
                reg = <0 0xe0000000 0 0x00100000>;
                no-map;
        };
};

固定領域に置くファイルシステムイメージを作成

予め固定領域にフォーマット済のファイルシステムイメージを置いておけば、そのまま kernel 起動後にマウントすることができるようになります。ここでは例として ext4 イメージを作成して u-boot でロードしておくことを考えます。

$ dd if=/dev/zero of=temp.ext4 bs=1k count=1k
$ mkfs.ext4 temp.ext4
$ sudo mount -o loop temp.ext4 /mnt
$ sudo touch /mnt/hoge
$ sudo umount /mnt
$ cp temp.ext4 /tftpboot/

kernel 起動

U-Boot にて ext4 イメージを固定領域に置き、command line にて phram に固定領域を指定して kernel を起動します。

=> tftpboot 0xe0000000 temp.ext4
=> setenv bootargs $bootargs phram.phram=fs0,0xe0000000,0x100000

reserved-memory が正しく設定されていれば、kernel 起動時にメッセージが表示されます。

OF: reserved mem: 0x00000000e0000000..0x00000000e00fffff (1024 KiB) nomap non-reusable memory@e0000000

phram が正しく有効になっていれば、同様にメッセージが表示されます。

phram: fs0 device: 0x100000 at 0xe0000000 for erasesize 0x1000

/dev/mtdblock0 が作成されています。

# ls -al /dev/mtdblock0
brw-rw----    1 root    disk     31,   0 Jan  1  1970 /dev/mtdblock0
# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00100000 00001000 "fs0"

これをマウントすれば、先に作成した ext4 としてアクセスできるようになります。

# mount /dev/mtdblock0 /mnt
# ls /mnt
hoge

もちろん、U-Boot で予め rootfs イメージを固定位置に読み込んで command line には "root=/dev/mtdblock0" も追加しておけば、rootfs として kernel 起動時に扱うこともできます。

動的にMTD作成

phram は kernel 起動後も MTD を作成することができます。sysfs に command line と同様のパラメータを与えることで、その場で MTD が作成されます。

# echo "fs1,0xe0000000,0x1000" > /sys/modules/phram/parameters/phram
phram: fs1 device: 0x1000 at 0xe0000000 for erasesize 0x1000

kernel が map しないメモリ領域であればどこでも指定できるので、重複やアクセス可否の注意が必要です。


コメント

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