新しいZYNQボードでLinuxが起動するまでに苦労したこと
新しく作ったZYNQのボードでLinuxを起動させて、GigabitEtherと、USBまで認識するようになりました。
オリジナルボード向けのLinux構築のための基本的な手順はこの同人誌「ZYNQで実用的なシステムを構築するための本」に書いたとおりなのですが、今回は最新版のU-boot 2023.1を使ってみることにしたので、結構ハマりました。
まず、この基板ではUART0ではなくUART1を使っています。そのため、過去に作ったFSBLやU-Bootをそのまま動かそうとしてもコンソールに文字が出てきません。コンソールから文字を出すだけのために全部作り直すことになったのですが、ダウンロードしたU-Boot 2023.1はいろいろ変わっていて、findしたりfgrepしたりでカーネルのソースを大冒険でした。
新U-BOOTではGigabitEther PHYを認識するためのデバイスツリーの書き方が変わっていて後方互換性がありません。
&gem0 {
status = "okay";
phy-mode = "rgmii-id";
phy-handle = <ðernet_phy>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gem0_default>;
ethernet_phy: ethernet-phy@7 {
reg = <7>;
compatible = "ethernet-phy-id0022.1641";
};
};
使用しているGbEのPHYはMicrelのKSZ9131RNXなのですが、以前と違って、compatible = "ethernet-phy-id0022.1641";のようにcompatibleにベンダIDとデバイスIDまで書かなければならなくなりました。
ぶっちゃけU-BootがGbEを認識しなくてもLinuxで認識すればよいので、ここにこだわらなくてもよいのですが、U-Bootの起動時にGigabitEtherがnot foundとか言われると嫌じゃないですか?pinctrlを書く必要があるのかどうかはわかりません。
USBにはUSB3317とLAN9514を使っていますが、これはRESETを一瞬Lにするパルスを与えないとだめなようです。USBのRESET端子をPLから操作できるようにしておいて命拾いをしました。
あと、U-BOOT 2023.1ではuEnv.txtではなくboot.scrになりました。このboot.scrの作り方が毎回毎回謎なんですよね。
fatload mmc 0 0x03000000 uImage && fatload mmc 0 0x02A00000 devicetree.dtb && bootm 0x03000000 - 0x02A00000
というテキストファイルを作ってboot.txtという名前で保存しておいて、
mkimage -A arm -O linux -T script -C none -a 0 -e 0 -d boot.txt boot.scr
で生成できるはずです。従来、uEnv.txtを書けばZYNQ Linuxは起動したのですが、U-Boot 2023.1ではboot.scrが必須になっていました。(おそらくもっと前から必須になっていた)
uEnv.txtは環境変数を定義するだけのファイルであったのに対し、boot.scrはコマンドを実行するので、例えばNANDフラッシュからブートしてだめだったらSDカードを読み入って、それでも最後にネットワークブートする、というようなコマンドが書けます。そんな機能私はいらないんですけどね。
ZYNQのPSの設定を変えたとき、その設定を反映させるのは論理合成して.bitを作ることではありません。PSを変えたら、export hardwareしてxsaファイルを作り、Vitisでハードウェア情報をアップデートしてFSBLを作り直さなければなりません。
そのやり方ですが、VivadoでFile→Export Hardwareをしたら、Vitisでプラットフォームプロジェクト(緑のアイコン)を右クリックし、Update Hardware Specificationを実行します。
XSAファイルを開くダイアログが出るので、Vitisで生成したXSAを指定します。
これでアップデートがされるので、最後にFSBLのビルドボタンを忘れずに押します。
そうしてfsbl.elfが出来たら再びboot.binに固めて完成です。
最も苦労したのは、Linuxが起動したときにmmc0blkp2をマウントできなくてカーネルパニックする件です。
[ 1.779581] VFS: Cannot open root device "mmcblk0p2" or unknown-block(179,2): error -30
このようなエラーが最初に出て、最後には
[ 1.779581] VFS: Cannot open root device "mmcblk0p2" or unknown-block(179,2): error -30
[ 1.787646] usb 1-1: new high-speed USB device number 2 using ci_hdrc
[ 1.790999] Please append a correct "root=" boot option; here are the available partitions:
[ 1.802611] 0100 16384 ram0
[ 1.802625] (driver?)
[ 1.808715] 0101 16384 ram1
[ 1.808725] (driver?)
[ 1.814862] 0102 16384 ram2
[ 1.814873] (driver?)
[ 1.821003] 0103 16384 ram3
[ 1.821014] (driver?)
[ 1.827108] 0104 16384 ram4
[ 1.827118] (driver?)
[ 1.833271] 0105 16384 ram5
[ 1.833282] (driver?)
[ 1.839372] 0106 16384 ram6
[ 1.839381] (driver?)
[ 1.845502] 0107 16384 ram7
[ 1.845512] (driver?)
[ 1.851628] 0108 16384 ram8
[ 1.851639] (driver?)
[ 1.857748] 0109 16384 ram9
[ 1.857758] (driver?)
[ 1.863869] 010a 16384 ram10
[ 1.863879] (driver?)
[ 1.870056] 010b 16384 ram11
[ 1.870065] (driver?)
[ 1.876254] 010c 16384 ram12
[ 1.876264] (driver?)
[ 1.882465] 010d 16384 ram13
[ 1.882475] (driver?)
[ 1.888648] 010e 16384 ram14
[ 1.888657] (driver?)
[ 1.894847] 010f 16384 ram15
[ 1.894857] (driver?)
[ 1.901059] 1f00 1024 mtdblock0
[ 1.901069] (driver?)
[ 1.907588] 1f01 5120 mtdblock1
[ 1.907597] (driver?)
[ 1.914134] 1f02 128 mtdblock2
[ 1.914145] (driver?)
[ 1.920669] 1f03 6016 mtdblock3
[ 1.920679] (driver?)
[ 1.927215] 1f04 4096 mtdblock4
[ 1.927224] (driver?)
[ 1.933760] b300 30253056 mmcblk0
[ 1.933770] driver: mmcblk
[ 1.940553] b301 307200 mmcblk0p1 58f06737-01
[ 1.940563]
[ 1.947368] b302 29944832 mmcblk0p2 58f06737-02
[ 1.947379]
[ 1.954188] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(179,2)
[ 1.962628] CPU1: stopping
[ 1.965335] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 5.15.0-xilinx-00211-g528b5fb42f76-dirty #1
[ 1.974125] Hardware name: Xilinx Zynq Platform
[ 1.978656] [<c010cb38>] (unwind_backtrace) from [<c0109060>] (show_stack+0x10/0x14)
[ 1.986426] [<c0109060>] (show_stack) from [<c0ba2ba4>] (dump_stack_lvl+0x40/0x4c)
[ 1.994013] [<c0ba2ba4>] (dump_stack_lvl) from [<c010b1f0>] (do_handle_IPI+0x80/0x140)
[ 2.001945] [<c010b1f0>] (do_handle_IPI) from [<c010b2c4>] (ipi_handler+0x14/0x20)
[ 2.009522] [<c010b2c4>] (ipi_handler) from [<c015be20>] (handle_percpu_devid_irq+0x4c/0xe8)
[ 2.017986] [<c015be20>] (handle_percpu_devid_irq) from [<c0156d04>] (handle_irq_desc+0x24/0x34)
[ 2.026788] [<c0156d04>] (handle_irq_desc) from [<c0157388>] (handle_domain_irq+0x40/0x54)
[ 2.035059] [<c0157388>] (handle_domain_irq) from [<c0390e24>] (gic_handle_irq+0x70/0x80)
[ 2.043254] [<c0390e24>] (gic_handle_irq) from [<c0100afc>] (__irq_svc+0x5c/0x90)
[ 2.050743] Exception stack(0xc1481f08 to 0xc1481f50)
[ 2.055793] 1f00: 00000000 00000000 1da99000 debdd540 c1288be0 00000000
[ 2.063970] 1f20: 74e253fa 74fb46dc 00000000 00000000 debdc878 00000000 fffffff5 c1481f58
[ 2.072143] 1f40: c098c320 c098c344 60000113 ffffffff
[ 2.077184] [<c0100afc>] (__irq_svc) from [<c098c344>] (cpuidle_enter_state+0x17c/0x304)
[ 2.085292] [<c098c344>] (cpuidle_enter_state) from [<c098c508>] (cpuidle_enter+0x28/0x38)
[ 2.093571] [<c098c508>] (cpuidle_enter) from [<c013edb8>] (do_idle+0x248/0x270)
[ 2.100985] [<c013edb8>] (do_idle) from [<c013ef44>] (cpu_startup_entry+0x18/0x1c)
[ 2.108570] [<c013ef44>] (cpu_startup_entry) from [<00101450>] (0x101450)
[ 2.115375] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(179,2) ]---
でカーネルクラッシュします。
この原因ですが、PSのSDIOのWPにHを入れっぱなしだったことが原因でした。WPはLにしなければなりません。
他にも、LinuxでUSBを認識させるには、dr_mode = "host";が必要です。
usb@e0002000 {
compatible = "xlnx,zynq-usb-2.20a\0chipidea,usb2";
status = "okay";
clocks = <0x01 0x1c>;
interrupt-parent = <0x04>;
interrupts = <0x00 0x15 0x04>;
reg = <0xe0002000 0x1000>;
phy_type = "ulpi";
dr_mode = "host";
usb-phy = <0x06>;
};
これがないとUSBを認識せず、lsusbで何も出てこなくなります。
最終的にLinuxは起動して、USBもGbEも認識するようになりました。
なんだか他にもいっぱいあった気がしますが、大きなハマりポイントは以上のとおりでした。
| 固定リンク
コメント