이 글의 질문 · 원본 boot.img를 풀었다가 그대로 다시 만들었는데 왜 동일한 파일이 나오지 않는가?
boot.img 안의 kernel과 ramdisk
bootloader는 boot.img를 읽어 kernel과 ramdisk를 메모리에 올린다. ramdisk, 즉 initramfs는 kernel이 처음 root filesystem으로 사용하는 영역이고, 그 안의 init은 fstab에 따라 초기 mount를 수행한다.
기존 firmware의 boot.img를 unmkbootimg로 분리했다.
unmkbootimg --input boot.img \ --kernel kernel.img \ --ramdisk ramdisk.cpio.gz kernel written to 'kernel.img' (24627216 bytes) ramdisk written to 'ramdisk.cpio.gz' (743509 bytes)
tool이 출력한 재조립 명령은 다음과 같았다.
mkbootimg --base 0 --pagesize 2048 --board SRPVD01I001 \ --kernel_offset 0x10008000 \ --ramdisk_offset 0x10000000 \ --second_offset 0x00000000 \ --tags_offset 0x10000000 \ --kernel kernel.img \ --ramdisk ramdisk.cpio.gz \ -o boot1.img
kernel과 ramdisk를 수정하지 않고 그대로 다시 합쳤다. 당연히 같은 파일이 나올 것이라고 생각했다.
발표자료에서 정리한 판단 근거
첫 번째 차이: byte 41
cmp boot1.img boot.img boot1.img boot.img differ: byte 41, line 1
차이가 파일의 아주 앞부분에서 발생했기 때문에 처음에는 시간이나 header의 부가 정보라고 생각했다. hex editor로 해당 byte를 맞춘 뒤 다시 비교했다.
cmp boot1.img boot.img boot1.img boot.img differ: byte 577, line 1
다시 수정한 뒤에는 차이가 byte 1645로 이동했다. 한 byte를 맞추는 문제가 아니라 header와 정렬, offset, 또는 mkbootimg 구현 자체가 달라 발생하는 문제였다.
당시 세운 원인 가설
- 사용한 mkbootimg tool이 오래되어 firmware를 만든 버전과 다를 수 있다.
- unmkbootimg가 출력한 offset만으로는 Samsung boot.img의 모든 header 정보를 복원하지 못할 수 있다.
- kernel이나 ramdisk가 아니라 padding·alignment·header field에서 차이가 날 수 있다.
- 동일한 의미의 boot image라도 binary 전체가 byte-for-byte 동일하지 않을 수 있다.
6월 4일 회의에서는 이 문제를 다음처럼 정리했다.
mkbootimg로 다시 합친 이미지가 원본과 다르다. 정확한 offset을 찾는 것과 AVB를 우회하는 것, 두 가지를 따로 해결해야 한다.
6월 24일에는 repacked file을 실제로 flashing해서 반응을 확인하는 방향도 제시했다. 단순 binary diff만 계속 보는 것이 아니라, 그 차이가 실제 boot에 영향을 주는 차이인지 확인하려는 것이었다.
문제를 둘로 분리하기
boot.img를 다시 만드는 문제와, 다시 만든 boot.img를 장치가 받아들이는 문제는 같지 않았다. 다음 단계부터는 두 번째 문제인 AVB와 vbmeta를 따로 분석하기 시작했다.