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