So-net無料ブログ作成

ZedBoard Linux (2) [FPGA]

とりあえず標準状態にはなったので、いじるのに関係しそうな所を眺めてみます。

ramdiskのイメージの中身を変更する方法。ramdisk8M.image.gzを解凍し、作業用の./mntフォルダにマウントさせます。変更後、アンマウントして再圧縮します。
$ gunzip ramdisk8M.image.gz
$ sudo mount -o loop ramdisk8M.image mnt
$ cd mnt
mntの中身を変更
$ sudo umount mnt
$ gzip ramdisk8M.image
IPアドレスの変更は./etc/init.d/rcS、マウントの設定は./etc/fstab、など、この辺はLinux通りですかね。
それほど頻繁に行うわけでは無いですが、ROM化するまでrootfsをNFSにした方が便利そうです。

u-bootの設定。「~/u-boot-digilent/include/configs」下の「zynq_zed.h」に色々設定が見られます。30行目付近を抜粋。
#define CONFIG_ZED /* Community Board */

/* Default environment */
#define CONFIG_IPADDR   192.168.1.10
#define CONFIG_SERVERIP 192.168.1.50

#undef CONFIG_ZYNQ_XIL_LQSPI

/* No NOR Flash available on ZedBoard */
#define CONFIG_SYS_NO_FLASH
#define CONFIG_ENV_IS_NOWHERE

#undef CONFIG_EXTRA_ENV_SETTINGS
#define CONFIG_EXTRA_ENV_SETTINGS 	\
	"ethaddr=00:0a:35:00:01:22\0"	\
	"kernel_size=0x140000\0" 	\
	"ramdisk_size=0x200000\0" 	\
	"qspiboot=sf probe 0 0 0;" \
		"sf read 0x8000 0x100000 0x2c0000;" \
		"sf read 0x1000000 0x3c0000 0x40000;" \
		"sf read 0x800000 0x400000 0x800000;" \
		"go 0x8000\0" \
	"sdboot_linaro=echo Copying Linux from SD to RAM...;" \
		"mmcinfo;" \
		"fatload mmc 0 0x8000 zImage;" \
		"fatload mmc 0 0x1000000 devicetree_linaro.dtb;" \
		"go 0x8000\0" \
	"sdboot=echo Copying Linux from SD to RAM...;" \
		"mmcinfo;" \
		"fatload mmc 0 0x8000 zImage;" \
		"fatload mmc 0 0x1000000 devicetree.dtb;" \
		"fatload mmc 0 0x800000 ramdisk8M.image.gz;" \
		"go 0x8000\0" \
	"jtagboot=echo TFTPing Linux to RAM...;" \
		"tftp 0x8000 zImage;" \
		"tftp 0x1000000 devicetree.dtb;" \
		"tftp 0x800000 ramdisk8M.image.gz;" \
		"go 0x8000\0"
イメージをコピーしてカーネルにジャンプする部分です。IPアドレスとかサーバーのアドレスもここら辺で変えられるようです。
・0x0000_8000:zImage
・0x0100_0000 :devicetree.dtb
・0x0080_0000: ramdisk8M.image.gz
にロードしてるのがわかります。「sdboot」とかがマクロのように定義され、u-bootのコマンドラインから「run sdboot」とすると定義した処理が行われます(手でひとつずつ打っても同じです)。
u-bootが立ち上がり、なにもせず数秒経つと自動的に上のマクロのどれかが実行されます。どれを実行するかを選択しているのは「modeboot」変数で、「\u-boot-digilent\board\xilinx\zynq_common\board.c」で設定されているようです。80行目付近。
int board_late_init (void)
{
	u32 boot_mode;

	boot_mode = (XIo_In32(BOOT_MODE_REG) & BOOT_MODES_MASK);
	switch(boot_mode) {
	case QSPI_MODE:
		setenv("modeboot", "run qspiboot");
		break;
	case NAND_FLASH_MODE:
		setenv("modeboot", "run nandboot");
		break;
	case NOR_FLASH_MODE:
		setenv("modeboot", "run norboot");
		break;
	case SD_MODE:
		setenv("modeboot", "run sdboot");
		break;
	case JTAG_MODE:
		setenv("modeboot", "run jtagboot");
		break;
	default:
		setenv("modeboot", "");
		break;
	}

	return 0;
}
ブートモードジャンパーの値で切り替えてます。通常LinuxはSDからブートしているので、「sdboot」が選ばれるという仕組みです。
これらの設定は「~/u-boot-digilent/include/autoconf.mk」に集められます。このファイルはmake時に自動生成されます。どんな設定がどんな名前で定義されてるのか、このファイルとREADMEから追いかけるようにしています。

一方、devicetree.dts。標準のdtsの48行目付近。
chosen {
	/*bootargs = "console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait devtmpfs.mount=1";*/
	bootargs = "console=ttyPS0,115200 root=/dev/ram rw initrd=0x800000,8M earlyprintk rootwait devtmpfs.mount=1";
	linux,stdout-path = "/axi@0/serial@e0001000";
};
ここでLinuxカーネルのブート引数を設定してます。シリアルポートの設定や、先にコピーしたramdiskのアドレスなども与えています。コメントアウトされてる設定はSDカードをパーティション分けして、rootにマウントさせてます。この方法は大容量のファイルシステムが使えますし、設定を保存しておくこともできます。けど、いきなりバンと電源を切ってしまうようなシステムだとちょっと怖いです。

SDからu-bootをブートして、nfsかtftpでzImageとdevicetree.dtbをダウンロードして、rootファイルシステムをnfsサーバーに置く、などはこの辺を設定すれば良さそうです。
※標準のカーネルだとnfsが無効になってるようなので、再コンパイルは必要。

……「devicetree.dtbは0x0100_0000にあるぞ」はどこでカーネルに教えてるんでしょう?カーネルは知る必要ない?いやいや、そんなことは…というかdevicetreeの仕組み自体よくわかってないので、もっと勉強が必要ですね。
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

Facebook コメント

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。

×

この広告は1年以上新しい記事の更新がないブログに表示されております。