Linux
FPGA
yocto
zynq
zybo

ZYBOのクロス開発環境の構築(3) u-bootの問題解決

More than 1 year has passed since last update.

はじめに

前回の投稿でu-bootでSDカードのアクセスに失敗するという現象が確認されたため問題箇所の特定と解決策の検討を行い、Yocto ProjectのLinux起動までを確認した。実働工数は色々調べ物をしながら24h程度。

u-bootのバージョン確認

通常、ビルド後のu-bootのソースコードは/build/tmp/work以下に置かれるが、今回はディスク容量の削減のためにlocal.confにworkディレクトリを削除する設定(INHERIT += "rm_work")を追記していたため消去されている。ここを修正した上で、u-bootだけのコンパイルを再実行する。
bitbakeの-cオプションでレシピを指定してコマンド実行すればよい。(bitbakeの使い方はUser Manual参照のこと)

$ source oe-init-build-env
$ bitbake -c compile u-boot

コンパイル完了後、u-bootのソースコードは/build/tmp/work/zybo_zynq7-poky-linux-gnueabi/u-boot/1_2017.01-r0/gitにバージョン管理された状態で生成される。ディレクトリ名称から想像するとu-bootのバージョンは2017.01のようである。リポジトリの確認をしてみる。

$ cd tmp/work/zybo_zynq7-poky-linux-gnueabi/u-boot/1_2017.01-r0/git
$ git branch
* master
$ git remote -v
origin https://git.denx.de/u-boot.git (fetch)
origin https://git.denx.de/u-boot.git (push)
$ git status
On branch master, working directory clean
このブランチはorigin/masterに比べて4541コミット遅れています。fast-forwardすることができます。
 (use "git pull" to update your local branch)
nothing to commit 

やはりちょっと古いソースコードが使われているようだ。
次に詳細確認のため、bitbakeのレシピの中でu-bootのソースコードを管理しているincludeファイルを確認する。

$ cd ~/source/poky/meta/recipes-bsp/u-boot
$ vim u-boot-common_2017.01.inc
u-boot-common_2017.01.inc
HOMEPAGE = "http://www.denx.de/wiki/U-Boot/WebHome"
SECTION = "bootloaders"

LICENSE = "GPLv2+"
LIC_FILES_CHKSUM = "file://Licenses/README;md5=a2c678cfd4a4d97135585cad908541c6"
PE = "1"

# We use the revision in order to avoid having to fetch it from the
# repo during parse
SRCREV = "a705ebc81b7f91bbd0ef7c634284208342901149"
SRC_URI = "git://git.denx.de/u-boot.git"

S = "${WORKDIR}/git"

SRC_REVを辿ると確かに本家u-bootの2017.01のTagに行き着いた。

u-bootの2017.05-rc1への更新

ひでみさんのブログ記事を参考にさせて頂き、ZYBO-Z7で正常動作が確認されている2017.05-rc1に更新をしてみることに。まずは先ほど調べたレシピのincludeファイル中のSRCREVを2017.05-rc1のものに修正する(ついでにファイル名も変更した)。因みに先ほどコンパイルした/poky/build/tmp/work以下のソースコードを直接変更してもbitbake core-image-minimalを再実行するとu-bootのソースコードはfetchされて上書きされてしまうので注意。u-bootのソースコードを改変したい場合は/meta-xilinx/recipes-bsp/u-bootのYoctoレシピにパッチを当てる必要がある。(この作業と同時にYoctoのレシピファイルの依存関係やパッチの当て方を調べていたのだが、本稿末尾の参考資料にリンクを記載したIwamatsuさんのスライド資料が大変参考になった)

u-boot-common_2017.05-rc1.inc
HOMEPAGE = "http://www.denx.de/wiki/U-Boot/WebHome"
SECTION = "bootloaders"

LICENSE = "GPLv2+"
LIC_FILES_CHKSUM = "file://Licenses/README;md5=a2c678cfd4a4d97135585cad908541c6"
PE = "1"

# We use the revision in order to avoid having to fetch it from the
# repo during parse
# SRCREV = "a705ebc81b7f91bbd0ef7c634284208342901149"

# fetch 2017.05-rc1
SRCREV = "11db152246607868f0e74db958947fbf79f28119"

SRC_URI = "git://git.denx.de/u-boot.git"

S = "${WORKDIR}/git"

