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