2014-12-24

Преобразование dtb.img (QCDT) в набор DTS-файлов

Порой при работе с образом ядра boot.img требуется изменить, содержащуюся в оном структуру Flattened Device Tree (FDT), или же необходимо просто изучение FDT структуры, когда нету исходников ядра. Попробую вкратце объяснить как из образа boot.img получить DTS-файлы и как полученные файлы упаковать обратно в boot.img.

Редактирование DTS-файлов рассматривать не буду, т.к. это другая история.

В образе boot.img кроме ядра и ramdisk'а содержится образ dtb.img , который представляет бинарную QCDT-структуру. В свою очередь QCDT-структура содержит в себе DTB-структуры (Device Tree Blob). Что бы из образа boot.img извлечь dtb.img нужно воспользоваться утилитой AndImgTool. Эта утилита для Windows платформы (существуют аналоги для Linux).

После получения файла dtb.img следует перейти на Linux платформу, т.к. оставшиеся две утилиты под Windows найти не удалось. В вашей Linux-подобной системе создайте директорию, в которую скопируйте файл dtb.img. В эту же директорию скопируйте утилиты dtc и dtbToolCM (скачать). Далее в консоли выполните следующий скрипт:
DTBIMG=dtb.img
DTBSIG="00 00 d0 0d fe ed"
DTBSIGOFF=2
rm -rf ./phone_dts
mkdir -p phone_dts
hexdump -v -e "1/1 \"%02x \"" $DTBIMG >./phone_dts/dtb_hex.txt
unset OFFSETS
unset SIZES
declare -a OFFSETS
declare -a SIZES
BCNT=0
for OFF in `grep -oba "$DTBSIG" ./phone_dts/dtb_hex.txt | awk -F':' '{print $1}'`; \
do \
  let "SIGOFF = OFF/3 + DTBSIGOFF"; \
  let "OFFSETS[BCNT] = SIGOFF"; \
  if [[ $BCNT > 0 ]]; then let "SIZES[BCNT-1] = SIGOFF - OFFSETS[BCNT-1]"; fi; \
  let "BCNT += 1"; \
done
rm ./phone_dts/dtb_hex.txt
ACNT=0
for OFF in "${OFFSETS[@]}"; \
do \
  DTNAME=$(printf "./phone_dts/dt_%02d" $ACNT); \
  if [[ $ACNT == $(($BCNT-1)) ]]; then \
    dd if=$DTBIMG of=$DTNAME.bin ibs=1 skip=$(($OFF)); \
  else \
    dd if=$DTBIMG of=$DTNAME.bin ibs=1 skip=$(($OFF)) count=$((${SIZES[$ACNT]})); \
  fi; \
  ./dtc -I dtb $DTNAME.bin -O dts -o $DTNAME.dts; \
  rm $DTNAME.bin; \
  let "ACNT += 1"; \
done
В результате появится новая директория "phone_dts", в которой будут находится все DTS-файлы, содержащиеся в dtb.img образе. Теперь эти файлы можно изучать и редактировать.

Замечу, что полученные DTS-файлы являются "очищенным" вариантом файлов, которые изначально находились в исходниках ядра по пути "/arch/arm/boot/dts".

Перед компилированием  DTS-файлов следует узнать версию QCDT-структуры (параметр QCDT_FORMAT). Для этого следует просто напросто посмотреть содержимого 4-ого байтика в оригинальм файле dtb.img.
Следующий скрипт формирует из всех DTS-файлов новую QCDT-стуктуру (dtb.img):
QCDT_FORMAT=1
PAGE_SIZE=2048
PHONE_DTS_FILES=./phone_dts/dt_*.dts
for DTSNAME in $PHONE_DTS_FILES; \
do \
  ./dtc -I dts $DTSNAME -O dtb -o $DTSNAME.dtb; \
done
if [[ $QCDT_FORMAT == 2 ]]; then FMT=-2; else unset FMT; fi;
./dtbToolCM $FMT -o new_dtb.img -s $PAGE_SIZE phone_dts/
rm -rf ./phone_dts/*.dtb
В результате появится файлик new_dtb.img , переименовав который в dtb.img можно собрать обновлённый образ boot.img (при помощи утилиты AndImgTool).

7 комментариев:

  1. У меня не получается пишет так!
    165888+0 записей получено
    324+0 записей отправлено
    скопировано 165888 байт (166 kB), 0,0814656 c, 2,0 MB/c
    bash: ./dtc: Отказано в доступе

    ОтветитьУдалить
  2. при компилировании выдаёт следующее:
    bash: ./dtbToolCM: Нет такого файла или каталога
    видимо в системе чего-то не хватает?

    ОтветитьУдалить
  3. Этот комментарий был удален автором.

    ОтветитьУдалить
  4. Этот комментарий был удален автором.

    ОтветитьУдалить
  5. Этот комментарий был удален автором.

    ОтветитьУдалить
  6. Если у кого не будет что-то работать то проверьте установлена ли галочка "Разрешить выполнение файла как программы" то есть сделать утилиты исполняемыми, естественно всё делать нужно из под рута, а ещё нужно скопировать утилиту dtbToolCM в директорию /bin, если не будет работать dtc то её туда же. Если и после этого не будет работать то возможно нет нужных библиотек, для того чтобы их установить выполните в консоли следующую команду:
    sudo apt install gcc-multilib
    если что-то не будет устанавливаться то ещё выполните эту команду:
    sudo apt --fix-broken install
    После этого всё должно работать. Если не будет работать то попробуйте утилиты ещё скопировать и в директорию /usr/bin
    Все манипуляции проводил на только что установленной ubuntu 17.04 amd64.

    ОтветитьУдалить