Xilinx社の Zynq や Altera社の Cyclene V SoC などの ARM プロセッサをターゲットにした Linux カーネルをブートする時、Device Tree Blob(DTB)が必要になります。
通常は Linux カーネルをビルドする際に自動的に DTB も生成されるのですが、なんらかの事情で自力でコンパイルする必要が生じることもあります。
その際、たまに Device Tree Source(DTS)にCプリプロセッサのマクロ(#include や #define)を使っているものがあります。例えば、Altera社の Cyclone V SoC を使った DE0-Nano-SoC 用の Device Tree Source(socfpga_cyclone5_sockit.dts)など。
このような Device Tree Source(DTS) を Device Tree Compiler(dtc) を使ってコンパイルする時は次のようにします。
gcc -E -P -nostdinc -undef -x assembler-with-cpp -I $(LINUX_KERNEL_SRC)/arch/arm/boot/dts -I $(LINUX_KERNEL_SRC)/include $(DTS_SRC_FILE) | dtc -I dts -O dtb -i $(LINUX_KERNEL_SRC)/arch/arm/boot/dts -o $(DTB_OUT_FILE)
- $(LINUX_KERNEL_SRC) には Linux カーネルのソースコードのディレクトリを指定します。
- gcc の -E オプションで C Preprocessor のみを使うことを指定します。
- gcc の -P オプションで #line 指示子を生成しないよう指示します。そうしないと後段の dtc でエラーになります。
- gcc の -nostdinc オプションで標準インクルードディレクトリを無効化します。
- gcc の -undef オプションで組み込みマクロを無効化します。例えば 'linux' という単語が定数に置換されるのを防ぎます。
- gcc の -x assembler-with-cpp で、Device Tree Source(DTS)に含まれる #から始まる文(#address-cellsや#size-cells)をエラーにしないようにします。これをつけないと元々あった#から始まる文が削除されてしまいます。
- gcc の -I オプションで gccが インクルードするパスを指定します。ここでは Linux カーネルのソースコードに含まれる Device Tree Source のパスと、Linux カーネルのインクルードパスを指定しています。
- dtc の -I オプションで入力フォーマットを指定します。ここでは Device Tree Source(dts)を指定しています。
- dtc の -O オプションで出力フォーマットを指定します。ここでは Device Tree Blob(dtb)を指定しています。
- dtc の -i オプションで dtcが インクルードするパスを指定します。ここでは Linux カーネルのソースコードに含まれる Device Tree Source のパスを指定しています。
- dtc の -o オプションで出力するファイル名を指定します。