トップ 差分 一覧 Farm ソース 検索 ヘルプ PDF RSS ログイン

Diary/2015-3-3

Embedded Linux Hands-on Tutorial -- ZedBoard

Linux + Zynqに慣れるべく,2013年と2年前の資料だけど,Embedded Linux Hands-on Tutorial -- ZedBoard をやってみる.

ISEは14.4.
14.7でやろうとしたら,PSのIPコアのバージョンがあがっているためか,そのままではBitStreamが生成できなかった.
OSはCentOS 6.2を用意.
今日びCnetOS 6.2のリポジトリはそうそうないので,

baseurl=http://vault.centos.org/6.2/os/$basearch/

とかを使う.(cf. http://d.hatena.ne.jp/tmatsuu/20120324/1332578375)
x86_64版でインストールするけど,CodeSaurcyの都合で32bit実行/開発環境も必要.

sudo yum install compat-libstdc++-33-3.2.3-69.el6.i686
sudo yum install glibc-devel.i686 glibc-devel

とかした上でISEをインストールする必要があるので注意.

準備

設計イメージのダウンロードと展開
wget http://www.digilentinc.com/Data/Products/ZEDBOARD/ZedBoard_Linux_Design.zip
unzip ZedBoard_Linux_Design.zip

XPSで開く
source /opt/Xilinx/14.4/ISE_DS/settings64.sh
xps ZedBoard_Linux_Design/hw/xps_proj/system.xmp &

HWの変更と合成

PSのGPIOコアからLEDをはずす
  1. I/O Peripheralsをクリック
  2. Zynq PS MIO Configurationsダイアログが開く → EMIO GPIOの幅を60から52に変更 (8 LEDピンの削除)
  3. Portsタブを開いてポートの設定
    1. processing_system7_0の(IO_IF) GPIO_0を選択
    2. ポートをNo Connectionに
    3. ポートをExternal Portsに.名前のprefixの_pinを削除(既存のUCFとできるだけあわせるため)

Create and Import Peripheral Wizardでmyledを作る
  • コア名はmyled.
  • AXI4-Lite
  • software resetとinclude data phase timerはオフ
  • レジスタの数は1つ
  • user_logicは(私の場合)VHDLのままでいい

myledの追加と編集
  • add IP.パラメタはデフォルトのまま
  • ソースコードを修正.Browse HDL Sources...でHDLコードに,View MPDでmpdファイルに簡単にアクセスできる
    • user_logic.vhdの修正
101  LED : out std_logic_vector(7 downto 0);
148  LED <= slv_reg0(7 downto 0);
    • myled.vhdの修正
141  LED : out std_logic_vector(7 downto 0);
306  LED => LED,
    • myled_v2_1_0.mpdの修正
40 PORT LED = "", DIR = O, VEC = [7:0]
  • Project -> Rescan User RepositriesでIPコアをリスキャン
  • Portsタブでmyled_0を開くと追加したLEDな出力ポートができているので外部出力ピンに
  • UCFでピン割り当てを変更
    • ProjectタブのUCF File: data/system.ucf からアクセスできる
    • 80行目付近からのOn-board LED'sのprocessing_system7_0_GPIO<>をmyled_0_LED_pin<>に変更.
    • 以降のペリフェラルに対するprocessing_sytem7_0_GPIO<>のインデックスを8減らす

Bitファイルの生成
  • Hardware->Genearete Bitstream

U-BOOT作る

U-Bootのコンパイルの準備

gitで取得するかBranchのアーカイブかを利用する.

git clone https://github.com/Digilent/u-boot-digilent

ドキュメントに沿ったバージョンのものをダウンロードしてみた.

wget https://github.com/Digilent/u-boot-digilent/archive/v2012.04-digilent-13.01.zip

展開して,もぐる

unzip v2012.04-digilent-13.01.zip
cd u-boot-digilent-2012.04-digilent-13.01

U-Bootのコンパイルのための設定
  • IPアドレスの設定.include/configs/zynq_zed.h を編集.

/* Default environment */
#define CONFIG_IPADDR 10.0.0.1
#define CONFIG_SERVERIP 10.0.0.3

ビルド

次のようにしてビルド.

make CROSS_COMPILE=arm-xilinx-linux-gnueabi- zynq_zed_config
make CROSS_COMPILE=arm-xilinx-linux-gnueabi-

できあがったものをコピー.
cp u-boot ../ZedBoard_Linux_Design/boot_image/u-boot.elf

FSBLを作ってBOOT.BINを作る

BOOT.BINを作る(準備)

(閉じていれば)xpsでxmpを再び開く.

xps ZedBoard_Linux_Design/hw/xps_proj/system.xmp &

Project→Export Hardware Design to SDKでExportしつつSDK起動.
ワークスペースは,

ZedBoard_Linux_Design/hw/xps_proj/SDK/SDK_Export

にある.
File⇒New⇒Project...でXilinxのApplication Projectの作成を開始.
キモは,

Project Name: FSBL
Hardware Plat: xps_proj_hw_platform
OS Platform: standalone

くらいか.Available Templatesでは,Zynq FSBLを選択.

main.cの修正

ZedBoardでは,FSBLで,USB-ResetピンのトグルによってUSB PHYチップをリセットする必要があるらしい.
main.cのFsbHandOff()の呼び出しの前(472行目)に次のコードを追加.

472
473   /* Reset the USB */
474    {
475         fsbl_printf(DEBUG_GENERAL, "Reset USB...\r\n");
476
477         /* Set data dir */
478         *(unsigned int *)0xe000a284 = 0x00000001;
479
480         /* Set OEN */
481         *(unsigned int *)0xe000a288 = 0x00000001;
482         Xil_DCacheFlush();
483         /* For REVB Set data value low for reset, then back high */
484 #ifdef ZED_REV_A
485         *(unsigned int *)0xe000a048 = 0x00000001;
486         Xil_DCacheFlush();
487         *(unsigned int *)0xe000a048 = 0x00000000;
488         Xil_DCacheFlush();
489 #else
490         *(unsigned int *)0xe000a048 = 0x00000000;
491         Xil_DCacheFlush();
492         *(unsigned int *)0xe000a048 = 0x00000001;
493         Xil_DCacheFlush();
494 #endif
495    }

デフォルトで自動Buildだけど,念の為にCleanしてBuild.

BOOT.BINを作る

Xilinx Tools⇒Create Zynq Boot Imageでツールを起動.
FSLB elfには,

ZedBoard_Linux_Design/hw/xps_proj/SDK/SDK_Export/FSBL/Debug/FSBL.elf

を選択.
List of partitions int the boot imageは,FSBL.elf,system.bit,u-boot.elf の順.

ZedBoard_Linux_Design/hw/xps_proj/SDK/SDK_Export/FSBL/Debug/FSBL.elf
ZedBoard_Linux_Design/hw/xps_proj/SDK/SDK_Export/xps_proj_hw_platform/system.bit
ZedBoard_Linux_Design/boot_image/u-boot.elf

出力先のフォルダは,

ZedBoard_Linux_Design/boot_image/

にする.
できあがったu-boot.binをBOOT.BINにリネーム.

Linuxカーネルのコンパイル

Linuxカーネルのコンパイルの準備

gitのメインブランチかタグを切られたものを持ってくる.
u-bootのときと同じように,v3.6-digilent-13.01とタグを切られたものを持ってくることにする.
https://github.com/Digilent/linux-digilent/archive/v3.6-digilent-13.01.zip
wgetで取得したら拡張子がつかなかったので末尾に.zipをつけて,unzipで展開してもぐる.

コンフィグ

まずはデフォルトコンフィギュレーション

make ARCH=arm CROSS_COMPILE=arm-xilinx-linux-gnueabi- digilent_zed_defconfig

で,menuconfig

make ARCH=arm CROSS_COMPILE=arm-xilinx-linux-gnueabi- menuconfig

ちなみに,ncurses-develがなかったのでyumでインストール...
ドキュメントではPmodOLED1をビルトイン・ドライバからローダブルモジュールに変更している
具体的には Device Driver→PMOD Support と辿って,PmodOLED1の'*'を'M'に変更.

ビルド

Exitをつづけて終了したらビルド

make ARCH=arm CROSS_COMPILE=arm-xilinx-linux-gnueabi-

ビルドが終わったらarch/arm/boot/zImageができている

デバイスツリーを作る

カーネルソースの下で,

./scripts/dtc/dtc -I dts -O dtb -o ../devicetree.dtb arch/arm/boot/dts/digilent-zed.dts

を実行

SDカードにセットアップ

SDカードを用意

先頭1GBをvfat,残りをext4にする.

  • fdiskでパーティション作る
  • vfatとext4で,それぞれフォーマット.たとえば,
suudo mkfs -t vfat -n ZED_BOOT /dev/sdb1
sudo mkfs -t ext4 -L ROOT_FS /dev/sdb2

ルートファイルシステムの用意
  • Linaroをダウンロード.
wget http://releases.linaro.org/12.09/ubuntu/precise-images/ubuntu-desktop/linaro-precise-ubuntu-desktop-20120923-436.tar.gz
  • 展開
mkdir -p /tmp/linaro
sudo cp linaro-precise-ubuntu-desktop-20120923-436.tar.gz /tmp/linaro
cd /tmp/linaro
sudo tar zxf fs.tar.gz
  • ext4領域をマウント
mkdir -p /tmp/sd_ext4
sudo mount /dev/sdb2 /tmp/sd_ext4
  • 展開した一式をコピー.ドキュメントではrsync使ってる
cd binary/boot/filesystem.dir/
sudo rsync -a ./ /tmp/sd_ext4
sudo sync; sudo sync; sudo sync; # 念のため
  • unmountして取り出す
sudo umount /tmp/sd_ext4

BOOT.BIN,dtc,zImageをコピー

vfat領域に

  • BOOT.BIN
  • devicetree.dtb
  • zImage

をコピーする.

ZedBoardで起動してみる

HDMIケーブルつなぐとGUIがあがってくるのがわかる.

apt-get install openssh-server

とかするとsshdがインストールできる.
sshでログインできるようにrootのパスワードを適当に設定.

myled用のドライバを作る


準備

カーネルソースにアクセスしやすいようにシンボリックリンクを用意

ln -s linux-digilent-3.6-digilent-13.01 linux-digilent

作業用のディレクトリを用意して移動

mkdir drivers
cd drivers

必要なファイルを書いてmake

Makefileを書く

obj-m := myled.o

all:
make -C ../linux-digilent/ M=$(PWD) modules

clean:
make -C ../linux-digilent/ M=$(PWD) clean

myled.c(329)を書いて,make.

make ARCH=arm CROSS_COMPILE=arm-xilinx-linux-gnueabi- 

デバイスツリーを更新

myledのアドレスをxpsで確認.今回は0x7e400000-0x7e40ffffの64KBの空間だった.
サンプルをコピー

cp ../linux-digilent/arch/arm/boot/dts/digilent-zed.dts .

一番最後にエントリを追加.

               myled {
                       compatible = "dglnt,myled-1.00.a";
                       reg = <0x7e400000 0x10000>;
               };

編集したらデバイスツリーを作りなおす

../linux-digilent/scripts/dtc/dtc -I dts -O dtb -o devicetree.dtb digilent-zed.dts

システムに反映

scpでmyled.koとdevicetree.dtbをコピー.
ブートパーティションはマウントされてないので,マウントしてコピー

mount /dev/mmcblk0p1 /mnt/
cp /root/devicetree.dtb /mnt/

で,リブート.
再起動したら,/proc/myledができている.

insmod myled.ko
echo 0x0F > /proc/myled
echo 0xF0 > /proc/myled

とかして楽しむ

ユーザアプリを書く

作業用ディレクトリをつくって,もぐる

mkdir user_app
cd user_app

led_blink.c(334)を書く.Makefileも用意.ドキュメントのMakefileは何か変な感じだったので注意.

また,クロスコンパイル環境とターゲットでライブラリがちぐはぐなので-staticが必要だった.

CC = arm-xilinx-linux-gnueabi-gcc
CFLAGS = -g -static

all : led_blink

led_blink : led_blink.c
	${CC} ${CFLAGS} -o $@ $^
clean :
	rm -rfv *.o
	rm -rfv led_blink

.PHONY : clean

Linaroの場合,ホストコンパイラもあるので,ソースをコンパイルしてもOK.