ZedBoard Linux (1) [FPGA]
ZedBoardでLinuxを実行するまでのメモ。
まずは変更を加えずに、標準の環境ができるまでにします。
Digilentのホームページから「ZedBoard_ELHoT」「ZedBoard_Linux_Design」の2つを落としておきます。手順書やソースファイルなどが入っています。
ISE14.6を使用(元のドキュメントでは14.4)。VMware+Ubuntu 12.04 LTS。ホストはWindows7。
ARMのGCCなどを個別に集めても構築できるらしいですが、Xilinxのツールを入れてしまいます。
XilinxのDownloadページから「Software Development Kit」をダウンロード。約1.7GB。でかい。
毎回忘れる、カーネルコンフィグメニューに必要なncurses-devをインストール。
以下はログインするたびに実行。デフォルトで設定するようにしてもOK。
XilinxのSDK環境変数設定。
Linuxのソースを取得、構築。
標準のコンフィグは「~/linux-digilent/arch/arm/configs/digilent_zed_defconfig」です。これを「.config」にコピーしても良いです。
u-bootの作成。
「~/u-boot-digilent/include/configs/zynq_zed.h」がZedBoardの設定ファイルです。必要に応じて編集します。
Device Tree Generatorを導入。
SDK上でハードウェアからdtsファイルを作ってくれるツールです。自分でハードウェアをカスタマイズしたときは、このツールでdtsファイルを作ります。
ちなみに、このフォルダをWindowsの「C:\Xilinx\SDK\2013.2\sw\lib\bsp」にコピーすればWindowsのSDKでもDevice Tree Generatorが使えます。
FSBLを作成。SDKを立ち上げます。
標準の「hw_platform」のフォルダをコピーしておきます。ついでに「system.bit」を「hw_platform」の中にコピーします。本来これらはPlanAheadからExportされます。
このフォルダの中の「system.xml」を元にHardware Platform Specificationを作成します。
New → Others → Xilinx → Hardware Platform Specification を選びます。
コピーしたフォルダの「system.xml」を指定します。
Finishで「hw_platform」フォルダができます。
New → Application Projectで新しく「FSBL」というプロジェクトを作ります。テンプレートとしてFSBLを選びます。設定はデフォルトのまま。
自動的にBuildが始まりますが、gmakeを呼んでいてBuildに失敗するので、makeにシンボリックリンクさせます。ホントはどう対処するのが正しいんだろ?
※ZedBoardではUSBのリセットをFSBLで行うようになっています。手順書に書いてありますがここでは割愛。
ブートイメージを作ります。
SDK上で「FSBL」が選択された状態で、Xilinx Tools → Create Zynq Boot Imageを選択します。
「FSBL.elf」と「system.bit」と「u-boot.elf」を選択し、Createします。
デフォルトでは「~/workspace/FSBL/bootimage/u-boot.bin」というファイルができます。
これを「BOOT.BIN」にリネームして、SDカードにコピーします。
※多分このSDKの作業はWindows上でも同じように動作するはずです。
Device Tree Blobを作成します。
「devicetree.dts」が標準のソースファイルです。コンパイル済みの「devicetree.dtb」をそのまま使っても同じです。
自分でカスタマイズしたハードウェア用にdtsを作るときは、先に入れたDevice Tree Generatorを使うようです。New → Board Support Packageでdevice-treeを選択します。
オプション設定。とりあえずコンソールをUARTに割り当てます。
「ps7_coretex9_0/libsrc/device-tree_xxx/xilinx.dts」が生成されます。「xilinx.dts」と標準の「devicetree.dts」を見比べてみると、生成されたdtsに後で人が色々手を加えてあるようです。dtsの変更はまた今度、今回は標準のdtsを使います。
dtbへのコンパイル。
これまで作った
・BOOT.BIN (FSBL+ビットストリーム+u-boot)
・zImage (Linuxカーネル)
・devicetree.dtb
・ramdisk8M.image.gz (これは標準のまま)
の4つをSDカードにコピーします。ファイル名はコード内で決め打ちなのでこのままです。BOOT.BIN以外はソースを書き換えればファイル名の変更はできます。
後はSDカードをZedBoardに挿して、シリアルポートをつないで、電源を入れれば立ち上がる、はず。
標準ではIPアドレスが192.168.1.10決め打ちです。環境に合わせ、一時的に変更します。
とりあえず動いたので、これから自分の目的に合わせてカスタマイズしていくことになります。
まずは変更を加えずに、標準の環境ができるまでにします。
Digilentのホームページから「ZedBoard_ELHoT」「ZedBoard_Linux_Design」の2つを落としておきます。手順書やソースファイルなどが入っています。
ISE14.6を使用(元のドキュメントでは14.4)。VMware+Ubuntu 12.04 LTS。ホストはWindows7。
ARMのGCCなどを個別に集めても構築できるらしいですが、Xilinxのツールを入れてしまいます。
XilinxのDownloadページから「Software Development Kit」をダウンロード。約1.7GB。でかい。
$ tar xvf Xilinx_SDK_2013.2_0616_1.tar $ cd Xilinx_SDK_2013.2_0616_1 $ sudo sh xsetupデフォルトでは「/opt/Xilinx/SDK/2013.02/」にインストールされます。
毎回忘れる、カーネルコンフィグメニューに必要なncurses-devをインストール。
$ sudo apt-get install ncurses-dev
以下はログインするたびに実行。デフォルトで設定するようにしてもOK。
XilinxのSDK環境変数設定。
$ source /opt/Xilinx/SDK/2013.2/settings32.shついでにARMクロスコンパイル用の環境設定スクリプトも作成&実行。
$ cat armenv.sh #!/bin/bash export CCOMPILER=arm-xilinx-linux-gnueabi-gcc export ARCH=arm export CROSS_COMPILE=arm-xilinx-linux-gnueabi- $ source ./armenv.sh
Linuxのソースを取得、構築。
$ git clone https://github.com/Digilent/linux-digilentこれまた結構でかいので時間かかります。「~/linux-digilent」フォルダができます。
標準のコンフィグは「~/linux-digilent/arch/arm/configs/digilent_zed_defconfig」です。これを「.config」にコピーしても良いです。
$ cd linux-digilent $ cp ./arch/arm/configs/digilent_zed_defconfig .config $ make menuconfig $ make「~/linux-digilent/arch/arm/boot/zImage」にカーネルイメージができます。
u-bootの作成。
$ git clone https://github.com/Digilent/u-boot-digilent「~/u-boot-digilent」フォルダができます。
「~/u-boot-digilent/include/configs/zynq_zed.h」がZedBoardの設定ファイルです。必要に応じて編集します。
$ make zynq_zed_config $ makemakeが終わると「u-boot」ができます。これを「u-boot.elf」とかにリネームしてコピー。
Device Tree Generatorを導入。
SDK上でハードウェアからdtsファイルを作ってくれるツールです。自分でハードウェアをカスタマイズしたときは、このツールでdtsファイルを作ります。
$ git clone git://git.xilinx.com/device-tree.git bsp/device-tree_v0_00_x $ sudo cp -r bsp/device-tree_v0_00_x/ /opt/Xilinx/SDK/2013.2/sw/lib/bsp/「~/bsp/device-tree_v0_00_x」フォルダができるので、SDKの標準リポジトリにコピー。
ちなみに、このフォルダをWindowsの「C:\Xilinx\SDK\2013.2\sw\lib\bsp」にコピーすればWindowsのSDKでもDevice Tree Generatorが使えます。
FSBLを作成。SDKを立ち上げます。
$ xsdk (Xilinx SDK:15612): LIBDBUSMENU-GTK-CRITICAL **: watch_submenu: assertion `GTK_IS_MENU_SHELL(menu)' failedというエラーが出て、SDKのメニューが表示されない。ググったところ、
$ export UBUNTU_MENUPROXY=0としてからSDKを立ち上げればば良いらしいです。先の「~/armenv.sh」に追加記述しておいてもOK。
標準の「hw_platform」のフォルダをコピーしておきます。ついでに「system.bit」を「hw_platform」の中にコピーします。本来これらはPlanAheadからExportされます。
このフォルダの中の「system.xml」を元にHardware Platform Specificationを作成します。
New → Others → Xilinx → Hardware Platform Specification を選びます。
コピーしたフォルダの「system.xml」を指定します。
Finishで「hw_platform」フォルダができます。
New → Application Projectで新しく「FSBL」というプロジェクトを作ります。テンプレートとしてFSBLを選びます。設定はデフォルトのまま。
自動的にBuildが始まりますが、gmakeを呼んでいてBuildに失敗するので、makeにシンボリックリンクさせます。ホントはどう対処するのが正しいんだろ?
$ sudo ln -s /usr/bin/make /usr/bin/gmake再度Build。「FSBL.elf」ができます。
※ZedBoardではUSBのリセットをFSBLで行うようになっています。手順書に書いてありますがここでは割愛。
ブートイメージを作ります。
SDK上で「FSBL」が選択された状態で、Xilinx Tools → Create Zynq Boot Imageを選択します。
「FSBL.elf」と「system.bit」と「u-boot.elf」を選択し、Createします。
デフォルトでは「~/workspace/FSBL/bootimage/u-boot.bin」というファイルができます。
これを「BOOT.BIN」にリネームして、SDカードにコピーします。
※多分このSDKの作業はWindows上でも同じように動作するはずです。
Device Tree Blobを作成します。
「devicetree.dts」が標準のソースファイルです。コンパイル済みの「devicetree.dtb」をそのまま使っても同じです。
自分でカスタマイズしたハードウェア用にdtsを作るときは、先に入れたDevice Tree Generatorを使うようです。New → Board Support Packageでdevice-treeを選択します。
オプション設定。とりあえずコンソールをUARTに割り当てます。
「ps7_coretex9_0/libsrc/device-tree_xxx/xilinx.dts」が生成されます。「xilinx.dts」と標準の「devicetree.dts」を見比べてみると、生成されたdtsに後で人が色々手を加えてあるようです。dtsの変更はまた今度、今回は標準のdtsを使います。
dtbへのコンパイル。
~/linux-digilent/scripts/dtc/dtc -I dts -O dtb -o devicetree.dtb devicetree.dts
これまで作った
・BOOT.BIN (FSBL+ビットストリーム+u-boot)
・zImage (Linuxカーネル)
・devicetree.dtb
・ramdisk8M.image.gz (これは標準のまま)
の4つをSDカードにコピーします。ファイル名はコード内で決め打ちなのでこのままです。BOOT.BIN以外はソースを書き換えればファイル名の変更はできます。
後はSDカードをZedBoardに挿して、シリアルポートをつないで、電源を入れれば立ち上がる、はず。
U-Boot 2012.04.01 (Sep 25 2013 - 00:19:21) DRAM: 512 MiB WARNING: Caches not enabled MMC: SDHCI: 0 Using default environment In: serial Out: serial Err: serial Net: zynq_gem Hit any key to stop autoboot: 0 Copying Linux from SD to RAM... Device: SDHCI Manufacturer ID: 1d OEM: 4144 Name: SD Tran Speed: 25000000 Rd Block Len: 512 SD version 1.10 High Capacity: No Capacity: 1.9 GiB Bus Width: 4-bit reading zImage 2527040 bytes read reading devicetree.dtb 9648 bytes read reading ramdisk8M.image.gz 3694324 bytes read ## Starting application at 0x00008000 ... Uncompressing Linux... done, booting the kernel. [ 0.000000] Booting Linux on physical CPU 0 [ 0.000000] Linux version 3.6.0-digilent-13.01-00002-g06b3889 (develop@vm-ubuntu) (gcc version 4.7.2 (Sourcery CodeBench Lite 2012.09-104) ) #1 SMP PREEMPT Wed Sep 25 00:32:40 JST 2013 [ 0.000000] CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache [ 0.000000] Machine: Xilinx Zynq Platform, model: Xilinx Zynq ZED [ 0.000000] Memory policy: ECC disabled, Data cache writealloc [ 0.000000] PERCPU: Embedded 7 pages/cpu @c140a000 s6976 r8192 d13504 u32768 [ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 130048 [ 0.000000] Kernel command line: console=ttyPS0,115200 root=/dev/ram rw initrd=0x800000,8M earlyprintk rootwait devtmpfs.mount=1 [ 0.000000] PID hash table entries: 2048 (order: 1, 8192 bytes) [ 0.000000] Dentry cache hash table entries: 65536 (order: 6, 262144 bytes) [ 0.000000] Inode-cache hash table entries: 32768 (order: 5, 131072 bytes) [ 0.000000] Memory: 512MB = 512MB total [ 0.000000] Memory: 506424k/506424k available, 17864k reserved, 0K highmem [ 0.000000] Virtual kernel memory layout: [ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB) [ 0.000000] fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB) [ 0.000000] vmalloc : 0xe0800000 - 0xfd000000 ( 456 MB) [ 0.000000] lowmem : 0xc0000000 - 0xe0000000 ( 512 MB) [ 0.000000] pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB) [ 0.000000] modules : 0xbf000000 - 0xbfe00000 ( 14 MB) [ 0.000000] .text : 0xc0008000 - 0xc0473a60 (4527 kB) [ 0.000000] .init : 0xc0474000 - 0xc0499b40 ( 151 kB) [ 0.000000] .data : 0xc049a000 - 0xc04d4ae0 ( 235 kB) [ 0.000000] .bss : 0xc04d4b04 - 0xc04ee100 ( 102 kB) [ 0.000000] Preemptible hierarchical RCU implementation. [ 0.000000] Dump stacks of tasks blocking RCU-preempt GP. [ 0.000000] RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=2. [ 0.000000] NR_IRQS:512 [ 0.000000] Zynq clock init [ 0.000000] xlnx,ps7-ttc-1.00.a #0 at 0xe0800000, irq=43 [ 0.000000] sched_clock: 32 bits at 100 Hz, resolution 10000000ns, wraps every 4294967286ms [ 0.000000] Console: colour dummy device 80x30 [ 0.090000] Calibrating delay loop... 1332.01 BogoMIPS (lpj=6660096) [ 0.090000] pid_max: default: 32768 minimum: 301 [ 0.090000] Mount-cache hash table entries: 512 [ 0.090000] CPU: Testing write buffer coherency: ok [ 0.090000] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000 [ 0.090000] hw perfevents: enabled with ARMv7 Cortex-A9 PMU driver, 7 counters available [ 0.090000] Setting up static identity map for 0x32be88 - 0x32bebc [ 0.090000] L310 cache controller enabled [ 0.090000] l2x0: 8 ways, CACHE_ID 0x410000c8, AUX_CTRL 0x72360000, Cache size: 524288 B [ 0.130000] Map SLCR registers [ 0.130000] CPU1: Booted secondary processor [ 0.220000] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001 [ 0.220000] Brought up 2 CPUs [ 0.220000] SMP: Total of 2 processors activated (2664.03 BogoMIPS). [ 0.220000] devtmpfs: initialized [ 0.220000] NET: Registered protocol family 16 [ 0.220000] DMA: preallocated 256 KiB pool for atomic coherent allocations [ 0.220000] xgpiops e000a000.ps7-gpio: gpio at 0xe000a000 mapped to 0xe084a000 [ 0.230000] registering platform device 'pl330' id 0 [ 0.230000] registering platform device 'arm-pmu' id 0 [ 0.230000] registering platform device 'zynq-dvfs' id 0 [ 0.230000] [ 0.230000] ############################################### [ 0.230000] # # [ 0.230000] # Board ZED Init # [ 0.230000] # # [ 0.230000] ############################################### [ 0.230000] [ 0.230000] hw-breakpoint: found 5 (+1 reserved) breakpoint and 1 watchpoint registers. [ 0.230000] hw-breakpoint: maximum watchpoint size is 4 bytes. [ 0.250000] xslcr xslcr.0: at 0xF8000000 mapped to 0xF8000000 [ 0.270000] bio: create slab立ち上がりました。なんかinsmodでエラーが出ちゃってますが、これは後でどうにかなるでしょう。at 0 [ 0.270000] SCSI subsystem initialized [ 0.270000] usbcore: registered new interface driver usbfs [ 0.270000] usbcore: registered new interface driver hub [ 0.270000] usbcore: registered new device driver usb [ 0.270000] Advanced Linux Sound Architecture Driver Version 1.0.25. [ 0.270000] Switching to clocksource xttcpss_timer1 [ 0.280000] NET: Registered protocol family 2 [ 0.280000] TCP established hash table entries: 16384 (order: 5, 131072 bytes) [ 0.280000] TCP bind hash table entries: 16384 (order: 5, 131072 bytes) [ 0.280000] TCP: Hash tables configured (established 16384 bind 16384) [ 0.280000] TCP: reno registered [ 0.280000] UDP hash table entries: 256 (order: 1, 8192 bytes) [ 0.280000] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes) [ 0.280000] NET: Registered protocol family 1 [ 0.280000] RPC: Registered named UNIX socket transport module. [ 0.280000] RPC: Registered udp transport module. [ 0.280000] RPC: Registered tcp transport module. [ 0.280000] RPC: Registered tcp NFSv4.1 backchannel transport module. [ 0.280000] Trying to unpack rootfs image as initramfs... [ 0.280000] rootfs image is not initramfs (no cpio magic); looks like an initrd [ 0.320000] Freeing initrd memory: 8192K [ 0.320000] pl330 dev 0 probe success [ 0.320000] msgmni has been set to 1005 [ 0.320000] io scheduler noop registered [ 0.320000] io scheduler deadline registered [ 0.320000] io scheduler cfq registered (default) [ 0.320000] e0001000.serial: ttyPS0 at MMIO 0xe0001000 (irq = 82) is a xuartps [ 0.840000] console [ttyPS0] enabled [ 0.840000] xdevcfg f8007000.ps7-dev-cfg: ioremap f8007000 to e0850000 with size 1000 [ 0.850000] [drm] Initialized drm 1.1.0 20060810 [ 0.860000] brd: module loaded [ 0.870000] loop: module loaded [ 0.880000] xqspips e000d000.ps7-qspi: master is unqueued, this is deprecated [ 0.880000] xqspips e000d000.ps7-qspi: at 0xE000D000 mapped to 0xE0852000, irq=51 [ 0.890000] libphy: XEMACPS mii bus: probed [ 0.900000] xemacps e000b000.ps7-ethernet: pdev->id -1, baseaddr 0xe000b000, irq 54 [ 0.910000] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver [ 0.910000] usb_hcd_xusbps_probe: No OTG assigned! [ 0.920000] usb_hcd_xusbps_probe: OTG now assigned! [ 0.920000] xusbps-ehci xusbps-ehci.0: Xilinx PS USB EHCI Host Controller [ 0.930000] xusbps-ehci xusbps-ehci.0: new USB bus registered, assigned bus number 1 [ 0.970000] xusbps-ehci xusbps-ehci.0: irq 53, io mem 0x00000000 [ 0.990000] xusbps-ehci xusbps-ehci.0: USB 2.0 started, EHCI 1.00 [ 0.990000] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002 [ 1.000000] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1 [ 1.010000] usb usb1: Product: Xilinx PS USB EHCI Host Controller [ 1.010000] usb usb1: Manufacturer: Linux 3.6.0-digilent-13.01-00002-g06b3889 ehci_hcd [ 1.020000] usb usb1: SerialNumber: xusbps-ehci.0 [ 1.020000] hub 1-0:1.0: USB hub found [ 1.030000] hub 1-0:1.0: 1 port detected [ 1.030000] Initializing USB Mass Storage driver... [ 1.040000] usbcore: registered new interface driver usb-storage [ 1.040000] USB Mass Storage support registered. [ 1.050000] mousedev: PS/2 mouse device common for all mice [ 1.060000] sdhci: Secure Digital Host Controller Interface driver [ 1.060000] sdhci: Copyright(c) Pierre Ossman [ 1.070000] sdhci-pltfm: SDHCI platform and OF driver helper [ 1.070000] mmc0: Invalid maximum block size, assuming 512 bytes [ 1.080000] No connectors reported connected with modes [ 1.090000] [drm] Cannot find any crtc or sizes - going 1024x768 [ 1.110000] Console: switching to colour frame buffer device 128x48 [ 1.120000] mmc0: SDHCI controller on e0100000.ps7-sdio [e0100000.ps7-sdio] using ADMA [ 1.130000] usbcore: registered new interface driver usbhid [ 1.130000] usbhid: USB HID core driver [ 1.130000] spi_gpio spi_gpio.2: master is unqueued, this is deprecated [ 1.130000] pmodoled-gpio-spi [zed_oled] SPI Probing [ 1.180000] fb0: frame buffer device [ 1.180000] drm: registered panic notifier [ 1.190000] [drm] Initialized analog_drm 1.0.0 20110530 on minor 0 [ 1.200000] mmc0: SD Status: Invalid Allocation Unit size. [ 1.210000] mmc0: new high speed SD card at address b368 [ 1.210000] mmcblk0: mmc0:b368 SD 1.86 GiB [ 1.220000] mmcblk0: p1 [ 1.300000] adv7511 0-0039: Failed to add route DAI IN->TMDS [ 1.310000] adv7511-hdmi-snd adv7511_hdmi_snd.2: adv7511 <-> 75c00000.axi-spdif-tx mapping ok [ 1.320000] TCP: cubic registered [ 1.320000] NET: Registered protocol family 17 [ 1.330000] VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4 [ 1.330000] Registering SWP/SWPB emulation handler [ 1.340000] registered taskstats version 1 [ 1.340000] drivers/rtc/hctosys.c: unable to open rtc device (rtc0) [ 1.350000] ALSA device list: [ 1.350000] #0: HDMI monitor [ 1.360000] RAMDISK: gzip image found at block 0 [ 1.680000] EXT4-fs (ram0): couldn't mount as ext3 due to feature incompatibilities [ 1.710000] EXT4-fs (ram0): mounting ext2 file system using the ext4 subsystem [ 1.710000] EXT4-fs (ram0): warning: mounting unchecked fs, running e2fsck is recommended [ 1.720000] EXT4-fs (ram0): mounted filesystem without journal. Opts: (null) [ 1.730000] VFS: Mounted root (ext2 filesystem) on device 1:0. [ 1.730000] devtmpfs: mounted [ 1.740000] Freeing init memory: 148K Starting rcS... ++ Mounting filesystem ++ Setting up mdev ++ Configure static IP 192.168.1.10 ++ Starting telnet daemon ++ Starting http daemon ++ Starting ftp daemon ++ Starting dropbear (ssh) daemon ++ Starting OLED Display insmod: can't read '/lib/modules/3.6.0-digilent-13.01-00002-g06b3889/pmodoled-gpio.ko': No such file or directory ++ Exporting LEDs & SWs rcS Complete zynq> [ 6.980000] xemacps e000b000.ps7-ethernet: Set clk to 124999998 Hz [ 6.980000] xemacps e000b000.ps7-ethernet: link up (1000/FULL)
標準ではIPアドレスが192.168.1.10決め打ちです。環境に合わせ、一時的に変更します。
zynq> ifconfig eth0 down zynq> ifconfig eth0 192.168.0.201 zynq> ifconfig eth0 up zynq> [ 358.170000] xemacps e000b000.ps7-ethernet: Set clk to 124999998 Hz [ 358.170000] xemacps e000b000.ps7-ethernet: link up (1000/FULL)
develop@vm-ubuntu:~$ ssh root@192.168.0.201 root@192.168.0.201's password: root zynq>とかやるとリモートでログインできます。ブラウザでhttp://192.168.0.201/を見るとWelcomeページが表示されます。
とりあえず動いたので、これから自分の目的に合わせてカスタマイズしていくことになります。