はじめに
「Zynq MPSoCで、コンピュータを学ぼう」のその2です。
- その1 : Xilinx社のZynqUltrascale+ MPSoC について
- その2 : Zynq Ultrascale+ MPSoC がどのように立ち上がっていくのか
- その3 : Linux の dts を見て、どのようなハードウェアを使っているのか?
- その4 : Linux の デバイスドライバについて
- その5 : Programmable Logic
- その6 : QEMU (Zynq Ultrascale+ MPSoC の実物が無くても、Linuxが立ち上がる)
Linux の dts を見て、どのようなハードウェアを使っているのか?
Linux のソースコードを調べるポイントとしては、次の2つです。
- dts ファイルの中を見て、どのようなハードウェアを使っているのか?
- dts ファイルの中で使っているハードウェアのデバイスドライバは何をやっているのか?
今回は、この2つの内、最初の dts ファイルの中を見ていきます。
dts って何?
dts とは、device tree source の略です。Qiita に説明があります。
qiita.com
dts を DTC (Device Tree Compiler) というソフトウェアでコンパイルしたのが、DTB (Device Tree Blob) です。この DTB ファイルを Linux で使います。
Linuxで使っている DTB ファイルは、DTC にて逆アセンブルしてくれます。
Xilinx社に関係する dts の場所は、
github.com
にあります。
- Ultra96 v1用 : avnet-ultra96-rev1.dts
- Kria KV260用 : zynqmp-sm-k26-revA.dts / zynqmp-smk-k26-revA.dts
の dts があります。
Ultra96 v1用の avnet-ultra96-rev1.dts を見てみます。zynqmp-zcu100-revC.dts という dts ファイルを include しています。
/dts-v1/;
#include "zynqmp-zcu100-revC.dts"
/ {
model = "Avnet Ultra96 Rev1";
compatible = "avnet,ultra96-rev1", "avnet,ultra96",
"xlnx,zynqmp-zcu100-revC", "xlnx,zynqmp-zcu100",
"xlnx,zynqmp";
};
zynqmp-zcu100-revC.dts の最初で、zynqmp.dtsi ファイルを include しています。
/dts-v1/;
#include "zynqmp.dtsi"
#include "zynqmp-clk-ccf.dtsi"
#include <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
#include <dt-bindings/phy/phy.h>
zynqmp-sm-k26-revA.dts でも同様に zynqmp.dtsi ファイルを include しています。
zynqmp.dtsi の中を覗いてみますと、下記の cpus に、ARM Cortex-A53x4 のエントリーがあります。
#include <dt-bindings/dma/xlnx-zynqmp-dpdma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power/xlnx-zynqmp-power.h>
#include <dt-bindings/reset/xlnx-zynqmp-resets.h>
/ {
compatible = "xlnx,zynqmp";
#address-cells = <2>;
#size-cells = <2>;
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
compatible = "arm,cortex-a53";
device_type = "cpu";
enable-method = "psci";
operating-points-v2 = <&cpu_opp_table>;
reg = <0x0>;
cpu-idle-states = <&CPU_SLEEP_0>;
};
cpu1: cpu@1 {
compatible = "arm,cortex-a53";
device_type = "cpu";
enable-method = "psci";
reg = <0x1>;
operating-points-v2 = <&cpu_opp_table>;
cpu-idle-states = <&CPU_SLEEP_0>;
};
cpu2: cpu@2 {
compatible = "arm,cortex-a53";
device_type = "cpu";
enable-method = "psci";
reg = <0x2>;
operating-points-v2 = <&cpu_opp_table>;
cpu-idle-states = <&CPU_SLEEP_0>;
};
cpu3: cpu@3 {
compatible = "arm,cortex-a53";
device_type = "cpu";
enable-method = "psci";
reg = <0x3>;
operating-points-v2 = <&cpu_opp_table>;
cpu-idle-states = <&CPU_SLEEP_0>;
};
idle-states {
entry-method = "psci";
CPU_SLEEP_0: cpu-sleep-0 {
compatible = "arm,idle-state";
arm,psci-suspend-param = <0x40000000>;
local-timer-stop;
entry-latency-us = <300>;
exit-latency-us = <600>;
min-residency-us = <10000>;
};
};
};
cpus の cpu0 を詳しく見てみます。cpuX: cpu@X の X は、コアの番号です。compatible の部分がどんなコアかを示すもので、"arm,cortex-a53"、つまり、ARM Cortex-A53 だということを示しています。
cpu0: cpu@0 {
compatible = "arm,cortex-a53";
device_type = "cpu";
enable-method = "psci";
operating-points-v2 = <&cpu_opp_table>;
reg = <0x0>;
cpu-idle-states = <&CPU_SLEEP_0>;
};
この中のポイントは、enable-method です。これは、省エネの時にどのような方法を行って制御するのかを示すもので、ここでは、"psci" となっています。psci とは、Power State Coordination Interface の略で、サスペンド、シャットダウン、リブートなど、Arm プロセッサのシステ ム電源ステータスを制御するための標準インターフェイスです。psci のエントリーは、下記のようになっています。"arm,psic-0.2", method が "smc" です。
psci {
compatible = "arm,psci-0.2";
method = "smc";
};
PSCIについては、下記のスライドにまとめていますので、参考にしてくださいね。
www.slideshare.net
PSCIは、ARM v8 64ビットの標準的な省エネ機能を実現するソフトウェアです。ただし、サーバーやAppleのM1シリーズ/M2 に関しては、"psci" にはなっていません。M1 (t8103) の dts ファイル (t8103.dts) の cpu0 のエントリーを見てみます。enable-method は、"spin-table" になっています。
cpu0: cpu@0 {
compatible = "apple,icestorm";
device_type = "cpu";
reg = <0x0 0x0>;
enable-method = "spin-table";
cpu-release-addr = <0 0>; /* To be filled by loader */
};
"spin-table" の時の処理は、下記の smp_spin_table.c がそのようです。
github.com
おわりに
2016年2月20日(金)のZynq Ultrasclae+ MPSoC 勉強会で使った資料です。
この時には、Zynq Ultrascale+ MPSoC の実物はまだリリースされていませんでした。
こちらには、前半はブートの説明、後半はLinuxの説明をしています。
参考までに