系統 - Debian - Kernel - 如何找出Kernel Append DTB



chk.py

import os
import sys
import struct

filename = sys.argv[1]

with open(filename, "rb") as f:
    data = f.read()

print(f"total file : {len(data):,} bytes")
print(f"total hex  : 0x{len(data):x}")

# --------------------------------------------------
# Verify gzip header
# --------------------------------------------------

if data[:3] != b'\x1f\x8b\x08':
    raise SystemExit("Not a gzip file")

print("gzip header: OK")

# --------------------------------------------------
# gzip footer
#
# gzip format:
#
#   header
#   deflate stream
#   CRC32    4 bytes
#   ISIZE    4 bytes
#
# ISIZE = uncompressed size modulo 2^32
# --------------------------------------------------

isize = struct.unpack("<I", data[-4:])[0]

print(f"gzip ISIZE : {isize:,} bytes")
print(f"gzip ISIZE : 0x{isize:x}")

# --------------------------------------------------
# Find FDT magic
# --------------------------------------------------

magic = b'\xd0\x0d\xfe\xed'

positions = []
pos = 0

while True:
    p = data.find(magic, pos)

    if p < 0:
        break

    positions.append(p)
    pos = p + 1

print()
print("FDT magic locations:")

for p in positions:
    print(f"  0x{p:x} ({p:,})")

# --------------------------------------------------
# Analyze each FDT
# --------------------------------------------------

print()
print("FDT information:")

for i, p in enumerate(positions):
    if p + 8 > len(data):
        continue

    totalsize = struct.unpack(">I", data[p + 4:p + 8])[0]

    print(f"  FDT #{i}")
    print(f"    offset : 0x{p:x} ({p:,})")
    print(f"    size   : {totalsize:,} bytes")
    print(f"    end    : 0x{p + totalsize:x} ({p + totalsize:,})")

# --------------------------------------------------
# Find first FDT after the gzip compressed data
#
# We know the compressed kernel itself is before
# the appended DTB.
# --------------------------------------------------

if positions:
    p = positions[0]

    print()
    print("First FDT:")
    print(f"  offset : 0x{p:x}")
    print(f"  size   : {struct.unpack('>I', data[p+4:p+8])[0]:,}")

    print()
    print("Possible gzip+DTB layout:")
    print(f"  gzip/Image : 0x00000000 - 0x{p:x}")
    print(f"  DTB        : 0x{p:x} - ...")

檢查Kernel Append DTB

$ python3 ./chk.py repack/kernel 
    total file : 16,228,472 bytes
    total hex  : 0xf7a078
    gzip header: OK
    gzip ISIZE : 6,776,178 bytes
    gzip ISIZE : 0x676572

    FDT magic locations:
      0xe380d1 (14,909,649)
      0xea9b4a (15,375,178)
      0xf1b431 (15,840,305)

    FDT information:
      FDT #0
        offset : 0xe380d1 (14,909,649)
        size   : 465,529 bytes
        end    : 0xea9b4a (15,375,178)
      FDT #1
        offset : 0xea9b4a (15,375,178)
        size   : 465,127 bytes
        end    : 0xf1b431 (15,840,305)
      FDT #2
        offset : 0xf1b431 (15,840,305)
        size   : 388,167 bytes
        end    : 0xf7a078 (16,228,472)

    First FDT:
      offset : 0xe380d1
      size   : 465,529

    Possible gzip+DTB layout:
      gzip/Image : 0x00000000 - 0xe380d1
      DTB        : 0xe380d1 - ...

取出DTB

$ dd if=repack/kernel of=dtb0.bin bs=1 skip=$((0xe380d1)) count=465529 status=progress
$ dd if=repack/kernel of=dtb1.bin bs=1 skip=$((0xea9b4a)) count=465127 status=progress
$ dd if=repack/kernel of=dtb2.bin bs=1 skip=$((0xf1b431)) count=388167 status=progress

Append DTB

$ cat Image.gz dtb0.bin dtb1.bin dtb2.bin > kernel