Pylone Blog - タグ:embedded-linux
SBC6000X エミュレータ
先日発売いたしました、組込みLinux開発用CPUボード SBC6000X を QEMU でサポートしましたので公開します。
ベースにした QEMU のバージョンは 0.15.1 です。
| SBC6000X エミュレータ | |||
| qemu-sbc6000x-0.15.1-pylone1.tar.bz2 ソースコード | 0.15.1-pylone1 | ダウンロード | 4.6MB |
概要
ARM926 は本家 QEMU でサポートされているため、同コア の SoC を搭載したプラットフォームがいくつかサポートされています。 しかし、同コアを使用した SBC6000X のマイクロプロセッサである AT91SAM9261 は今のところサポートされていません。
そこで、Linux の起動に必要となる周辺デバイスのエミュレーションを追加しました。
現状
SBC6000X 用 Linux が起動できる必要最小限のエミュレーションを目標にしたため、実機を完全にエミュレート出来るまでに至っていません。
クイックスタート
ホスト OS として Debian GNU/Linux Squeeze を例に説明します。
SBC6000X 用の Buildroot を用いたビルド にて環境一式が整っていることを前提とします (以降、SBC6000X 用 Buildroot のディレクトリを ~/buildroot-sbc6000x とします)。
現時点では、NAND デバイスをまだエミュレートできないため、ここでは、rootfs に NFS を使用します。 以下の設定を追加し、反映します (以降、NFS として export するディレクトリを /opt/sbc6000x とします)。
# vi /etc/exports /opt/sbc6000x 127.0.0.1(rw,sync,subtree_check,no_root_squash,insecure) # exportfs -a
次に、QEMU をビルドするためのライブラリ (開発版パッケージ) をインストールします。 既にインストール済みの場合は不要です。
# apt-get install libglib2.0-dev # apt-get install zlib1g-dev # apt-get install libsdl1.2-dev
最後に、ビルドして実行するまでの手順です。
$ mkdir ~/qemu-sbc6000x $ cd ~/qemu-sbc6000x $ wget http://downloads.pylone.jp/sbc6000x/src/qemu-sbc6000x-0.15.1-pylone1.tar.bz2 $ tar xjf qemu-sbc6000x-0.15.1-pylone1.tar.bz2 $ cd qemu-sbc6000x-0.15.1-pylone1 $ ./configure --target-list=arm-softmmu $ make $ ./arm-softmmu/qemu-system-arm \ -M sbc6000x \ -m 256 \ -serial stdio \ -kernel ~/buildroot-sbc6000x/output/images/uImage \ -append "console=ttyS0 root=/dev/nfs rw nfsroot=10.0.2.2:/opt/sbc6000x ip=dhcp"
起動後にログイン可能なユーザーは "root"、または "default" (一般ユーザ) です (何れもパスワードはありません)。
終了するには、QEMU ウィンドウを閉じるか、起動した端末上で Ctrl-C を発行して QEMU を終了してください。
その他の詳しい使い方については SBC6000X エミュレータマニュアル を参照してください。
既知の問題点
起動中、まれに、
mmc0: host doesn't support card's voltages mmc0: error -22 whilst initialising SDIO card mmc0: host doesn't support card's voltages mmc0: error -22 whilst initialising MMC card mmc0: host doesn't support card's voltages mmc0: error -22 whilst initialising SDIO card mmc0: host doesn't support card's voltages mmc0: error -22 whilst initialising MMC card
というタイミングで起動が停止してしまいますが、終了して再起動してみてください。
おわりに
QEMU に対して追加実装した部分の完成度はまだ低いですが、Linux の基本的な動作は確認できると思います。 SBC6000X のソフトウェアの検討や、組み込み Linux 開発の入門を目的とした使い方をしていただければ幸いです。
ドキュメント
クロス開発環境のRPMパッケージ (gcc-4.4)
クロス開発環境のDebianパッケージ (gcc-4.4) を alien で変換したRPMパッケージを 公開します。
概要
クロス開発環境のDebianパッケージ (gcc-4.4) を参照してください。
対応状況
クロス開発環境のDebianパッケージ (gcc-4.4) を参照してください。
yumによるインストール (Fedora)
以下の内容で/etc/yum.repos.d/pylone-jp.repoを作成して、yumレポジトリを追加します。
[cross-toolchain] name=Cross Toolchain baseurl=http://downloads.pylone.jp/cross-toolchain/squeeze/rpm/ enabled=1 gpgcheck=0
必要なツールをインストールします。 TARGET-SUFFIX は arm-linux-gnueabi、mipsel-linux-gnu、sh4-linux-gnu、powerpc-linux-gnu の何れかに置き換えてください。
gcc-4.4
# yum install gcc-4.4-TARGET-SUFFIX-linux-gnu
g++-4.4
# yum install g++-4.4-TARGET-SUFFIX-linux-gnu
gdb
# yum install gdb-TARGET-SUFFIX-linux-gnu
依存関係について
alienによる変換ではパッケージ間の依存関係が一部われますが、本パッケージではspecファイルを修正して依存関係を追加しています。
更新履歴
- 2010/11/22: 公開
クロス開発環境のDebianパッケージ (gcc-4.4)
社内で使っているクロス開発環境の Debian パッケージを公開します。
更新履歴
- 2010/11/16: 公開
- 2010/12/17: powerpcspeを追加
概要
- ホストアーキテクチャ: i386
- ターゲットアーキテクチャ: armel, mipsel, powerpc, sh4, powerpcspeNew!
- コンパイラ: gcc-4.4, g++-4.4
- ターゲットのlibc: testing (squeeze) の eglibc
- biarch: 無効
基本的には (2010/11/11時点の) squeeze の binutils と gcc-4.4 を debian/README.cross 等の手順にそってビルドしたものですが、 依存するパッケージを調整するなどして、lenny にもインストールできるようにしてあります。
powerpcspe だけは sid/squeeze でないとインストールできません。
対応状況
| gcc-4.4 | g++-4.4 | |
|---|---|---|
| armel | △ | △ |
| mipsel | △ | △ |
| powerpc | ○ | △ |
| powerpcspeNew! | ○ | △ |
| sh4 | ○ | △ |
- ○:動作を確認済み
- △:パッケージはあるが、まだ動作が確認できていないもの
インストール
sources.list (5) に以下の apt line を加えます。
deb http://downloads.pylone.jp/cross-toolchain/squeeze/deb ./
(まだ行っていなければ) pylone.jp の鍵を導入します。
# wget http://pylone.jp/pubkey.asc -O - | apt-key add -
パッケージ情報を更新します。
# apt-get update
必要なツールをインストールします。TARGET-SUFFIX は arm-linux-gnueabi, mipsel-linux-gnu, sh4-linux-gnu, powerpc-linux-gnu, powerpc-linux-gnuspe の何れかに置き換えてください。
gcc-4.4
# apt-get install gcc-4.4-TARGET-SUFFIX
g++-4.4
# apt-get install g++-4.4-TARGET-SUFFIX
gdb
# apt-get install gdb-TARGET-SUFFIX
リンク
PowerPCボードADS512101へのLinuxカーネルの移植
Freescale社製PowerPCボードADS512101へLinuxカーネルを移植する手順を紹介します。
Freescale社ではADS512101用のLinuxBSPを公開しており、ソースコードから環境を構築することが可能ですが、Linuxカーネルのバージョンが2.6.24と若干古いため、比較的新しいバージョンを移植することが目的です。
予め
- PowerPC向けクロス開発ツール
- tftpサーバ
をインストールした環境を前提とします。
尚、使用するU-Boot、及びLinuxカーネルのバージョンは以下のとおりです。
- U-Boot 2009.1
- Linuxカーネル 2.6.28
U-Bootのビルド
オフィシャルサイトからソースコードを取得し、展開します。
% wget ftp://ftp.denx.de/pub/u-boot/u-boot-2009.01.tar.bz2 % tar xjfv u-boot-2009.01.tar.bz2
ターゲットにADS5121を指定してビルドします。
% cd u-boot-2009.01 % make ads5121_config % CROSS_COMPILE=powerpc-linux-gnu- make
Linuxカーネルのビルド
オフィシャルサイトからソースコードを取得し、展開します。
% wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.28.tar.bz2 % tar xjfv linux-2.6.28.tar.bz2
ADS5121ボード用(v2.6.28向け)のパイロン製パッチを取得・適用します
% wget http://code.pylone.jp/hg/linux-2.6-ads5121-mq/raw-file/tip/ads5121 % cd linux-2.6.28 % patch -p1 < ../ads5121
カーネル設定ファイルを設置後、必要に応じて設定を変更しビルドします(デフォルトでU-Boot形式が生成されます)。
% cp arch/powerpc/configs/ads5121_defconfig .config % ARCH=powerpc CROSS_COMPILE=powerpc-linux-gnu- make menuconfig % ARCH=powerpc CROSS_COMPILE=powerpc-linux-gnu- make
デバイスツリーのビルド
デバイスツリーとは簡単に説明すると、
- PowerPC/Linux固有の仕組みで、ボード依存のデバイス情報(I/Oアドレス等)を定義したもの
- デバイスツリーを定義したソースファイル(*.dts)をコンパイラ(dtc)にてコンパイルしバイナリファイル(*.dtb)を得る
- *.dtbファイルはLinuxカーネルイメージとは別にメモリ上に置かれ、Linuxカーネルはその内容からボードに関する各デバイス情報を把握する
といったものです。
デバイスツリーコンパイラはLinuxカーネルに含まれているため、以下の様にしてADS5121向けデバイスツリーソースをコンパイルします。
% cd (Linuxカーネルのディレクトリ)/arch/powerpc/boot % ./dtc -O dtb -o ads5121.dtb dts/mpc5121ads.dts
Flash更新
tftpに備えて、これまで生成したバイナリファイルを、tftpサーバのディレクトリ(/srv/tftp/とします)にコピーしておきます。
# cp (U-Bootのディレクトリ)/u-boot.bin /srv/tftp/ # cp (Linuxカーネルのディレクトリ)/arch/powerpc/boot/uImage /srv/tftp/ # cp (Linuxカーネルのディレクトリ)/arch/powerpc/boot/ads5121.dtb /srv/tftp/
シリアルコンソールとしてシリアルクロスケーブルをHostPCとボードを接続します。通信設定は以下のとおりです。
| ボーレート | 115200 |
|---|---|
| ビット長 | 8 |
| フロー制御 | なし |
| ストップビット | 1 |
ボードの電源を投入後、SW1を押下しボード標準のU-Bootを起動します。このとき、
Hit any key to stop autoboot:
のカウントダウンが開始されたらキャンセルします。
tftpに備え、必要に応じて環境変数を設定します。 (ここでは、tftpサーバとなるHostPCのIPアドレスを192.168.0.26、ボードのIPアドレスを192.168.0.120とします)
=> setenv netmask=255.255.255.0 => setenv ipaddr=192.168.0.120 => setenv serverip=192.168.0.26
先ほどビルドしたU-BootをFlashに書き込みます。FlashのI/O開始アドレスは 0xFC000000 で、内容は以下の様になっています。
| アドレス | セクタ番号 | 内容 |
|---|---|---|
| FC000000 | 0 | Protected |
| FC040000 | 1 | File system |
| FFC40000 | 241 | Linux カーネル |
| FFEC0000 | 251 | Device tree |
| FFF00000 | 252 | U-Boot |
| FFF40000 | 253 | U-Boot 環境変数 |
まず、更新するU-BootをRAM上のダウンロード領域(0x20000000)へダウンロードします。
=> tftp 2000000 u-boot.bin
Using FEC ETHERNET device
TFTP from server 192.168.0.26; our IP address is 192.168.0.120
Filename 'u-boot.bin'.
Load address: 0x2000000
Loading: ################################################
done
Bytes transferred = 241680 (3b010 hex)
そして、Flashのライトプロテクトを解除、該当のセクタを消去し、書き込みます。
=> protect off bank 1 => erase 1:252-252 => cp.b 2000000 fff00000 3b010
上記cpコマンドのサイズ(0x3b010)はtftpコマンドで実際に転送されたサイズを指定しています
Linuxカーネルを更新する場合も同様の手順になります。
=> tftp 2000000 uImage => protect off bank 1 => erase 1:241-250 => cp.b 2000000 FFC40000 <size>
FlashのライトプロテクトはU-Boot更新時に解除していますので続けて更新する場合は不要です。
デバイスファイルも同様の手順です。
=> tftp 2000000 mpc5121ads.dtb => protect off bank 1 => erase 1:251-251 => cp.b 2000000 FFEC0000 <size>
起動
ボード標準のU-Boot起動コマンドでFlash上のrootfsから起動するには以下の様にします。
=> run jffs2boot
カーネルコマンドラインを指定して起動する場合は以下の様にします
=> set bootargs console=ttyPSC0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2 mem=256M => bootm ffc40000 - ffec0000
bootmコマンドの引数はそれぞれ、
- ffc40000 : カーネルのアドレス
- - : initial ramdiskのアドレス(未使用なので省略を示す'-')
- ffec0000 : デバイスツリーのアドレス
と言う意味になります。
Flashを更新せずにRAMから起動する場合
デバッグ段階などで、Linuxカーネルやデバイスツリーを頻繁に更新するようなケースで、毎回Flashに書き込みをしていては非効率です。そこで両ファイルをFlashに書き込まずにRAMから起動する場合は以下の様にします。
=> tftp 2000000 uImage => tftp 3000000 ads5121.dtb => set bootargs console=ttyPSC0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2 mem=256M => bootm 2000000 - 3000000
または、Flash上のデバイスツリーファイルを使用する場合は、最後のbootmコマンドのデバイスツリーファイルのアドレスを、
=> bootm 2000000 - ffec0000
とします。
jffs2イメージをloopback mount
block2mtdドライバを使えば、jffs2イメージファイルをloopbackでmountできます。
erasesize 128K (131072) のrootfs.jffs2を/mntにmountする場合
mount:
# modprobe jffs2 # modprobe mtdblock # losetup /dev/loop0 rootfs.jffs2 # modprobe block2mtd block2mtd=/dev/loop0,131072 # mount -t jffs2 -o ro /dev/mtdblock0 /mnt
umount:
# umount /mnt # rmmod block2mtd # losetup -d /dev/loop0
![[広告] 組込みLinux開発用CPUボード SBC6000X](/i/sbc6000x-ad.jpg)