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