上記の変更内容をgit commitしたうえで再度ビルドを実行してみる。念の為、実行前に前回のビルドファイルやキャッシュをクリーンしておく。ここのようにエラーが出ることもあるようなので、その場合はエラーで指摘されたレシピのビルド生成物とキャッシュをクリーンすることで解決する。(rm -rfで消さないように。linux-xlnxも必要であれば消去)
https://stackoverflow.com/questions/45341760/how-should-the-sstate-cache-directory-be-deleted-in-yocto

$ bitbake -c clean u-boot
$ bitbake -c cleansstate u-boot
$ bitbake core-image-minimal

暫くするとエラーでビルド中止となった。メッセージを確認してみるとdefault-gcc.patchが既に2017.05-rc1では反映されているため不要のようだ。

ERROR: u-boot-mkimage-native-1_2017.05-rc1-r0 do_patch: Command Error: 'quilt --quiltrc /home/ryuichiro/sources/poky/build/tmp/work/x86_64-linux/u-boot-mkimage-native/1_2017.05-rc1-r0/recipe-sysroot-native/etc/quiltrc push' exited with 0  Output:
Applying patch default-gcc.patch
patching file tools/Makefile
Hunk #1 FAILED at 262.
1 out of 1 hunk FAILED -- rejects in file tools/Makefile
patching file tools/env/Makefile
Hunk #1 FAILED at 8.
1 out of 1 hunk FAILED -- rejects in file tools/env/Makefile
Patch default-gcc.patch can be reverse-applied
ERROR: u-boot-mkimage-native-1_2017.05-rc1-r0 do_patch: Function failed: patch_do_patch
ERROR: Logfile of failure stored in: /home/ryuichiro/sources/poky/build/tmp/work/x86_64-linux/u-boot-mkimage-native/1_2017.05-rc1-r0/temp/log.do_patch.10855
ERROR: Task (virtual:native:/home/ryuichiro/sources/poky/meta/recipes-bsp/u-boot/u-boot-mkimage_2017.05-rc1.bb:do_patch) failed with exit code '1'

/poky/meta/recipes-bsp/u-boot/にu-boot-mkimageのレシピファイル(.bb)があるので、default-gcc.patchをincludeから除外してビルド再実行すると正常に終了した。

ZYBOの起動確認 再び

前回の手順に従い生成ファイルをSDカードにコピーしてZYBOの起動確認を実施する。最終的にはKernel Panicが起きて止まっているがu-bootが正常に動作してLinuxが起動した…!
Kernel Panicは別要因による問題(ramdiskか?)のため次回に検討をすることにして、本稿ではu-bootの不具合に着目したい。
(※追記 単純にパーティション2にrootfilesystemを置き忘れていただけでした…解決です)

U-Boot SPL 2017.05-rc1-dirty (Oct 25 2017 - 22:25:24)
mmc boot
Trying to boot from MMC1
reading system.dtb
spl_load_image_fat_os: error reading image system.dtb, err - -1
reading u-boot.img
reading u-boot.img


U-Boot 2017.05-rc1-dirty (Oct 25 2017 - 22:25:24 +0900)

Model: Zynq ZYBO Development Board
Board: Xilinx Zynq
I2C:   ready
DRAM:  ECC disabled 512 MiB
MMC:   sdhci@e0100000: 0
SF: Detected s25fl128s_64k with page size 256 Bytes, erase size 64 KiB, total 16 MiB
*** Warning - bad CRC, using default environment

In:    serial@e0001000
Out:   serial@e0001000
Err:   serial@e0001000
Model: Zynq ZYBO Development Board
Board: Xilinx Zynq
Net:   ZYNQ GEM: e000b000, phyaddr 0, interface rgmii-id
I2C EEPROM MAC address read failed

