Pylone Blog - タグ:powerpc

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 で、内容は以下の様になっています。

アドレスセクタ番号内容
FC0000000Protected
FC0400001File system
FFC40000241Linux カーネル
FFEC0000251Device tree
FFF00000252U-Boot
FFF40000253U-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

とします。