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 24 --annotate synonym for -T 23 --color synonym for -c (requires d << 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="" << 180 dtx_file_1="" 182 dtx_file_1="" 181 dtx_file_2="" 183 dtx_file_2="" 182 dtc_sort="-s" 184 dtc_sort="-s" 183 help=0 185 help=0 184 srctree="" 186 srctree="" 185 187 186 188 187 while [ $# -gt 0 ] ; do 189 while [ $# -gt 0 ] ; do 188 190 189 case $1 in 191 case $1 in 190 192 191 -c | --color ) << 192 if diff --color /dev/null /dev << 193 diff_color="--color=al << 194 fi << 195 shift << 196 ;; << 197 << 198 -f ) 193 -f ) 199 diff_flags="--unified=999999" 194 diff_flags="--unified=999999" 200 shift 195 shift 201 ;; 196 ;; 202 197 203 -h | -help | --help ) 198 -h | -help | --help ) 204 help=1 199 help=1 205 shift 200 shift 206 ;; 201 ;; 207 202 208 -s ) 203 -s ) 209 srctree="$2" 204 srctree="$2" 210 shift 2 205 shift 2 211 ;; 206 ;; 212 207 213 -S ) 208 -S ) 214 git_root=`git rev-parse --show 209 git_root=`git rev-parse --show-toplevel 2>/dev/null` 215 srctree="${git_root}" 210 srctree="${git_root}" 216 shift 211 shift 217 ;; 212 ;; 218 213 219 -T | --annotate ) 214 -T | --annotate ) 220 if [ "${annotate}" = "" ] ; t 215 if [ "${annotate}" = "" ] ; then 221 annotate="-T" 216 annotate="-T" 222 elif [ "${annotate}" = "-T" ] 217 elif [ "${annotate}" = "-T" ] ; then 223 annotate="-T -T" 218 annotate="-T -T" 224 fi 219 fi 225 shift 220 shift 226 ;; 221 ;; 227 -u ) 222 -u ) 228 dtc_sort="" 223 dtc_sort="" 229 shift 224 shift 230 ;; 225 ;; 231 226 232 *) 227 *) 233 if [ "${dtx_file_1}" = "" ] ; 228 if [ "${dtx_file_1}" = "" ] ; then 234 dtx_file_1="$1" 229 dtx_file_1="$1" 235 elif [ "${dtx_file_2}" = "" ] 230 elif [ "${dtx_file_2}" = "" ] ; then 236 dtx_file_2="$1" 231 dtx_file_2="$1" 237 else 232 else 238 echo "" 233 echo "" >&2 239 echo "ERROR: Unexpecte 234 echo "ERROR: Unexpected parameter: $1" >&2 240 echo "" 235 echo "" >&2 241 exit 2 236 exit 2 242 fi 237 fi 243 shift 238 shift 244 ;; 239 ;; 245 240 246 esac 241 esac 247 242 248 done 243 done 249 244 250 if [ "${srctree}" = "" ] ; then 245 if [ "${srctree}" = "" ] ; then 251 srctree="." 246 srctree="." 252 fi 247 fi 253 248 254 if [ "${dtx_file_2}" != "" ]; then 249 if [ "${dtx_file_2}" != "" ]; then 255 cmd_diff=1 250 cmd_diff=1 256 fi 251 fi 257 252 258 if (( ${help} )) ; then 253 if (( ${help} )) ; then 259 usage 254 usage 260 exit 1 255 exit 1 261 fi 256 fi 262 257 263 # this must follow check for ${help} 258 # this must follow check for ${help} 264 if [ "${dtx_file_1}" = "" ]; then 259 if [ "${dtx_file_1}" = "" ]; then 265 echo "" 260 echo "" >&2 266 echo "ERROR: parameter DTx required" 261 echo "ERROR: parameter DTx required" >&2 267 echo "" 262 echo "" >&2 268 exit 2 263 exit 2 269 fi 264 fi 270 265 271 266 272 # ----- prefer dtc from linux kernel, allow f 267 # ----- prefer dtc from linux kernel, allow fallback to dtc in $PATH 273 268 274 if [ "${KBUILD_OUTPUT:0:2}" = ".." ] ; then 269 if [ "${KBUILD_OUTPUT:0:2}" = ".." ] ; then 275 __KBUILD_OUTPUT="${srctree}/${KBUILD_O 270 __KBUILD_OUTPUT="${srctree}/${KBUILD_OUTPUT}" 276 elif [ "${KBUILD_OUTPUT}" = "" ] ; then 271 elif [ "${KBUILD_OUTPUT}" = "" ] ; then 277 __KBUILD_OUTPUT="." 272 __KBUILD_OUTPUT="." 278 else 273 else 279 __KBUILD_OUTPUT="${KBUILD_OUTPUT}" 274 __KBUILD_OUTPUT="${KBUILD_OUTPUT}" 280 fi 275 fi 281 276 282 DTC="${__KBUILD_OUTPUT}/scripts/dtc/dtc" 277 DTC="${__KBUILD_OUTPUT}/scripts/dtc/dtc" 283 278 284 if [ ! -x ${DTC} ] ; then 279 if [ ! -x ${DTC} ] ; then 285 __DTC="dtc" 280 __DTC="dtc" 286 if grep -q "^CONFIG_DTC=y" ${__KBUILD_ 281 if grep -q "^CONFIG_DTC=y" ${__KBUILD_OUTPUT}/.config 2>/dev/null; then 287 make_command=' 282 make_command=' 288 make scripts' 283 make scripts' 289 else 284 else 290 make_command=' 285 make_command=' 291 Enable CONFIG_DTC in the kernel confi 286 Enable CONFIG_DTC in the kernel configuration 292 make scripts' 287 make scripts' 293 fi 288 fi 294 if ( ! which ${__DTC} >/dev/null ) ; t 289 if ( ! which ${__DTC} >/dev/null ) ; then 295 290 296 # use spaces instead of tabs i 291 # use spaces instead of tabs in the error message 297 cat >&2 <<eod 292 cat >&2 <<eod 298 293 299 ERROR: unable to find a 'dtc' program 294 ERROR: unable to find a 'dtc' program 300 295 301 Preferred 'dtc' (built from Linux kernel so 296 Preferred 'dtc' (built from Linux kernel source tree) was not found or 302 is not executable. 297 is not executable. 303 298 304 'dtc' is: ${DTC} 299 'dtc' is: ${DTC} 305 300 306 If it does not exist, create it from the 301 If it does not exist, create it from the root of the Linux source tree: 307 ${make_command} 302 ${make_command} 308 303 309 If not at the root of the Linux kernel s 304 If not at the root of the Linux kernel source tree -s SRCTREE or -S 310 may need to be specified to find 'dtc'. 305 may need to be specified to find 'dtc'. 311 306 312 If 'O=\${dir}' is specified in your Linu 307 If 'O=\${dir}' is specified in your Linux builds, this script requires 313 'export KBUILD_OUTPUT=\${dir}' or add \$ 308 'export KBUILD_OUTPUT=\${dir}' or add \${dir}/scripts/dtc to \$PATH 314 before running. 309 before running. 315 310 316 If \${KBUILD_OUTPUT} is a relative path, 311 If \${KBUILD_OUTPUT} is a relative path, then '-s SRCDIR', -S, or run 317 this script from the root of the Linux k 312 this script from the root of the Linux kernel source tree is required. 318 313 319 Fallback '${__DTC}' was also not in \${PATH 314 Fallback '${__DTC}' was also not in \${PATH} or is not executable. 320 315 321 eod 316 eod 322 exit 2 317 exit 2 323 fi 318 fi 324 DTC=${__DTC} 319 DTC=${__DTC} 325 fi 320 fi 326 321 327 322 328 # ----- cpp and dtc flags same as for linux s 323 # ----- cpp and dtc flags same as for linux source tree build of .dtb files, 329 # plus directories of the dtx file(s) 324 # plus directories of the dtx file(s) 330 325 331 dtx_path_1_dtc_include="-i `dirname ${dtx_file 326 dtx_path_1_dtc_include="-i `dirname ${dtx_file_1}`" 332 327 333 dtx_path_2_dtc_include="" 328 dtx_path_2_dtc_include="" 334 if (( ${cmd_diff} )) ; then 329 if (( ${cmd_diff} )) ; then 335 dtx_path_2_dtc_include="-i `dirname ${ 330 dtx_path_2_dtc_include="-i `dirname ${dtx_file_2}`" 336 fi 331 fi 337 332 338 cpp_flags="\ 333 cpp_flags="\ 339 -nostdinc 334 -nostdinc \ 340 -I${srctree}/scripts/dtc/include-prefi 335 -I${srctree}/scripts/dtc/include-prefixes \ 341 -undef -D__DTS__" 336 -undef -D__DTS__" 342 337 343 DTC="\ 338 DTC="\ 344 ${DTC} 339 ${DTC} \ 345 -i ${srctree}/scripts/dtc/include-pref 340 -i ${srctree}/scripts/dtc/include-prefixes \ 346 -O dts -qq -f ${dtc_sort} ${annotate} 341 -O dts -qq -f ${dtc_sort} ${annotate} -o -" 347 342 348 343 349 # ----- do the diff or decompile 344 # ----- do the diff or decompile 350 345 351 if (( ${cmd_diff} )) ; then 346 if (( ${cmd_diff} )) ; then 352 347 353 diff ${diff_flags} ${diff_color} --lab !! 348 diff ${diff_flags} --label "${dtx_file_1}" --label "${dtx_file_2}" \ 354 <(compile_to_dts "${dtx_file_1 349 <(compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}") \ 355 <(compile_to_dts "${dtx_file_2 350 <(compile_to_dts "${dtx_file_2}" "${dtx_path_2_dtc_include}") 356 351 357 else 352 else 358 353 359 compile_to_dts "${dtx_file_1}" "${dtx_ 354 compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}" 360 355 361 fi 356 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.