Warning: ethernet@e000b000 (eth0) using random MAC address - fa:6c:09:bb:2a:ec
eth0: ethernet@e000b000
reading uEnv.txt
586 bytes read in 13 ms (43.9 KiB/s)
Importing environment from mmc ...
Checking if uenvcmd is set ...
Running uenvcmd ...
reading uImage
3596792 bytes read in 209 ms (16.4 MiB/s)
reading uImage-zynq-zybo.dtb
9235 bytes read in 18 ms (501 KiB/s)
## Booting kernel from Legacy Image at 03000000 ...
   Image Name:   Linux-4.9.0-xilinx-v2017.1
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    3596728 Bytes = 3.4 MiB
   Load Address: 00008000
   Entry Point:  00008000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 02a00000
   Booting using the fdt blob at 0x2a00000
   Loading Kernel Image ... OK
   Loading Device Tree to 1eb28000, end 1eb2d412 ... OK

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.9.0-xilinx-v2017.1 (oe-user@oe-host) (gcc version 6.3.0 (GCC) ) #2 SMP PREEMPT Thu Oct 26 09:59:57 JST 2017
[    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] OF: fdt:Machine model: Zynq ZYBO Development Board
[    0.000000] Memory policy: Data cache writealloc
[    0.000000] percpu: Embedded 14 pages/cpu @dfbd4000 s25932 r8192 d23220 u57344
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 130048
[    0.000000] Kernel command line: console=ttyPS0,115200 root=/dev/mmcblk0p2 rw rootwait earlyprintk
[    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: 510968K/524288K available (5120K kernel code, 203K rwdata, 1324K rodata, 1024K init, 224K bss, 13320K reserved, 0K cma-reserved, 0K highmem)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
[    0.000000]     vmalloc : 0xe0800000 - 0xff800000   ( 496 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 - 0xc0600000   (6112 kB)
[    0.000000]       .init : 0xc0800000 - 0xc0900000   (1024 kB)
[    0.000000]       .data : 0xc0900000 - 0xc0932c80   ( 204 kB)
[    0.000000]        .bss : 0xc0932c80 - 0xc096afd8   ( 225 kB)
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000]  Build-time adjustment of leaf fanout to 32.
[    0.000000]  RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=2.
[    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=32, nr_cpu_ids=2
[    0.000000] NR_IRQS:16 nr_irqs:16 16
[    0.000000] efuse mapped to e0800000
[    0.000000] slcr mapped to e0802000
[    0.000000] L2C: platform modifies aux control register: 0x02060000 -> 0x32460000
[    0.000000] L2C: DT/platform modifies aux control register: 0x02060000 -> 0x32460000
[    0.000000] L2C-310 erratum 769419 enabled
[    0.000000] L2C-310 enabling early BRESP for Cortex-A9
[    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
[    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
[    0.000000] L2C-310 cache controller enabled, 8 ways, 512 kB
[    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x46460001
[    0.000000] zynq_clock_init: clkc starts at e0802100
[    0.000000] Zynq clock init
[    0.000010] sched_clock: 64 bits at 325MHz, resolution 3ns, wraps every 4398046511103ns
[    0.000032] clocksource: arm_global_timer: mask: 0xffffffffffffffff max_cycles: 0x4af477f6aa, max_idle_ns: 440795207830 ns
[    0.000061] Switching to timer-based delay loop, resolution 3ns
[    0.000158] clocksource: ttc_clocksource: mask: 0xffff max_cycles: 0xffff, max_idle_ns: 551318127 ns
[    0.000188] timer #0 at e080a000, irq=17
[    0.000522] Console: colour dummy device 80x30
[    0.000546] Calibrating delay loop (skipped), value calculated using timer frequency.. 650.00 BogoMIPS (lpj=3250000)
[    0.000563] pid_max: default: 32768 minimum: 301
[    0.000701] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.000714] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.001330] CPU: Testing write buffer coherency: ok
[    0.001538] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
[    0.001599] Setting up static identity map for 0x100000 - 0x100058
[    0.170660] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
[    0.170766] Brought up 2 CPUs
[    0.170786] SMP: Total of 2 processors activated (1300.00 BogoMIPS).
[    0.170795] CPU: All CPU(s) started in SVC mode.
[    0.171759] devtmpfs: initialized
[    0.174463] VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4
[    0.174798] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.174892] pinctrl core: initialized pinctrl subsystem
[    0.175975] NET: Registered protocol family 16
[    0.176898] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.200704] cpuidle: using governor menu
[    0.213513] hw-breakpoint: found 5 (+1 reserved) breakpoint and 1 watchpoint registers.
[    0.213530] hw-breakpoint: maximum watchpoint size is 4 bytes.
[    0.213651] zynq-ocm f800c000.ocmc: ZYNQ OCM pool: 256 KiB @ 0xe0880000
[    0.214022] zynq-pinctrl 700.pinctrl: zynq pinctrl initialized
[    0.232688] SCSI subsystem initialized
[    0.233047] usbcore: registered new interface driver usbfs
[    0.233144] usbcore: registered new interface driver hub
[    0.233226] usbcore: registered new device driver usb
[    0.233411] phy0 supply vcc not found, using dummy regulator
[    0.233685] pps_core: LinuxPPS API ver. 1 registered
[    0.233698] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[    0.233743] PTP clock support registered
[    0.233799] EDAC MC: Ver: 3.0.0
[    0.234597] FPGA manager framework
[    0.234854] fpga-region fpga-full: FPGA Region probed
[    0.240940] clocksource: Switched to clocksource arm_global_timer
[    0.254068] NET: Registered protocol family 2
[    0.254827] TCP established hash table entries: 4096 (order: 2, 16384 bytes)
[    0.254885] TCP bind hash table entries: 4096 (order: 3, 32768 bytes)
[    0.254966] TCP: Hash tables configured (established 4096 bind 4096)
[    0.255020] UDP hash table entries: 256 (order: 1, 8192 bytes)
[    0.255051] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes)
[    0.255215] NET: Registered protocol family 1
[    0.255631] RPC: Registered named UNIX socket transport module.
[    0.255645] RPC: Registered udp transport module.
[    0.255654] RPC: Registered tcp transport module.
[    0.255663] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    0.256176] hw perfevents: enabled with armv7_cortex_a9 PMU driver, 7 counters available
[    0.257403] futex hash table entries: 512 (order: 3, 32768 bytes)
[    0.257472] audit: initializing netlink subsys (disabled)
[    0.257519] audit: type=2000 audit(0.240:1): initialized
[    0.258344] workingset: timestamp_bits=30 max_order=17 bucket_order=0
[    0.259080] jffs2: version 2.2. (NAND) (SUMMARY)  c 2001-2006 Red Hat, Inc.
[    0.259945] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 248)
[    0.259962] io scheduler noop registered
[    0.259973] io scheduler deadline registered
[    0.259992] io scheduler cfq registered (default)
[    0.263079] dma-pl330 f8003000.dmac: Loaded driver for PL330 DMAC-241330
[    0.263101] dma-pl330 f8003000.dmac:     DBUFF-128x8bytes Num_Chans-8 Num_Peri-4 Num_Events-16
[    0.263864] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[    0.266114] e0001000.serial: ttyPS0 at MMIO 0xe0001000 (irq = 143, base_baud = 6250000) is a xuartps
[    0.903529] console [ttyPS0] enabled
[    0.907779] xdevcfg f8007000.devcfg: ioremap 0xf8007000 to e0875000
[    0.918294] brd: module loaded
[    0.929153] loop: module loaded
[    0.934418] zynq-qspi e000d000.spi: couldn't determine configuration info about dual memories. defaulting to single memory
[    0.949775] libphy: Fixed MDIO Bus: probed
[    0.959143] CAN device driver interface
[    0.964528] libphy: MACB_mii_bus: probed
[    0.969047] macb e000b000.ethernet eth0: Cadence GEM rev 0x00020118 at 0xe000b000 irq 145 (fa:6c:09:bb:2a:ec)
[    0.978914] RTL8211E Gigabit Ethernet e000b000.etherne:00: attached PHY driver [RTL8211E Gigabit Ethernet] (mii_bus:phy_addr=e000b000.etherne:00, irq=-1)
[    0.994029] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    1.000614] usbcore: registered new interface driver usb-storage
[    1.006880] e0002000.usb supply vbus not found, using dummy regulator
[    1.033682] ci_hdrc ci_hdrc.0: EHCI Host Controller
[    1.038507] ci_hdrc ci_hdrc.0: new USB bus registered, assigned bus number 1
[    1.070975] ci_hdrc ci_hdrc.0: USB 2.0 started, EHCI 1.00
[    1.077186] hub 1-0:1.0: USB hub found
[    1.080893] hub 1-0:1.0: 1 port detected
[    1.086400] mousedev: PS/2 mouse device common for all mice
[    1.092186] i2c /dev entries driver
[    1.097199] EDAC MC: ECC not enabled
[    1.101643] cpufreq: cpufreq_online: CPU0: Running at unlisted freq: 650000 KHz
[    1.108884] cpufreq: cpufreq_online: CPU0: Unlisted initial frequency changed to: 666667 KHz
[    1.117461] Xilinx Zynq CpuIdle Driver started
[    1.122409] sdhci: Secure Digital Host Controller Interface driver
[    1.128508] sdhci: Copyright(c) Pierre Ossman
[    1.132875] sdhci-pltfm: SDHCI platform and OF driver helper
[    1.201007] mmc0: SDHCI controller on e0100000.sdhci [e0100000.sdhci] using DMA
[    1.208583] ledtrig-cpu: registered to indicate activity on CPUs
[    1.217842] usbcore: registered new interface driver usbhid
[    1.223381] usbhid: USB HID core driver
[    1.239118] NET: Registered protocol family 10
[    1.244595] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[    1.251269] NET: Registered protocol family 17
[    1.255640] can: controller area network core (rev 20120528 abi 9)
[    1.261917] NET: Registered protocol family 29
[    1.266305] can: raw protocol (rev 20120528)
[    1.270553] can: broadcast manager protocol (rev 20161123 t)
[    1.276205] can: netlink gateway (rev 20130117) max_hops=1
[    1.281917] Registering SWP/SWPB emulation handler
[    1.292947] Waiting for root device /dev/mmcblk0p2...
[    1.298009] mmc0: new high speed SDHC card at address 1234
[    1.304056] mmcblk0: mmc0:1234 SA16G 14.5 GiB 
[    1.309706]  mmcblk0: p1 p2
[    1.422402] EXT4-fs (mmcblk0p2): couldn't mount as ext3 due to feature incompatibilities
[    1.431558] EXT4-fs (mmcblk0p2): couldn't mount as ext2 due to feature incompatibilities
[    1.625262] random: fast init done
[    1.737654] EXT4-fs (mmcblk0p2): recovery complete
[    1.745070] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
[    1.753139] VFS: Mounted root (ext4 filesystem) on device 179:2.
[    1.759166] devtmpfs: mounted
[    1.763303] Freeing unused kernel memory: 1024K (c0800000 - c0900000)
INIT: version 2.88 booting
Starting udev
[    2.223616] udevd[680]: starting version 3.2.1
[    2.267256] udevd[681]: starting eudev-3.2.1
[    2.367525] EXT4-fs (mmcblk0p2): re-mounted. Opts: data=ordered
Fri Oct 27 07:02:50 UTC 2017
INIT: Entering runlevel: 5
Configuring network interfaces... [    2.875222] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
udhcpc (v1.24.1) started
Sending discover...
[    4.607951] random: crng init done
Sending discover...
[    7.380965] mmc0: Card stuck in programming state! mmc_do_erase
Sending discover...
No lease, forking to background
done.
Starting syslogd/klogd: done

