이전 포스팅에서 본 sparse file 의 헤더를 읽어보았습니다.
헤더는 아래와 같이 정의되어 있습니다.
typedef struct sparse_header {
__le32 magic; /* 0xed26ff3a */
__le16 major_version; /* (0x1) - reject images with higher major versions */
__le16 minor_version; /* (0x0) - allow images with higer minor versions */
__le16 file_hdr_sz; /* 28 bytes for first revision of the file format */
__le16 chunk_hdr_sz; /* 12 bytes for first revision of the file format */
__le32 blk_sz; /* block size in bytes, must be a multiple of 4 (4096) */
__le32 total_blks; /* total blocks in the non-sparse output image */
__le32 total_chunks; /* total chunks in the sparse input image */
__le32 image_checksum; /* CRC32 checksum of the original data, counting "don't care" */
/* as 0. Standard 802.3 polynomial, use a Public Domain */
/* table implementation */
} sparse_header_t;
#define SPARSE_HEADER_MAGIC 0xed26ff3a
덤프를 떠서 읽어보면
$ ls -l rootfs.ext4
-rw-r--r-- 2 user user 1179648000 10월 30 16:50 rootfs.ext4
$ hexdump rootfs.ext4.img -n 28
0000000 ff3a ed26 0001 0000 001c 000c 1000 0000
0000010 6500 0004 0054 0000 0000 0000
000001c
magic 값 0xed26ff3a 을 먼저 확인할 수 있습니다.
major_version 값 0x1 과, minor_verson 값 0x0 이 확인됩니다.
file_hdr_sz 가 0x1c(28) 입니다.
chunk_hdr_sz 가 0xc(12) 입니다.
blk_sz 는 0x1000.
total_blks 는 0x46500.
total_chunks 는 0x54.
total_blks * blk_sz = 0x46500 * 0x1000 = 0x46500000 = 1,179,648,000
sparse file 의 원본 ext4 파일의 크기가 나옵니다.
sparse header 의 크기인 0x1c 뒤에는 chunk header 가 0xc 크기로 저장되어 있습니다.
#define CHUNK_TYPE_RAW 0xCAC1
#define CHUNK_TYPE_FILL 0xCAC2
#define CHUNK_TYPE_DONT_CARE 0xCAC3
#define CHUNK_TYPE_CRC32 0xCAC4
typedef struct chunk_header {
__le16 chunk_type; /* 0xCAC1 -> raw; 0xCAC2 -> fill; 0xCAC3 -> don't care */
__le16 reserved1;
__le32 chunk_sz; /* in blocks in output image */
__le32 total_sz; /* in bytes of chunk input file including chunk header and data */
} chunk_header_t;
$ hexdump rootfs.ext4.img -n 40
0000000 ff3a ed26 0001 0000 001c 000c 1000 0000
0000010 6500 0004 0054 0000 0000 0000 cac1 0000
0000020 008e 0000 e00c 0008
0000028
chunk_type 의 값 0xcac1 이 확인됩니다.
여기부터는 chunk header 와 chunk data 가 반복될 것입니다.
아래의 사이트에 헤더 정보에 대한 설명이 있습니다.
https://source.android.com/docs/core/architecture/bootloader/images?hl=ko#sparse-format
스파스 이미지 형식에는 파일 헤더와 일련의 청크가 차례대로 포함됩니다. 파일 헤더, 청크 헤더, 청크 데이터는 4바이트의 배수이며 모든 필드는 부호 없는 little-endian입니다.
파일 헤더는 다음 형식을 사용합니다.
- 32비트 매직: 0xed26ff3a
- 16비트 주 버전(0x1) - 상위 주 버전이 있는 이미지 거부
- 16비트 부 버전(0x0) - 상위 부 버전이 있는 이미지 허용
- 바이트 단위의 16비트 파일 헤더 크기(v1.0에서 28바이트)
- 바이트 단위의 16비트 청크 헤더 크기(v1.0에서 12바이트)
- 바이트 단위의 32비트 블록 크기, 4의 배수여야 함
- 출력 파일의 총 32비트 블록
- 입력 파일의 총 32비트 청크
- 원본 데이터의 32비트 CRC32 체크섬. '상관없음'을 표준 802.3 다항식에 따라 0으로 계산합니다(공개 도메인 테이블 구현 사용).
파일 청크는 다음 형식을 사용합니다.
- 16비트 청크 유형:
- 0xCAC1 원시(블록 단위의 크기 * 바이트 단위의 블록 크기가 이어짐)
- 0xCAC2 채우기(4바이트의 채우기 데이터가 이어짐)
- 0xCAC3 상관없음(0바이트가 이어짐)
- 16비트 예약(0으로 쓰고 읽기에서는 무시됨)
- 출력 이미지의 블록 단위로 된 32비트 청크 크기
- 청크 헤더와 데이터를 포함한 청크 입력 파일의 총 32비트 크기(바이트 단위)
'Android' 카테고리의 다른 글
Android partitions (3) | 2024.10.18 |
---|---|
Sparse file (0) | 2024.10.16 |