トップ 一覧 Farm 検索 ヘルプ RSS ログイン

Diary/2015-3-3の変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
!Embedded Linux Hands-on Tutorial -- ZedBoard
Linux + Zynqに慣れるべく,2013年と2年前の資料だけど,[Embedded Linux Hands-on Tutorial -- ZedBoard|http://www.digilentinc.com/Data/Documents/Product%20Documentation/ZedBoard_ELHoT.zip] をやってみる.

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をはずす
+ I/O Peripheralsをクリック
+ Zynq PS MIO Configurationsダイアログが開く → EMIO GPIOの幅を60から52に変更 (8 LEDピンの削除)
+ Portsタブを開いてポートの設定
++ processing_system7_0の(IO_IF) GPIO_0を選択
++ ポートをNo Connectionに
++ ポートを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

{{ref myled.c}}を書いて,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
{{ref led_blink.c}}を書く.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.