Poky (Yocto Project Reference Distro) 2.3.2 zybo-zynq7 /dev/ttyPS0

zybo-zynq7 login: root
root@zybo-zynq7:~# 

SDカードからのブート不具合の原因調査

u-bootバージョン間のソースコード差分を確かめてみる。Xilinxのユーザーフォーラムでの議論を踏まえて、Clock設定を疑いながらgitで差分をチェック。

clk.c.diff
diff --git a/arch/arm/mach-zynq/clk.c b/arch/arm/mach-zynq/clk.c
index 40383c1..1369cd0 100644
--- a/arch/arm/mach-zynq/clk.c
+++ b/arch/arm/mach-zynq/clk.c
@@ -4,645 +4,65 @@
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
+#include <clk.h>
 #include <common.h>
-#include <errno.h>
-#include <asm/io.h>
-#include <asm/arch/hardware.h>
+#include <dm.h>
 #include <asm/arch/clk.h>

-/* Board oscillator frequency */
-#ifndef CONFIG_ZYNQ_PS_CLK_FREQ
-# define CONFIG_ZYNQ_PS_CLK_FREQ       33333333UL
-#endif
-
-/* Register bitfield defines */
-#define PLLCTRL_FBDIV_MASK     0x7f000
-#define PLLCTRL_FBDIV_SHIFT    12
-#define PLLCTRL_BPFORCE_MASK   (1 << 4)
-#define PLLCTRL_PWRDWN_MASK    2
-#define PLLCTRL_PWRDWN_SHIFT   1
-#define PLLCTRL_RESET_MASK     1
-#define PLLCTRL_RESET_SHIFT    0
-
-#define ZYNQ_CLK_MAXDIV                0x3f
-#define CLK_CTRL_DIV1_SHIFT    20
-#define CLK_CTRL_DIV1_MASK     (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV1_SHIFT)
-#define CLK_CTRL_DIV0_SHIFT    8
-#define CLK_CTRL_DIV0_MASK     (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV0_SHIFT)
-#define CLK_CTRL_SRCSEL_SHIFT  4
-#define CLK_CTRL_SRCSEL_MASK   (0x3 << CLK_CTRL_SRCSEL_SHIFT)
-
-#define CLK_CTRL_DIV2X_SHIFT   26
-#define CLK_CTRL_DIV2X_MASK    (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV2X_SHIFT)
-#define CLK_CTRL_DIV3X_SHIFT   20
-#define CLK_CTRL_DIV3X_MASK    (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV3X_SHIFT)
-
-#define ZYNQ_CLKMUX_SEL_0      0
-#define ZYNQ_CLKMUX_SEL_1      1
-#define ZYNQ_CLKMUX_SEL_2      2
-#define ZYNQ_CLKMUX_SEL_3      3

