1 #! /bin/bash 1 #! /bin/bash 2 # SPDX-License-Identifier: GPL-2.0-only << 3 2 4 # Copyright (C) 2015 Frank Rowand 3 # Copyright (C) 2015 Frank Rowand 5 # 4 # >> 5 # This program is free software; you can redistribute it and/or modify >> 6 # it under the terms of the GNU General Public License as published by >> 7 # the Free Software Foundation; version 2 of the License. 6 8 7 9 8 usage() { 10 usage() { 9 11 10 # use spaces instead of tabs in the us 12 # use spaces instead of tabs in the usage message 11 cat >&2 <<eod 13 cat >&2 <<eod 12 14 13 Usage: 15 Usage: 14 16 15 `basename $0` DTx 17 `basename $0` DTx 16 decompile DTx 18 decompile DTx 17 19 18 `basename $0` DTx_1 DTx_2 20 `basename $0` DTx_1 DTx_2 19 diff DTx_1 and DTx_2 21 diff DTx_1 and DTx_2 20 22 21 23 22 --annotate synonym for -T << 23 --color synonym for -c (requires d << 24 -c enable colored output << 25 -f print full dts in diff (-- 24 -f print full dts in diff (--unified=99999) 26 -h synonym for --help 25 -h synonym for --help 27 -help synonym for --help 26 -help synonym for --help 28 --help print this message and exi 27 --help print this message and exit 29 -s SRCTREE linux kernel source tree i 28 -s SRCTREE linux kernel source tree is at path SRCTREE 30 (default is current di 29 (default is current directory) 31 -S linux kernel source tree i 30 -S linux kernel source tree is at root of current git repo 32 -T annotate output .dts with << 33 (-T -T for more detail << 34 -u unsorted, do not sort DTx 31 -u unsorted, do not sort DTx 35 32 36 33 37 Each DTx is processed by the dtc compiler to p 34 Each DTx is processed by the dtc compiler to produce a sorted dts source 38 file. If DTx is a dts source file then it is 35 file. If DTx is a dts source file then it is pre-processed in the same 39 manner as done for the compile of the dts sour 36 manner as done for the compile of the dts source file in the Linux kernel 40 build system ('#include' and '/include/' direc 37 build system ('#include' and '/include/' directives are processed). 41 38 42 If two DTx are provided, the resulting dts sou 39 If two DTx are provided, the resulting dts source files are diffed. 43 40 44 If DTx is a directory, it is treated as a DT s 41 If DTx is a directory, it is treated as a DT subtree, such as 45 /proc/device-tree. 42 /proc/device-tree. 46 43 47 If DTx contains the binary blob magic value in 44 If DTx contains the binary blob magic value in the first four bytes, 48 it is treated as a binary blob (aka .dtb or 45 it is treated as a binary blob (aka .dtb or FDT). 49 46 50 Otherwise DTx is treated as a dts source file 47 Otherwise DTx is treated as a dts source file (aka .dts). 51 48 52 If this script is not run from the root of 49 If this script is not run from the root of the linux source tree, 53 and DTx utilizes '#include' or '/include/' 50 and DTx utilizes '#include' or '/include/' then the path of the 54 linux source tree can be provided by '-s SR 51 linux source tree can be provided by '-s SRCTREE' or '-S' so that 55 include paths will be set properly. 52 include paths will be set properly. 56 53 57 The shell variable \${ARCH} must provide th 54 The shell variable \${ARCH} must provide the architecture containing 58 the dts source file for include paths to be 55 the dts source file for include paths to be set properly for '#include' 59 or '/include/' to be processed. 56 or '/include/' to be processed. 60 57 61 If DTx_1 and DTx_2 are in different archite 58 If DTx_1 and DTx_2 are in different architectures, then this script 62 may not work since \${ARCH} is part of the 59 may not work since \${ARCH} is part of the include path. The following 63 workaround can be used: 60 workaround can be used: 64 61 65 `basename $0` ARCH=arch_of_dtx_1 DTx_1 > 62 `basename $0` ARCH=arch_of_dtx_1 DTx_1 >tmp_dtx_1.dts 66 `basename $0` ARCH=arch_of_dtx_2 DTx_2 > 63 `basename $0` ARCH=arch_of_dtx_2 DTx_2 >tmp_dtx_2.dts 67 `basename $0` tmp_dtx_1.dts tmp_dtx_2.dt 64 `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts 68 rm tmp_dtx_1.dts tmp_dtx_2.dts 65 rm tmp_dtx_1.dts tmp_dtx_2.dts 69 66 70 If DTx_1 and DTx_2 are in different directo 67 If DTx_1 and DTx_2 are in different directories, then this script will 71 add the path of DTx_1 and DTx_2 to the incl 68 add the path of DTx_1 and DTx_2 to the include paths. If DTx_2 includes 72 a local file that exists in both the path o 69 a local file that exists in both the path of DTx_1 and DTx_2 then the 73 file in the path of DTx_1 will incorrectly 70 file in the path of DTx_1 will incorrectly be included. Possible 74 workaround: 71 workaround: 75 72 76 `basename $0` DTx_1 >tmp_dtx_1.dts 73 `basename $0` DTx_1 >tmp_dtx_1.dts 77 `basename $0` DTx_2 >tmp_dtx_2.dts 74 `basename $0` DTx_2 >tmp_dtx_2.dts 78 `basename $0` tmp_dtx_1.dts tmp_dtx_2.dt 75 `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts 79 rm tmp_dtx_1.dts tmp_dtx_2.dts 76 rm tmp_dtx_1.dts tmp_dtx_2.dts 80 77 81 eod 78 eod 82 } 79 } 83 80 84 81 85 compile_to_dts() { 82 compile_to_dts() { 86 83 87 dtx="$1" 84 dtx="$1" 88 dtc_include="$2" << 89 85 90 if [ -d "${dtx}" ] ; then 86 if [ -d "${dtx}" ] ; then 91 87 92 # ----- input is file tree 88 # ----- input is file tree 93 89 94 if ( ! ${DTC} -I fs ${dtx} ) ; 90 if ( ! ${DTC} -I fs ${dtx} ) ; then 95 exit 3 91 exit 3 96 fi 92 fi 97 93 98 elif [ -f "${dtx}" ] && [ -r "${dtx}" 94 elif [ -f "${dtx}" ] && [ -r "${dtx}" ] ; then 99 95 100 magic=`hexdump -n 4 -e '/1 "%0 96 magic=`hexdump -n 4 -e '/1 "%02x"' ${dtx}` 101 if [ "${magic}" = "d00dfeed" ] 97 if [ "${magic}" = "d00dfeed" ] ; then 102 98 103 # ----- input is FDT 99 # ----- input is FDT (binary blob) 104 100 105 if ( ! ${DTC} -I dtb $ 101 if ( ! ${DTC} -I dtb ${dtx} ) ; then 106 exit 3 102 exit 3 107 fi 103 fi 108 104 109 return 105 return 110 106 111 fi 107 fi 112 108 113 # ----- input is DTS (source) 109 # ----- input is DTS (source) 114 110 115 if ( cpp ${cpp_flags} -x assem 111 if ( cpp ${cpp_flags} -x assembler-with-cpp ${dtx} \ 116 | ${DTC} ${dtc_include !! 112 | ${DTC} -I dts ) ; then 117 return 113 return 118 fi 114 fi 119 115 120 echo "" 116 echo "" >&2 121 echo "Possible hints to resolv 117 echo "Possible hints to resolve the above error:" >&2 122 echo " (hints might not fix t 118 echo " (hints might not fix the problem)" >&2 123 119 124 hint_given=0 120 hint_given=0 125 121 126 if [ "${ARCH}" = "" ] ; then 122 if [ "${ARCH}" = "" ] ; then 127 hint_given=1 123 hint_given=1 128 echo "" 124 echo "" >&2 129 echo " shell variable 125 echo " shell variable \$ARCH not set" >&2 130 fi 126 fi 131 127 132 dtx_arch=`echo "/${dtx}" | sed 128 dtx_arch=`echo "/${dtx}" | sed -e 's|.*/arch/||' -e 's|/.*||'` 133 129 134 if [ "${dtx_arch}" != "" -a " 130 if [ "${dtx_arch}" != "" -a "${dtx_arch}" != "${ARCH}" ] ; then 135 hint_given=1 131 hint_given=1 136 echo "" 132 echo "" >&2 137 echo " architecture $ 133 echo " architecture ${dtx_arch} is in file path," >&2 138 echo " but does not m 134 echo " but does not match shell variable \$ARCH" >&2 139 echo " >>\$ARCH<< is: 135 echo " >>\$ARCH<< is: >>${ARCH}<<" >&2 140 fi 136 fi 141 137 142 if [ ! -d ${srctree}/arch/${AR 138 if [ ! -d ${srctree}/arch/${ARCH} ] ; then 143 hint_given=1 139 hint_given=1 144 echo "" 140 echo "" >&2 145 echo " ${srctree}/arc 141 echo " ${srctree}/arch/${ARCH}/ does not exist" >&2 146 echo " Is \$ARCH='${A 142 echo " Is \$ARCH='${ARCH}' correct?" >&2 147 echo " Possible fix: 143 echo " Possible fix: use '-s' option" >&2 148 144 149 git_root=`git rev-pars 145 git_root=`git rev-parse --show-toplevel 2>/dev/null` 150 if [ -d ${git_root}/ar 146 if [ -d ${git_root}/arch/ ] ; then 151 echo " Possib 147 echo " Possible fix: use '-S' option" >&2 152 fi 148 fi 153 fi 149 fi 154 150 155 if [ $hint_given = 0 ] ; then 151 if [ $hint_given = 0 ] ; then 156 echo "" 152 echo "" >&2 157 echo " No hints avail 153 echo " No hints available." >&2 158 fi 154 fi 159 155 160 echo "" 156 echo "" >&2 161 157 162 exit 3 158 exit 3 163 159 164 else 160 else 165 echo "" 161 echo "" >&2 166 echo "ERROR: ${dtx} does not e 162 echo "ERROR: ${dtx} does not exist or is not readable" >&2 167 echo "" 163 echo "" >&2 168 exit 2 164 exit 2 169 fi 165 fi 170 166 171 } 167 } 172 168 173 169 174 # ----- start of script 170 # ----- start of script 175 171 176 annotate="" << 177 cmd_diff=0 172 cmd_diff=0 178 diff_flags="-u" 173 diff_flags="-u" 179 diff_color="" << 180 dtx_file_1="" 174 dtx_file_1="" 181 dtx_file_2="" 175 dtx_file_2="" 182 dtc_sort="-s" 176 dtc_sort="-s" 183 help=0 177 help=0 184 srctree="" 178 srctree="" 185 179 186 180 187 while [ $# -gt 0 ] ; do 181 while [ $# -gt 0 ] ; do 188 182 189 case $1 in 183 case $1 in 190 184 191 -c | --color ) << 192 if diff --color /dev/null /dev << 193 diff_color="--color=al << 194 fi << 195 shift << 196 ;; << 197 << 198 -f ) 185 -f ) 199 diff_flags="--unified=999999" 186 diff_flags="--unified=999999" 200 shift 187 shift 201 ;; 188 ;; 202 189 203 -h | -help | --help ) 190 -h | -help | --help ) 204 help=1 191 help=1 205 shift 192 shift 206 ;; 193 ;; 207 194 208 -s ) 195 -s ) 209 srctree="$2" 196 srctree="$2" 210 shift 2 197 shift 2 211 ;; 198 ;; 212 199 213 -S ) 200 -S ) 214 git_root=`git rev-parse --show 201 git_root=`git rev-parse --show-toplevel 2>/dev/null` 215 srctree="${git_root}" 202 srctree="${git_root}" 216 shift 203 shift 217 ;; 204 ;; 218 205 219 -T | --annotate ) << 220 if [ "${annotate}" = "" ] ; t << 221 annotate="-T" << 222 elif [ "${annotate}" = "-T" ] << 223 annotate="-T -T" << 224 fi << 225 shift << 226 ;; << 227 -u ) 206 -u ) 228 dtc_sort="" 207 dtc_sort="" 229 shift 208 shift 230 ;; 209 ;; 231 210 232 *) 211 *) 233 if [ "${dtx_file_1}" = "" ] ; 212 if [ "${dtx_file_1}" = "" ] ; then 234 dtx_file_1="$1" 213 dtx_file_1="$1" 235 elif [ "${dtx_file_2}" = "" ] 214 elif [ "${dtx_file_2}" = "" ] ; then 236 dtx_file_2="$1" 215 dtx_file_2="$1" 237 else 216 else 238 echo "" 217 echo "" >&2 239 echo "ERROR: Unexpecte 218 echo "ERROR: Unexpected parameter: $1" >&2 240 echo "" 219 echo "" >&2 241 exit 2 220 exit 2 242 fi 221 fi 243 shift 222 shift 244 ;; 223 ;; 245 224 246 esac 225 esac 247 226 248 done 227 done 249 228 250 if [ "${srctree}" = "" ] ; then 229 if [ "${srctree}" = "" ] ; then 251 srctree="." 230 srctree="." 252 fi 231 fi 253 232 254 if [ "${dtx_file_2}" != "" ]; then 233 if [ "${dtx_file_2}" != "" ]; then 255 cmd_diff=1 234 cmd_diff=1 256 fi 235 fi 257 236 258 if (( ${help} )) ; then 237 if (( ${help} )) ; then 259 usage 238 usage 260 exit 1 239 exit 1 261 fi 240 fi 262 241 263 # this must follow check for ${help} 242 # this must follow check for ${help} 264 if [ "${dtx_file_1}" = "" ]; then 243 if [ "${dtx_file_1}" = "" ]; then 265 echo "" 244 echo "" >&2 266 echo "ERROR: parameter DTx required" 245 echo "ERROR: parameter DTx required" >&2 267 echo "" 246 echo "" >&2 268 exit 2 247 exit 2 269 fi 248 fi 270 249 271 250 272 # ----- prefer dtc from linux kernel, allow f 251 # ----- prefer dtc from linux kernel, allow fallback to dtc in $PATH 273 252 274 if [ "${KBUILD_OUTPUT:0:2}" = ".." ] ; then 253 if [ "${KBUILD_OUTPUT:0:2}" = ".." ] ; then 275 __KBUILD_OUTPUT="${srctree}/${KBUILD_O 254 __KBUILD_OUTPUT="${srctree}/${KBUILD_OUTPUT}" 276 elif [ "${KBUILD_OUTPUT}" = "" ] ; then 255 elif [ "${KBUILD_OUTPUT}" = "" ] ; then 277 __KBUILD_OUTPUT="." 256 __KBUILD_OUTPUT="." 278 else 257 else 279 __KBUILD_OUTPUT="${KBUILD_OUTPUT}" 258 __KBUILD_OUTPUT="${KBUILD_OUTPUT}" 280 fi 259 fi 281 260 282 DTC="${__KBUILD_OUTPUT}/scripts/dtc/dtc" 261 DTC="${__KBUILD_OUTPUT}/scripts/dtc/dtc" 283 262 284 if [ ! -x ${DTC} ] ; then 263 if [ ! -x ${DTC} ] ; then 285 __DTC="dtc" 264 __DTC="dtc" 286 if grep -q "^CONFIG_DTC=y" ${__KBUILD_ 265 if grep -q "^CONFIG_DTC=y" ${__KBUILD_OUTPUT}/.config 2>/dev/null; then 287 make_command=' 266 make_command=' 288 make scripts' 267 make scripts' 289 else 268 else 290 make_command=' 269 make_command=' 291 Enable CONFIG_DTC in the kernel confi 270 Enable CONFIG_DTC in the kernel configuration 292 make scripts' 271 make scripts' 293 fi 272 fi 294 if ( ! which ${__DTC} >/dev/null ) ; t 273 if ( ! which ${__DTC} >/dev/null ) ; then 295 274 296 # use spaces instead of tabs i 275 # use spaces instead of tabs in the error message 297 cat >&2 <<eod 276 cat >&2 <<eod 298 277 299 ERROR: unable to find a 'dtc' program 278 ERROR: unable to find a 'dtc' program 300 279 301 Preferred 'dtc' (built from Linux kernel so 280 Preferred 'dtc' (built from Linux kernel source tree) was not found or 302 is not executable. 281 is not executable. 303 282 304 'dtc' is: ${DTC} 283 'dtc' is: ${DTC} 305 284 306 If it does not exist, create it from the 285 If it does not exist, create it from the root of the Linux source tree: 307 ${make_command} 286 ${make_command} 308 287 309 If not at the root of the Linux kernel s 288 If not at the root of the Linux kernel source tree -s SRCTREE or -S 310 may need to be specified to find 'dtc'. 289 may need to be specified to find 'dtc'. 311 290 312 If 'O=\${dir}' is specified in your Linu 291 If 'O=\${dir}' is specified in your Linux builds, this script requires 313 'export KBUILD_OUTPUT=\${dir}' or add \$ 292 'export KBUILD_OUTPUT=\${dir}' or add \${dir}/scripts/dtc to \$PATH 314 before running. 293 before running. 315 294 316 If \${KBUILD_OUTPUT} is a relative path, 295 If \${KBUILD_OUTPUT} is a relative path, then '-s SRCDIR', -S, or run 317 this script from the root of the Linux k 296 this script from the root of the Linux kernel source tree is required. 318 297 319 Fallback '${__DTC}' was also not in \${PATH 298 Fallback '${__DTC}' was also not in \${PATH} or is not executable. 320 299 321 eod 300 eod 322 exit 2 301 exit 2 323 fi 302 fi 324 DTC=${__DTC} 303 DTC=${__DTC} 325 fi 304 fi 326 305 327 306 328 # ----- cpp and dtc flags same as for linux s 307 # ----- cpp and dtc flags same as for linux source tree build of .dtb files, 329 # plus directories of the dtx file(s) 308 # plus directories of the dtx file(s) 330 309 331 dtx_path_1_dtc_include="-i `dirname ${dtx_file 310 dtx_path_1_dtc_include="-i `dirname ${dtx_file_1}`" 332 311 333 dtx_path_2_dtc_include="" 312 dtx_path_2_dtc_include="" 334 if (( ${cmd_diff} )) ; then 313 if (( ${cmd_diff} )) ; then 335 dtx_path_2_dtc_include="-i `dirname ${ 314 dtx_path_2_dtc_include="-i `dirname ${dtx_file_2}`" 336 fi 315 fi 337 316 338 cpp_flags="\ 317 cpp_flags="\ 339 -nostdinc 318 -nostdinc \ 340 -I${srctree}/scripts/dtc/include-prefi !! 319 -I${srctree}/arch/${ARCH}/boot/dts \ >> 320 -I${srctree}/arch/${ARCH}/boot/dts/include \ >> 321 -I${srctree}/drivers/of/testcase-data \ 341 -undef -D__DTS__" 322 -undef -D__DTS__" 342 323 343 DTC="\ !! 324 dtc_flags="\ 344 ${DTC} !! 325 -i ${srctree}/arch/${ARCH}/boot/dts/ \ 345 -i ${srctree}/scripts/dtc/include-pref !! 326 -i ${srctree}/kernel/dts \ 346 -O dts -qq -f ${dtc_sort} ${annotate} !! 327 ${dtx_path_1_dtc_include} \ >> 328 ${dtx_path_2_dtc_include}" >> 329 >> 330 DTC="${DTC} ${dtc_flags} -O dts -qq -f ${dtc_sort} -o -" 347 331 348 332 349 # ----- do the diff or decompile 333 # ----- do the diff or decompile 350 334 351 if (( ${cmd_diff} )) ; then 335 if (( ${cmd_diff} )) ; then 352 336 353 diff ${diff_flags} ${diff_color} --lab !! 337 diff ${diff_flags} \ 354 <(compile_to_dts "${dtx_file_1 !! 338 <(compile_to_dts "${dtx_file_1}") \ 355 <(compile_to_dts "${dtx_file_2 !! 339 <(compile_to_dts "${dtx_file_2}") 356 340 357 else 341 else 358 342 359 compile_to_dts "${dtx_file_1}" "${dtx_ !! 343 compile_to_dts "${dtx_file_1}" 360 344 361 fi 345 fi
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.