0001
0002
0003
0004
0005
0006
0007
0008 usage() {
0009
0010
0011 cat >&2 <<eod
0012
0013 Usage:
0014
0015 `basename $0` DTx
0016 decompile DTx
0017
0018 `basename $0` DTx_1 DTx_2
0019 diff DTx_1 and DTx_2
0020
0021
0022 --annotate synonym for -T
0023 --color synonym for -c (requires diff with --color support)
0024 -c enable colored output
0025 -f print full dts in diff (--unified=99999)
0026 -h synonym for --help
0027 -help synonym for --help
0028 --help print this message and exit
0029 -s SRCTREE linux kernel source tree is at path SRCTREE
0030 (default is current directory)
0031 -S linux kernel source tree is at root of current git repo
0032 -T annotate output .dts with input source file and line
0033 (-T -T for more details)
0034 -u unsorted, do not sort DTx
0035
0036
0037 Each DTx is processed by the dtc compiler to produce a sorted dts source
0038 file. If DTx is a dts source file then it is pre-processed in the same
0039 manner as done for the compile of the dts source file in the Linux kernel
0040 build system ('#include' and '/include/' directives are processed).
0041
0042 If two DTx are provided, the resulting dts source files are diffed.
0043
0044 If DTx is a directory, it is treated as a DT subtree, such as
0045 /proc/device-tree.
0046
0047 If DTx contains the binary blob magic value in the first four bytes,
0048 it is treated as a binary blob (aka .dtb or FDT).
0049
0050 Otherwise DTx is treated as a dts source file (aka .dts).
0051
0052 If this script is not run from the root of the linux source tree,
0053 and DTx utilizes '#include' or '/include/' then the path of the
0054 linux source tree can be provided by '-s SRCTREE' or '-S' so that
0055 include paths will be set properly.
0056
0057 The shell variable \${ARCH} must provide the architecture containing
0058 the dts source file for include paths to be set properly for '#include'
0059 or '/include/' to be processed.
0060
0061 If DTx_1 and DTx_2 are in different architectures, then this script
0062 may not work since \${ARCH} is part of the include path. The following
0063 workaround can be used:
0064
0065 `basename $0` ARCH=arch_of_dtx_1 DTx_1 >tmp_dtx_1.dts
0066 `basename $0` ARCH=arch_of_dtx_2 DTx_2 >tmp_dtx_2.dts
0067 `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts
0068 rm tmp_dtx_1.dts tmp_dtx_2.dts
0069
0070 If DTx_1 and DTx_2 are in different directories, then this script will
0071 add the path of DTx_1 and DTx_2 to the include paths. If DTx_2 includes
0072 a local file that exists in both the path of DTx_1 and DTx_2 then the
0073 file in the path of DTx_1 will incorrectly be included. Possible
0074 workaround:
0075
0076 `basename $0` DTx_1 >tmp_dtx_1.dts
0077 `basename $0` DTx_2 >tmp_dtx_2.dts
0078 `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts
0079 rm tmp_dtx_1.dts tmp_dtx_2.dts
0080
0081 eod
0082 }
0083
0084
0085 compile_to_dts() {
0086
0087 dtx="$1"
0088 dtc_include="$2"
0089
0090 if [ -d "${dtx}" ] ; then
0091
0092
0093
0094 if ( ! ${DTC} -I fs ${dtx} ) ; then
0095 exit 3
0096 fi
0097
0098 elif [ -f "${dtx}" ] && [ -r "${dtx}" ] ; then
0099
0100 magic=`hexdump -n 4 -e '/1 "%02x"' ${dtx}`
0101 if [ "${magic}" = "d00dfeed" ] ; then
0102
0103
0104
0105 if ( ! ${DTC} -I dtb ${dtx} ) ; then
0106 exit 3
0107 fi
0108
0109 return
0110
0111 fi
0112
0113
0114
0115 if ( cpp ${cpp_flags} -x assembler-with-cpp ${dtx} \
0116 | ${DTC} ${dtc_include} -I dts ) ; then
0117 return
0118 fi
0119
0120 echo "" >&2
0121 echo "Possible hints to resolve the above error:" >&2
0122 echo " (hints might not fix the problem)" >&2
0123
0124 hint_given=0
0125
0126 if [ "${ARCH}" = "" ] ; then
0127 hint_given=1
0128 echo "" >&2
0129 echo " shell variable \$ARCH not set" >&2
0130 fi
0131
0132 dtx_arch=`echo "/${dtx}" | sed -e 's|.*/arch/||' -e 's|/.*||'`
0133
0134 if [ "${dtx_arch}" != "" -a "${dtx_arch}" != "${ARCH}" ] ; then
0135 hint_given=1
0136 echo "" >&2
0137 echo " architecture ${dtx_arch} is in file path," >&2
0138 echo " but does not match shell variable \$ARCH" >&2
0139 echo " >>\$ARCH<< is: >>${ARCH}<<" >&2
0140 fi
0141
0142 if [ ! -d ${srctree}/arch/${ARCH} ] ; then
0143 hint_given=1
0144 echo "" >&2
0145 echo " ${srctree}/arch/${ARCH}/ does not exist" >&2
0146 echo " Is \$ARCH='${ARCH}' correct?" >&2
0147 echo " Possible fix: use '-s' option" >&2
0148
0149 git_root=`git rev-parse --show-toplevel 2>/dev/null`
0150 if [ -d ${git_root}/arch/ ] ; then
0151 echo " Possible fix: use '-S' option" >&2
0152 fi
0153 fi
0154
0155 if [ $hint_given = 0 ] ; then
0156 echo "" >&2
0157 echo " No hints available." >&2
0158 fi
0159
0160 echo "" >&2
0161
0162 exit 3
0163
0164 else
0165 echo "" >&2
0166 echo "ERROR: ${dtx} does not exist or is not readable" >&2
0167 echo "" >&2
0168 exit 2
0169 fi
0170
0171 }
0172
0173
0174
0175
0176 annotate=""
0177 cmd_diff=0
0178 diff_flags="-u"
0179 diff_color=""
0180 dtx_file_1=""
0181 dtx_file_2=""
0182 dtc_sort="-s"
0183 help=0
0184 srctree=""
0185
0186
0187 while [ $
0188
0189 case $1 in
0190
0191 -c | --color )
0192 if diff --color /dev/null /dev/null 2>/dev/null ; then
0193 diff_color="--color=always"
0194 fi
0195 shift
0196 ;;
0197
0198 -f )
0199 diff_flags="--unified=999999"
0200 shift
0201 ;;
0202
0203 -h | -help | --help )
0204 help=1
0205 shift
0206 ;;
0207
0208 -s )
0209 srctree="$2"
0210 shift 2
0211 ;;
0212
0213 -S )
0214 git_root=`git rev-parse --show-toplevel 2>/dev/null`
0215 srctree="${git_root}"
0216 shift
0217 ;;
0218
0219 -T | --annotate )
0220 if [ "${annotate}" = "" ] ; then
0221 annotate="-T"
0222 elif [ "${annotate}" = "-T" ] ; then
0223 annotate="-T -T"
0224 fi
0225 shift
0226 ;;
0227 -u )
0228 dtc_sort=""
0229 shift
0230 ;;
0231
0232 *)
0233 if [ "${dtx_file_1}" = "" ] ; then
0234 dtx_file_1="$1"
0235 elif [ "${dtx_file_2}" = "" ] ; then
0236 dtx_file_2="$1"
0237 else
0238 echo "" >&2
0239 echo "ERROR: Unexpected parameter: $1" >&2
0240 echo "" >&2
0241 exit 2
0242 fi
0243 shift
0244 ;;
0245
0246 esac
0247
0248 done
0249
0250 if [ "${srctree}" = "" ] ; then
0251 srctree="."
0252 fi
0253
0254 if [ "${dtx_file_2}" != "" ]; then
0255 cmd_diff=1
0256 fi
0257
0258 if (( ${help} )) ; then
0259 usage
0260 exit 1
0261 fi
0262
0263
0264 if [ "${dtx_file_1}" = "" ]; then
0265 echo "" >&2
0266 echo "ERROR: parameter DTx required" >&2
0267 echo "" >&2
0268 exit 2
0269 fi
0270
0271
0272
0273
0274 if [ "${KBUILD_OUTPUT:0:2}" = ".." ] ; then
0275 __KBUILD_OUTPUT="${srctree}/${KBUILD_OUTPUT}"
0276 elif [ "${KBUILD_OUTPUT}" = "" ] ; then
0277 __KBUILD_OUTPUT="."
0278 else
0279 __KBUILD_OUTPUT="${KBUILD_OUTPUT}"
0280 fi
0281
0282 DTC="${__KBUILD_OUTPUT}/scripts/dtc/dtc"
0283
0284 if [ ! -x ${DTC} ] ; then
0285 __DTC="dtc"
0286 if grep -q "^CONFIG_DTC=y" ${__KBUILD_OUTPUT}/.config 2>/dev/null; then
0287 make_command='
0288 make scripts'
0289 else
0290 make_command='
0291 Enable CONFIG_DTC in the kernel configuration
0292 make scripts'
0293 fi
0294 if ( ! which ${__DTC} >/dev/null ) ; then
0295
0296
0297 cat >&2 <<eod
0298
0299 ERROR: unable to find a 'dtc' program
0300
0301 Preferred 'dtc' (built from Linux kernel source tree) was not found or
0302 is not executable.
0303
0304 'dtc' is: ${DTC}
0305
0306 If it does not exist, create it from the root of the Linux source tree:
0307 ${make_command}
0308
0309 If not at the root of the Linux kernel source tree -s SRCTREE or -S
0310 may need to be specified to find 'dtc'.
0311
0312 If 'O=\${dir}' is specified in your Linux builds, this script requires
0313 'export KBUILD_OUTPUT=\${dir}' or add \${dir}/scripts/dtc to \$PATH
0314 before running.
0315
0316 If \${KBUILD_OUTPUT} is a relative path, then '-s SRCDIR', -S, or run
0317 this script from the root of the Linux kernel source tree is required.
0318
0319 Fallback '${__DTC}' was also not in \${PATH} or is not executable.
0320
0321 eod
0322 exit 2
0323 fi
0324 DTC=${__DTC}
0325 fi
0326
0327
0328
0329
0330
0331 dtx_path_1_dtc_include="-i `dirname ${dtx_file_1}`"
0332
0333 dtx_path_2_dtc_include=""
0334 if (( ${cmd_diff} )) ; then
0335 dtx_path_2_dtc_include="-i `dirname ${dtx_file_2}`"
0336 fi
0337
0338 cpp_flags="\
0339 -nostdinc \
0340 -I${srctree}/scripts/dtc/include-prefixes \
0341 -undef -D__DTS__"
0342
0343 DTC="\
0344 ${DTC} \
0345 -i ${srctree}/scripts/dtc/include-prefixes \
0346 -O dts -qq -f ${dtc_sort} ${annotate} -o -"
0347
0348
0349
0350
0351 if (( ${cmd_diff} )) ; then
0352
0353 diff ${diff_flags} ${diff_color} --label "${dtx_file_1}" --label "${dtx_file_2}" \
0354 <(compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}") \
0355 <(compile_to_dts "${dtx_file_2}" "${dtx_path_2_dtc_include}")
0356
0357 else
0358
0359 compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}"
0360
0361 fi