以下略

ここでPSの各種クロック周波数を設定するソースコードが消去されていることが分かる。上記の他/include/configs/zynq_zybo.hを見ても同様。おそらく、u-bootの2017.01では特定の周波数をu-bootで直接設定していたのだが、2017.05-rc1ではH/Wデザインに紐づく何らかのファイルを参照して動的にクロック周波数を設定するようになったのではないだろうか?

XilinxのZynq Technical Reference Manual (UG585) P.368を確認すると、ZynqはSDカードに供給するクロックとして最大50MHzまでサポートしており、コントローラ部のブロック図は以下の通りである。

SDControllerDiagram.png

これを踏まえてu-bootのコンソールでPSのClockを確認してみる。

Zynq> clk dump
clk     frequency
    armpll          1300000000
    ddrpll          1050000000
     iopll          1000000000
 cpu_6or4x           650000000
 cpu_3or2x           325000000
    cpu_2x           216666666
    cpu_1x           108333333
    ddr_2x           350000000
    ddr_3x           525000000
       dci            10096154
     lqspi           200000000
       smc            21666667
      pcap           200000000
      gem0           125000000
      gem1            16666667
     fclk0           100000000
     fclk1           142857143
     fclk2           200000000
     fclk3            50000000
     sdio0            50000000
     sdio1            50000000
     uart0           100000000
     uart1           100000000
      spi0            15873016
      spi1            15873016
 usb0_aper           108333333
 usb1_aper           108333333
 gem0_aper           108333333
 gem1_aper           108333333
sdio0_aper           108333333
sdio1_aper           108333333
 spi0_aper           108333333
 spi1_aper           108333333
 can0_aper           108333333
 can1_aper           108333333
 i2c0_aper           108333333
 i2c1_aper           108333333
uart0_aper           108333333
uart1_aper           108333333
 gpio_aper           108333333
lqspi_aper           108333333
  smc_aper           108333333
   dbg_trc            66666667
   dbg_apb            66666667
Zynq> 

SD/SDIO ContollerのRefence Clock:SDIO{0,1}、CPU_1x_clockに108.3 MHzが設定されていることが分かる。このReference ClockがSDカードのコントローラ内部で分周されてデバイスに供給される。最終的にはFull Speedモードの最大周波数の50MHzで動作させていると思うが、結局のところこの周波数は固定値ではなくVivadoで設計するH/Wデザインに依存するため2017.01ではその考慮がされていなかったのではないかと思う。2017.05-rc1のコミットログにそれらしき説明もあった。

commit e0f4de1afcdb80b4ccad10a877504baaeb7ae2c0
Author: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
Date:   Tue Jan 17 16:27:32 2017 +0100

    mmc: zynq: Determine base clock frequency via clock framework

    The zynq_sdhci controller driver use CONFIG_ZYNQ_SDHCI_MAX_FREQ as base
    clock frequency but this clock is not fixed and depends on the hardware
    configuration. Additionally the value of CONFIG_ZYNQ_SDHCI_MAX_FREQ
    doesn't match the real base clock frequency of SDIO_FREQ. Use the clock
    framework to determine the frequency at run time.

    Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
    Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>
    Signed-off-by: Michal Simek <michal.simek@xilinx.com>

具体的にどこでコケたのか十分に特定できていないためモヤモヤ感が残るが、今回はここまでにして先に進むことにしたい。

おわりに

u-bootの正常動作とYocto Linuxの起動を確認できた(PLの動作確認は未完)。時間があればYoctoのレシピにパッチをあてて、DEBUGモードでu-bootの詳細動作を見てみたいところ。

次回はPSとPLそれぞれのデバイスツリーをマージして、LinuxからPLのモジュールを制御するところまでを追っていく予定。

参考資料

https://www.slideshare.net/iwamatsu/ss-31662659
http://d.hatena.ne.jp/seinzumtode/20170412/1491958888