• 解决linux5.15编译时不生成boot.img 的问题


    平台:rk3399   (与平台关系不大)

    内核 :linux5.15

    下一个linux5.15的内核,编译的时候

    make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j6 rk3399-rock960.img

    目标rk3399-rock960.img 需要在arch/arm64/boot/dts/rockchip/ 目录下存在rk3399-rock960.dts文件 ,如果不存在,可以使用其他的dts文件作为目标。

    错误提示1:(没法编译img这个目标)

    make: *** No rule to make target 'rk3399-rock960.img'.  Stop.

    解决1:

    修改arch/arm64/Makefile,在文件末尾增加一段(其他的内容不变)

    MAKE_MODULES ?= y

    %.img:
    ifeq ("$(CONFIG_MODULES)$(MAKE_MODULES)$(srctree)","yy$(objtree)")
        $(Q)$(MAKE) rockchip/$*.dtb Image.lz4 modules    
    else
        $(Q)$(MAKE) rockchip/$*.dtb Image.lz4
    endif
        $(Q)$(srctree)/scripts/mkimg --dtb $*.dtb

    CLEAN_DIRS += out
    CLEAN_FILES += boot.img kernel.img resource.img zboot.img

    再执行上面的make命令,该错误就没有了。

    错误提示2:没有mkimg命令

    解决:

    从原(rk3399)sdk的内核中拷贝过来,这是个脚本文件。

    cp ../kernel/scripts/mkimg scripts/  

    shell脚本内容如下:

    1. #!/bin/bash
    2. # SPDX-License-Identifier: GPL-2.0
    3. # Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd.
    4. set -e
    5. usage() {
    6. cat >&2 << USAGE
    7. usage: $0 [-h] --dtb DTB
    8. optional arguments:
    9. -h, --help show this help message and exit
    10. --dtb DTB the dtb file name
    11. USAGE
    12. }
    13. # Parse command-line arguments
    14. while [ $# -gt 0 ]; do
    15. case $1 in
    16. --dtb)
    17. DTB=$2
    18. shift 2
    19. ;;
    20. -h)
    21. usage
    22. exit 0
    23. ;;
    24. --help)
    25. usage
    26. exit 0
    27. ;;
    28. *)
    29. shift
    30. ;;
    31. esac
    32. done
    33. srctree=${srctree-"."}
    34. objtree=${objtree-"."}
    35. if [ "${ARCH}" == "" ]; then
    36. if [ "$($srctree/scripts/config --state CONFIG_ARM)" == "y" ]; then
    37. ARCH=arm
    38. else
    39. ARCH=arm64
    40. fi
    41. fi
    42. LOGO_PATH=${srctree}/logo.bmp
    43. [ -f ${LOGO_PATH} ] && LOGO=logo.bmp
    44. LOGO_KERNEL_PATH=${srctree}/logo_kernel.bmp
    45. [ -f ${LOGO_KERNEL_PATH} ] && LOGO_KERNEL=logo_kernel.bmp
    46. KERNEL_IMAGE_PATH=${objtree}/arch/${ARCH}/boot/Image
    47. KERNEL_IMAGE_ARG="--kernel ${KERNEL_IMAGE_PATH}"
    48. if [ "${ARCH}" == "arm" ]; then
    49. DTB_PATH=${objtree}/arch/arm/boot/dts/${DTB}
    50. ZIMAGE=zImage
    51. else
    52. DTB_PATH=${objtree}/arch/arm64/boot/dts/rockchip/${DTB}
    53. ZIMAGE=Image.lz4
    54. fi
    55. KERNEL_ZIMAGE_PATH=${objtree}/arch/${ARCH}/boot/${ZIMAGE}
    56. KERNEL_ZIMAGE_ARG="--kernel ${KERNEL_ZIMAGE_PATH}"
    57. if [ ! -f ${DTB_PATH} ]; then
    58. echo "No dtb" >&2
    59. usage
    60. exit 1
    61. fi
    62. OUT=out
    63. ITB=${BOOT_IMG}
    64. ITS=${OUT}/boot.its
    65. MKIMAGE=${MKIMAGE-"mkimage"}
    66. MKIMAGE_ARG="-E -p 0x800"
    67. make_boot_img()
    68. {
    69. RAMDISK_IMG_PATH=${objtree}/ramdisk.img
    70. [ -f ${RAMDISK_IMG_PATH} ] && RAMDISK_IMG=ramdisk.img && RAMDISK_ARG="--ramdisk ${RAMDISK_IMG_PATH}"
    71. ${srctree}/scripts/mkbootimg \
    72. ${KERNEL_IMAGE_ARG} \
    73. ${RAMDISK_ARG} \
    74. --second resource.img \
    75. -o boot.img && \
    76. echo " Image: boot.img (with Image ${RAMDISK_IMG} resource.img) is ready";
    77. ${srctree}/scripts/mkbootimg \
    78. ${KERNEL_ZIMAGE_ARG} \
    79. ${RAMDISK_ARG} \
    80. --second resource.img \
    81. -o zboot.img && \
    82. echo " Image: zboot.img (with ${ZIMAGE} ${RAMDISK_IMG} resource.img) is ready"
    83. }
    84. make_boot_multi_dtb_img()
    85. {
    86. RAMDISK_IMG_PATH=${objtree}/ramdisk.img
    87. [ -f ${RAMDISK_IMG_PATH} ] && RAMDISK_IMG=ramdisk.img && RAMDISK_ARG="--ramdisk ${RAMDISK_IMG_PATH}"
    88. ${srctree}/scripts/mkbootimg \
    89. ${KERNEL_IMAGE_ARG} \
    90. ${RAMDISK_ARG} \
    91. --second resource_multi_dtb.img \
    92. -o boot.img && \
    93. echo " Image: boot.img (with Image ${RAMDISK_IMG} resource_multi_dtb.img) is ready";
    94. ${srctree}/scripts/mkbootimg \
    95. ${KERNEL_ZIMAGE_ARG} \
    96. ${RAMDISK_ARG} \
    97. --second resource_multi_dtb.img \
    98. -o zboot.img && \
    99. echo " Image: zboot.img (with ${ZIMAGE} ${RAMDISK_IMG} resource_multi_dtb.img) is ready"
    100. }
    101. repack_boot_img()
    102. {
    103. ${srctree}/scripts/repack-bootimg \
    104. --boot_img ${BOOT_IMG} --out ${OUT} \
    105. ${KERNEL_IMAGE_ARG} \
    106. --second resource.img \
    107. --dtb ${DTB_PATH} \
    108. -o boot.img &&
    109. echo " Image: boot.img (${BOOT_IMG} + Image) is ready";
    110. ${srctree}/scripts/repack-bootimg \
    111. --boot_img ${BOOT_IMG} --out ${OUT} \
    112. ${KERNEL_ZIMAGE_ARG} \
    113. --second resource.img \
    114. --dtb ${DTB_PATH} \
    115. -o zboot.img && \
    116. echo " Image: zboot.img (${BOOT_IMG} + ${ZIMAGE}) is ready"
    117. }
    118. repack_multi_dtb_boot_img()
    119. {
    120. ${srctree}/scripts/repack-bootimg \
    121. --boot_img ${BOOT_IMG} --out ${OUT} \
    122. ${KERNEL_IMAGE_ARG} \
    123. --second resource_multi_dtb.img \
    124. --dtb ${DTB_PATH} \
    125. -o boot.img &&
    126. echo " Image: boot.img (${BOOT_IMG} + Image + resource_multi_dtb) is ready";
    127. ${srctree}/scripts/repack-bootimg \
    128. --boot_img ${BOOT_IMG} --out ${OUT} \
    129. ${KERNEL_ZIMAGE_ARG} \
    130. --second resource_multi_dtb.img \
    131. --dtb ${DTB_PATH} \
    132. -o zboot.img && \
    133. echo " Image: zboot.img (${BOOT_IMG} + ${ZIMAGE}) is ready"
    134. }
    135. check_mkimage()
    136. {
    137. MKIMAGE=$(type -p ${MKIMAGE} || true)
    138. if [ -z "${MKIMAGE}" ]; then
    139. # Doesn't exist
    140. echo '"mkimage" command not found - U-Boot images will not be built' >&2
    141. exit 1;
    142. fi
    143. }
    144. unpack_itb()
    145. {
    146. rm -rf ${OUT}
    147. mkdir -p ${OUT}
    148. for NAME in $(fdtget -l ${ITB} /images)
    149. do
    150. # generate image
    151. NODE="/images/${NAME}"
    152. OFFS=$(fdtget -ti ${ITB} ${NODE} data-position)
    153. SIZE=$(fdtget -ti ${ITB} ${NODE} data-size)
    154. if [ -z ${OFFS} ]; then
    155. continue;
    156. fi
    157. if [ ${SIZE} -ne 0 ]; then
    158. dd if=${ITB} of=${OUT}/${NAME} bs=${SIZE} count=1 skip=${OFFS} iflag=skip_bytes >/dev/null 2>&1
    159. else
    160. touch ${OUT}/${NAME}
    161. fi
    162. done
    163. [ ! -f ${OUT}/kernel ] && echo "FIT ${ITB} no kernel" >&2 && exit 1 || true
    164. }
    165. gen_its()
    166. {
    167. TMP_ITB=${OUT}/boot.tmp
    168. # add placeholder
    169. cp ${ITB} ${TMP_ITB}
    170. for NAME in $(fdtget -l ${ITB} /images); do
    171. fdtput -t s ${TMP_ITB} /images/${NAME} data "/INCBIN/(${NAME})"
    172. done
    173. dtc -I dtb -O dts ${TMP_ITB} -o ${ITS} >/dev/null 2>&1
    174. rm -f ${TMP_ITB}
    175. # fixup placeholder: data = "/INCBIN/(...)"; -> data = /incbin/("...");
    176. sed -i "s/\"\/INCBIN\/(\(.*\))\"/\/incbin\/(\"\1\")/" ${ITS}
    177. # remove
    178. sed -i "/memreserve/d" ${ITS}
    179. sed -i "/timestamp/d" ${ITS}
    180. sed -i "/data-size/d" ${ITS}
    181. sed -i "/data-position/d" ${ITS}
    182. sed -i "/value/d" ${ITS}
    183. sed -i "/hashed-strings/d" ${ITS}
    184. sed -i "/hashed-nodes/d" ${ITS}
    185. sed -i "/signer-version/d" ${ITS}
    186. sed -i "/signer-name/d" ${ITS}
    187. }
    188. gen_itb()
    189. {
    190. [ -f ${OUT}/fdt ] && cp -a ${DTB_PATH} ${OUT}/fdt && FDT=" + ${DTB}"
    191. [ -f ${OUT}/resource ] && cp -a resource.img ${OUT}/resource && RESOURCE=" + resource.img"
    192. COMP=$(fdtget ${ITB} /images/kernel compression)
    193. case "${COMP}" in
    194. gzip) EXT=".gz";;
    195. lz4) EXT=".lz4";;
    196. bzip2) EXT=".bz2";;
    197. lzma) EXT=".lzma";;
    198. lzo) EXT=".lzo";;
    199. esac
    200. cp -a ${KERNEL_IMAGE_PATH}${EXT} ${OUT}/kernel && \
    201. ${MKIMAGE} ${MKIMAGE_ARG} -f ${ITS} boot.img >/dev/null && \
    202. echo " Image: boot.img (FIT ${BOOT_IMG} + Image${EXT}${FDT}${RESOURCE}) is ready";
    203. if [ "${EXT}" == "" ] && [ -f ${KERNEL_ZIMAGE_PATH} ]; then
    204. cp -a ${KERNEL_ZIMAGE_PATH} ${OUT}/kernel && \
    205. ${MKIMAGE} ${MKIMAGE_ARG} -f ${ITS} zboot.img >/dev/null && \
    206. echo " Image: zboot.img (FIT ${BOOT_IMG} + zImage${FDT}${RESOURCE}) is ready";
    207. fi
    208. }
    209. repack_itb()
    210. {
    211. check_mkimage
    212. unpack_itb
    213. gen_its
    214. gen_itb
    215. }
    216. # Create U-Boot FIT Image use ${BOOT_ITS}
    217. make_fit_boot_img()
    218. {
    219. ITS=${OUT}/boot.its
    220. check_mkimage
    221. mkdir -p ${OUT}
    222. rm -f ${OUT}/fdt ${OUT}/kernel ${OUT}/resource ${ITS}
    223. cp -a ${BOOT_ITS} ${ITS}
    224. cp -a ${DTB_PATH} ${OUT}/fdt
    225. cp -a ${KERNEL_ZIMAGE_PATH} ${OUT}/kernel
    226. cp -a resource.img ${OUT}/resource
    227. if [ "${ARCH}" == "arm64" ]; then
    228. sed -i -e 's/arch = ""/arch = "arm64"/g' -e 's/compression = ""/compression = "lz4"/' ${ITS}
    229. else
    230. sed -i -e 's/arch = ""/arch = "arm"/g' -e 's/compression = ""/compression = "none"/' ${ITS}
    231. fi
    232. FIT_DESC=$(${MKIMAGE} ${MKIMAGE_ARG} -f ${ITS} boot.img | grep "FIT description" | sed 's/FIT description: //')
    233. echo " Image: boot.img (${FIT_DESC}) is ready";
    234. }
    235. if [ -x ${srctree}/scripts/bmpconvert ]; then
    236. if [ -f ${LOGO_PATH} ]; then
    237. ${srctree}/scripts/bmpconvert ${LOGO_PATH};
    238. fi
    239. if [ -f ${LOGO_KERNEL_PATH} ]; then
    240. ${srctree}/scripts/bmpconvert ${LOGO_KERNEL_PATH};
    241. fi
    242. fi
    243. if [ "${srctree}" != "${objtree}" ]; then
    244. if [ -f ${LOGO_PATH} ]; then
    245. cp -a ${LOGO_PATH} ${objtree}/;
    246. fi
    247. if [ -f ${LOGO_KERNEL_PATH} ]; then
    248. cp -a ${LOGO_KERNEL_PATH} ${objtree}/;
    249. fi
    250. fi
    251. scripts/resource_tool ${DTB_PATH} ${LOGO} ${LOGO_KERNEL} >/dev/null
    252. echo " Image: resource.img (with ${DTB} ${LOGO} ${LOGO_KERNEL}) is ready"
    253. if [ -f "${BOOT_IMG}" ]; then
    254. if file -L -p -b ${BOOT_IMG} | grep -q 'Device Tree Blob' ; then
    255. repack_itb;
    256. elif [ -x ${srctree}/scripts/repack-bootimg ]; then
    257. if [[ $MULTI_DTB = "true" ]] ; then
    258. echo " ready to build multi dtb boot.img";
    259. repack_multi_dtb_boot_img;
    260. else
    261. repack_boot_img;
    262. fi
    263. fi
    264. elif [ -f "${BOOT_ITS}" ]; then
    265. make_fit_boot_img;
    266. elif [ -x ${srctree}/scripts/mkbootimg ]; then
    267. if [[ $MULTI_DTB = "true" ]] ; then
    268. echo " ready to build multi dtb boot.img";
    269. make_boot_multi_dtb_img;
    270. else
    271. make_boot_img;
    272. fi
    273. fi

    错误提示3:没有resource_tool命令

    解决:

    1. 从原sdk中拷贝c文件(当然可以直接拷贝二进程执行文件,拷贝二进制就不用修改makefile了)

    cp ../kernel/scripts/resource_tool.c scripts/

    resource_tool.c原文如下:

    1. // SPDX-License-Identifier: GPL-2.0+
    2. /*
    3. * (C) Copyright 2008-2015 Fuzhou Rockchip Electronics Co., Ltd
    4. */
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. /**
    14. * \brief SHA-1 context structure
    15. */
    16. typedef struct
    17. {
    18. unsigned long total[2]; /*!< number of bytes processed */
    19. unsigned long state[5]; /*!< intermediate digest state */
    20. unsigned char buffer[64]; /*!< data block being processed */
    21. }
    22. sha1_context;
    23. /*
    24. * 32-bit integer manipulation macros (big endian)
    25. */
    26. #ifndef GET_UINT32_BE
    27. #define GET_UINT32_BE(n,b,i) { \
    28. (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
    29. | ( (unsigned long) (b)[(i) + 1] << 16 ) \
    30. | ( (unsigned long) (b)[(i) + 2] << 8 ) \
    31. | ( (unsigned long) (b)[(i) + 3] ); \
    32. }
    33. #endif
    34. #ifndef PUT_UINT32_BE
    35. #define PUT_UINT32_BE(n,b,i) { \
    36. (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
    37. (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
    38. (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
    39. (b)[(i) + 3] = (unsigned char) ( (n) ); \
    40. }
    41. #endif
    42. /*
    43. * SHA-1 context setup
    44. */
    45. static
    46. void sha1_starts (sha1_context * ctx)
    47. {
    48. ctx->total[0] = 0;
    49. ctx->total[1] = 0;
    50. ctx->state[0] = 0x67452301;
    51. ctx->state[1] = 0xEFCDAB89;
    52. ctx->state[2] = 0x98BADCFE;
    53. ctx->state[3] = 0x10325476;
    54. ctx->state[4] = 0xC3D2E1F0;
    55. }
    56. static void sha1_process(sha1_context *ctx, const unsigned char data[64])
    57. {
    58. unsigned long temp, W[16], A, B, C, D, E;
    59. GET_UINT32_BE (W[0], data, 0);
    60. GET_UINT32_BE (W[1], data, 4);
    61. GET_UINT32_BE (W[2], data, 8);
    62. GET_UINT32_BE (W[3], data, 12);
    63. GET_UINT32_BE (W[4], data, 16);
    64. GET_UINT32_BE (W[5], data, 20);
    65. GET_UINT32_BE (W[6], data, 24);
    66. GET_UINT32_BE (W[7], data, 28);
    67. GET_UINT32_BE (W[8], data, 32);
    68. GET_UINT32_BE (W[9], data, 36);
    69. GET_UINT32_BE (W[10], data, 40);
    70. GET_UINT32_BE (W[11], data, 44);
    71. GET_UINT32_BE (W[12], data, 48);
    72. GET_UINT32_BE (W[13], data, 52);
    73. GET_UINT32_BE (W[14], data, 56);
    74. GET_UINT32_BE (W[15], data, 60);
    75. #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
    76. #define R(t) ( \
    77. temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
    78. W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
    79. ( W[t & 0x0F] = S(temp,1) ) \
    80. )
    81. #define P(a,b,c,d,e,x) { \
    82. e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
    83. }
    84. A = ctx->state[0];
    85. B = ctx->state[1];
    86. C = ctx->state[2];
    87. D = ctx->state[3];
    88. E = ctx->state[4];
    89. #define F(x,y,z) (z ^ (x & (y ^ z)))
    90. #define K 0x5A827999
    91. P (A, B, C, D, E, W[0]);
    92. P (E, A, B, C, D, W[1]);
    93. P (D, E, A, B, C, W[2]);
    94. P (C, D, E, A, B, W[3]);
    95. P (B, C, D, E, A, W[4]);
    96. P (A, B, C, D, E, W[5]);
    97. P (E, A, B, C, D, W[6]);
    98. P (D, E, A, B, C, W[7]);
    99. P (C, D, E, A, B, W[8]);
    100. P (B, C, D, E, A, W[9]);
    101. P (A, B, C, D, E, W[10]);
    102. P (E, A, B, C, D, W[11]);
    103. P (D, E, A, B, C, W[12]);
    104. P (C, D, E, A, B, W[13]);
    105. P (B, C, D, E, A, W[14]);
    106. P (A, B, C, D, E, W[15]);
    107. P (E, A, B, C, D, R (16));
    108. P (D, E, A, B, C, R (17));
    109. P (C, D, E, A, B, R (18));
    110. P (B, C, D, E, A, R (19));
    111. #undef K
    112. #undef F
    113. #define F(x,y,z) (x ^ y ^ z)
    114. #define K 0x6ED9EBA1
    115. P (A, B, C, D, E, R (20));
    116. P (E, A, B, C, D, R (21));
    117. P (D, E, A, B, C, R (22));
    118. P (C, D, E, A, B, R (23));
    119. P (B, C, D, E, A, R (24));
    120. P (A, B, C, D, E, R (25));
    121. P (E, A, B, C, D, R (26));
    122. P (D, E, A, B, C, R (27));
    123. P (C, D, E, A, B, R (28));
    124. P (B, C, D, E, A, R (29));
    125. P (A, B, C, D, E, R (30));
    126. P (E, A, B, C, D, R (31));
    127. P (D, E, A, B, C, R (32));
    128. P (C, D, E, A, B, R (33));
    129. P (B, C, D, E, A, R (34));
    130. P (A, B, C, D, E, R (35));
    131. P (E, A, B, C, D, R (36));
    132. P (D, E, A, B, C, R (37));
    133. P (C, D, E, A, B, R (38));
    134. P (B, C, D, E, A, R (39));
    135. #undef K
    136. #undef F
    137. #define F(x,y,z) ((x & y) | (z & (x | y)))
    138. #define K 0x8F1BBCDC
    139. P (A, B, C, D, E, R (40));
    140. P (E, A, B, C, D, R (41));
    141. P (D, E, A, B, C, R (42));
    142. P (C, D, E, A, B, R (43));
    143. P (B, C, D, E, A, R (44));
    144. P (A, B, C, D, E, R (45));
    145. P (E, A, B, C, D, R (46));
    146. P (D, E, A, B, C, R (47));
    147. P (C, D, E, A, B, R (48));
    148. P (B, C, D, E, A, R (49));
    149. P (A, B, C, D, E, R (50));
    150. P (E, A, B, C, D, R (51));
    151. P (D, E, A, B, C, R (52));
    152. P (C, D, E, A, B, R (53));
    153. P (B, C, D, E, A, R (54));
    154. P (A, B, C, D, E, R (55));
    155. P (E, A, B, C, D, R (56));
    156. P (D, E, A, B, C, R (57));
    157. P (C, D, E, A, B, R (58));
    158. P (B, C, D, E, A, R (59));
    159. #undef K
    160. #undef F
    161. #define F(x,y,z) (x ^ y ^ z)
    162. #define K 0xCA62C1D6
    163. P (A, B, C, D, E, R (60));
    164. P (E, A, B, C, D, R (61));
    165. P (D, E, A, B, C, R (62));
    166. P (C, D, E, A, B, R (63));
    167. P (B, C, D, E, A, R (64));
    168. P (A, B, C, D, E, R (65));
    169. P (E, A, B, C, D, R (66));
    170. P (D, E, A, B, C, R (67));
    171. P (C, D, E, A, B, R (68));
    172. P (B, C, D, E, A, R (69));
    173. P (A, B, C, D, E, R (70));
    174. P (E, A, B, C, D, R (71));
    175. P (D, E, A, B, C, R (72));
    176. P (C, D, E, A, B, R (73));
    177. P (B, C, D, E, A, R (74));
    178. P (A, B, C, D, E, R (75));
    179. P (E, A, B, C, D, R (76));
    180. P (D, E, A, B, C, R (77));
    181. P (C, D, E, A, B, R (78));
    182. P (B, C, D, E, A, R (79));
    183. #undef K
    184. #undef F
    185. ctx->state[0] += A;
    186. ctx->state[1] += B;
    187. ctx->state[2] += C;
    188. ctx->state[3] += D;
    189. ctx->state[4] += E;
    190. }
    191. #undef P
    192. #undef R
    193. #undef S
    194. /*
    195. * SHA-1 process buffer
    196. */
    197. static
    198. void sha1_update(sha1_context *ctx, const unsigned char *input,
    199. unsigned int ilen)
    200. {
    201. int fill;
    202. unsigned long left;
    203. if (ilen <= 0)
    204. return;
    205. left = ctx->total[0] & 0x3F;
    206. fill = 64 - left;
    207. ctx->total[0] += ilen;
    208. ctx->total[0] &= 0xFFFFFFFF;
    209. if (ctx->total[0] < (unsigned long) ilen)
    210. ctx->total[1]++;
    211. if (left && ilen >= fill) {
    212. memcpy ((void *) (ctx->buffer + left), (void *) input, fill);
    213. sha1_process (ctx, ctx->buffer);
    214. input += fill;
    215. ilen -= fill;
    216. left = 0;
    217. }
    218. while (ilen >= 64) {
    219. sha1_process (ctx, input);
    220. input += 64;
    221. ilen -= 64;
    222. }
    223. if (ilen > 0) {
    224. memcpy ((void *) (ctx->buffer + left), (void *) input, ilen);
    225. }
    226. }
    227. static const unsigned char sha1_padding[64] = {
    228. 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    229. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    230. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    231. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    232. };
    233. /*
    234. * SHA-1 final digest
    235. */
    236. static
    237. void sha1_finish (sha1_context * ctx, unsigned char output[20])
    238. {
    239. unsigned long last, padn;
    240. unsigned long high, low;
    241. unsigned char msglen[8];
    242. high = (ctx->total[0] >> 29)
    243. | (ctx->total[1] << 3);
    244. low = (ctx->total[0] << 3);
    245. PUT_UINT32_BE (high, msglen, 0);
    246. PUT_UINT32_BE (low, msglen, 4);
    247. last = ctx->total[0] & 0x3F;
    248. padn = (last < 56) ? (56 - last) : (120 - last);
    249. sha1_update (ctx, (unsigned char *) sha1_padding, padn);
    250. sha1_update (ctx, msglen, 8);
    251. PUT_UINT32_BE (ctx->state[0], output, 0);
    252. PUT_UINT32_BE (ctx->state[1], output, 4);
    253. PUT_UINT32_BE (ctx->state[2], output, 8);
    254. PUT_UINT32_BE (ctx->state[3], output, 12);
    255. PUT_UINT32_BE (ctx->state[4], output, 16);
    256. }
    257. /*
    258. * Output = SHA-1( input buffer )
    259. */
    260. static
    261. void sha1_csum(const unsigned char *input, unsigned int ilen,
    262. unsigned char *output)
    263. {
    264. sha1_context ctx;
    265. sha1_starts (&ctx);
    266. sha1_update (&ctx, input, ilen);
    267. sha1_finish (&ctx, output);
    268. }
    269. typedef struct {
    270. uint32_t total[2];
    271. uint32_t state[8];
    272. uint8_t buffer[64];
    273. } sha256_context;
    274. static
    275. void sha256_starts(sha256_context * ctx)
    276. {
    277. ctx->total[0] = 0;
    278. ctx->total[1] = 0;
    279. ctx->state[0] = 0x6A09E667;
    280. ctx->state[1] = 0xBB67AE85;
    281. ctx->state[2] = 0x3C6EF372;
    282. ctx->state[3] = 0xA54FF53A;
    283. ctx->state[4] = 0x510E527F;
    284. ctx->state[5] = 0x9B05688C;
    285. ctx->state[6] = 0x1F83D9AB;
    286. ctx->state[7] = 0x5BE0CD19;
    287. }
    288. static void sha256_process(sha256_context *ctx, const uint8_t data[64])
    289. {
    290. uint32_t temp1, temp2;
    291. uint32_t W[64];
    292. uint32_t A, B, C, D, E, F, G, H;
    293. GET_UINT32_BE(W[0], data, 0);
    294. GET_UINT32_BE(W[1], data, 4);
    295. GET_UINT32_BE(W[2], data, 8);
    296. GET_UINT32_BE(W[3], data, 12);
    297. GET_UINT32_BE(W[4], data, 16);
    298. GET_UINT32_BE(W[5], data, 20);
    299. GET_UINT32_BE(W[6], data, 24);
    300. GET_UINT32_BE(W[7], data, 28);
    301. GET_UINT32_BE(W[8], data, 32);
    302. GET_UINT32_BE(W[9], data, 36);
    303. GET_UINT32_BE(W[10], data, 40);
    304. GET_UINT32_BE(W[11], data, 44);
    305. GET_UINT32_BE(W[12], data, 48);
    306. GET_UINT32_BE(W[13], data, 52);
    307. GET_UINT32_BE(W[14], data, 56);
    308. GET_UINT32_BE(W[15], data, 60);
    309. #define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
    310. #define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
    311. #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
    312. #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
    313. #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
    314. #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
    315. #define F0(x,y,z) ((x & y) | (z & (x | y)))
    316. #define F1(x,y,z) (z ^ (x & (y ^ z)))
    317. #define R(t) \
    318. ( \
    319. W[t] = S1(W[t - 2]) + W[t - 7] + \
    320. S0(W[t - 15]) + W[t - 16] \
    321. )
    322. #define P(a,b,c,d,e,f,g,h,x,K) { \
    323. temp1 = h + S3(e) + F1(e,f,g) + K + x; \
    324. temp2 = S2(a) + F0(a,b,c); \
    325. d += temp1; h = temp1 + temp2; \
    326. }
    327. A = ctx->state[0];
    328. B = ctx->state[1];
    329. C = ctx->state[2];
    330. D = ctx->state[3];
    331. E = ctx->state[4];
    332. F = ctx->state[5];
    333. G = ctx->state[6];
    334. H = ctx->state[7];
    335. P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98);
    336. P(H, A, B, C, D, E, F, G, W[1], 0x71374491);
    337. P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF);
    338. P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5);
    339. P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B);
    340. P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1);
    341. P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4);
    342. P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5);
    343. P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98);
    344. P(H, A, B, C, D, E, F, G, W[9], 0x12835B01);
    345. P(G, H, A, B, C, D, E, F, W[10], 0x243185BE);
    346. P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
    347. P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
    348. P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
    349. P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
    350. P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
    351. P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
    352. P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
    353. P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
    354. P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
    355. P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
    356. P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
    357. P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
    358. P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
    359. P(A, B, C, D, E, F, G, H, R(24), 0x983E5152);
    360. P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
    361. P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
    362. P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
    363. P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
    364. P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
    365. P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
    366. P(B, C, D, E, F, G, H, A, R(31), 0x14292967);
    367. P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
    368. P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
    369. P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
    370. P(F, G, H, A, B, C, D, E, R(35), 0x53380D13);
    371. P(E, F, G, H, A, B, C, D, R(36), 0x650A7354);
    372. P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
    373. P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
    374. P(B, C, D, E, F, G, H, A, R(39), 0x92722C85);
    375. P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
    376. P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
    377. P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
    378. P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
    379. P(E, F, G, H, A, B, C, D, R(44), 0xD192E819);
    380. P(D, E, F, G, H, A, B, C, R(45), 0xD6990624);
    381. P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
    382. P(B, C, D, E, F, G, H, A, R(47), 0x106AA070);
    383. P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
    384. P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
    385. P(G, H, A, B, C, D, E, F, R(50), 0x2748774C);
    386. P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
    387. P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
    388. P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
    389. P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
    390. P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
    391. P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
    392. P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
    393. P(G, H, A, B, C, D, E, F, R(58), 0x84C87814);
    394. P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
    395. P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
    396. P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
    397. P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
    398. P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
    399. ctx->state[0] += A;
    400. ctx->state[1] += B;
    401. ctx->state[2] += C;
    402. ctx->state[3] += D;
    403. ctx->state[4] += E;
    404. ctx->state[5] += F;
    405. ctx->state[6] += G;
    406. ctx->state[7] += H;
    407. }
    408. #undef P
    409. #undef R
    410. #undef F1
    411. #undef F0
    412. #undef S3
    413. #undef S2
    414. #undef S1
    415. #undef S0
    416. #undef ROTR
    417. #undef SHR
    418. static
    419. void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length)
    420. {
    421. uint32_t left, fill;
    422. if (!length)
    423. return;
    424. left = ctx->total[0] & 0x3F;
    425. fill = 64 - left;
    426. ctx->total[0] += length;
    427. ctx->total[0] &= 0xFFFFFFFF;
    428. if (ctx->total[0] < length)
    429. ctx->total[1]++;
    430. if (left && length >= fill) {
    431. memcpy((void *) (ctx->buffer + left), (void *) input, fill);
    432. sha256_process(ctx, ctx->buffer);
    433. length -= fill;
    434. input += fill;
    435. left = 0;
    436. }
    437. while (length >= 64) {
    438. sha256_process(ctx, input);
    439. length -= 64;
    440. input += 64;
    441. }
    442. if (length)
    443. memcpy((void *) (ctx->buffer + left), (void *) input, length);
    444. }
    445. static uint8_t sha256_padding[64] = {
    446. 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    447. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    448. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    449. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    450. };
    451. static
    452. void sha256_finish(sha256_context * ctx, uint8_t digest[32])
    453. {
    454. uint32_t last, padn;
    455. uint32_t high, low;
    456. uint8_t msglen[8];
    457. high = ((ctx->total[0] >> 29)
    458. | (ctx->total[1] << 3));
    459. low = (ctx->total[0] << 3);
    460. PUT_UINT32_BE(high, msglen, 0);
    461. PUT_UINT32_BE(low, msglen, 4);
    462. last = ctx->total[0] & 0x3F;
    463. padn = (last < 56) ? (56 - last) : (120 - last);
    464. sha256_update(ctx, sha256_padding, padn);
    465. sha256_update(ctx, msglen, 8);
    466. PUT_UINT32_BE(ctx->state[0], digest, 0);
    467. PUT_UINT32_BE(ctx->state[1], digest, 4);
    468. PUT_UINT32_BE(ctx->state[2], digest, 8);
    469. PUT_UINT32_BE(ctx->state[3], digest, 12);
    470. PUT_UINT32_BE(ctx->state[4], digest, 16);
    471. PUT_UINT32_BE(ctx->state[5], digest, 20);
    472. PUT_UINT32_BE(ctx->state[6], digest, 24);
    473. PUT_UINT32_BE(ctx->state[7], digest, 28);
    474. }
    475. /*
    476. * Output = SHA-256( input buffer ).
    477. */
    478. static
    479. void sha256_csum(const unsigned char *input, unsigned int ilen,
    480. unsigned char *output)
    481. {
    482. sha256_context ctx;
    483. sha256_starts(&ctx);
    484. sha256_update(&ctx, input, ilen);
    485. sha256_finish(&ctx, output);
    486. }
    487. /* #define DEBUG */
    488. static bool g_debug =
    489. #ifdef DEBUG
    490. true;
    491. #else
    492. false;
    493. #endif /* DEBUG */
    494. #define LOGE(fmt, args...) \
    495. fprintf(stderr, "E/%s(%d): " fmt "\n", __func__, __LINE__, ##args)
    496. #define LOGD(fmt, args...) \
    497. do { \
    498. if (g_debug) \
    499. fprintf(stderr, "D/%s(%d): " fmt "\n", __func__, __LINE__, ##args); \
    500. } while (0)
    501. /* sync with ./board/rockchip/rk30xx/rkloader.c #define FDT_PATH */
    502. #define FDT_PATH "rk-kernel.dtb"
    503. #define DTD_SUBFIX ".dtb"
    504. #define DEFAULT_IMAGE_PATH "resource.img"
    505. #define DEFAULT_UNPACK_DIR "out"
    506. #define BLOCK_SIZE 512
    507. #define RESOURCE_PTN_HDR_SIZE 1
    508. #define INDEX_TBL_ENTR_SIZE 1
    509. #define RESOURCE_PTN_VERSION 0
    510. #define INDEX_TBL_VERSION 0
    511. #define RESOURCE_PTN_HDR_MAGIC "RSCE"
    512. typedef struct {
    513. char magic[4]; /* tag, "RSCE" */
    514. uint16_t resource_ptn_version;
    515. uint16_t index_tbl_version;
    516. uint8_t header_size; /* blocks, size of ptn header. */
    517. uint8_t tbl_offset; /* blocks, offset of index table. */
    518. uint8_t tbl_entry_size; /* blocks, size of index table's entry. */
    519. uint32_t tbl_entry_num; /* numbers of index table's entry. */
    520. } resource_ptn_header;
    521. #define INDEX_TBL_ENTR_TAG "ENTR"
    522. #define MAX_INDEX_ENTRY_PATH_LEN 220
    523. #define MAX_HASH_LEN 32
    524. typedef struct {
    525. char tag[4]; /* tag, "ENTR" */
    526. char path[MAX_INDEX_ENTRY_PATH_LEN];
    527. char hash[MAX_HASH_LEN]; /* hash data */
    528. uint32_t hash_size; /* 20 or 32 */
    529. uint32_t content_offset; /* blocks, offset of resource content. */
    530. uint32_t content_size; /* bytes, size of resource content. */
    531. } index_tbl_entry;
    532. #define OPT_VERBOSE "--verbose"
    533. #define OPT_HELP "--help"
    534. #define OPT_VERSION "--version"
    535. #define OPT_PRINT "--print"
    536. #define OPT_PACK "--pack"
    537. #define OPT_UNPACK "--unpack"
    538. #define OPT_TEST_LOAD "--test_load"
    539. #define OPT_TEST_CHARGE "--test_charge"
    540. #define OPT_IMAGE "--image="
    541. #define OPT_ROOT "--root="
    542. #define VERSION "2014-5-31 14:43:42"
    543. typedef struct {
    544. char path[MAX_INDEX_ENTRY_PATH_LEN];
    545. uint32_t content_offset; /* blocks, offset of resource content. */
    546. uint32_t content_size; /* bytes, size of resource content. */
    547. void *load_addr;
    548. } resource_content;
    549. typedef struct {
    550. int max_level;
    551. int num;
    552. int delay;
    553. char prefix[MAX_INDEX_ENTRY_PATH_LEN];
    554. } anim_level_conf;
    555. #define DEF_CHARGE_DESC_PATH "charge_anim_desc.txt"
    556. #define OPT_CHARGE_ANIM_DELAY "delay="
    557. #define OPT_CHARGE_ANIM_LOOP_CUR "only_current_level="
    558. #define OPT_CHARGE_ANIM_LEVELS "levels="
    559. #define OPT_CHARGE_ANIM_LEVEL_CONF "max_level="
    560. #define OPT_CHARGE_ANIM_LEVEL_NUM "num="
    561. #define OPT_CHARGE_ANIM_LEVEL_PFX "prefix="
    562. static char image_path[MAX_INDEX_ENTRY_PATH_LEN] = "\0";
    563. static int fix_blocks(size_t size)
    564. {
    565. return (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
    566. }
    567. static const char *fix_path(const char *path)
    568. {
    569. if (!memcmp(path, "./", 2)) {
    570. return path + 2;
    571. }
    572. return path;
    573. }
    574. static uint16_t switch_short(uint16_t x)
    575. {
    576. uint16_t val;
    577. uint8_t *p = (uint8_t *)(&x);
    578. val = (*p++ & 0xff) << 0;
    579. val |= (*p & 0xff) << 8;
    580. return val;
    581. }
    582. static uint32_t switch_int(uint32_t x)
    583. {
    584. uint32_t val;
    585. uint8_t *p = (uint8_t *)(&x);
    586. val = (*p++ & 0xff) << 0;
    587. val |= (*p++ & 0xff) << 8;
    588. val |= (*p++ & 0xff) << 16;
    589. val |= (*p & 0xff) << 24;
    590. return val;
    591. }
    592. static void fix_header(resource_ptn_header *header)
    593. {
    594. /* switch for be. */
    595. header->resource_ptn_version = switch_short(header->resource_ptn_version);
    596. header->index_tbl_version = switch_short(header->index_tbl_version);
    597. header->tbl_entry_num = switch_int(header->tbl_entry_num);
    598. }
    599. static void fix_entry(index_tbl_entry *entry)
    600. {
    601. /* switch for be. */
    602. entry->content_offset = switch_int(entry->content_offset);
    603. entry->content_size = switch_int(entry->content_size);
    604. }
    605. static int inline get_ptn_offset(void)
    606. {
    607. return 0;
    608. }
    609. static bool StorageWriteLba(int offset_block, void *data, int blocks)
    610. {
    611. bool ret = false;
    612. FILE *file = fopen(image_path, "rb+");
    613. if (!file)
    614. goto end;
    615. int offset = offset_block * BLOCK_SIZE;
    616. fseek(file, offset, SEEK_SET);
    617. if (offset != ftell(file)) {
    618. LOGE("Failed to seek %s to %d!", image_path, offset);
    619. goto end;
    620. }
    621. if (!fwrite(data, blocks * BLOCK_SIZE, 1, file)) {
    622. LOGE("Failed to write %s!", image_path);
    623. goto end;
    624. }
    625. ret = true;
    626. end:
    627. if (file)
    628. fclose(file);
    629. return ret;
    630. }
    631. static bool StorageReadLba(int offset_block, void *data, int blocks)
    632. {
    633. bool ret = false;
    634. FILE *file = fopen(image_path, "rb");
    635. if (!file)
    636. goto end;
    637. int offset = offset_block * BLOCK_SIZE;
    638. fseek(file, offset, SEEK_SET);
    639. if (offset != ftell(file)) {
    640. goto end;
    641. }
    642. if (!fread(data, blocks * BLOCK_SIZE, 1, file)) {
    643. goto end;
    644. }
    645. ret = true;
    646. end:
    647. if (file)
    648. fclose(file);
    649. return ret;
    650. }
    651. static bool write_data(int offset_block, void *data, size_t len)
    652. {
    653. bool ret = false;
    654. if (!data)
    655. goto end;
    656. int blocks = len / BLOCK_SIZE;
    657. if (blocks && !StorageWriteLba(offset_block, data, blocks)) {
    658. goto end;
    659. }
    660. int left = len % BLOCK_SIZE;
    661. if (left) {
    662. char buf[BLOCK_SIZE] = "\0";
    663. memcpy(buf, data + blocks * BLOCK_SIZE, left);
    664. if (!StorageWriteLba(offset_block + blocks, buf, 1))
    665. goto end;
    666. }
    667. ret = true;
    668. end:
    669. return ret;
    670. }
    671. /**********************load test************************/
    672. static int load_file(const char *file_path, int offset_block, int blocks);
    673. static int test_load(int argc, char **argv)
    674. {
    675. if (argc < 1) {
    676. LOGE("Nothing to load!");
    677. return -1;
    678. }
    679. const char *file_path;
    680. int offset_block = 0;
    681. int blocks = 0;
    682. if (argc > 0) {
    683. file_path = (const char *)fix_path(argv[0]);
    684. argc--, argv++;
    685. }
    686. if (argc > 0) {
    687. offset_block = atoi(argv[0]);
    688. argc--, argv++;
    689. }
    690. if (argc > 0) {
    691. blocks = atoi(argv[0]);
    692. }
    693. return load_file(file_path, offset_block, blocks);
    694. }
    695. static void free_content(resource_content *content)
    696. {
    697. if (content->load_addr) {
    698. free(content->load_addr);
    699. content->load_addr = 0;
    700. }
    701. }
    702. static void tests_dump_file(const char *path, void *data, int len)
    703. {
    704. FILE *file = fopen(path, "wb");
    705. if (!file)
    706. return;
    707. fwrite(data, len, 1, file);
    708. fclose(file);
    709. }
    710. static bool load_content(resource_content *content)
    711. {
    712. if (content->load_addr)
    713. return true;
    714. int blocks = fix_blocks(content->content_size);
    715. content->load_addr = malloc(blocks * BLOCK_SIZE);
    716. if (!content->load_addr)
    717. return false;
    718. if (!StorageReadLba(get_ptn_offset() + content->content_offset,
    719. content->load_addr, blocks)) {
    720. free_content(content);
    721. return false;
    722. }
    723. tests_dump_file(content->path, content->load_addr, content->content_size);
    724. return true;
    725. }
    726. static bool load_content_data(resource_content *content, int offset_block,
    727. void *data, int blocks)
    728. {
    729. if (!StorageReadLba(get_ptn_offset() + content->content_offset + offset_block,
    730. data, blocks)) {
    731. return false;
    732. }
    733. tests_dump_file(content->path, data, blocks * BLOCK_SIZE);
    734. return true;
    735. }
    736. static bool get_entry(const char *file_path, index_tbl_entry *entry)
    737. {
    738. bool ret = false;
    739. char buf[BLOCK_SIZE];
    740. resource_ptn_header header;
    741. if (!StorageReadLba(get_ptn_offset(), buf, 1)) {
    742. LOGE("Failed to read header!");
    743. goto end;
    744. }
    745. memcpy(&header, buf, sizeof(header));
    746. if (memcmp(header.magic, RESOURCE_PTN_HDR_MAGIC, sizeof(header.magic))) {
    747. LOGE("Not a resource image(%s)!", image_path);
    748. goto end;
    749. }
    750. /* test on pc, switch for be. */
    751. fix_header(&header);
    752. /* TODO: support header_size & tbl_entry_size */
    753. if (header.resource_ptn_version != RESOURCE_PTN_VERSION ||
    754. header.header_size != RESOURCE_PTN_HDR_SIZE ||
    755. header.index_tbl_version != INDEX_TBL_VERSION ||
    756. header.tbl_entry_size != INDEX_TBL_ENTR_SIZE) {
    757. LOGE("Not supported in this version!");
    758. goto end;
    759. }
    760. int i;
    761. for (i = 0; i < header.tbl_entry_num; i++) {
    762. /* TODO: support tbl_entry_size */
    763. if (!StorageReadLba(
    764. get_ptn_offset() + header.header_size + i * header.tbl_entry_size,
    765. buf, 1)) {
    766. LOGE("Failed to read index entry:%d!", i);
    767. goto end;
    768. }
    769. memcpy(entry, buf, sizeof(*entry));
    770. if (memcmp(entry->tag, INDEX_TBL_ENTR_TAG, sizeof(entry->tag))) {
    771. LOGE("Something wrong with index entry:%d!", i);
    772. goto end;
    773. }
    774. if (!strncmp(entry->path, file_path, sizeof(entry->path)))
    775. break;
    776. }
    777. if (i == header.tbl_entry_num) {
    778. LOGE("Cannot find %s!", file_path);
    779. goto end;
    780. }
    781. /* test on pc, switch for be. */
    782. fix_entry(entry);
    783. printf("Found entry:\n\tpath:%s\n\toffset:%d\tsize:%d\n", entry->path,
    784. entry->content_offset, entry->content_size);
    785. ret = true;
    786. end:
    787. return ret;
    788. }
    789. static bool get_content(resource_content *content)
    790. {
    791. bool ret = false;
    792. index_tbl_entry entry;
    793. if (!get_entry(content->path, &entry))
    794. goto end;
    795. content->content_offset = entry.content_offset;
    796. content->content_size = entry.content_size;
    797. ret = true;
    798. end:
    799. return ret;
    800. }
    801. static int load_file(const char *file_path, int offset_block, int blocks)
    802. {
    803. printf("Try to load:%s", file_path);
    804. if (blocks) {
    805. printf(", offset block:%d, blocks:%d\n", offset_block, blocks);
    806. } else {
    807. printf("\n");
    808. }
    809. bool ret = false;
    810. resource_content content;
    811. snprintf(content.path, sizeof(content.path), "%s", file_path);
    812. content.load_addr = 0;
    813. if (!get_content(&content)) {
    814. goto end;
    815. }
    816. if (!blocks) {
    817. if (!load_content(&content)) {
    818. goto end;
    819. }
    820. } else {
    821. void *data = malloc(blocks * BLOCK_SIZE);
    822. if (!data)
    823. goto end;
    824. if (!load_content_data(&content, offset_block, data, blocks)) {
    825. goto end;
    826. }
    827. }
    828. ret = true;
    829. end:
    830. free_content(&content);
    831. return ret;
    832. }
    833. /**********************load test end************************/
    834. /**********************anim test************************/
    835. static bool parse_level_conf(const char *arg, anim_level_conf *level_conf)
    836. {
    837. memset(level_conf, 0, sizeof(anim_level_conf));
    838. char *buf = NULL;
    839. buf = strstr(arg, OPT_CHARGE_ANIM_LEVEL_CONF);
    840. if (buf) {
    841. level_conf->max_level = atoi(buf + strlen(OPT_CHARGE_ANIM_LEVEL_CONF));
    842. } else {
    843. LOGE("Not found:%s", OPT_CHARGE_ANIM_LEVEL_CONF);
    844. return false;
    845. }
    846. buf = strstr(arg, OPT_CHARGE_ANIM_LEVEL_NUM);
    847. if (buf) {
    848. level_conf->num = atoi(buf + strlen(OPT_CHARGE_ANIM_LEVEL_NUM));
    849. if (level_conf->num <= 0) {
    850. return false;
    851. }
    852. } else {
    853. LOGE("Not found:%s", OPT_CHARGE_ANIM_LEVEL_NUM);
    854. return false;
    855. }
    856. buf = strstr(arg, OPT_CHARGE_ANIM_DELAY);
    857. if (buf) {
    858. level_conf->delay = atoi(buf + strlen(OPT_CHARGE_ANIM_DELAY));
    859. }
    860. buf = strstr(arg, OPT_CHARGE_ANIM_LEVEL_PFX);
    861. if (buf) {
    862. snprintf(level_conf->prefix, sizeof(level_conf->prefix), "%s",
    863. buf + strlen(OPT_CHARGE_ANIM_LEVEL_PFX));
    864. } else {
    865. LOGE("Not found:%s", OPT_CHARGE_ANIM_LEVEL_PFX);
    866. return false;
    867. }
    868. LOGD("Found conf:\nmax_level:%d, num:%d, delay:%d, prefix:%s",
    869. level_conf->max_level, level_conf->num, level_conf->delay,
    870. level_conf->prefix);
    871. return true;
    872. }
    873. static int test_charge(int argc, char **argv)
    874. {
    875. const char *desc;
    876. if (argc > 0) {
    877. desc = argv[0];
    878. } else {
    879. desc = DEF_CHARGE_DESC_PATH;
    880. }
    881. resource_content content;
    882. snprintf(content.path, sizeof(content.path), "%s", desc);
    883. content.load_addr = 0;
    884. if (!get_content(&content)) {
    885. goto end;
    886. }
    887. if (!load_content(&content)) {
    888. goto end;
    889. }
    890. char *buf = (char *)content.load_addr;
    891. char *end = buf + content.content_size - 1;
    892. *end = '\0';
    893. LOGD("desc:\n%s", buf);
    894. int pos = 0;
    895. while (1) {
    896. char *line = (char *)memchr(buf + pos, '\n', strlen(buf + pos));
    897. if (!line)
    898. break;
    899. *line = '\0';
    900. LOGD("splite:%s", buf + pos);
    901. pos += (strlen(buf + pos) + 1);
    902. }
    903. int delay = 900;
    904. int only_current_level = false;
    905. anim_level_conf *level_confs = NULL;
    906. int level_conf_pos = 0;
    907. int level_conf_num = 0;
    908. while (true) {
    909. if (buf >= end)
    910. break;
    911. const char *arg = buf;
    912. buf += (strlen(buf) + 1);
    913. LOGD("parse arg:%s", arg);
    914. if (!memcmp(arg, OPT_CHARGE_ANIM_LEVEL_CONF,
    915. strlen(OPT_CHARGE_ANIM_LEVEL_CONF))) {
    916. if (!level_confs) {
    917. LOGE("Found level conf before levels!");
    918. goto end;
    919. }
    920. if (level_conf_pos >= level_conf_num) {
    921. LOGE("Too many level confs!(%d >= %d)", level_conf_pos, level_conf_num);
    922. goto end;
    923. }
    924. if (!parse_level_conf(arg, level_confs + level_conf_pos)) {
    925. LOGE("Failed to parse level conf:%s", arg);
    926. goto end;
    927. }
    928. level_conf_pos++;
    929. } else if (!memcmp(arg, OPT_CHARGE_ANIM_DELAY,
    930. strlen(OPT_CHARGE_ANIM_DELAY))) {
    931. delay = atoi(arg + strlen(OPT_CHARGE_ANIM_DELAY));
    932. LOGD("Found delay:%d", delay);
    933. } else if (!memcmp(arg, OPT_CHARGE_ANIM_LOOP_CUR,
    934. strlen(OPT_CHARGE_ANIM_LOOP_CUR))) {
    935. only_current_level =
    936. !memcmp(arg + strlen(OPT_CHARGE_ANIM_LOOP_CUR), "true", 4);
    937. LOGD("Found only_current_level:%d", only_current_level);
    938. } else if (!memcmp(arg, OPT_CHARGE_ANIM_LEVELS,
    939. strlen(OPT_CHARGE_ANIM_LEVELS))) {
    940. if (level_conf_num) {
    941. goto end;
    942. }
    943. level_conf_num = atoi(arg + strlen(OPT_CHARGE_ANIM_LEVELS));
    944. if (!level_conf_num) {
    945. goto end;
    946. }
    947. level_confs =
    948. (anim_level_conf *)malloc(level_conf_num * sizeof(anim_level_conf));
    949. LOGD("Found levels:%d", level_conf_num);
    950. } else {
    951. LOGE("Unknown arg:%s", arg);
    952. goto end;
    953. }
    954. }
    955. if (level_conf_pos != level_conf_num || !level_conf_num) {
    956. LOGE("Something wrong with level confs!");
    957. goto end;
    958. }
    959. int i = 0, j = 0;
    960. for (i = 0; i < level_conf_num; i++) {
    961. if (!level_confs[i].delay) {
    962. level_confs[i].delay = delay;
    963. }
    964. if (!level_confs[i].delay) {
    965. LOGE("Missing delay in level conf:%d", i);
    966. goto end;
    967. }
    968. for (j = 0; j < i; j++) {
    969. if (level_confs[j].max_level == level_confs[i].max_level) {
    970. LOGE("Dup level conf:%d", i);
    971. goto end;
    972. }
    973. if (level_confs[j].max_level > level_confs[i].max_level) {
    974. anim_level_conf conf = level_confs[i];
    975. memmove(level_confs + j + 1, level_confs + j,
    976. (i - j) * sizeof(anim_level_conf));
    977. level_confs[j] = conf;
    978. }
    979. }
    980. }
    981. printf("Parse anim desc(%s):\n", desc);
    982. printf("only_current_level=%d\n", only_current_level);
    983. printf("level conf:\n");
    984. for (i = 0; i < level_conf_num; i++) {
    985. printf("\tmax=%d, delay=%d, num=%d, prefix=%s\n", level_confs[i].max_level,
    986. level_confs[i].delay, level_confs[i].num, level_confs[i].prefix);
    987. }
    988. end:
    989. free_content(&content);
    990. return 0;
    991. }
    992. /**********************anim test end************************/
    993. /**********************append file************************/
    994. static const char *PROG = NULL;
    995. static resource_ptn_header header;
    996. static bool just_print = false;
    997. static char root_path[MAX_INDEX_ENTRY_PATH_LEN] = "\0";
    998. static void version(void)
    999. {
    1000. printf("%s (cjf@rock-chips.com)\t" VERSION "\n", PROG);
    1001. }
    1002. static void usage(void)
    1003. {
    1004. printf("Usage: %s [options] [FILES]\n", PROG);
    1005. printf("Tools for Rockchip's resource image.\n");
    1006. version();
    1007. printf("Options:\n");
    1008. printf("\t" OPT_PACK "\t\t\tPack image from given files.\n");
    1009. printf("\t" OPT_UNPACK "\t\tUnpack given image to current dir.\n");
    1010. printf("\t" OPT_IMAGE "path"
    1011. "\t\tSpecify input/output image path.\n");
    1012. printf("\t" OPT_PRINT "\t\t\tJust print informations.\n");
    1013. printf("\t" OPT_VERBOSE "\t\tDisplay more runtime informations.\n");
    1014. printf("\t" OPT_HELP "\t\t\tDisplay this information.\n");
    1015. printf("\t" OPT_VERSION "\t\tDisplay version information.\n");
    1016. printf("\t" OPT_ROOT "path"
    1017. "\t\tSpecify resources' root dir.\n");
    1018. }
    1019. static int pack_image(int file_num, const char **files);
    1020. static int unpack_image(const char *unpack_dir);
    1021. enum ACTION {
    1022. ACTION_PACK,
    1023. ACTION_UNPACK,
    1024. ACTION_TEST_LOAD,
    1025. ACTION_TEST_CHARGE,
    1026. };
    1027. int main(int argc, char **argv)
    1028. {
    1029. PROG = fix_path(argv[0]);
    1030. enum ACTION action = ACTION_PACK;
    1031. argc--, argv++;
    1032. while (argc > 0 && argv[0][0] == '-') {
    1033. /* it's a opt arg. */
    1034. const char *arg = argv[0];
    1035. argc--, argv++;
    1036. if (!strcmp(OPT_VERBOSE, arg)) {
    1037. g_debug = true;
    1038. } else if (!strcmp(OPT_HELP, arg)) {
    1039. usage();
    1040. return 0;
    1041. } else if (!strcmp(OPT_VERSION, arg)) {
    1042. version();
    1043. return 0;
    1044. } else if (!strcmp(OPT_PRINT, arg)) {
    1045. just_print = true;
    1046. } else if (!strcmp(OPT_PACK, arg)) {
    1047. action = ACTION_PACK;
    1048. } else if (!strcmp(OPT_UNPACK, arg)) {
    1049. action = ACTION_UNPACK;
    1050. } else if (!strcmp(OPT_TEST_LOAD, arg)) {
    1051. action = ACTION_TEST_LOAD;
    1052. } else if (!strcmp(OPT_TEST_CHARGE, arg)) {
    1053. action = ACTION_TEST_CHARGE;
    1054. } else if (!memcmp(OPT_IMAGE, arg, strlen(OPT_IMAGE))) {
    1055. snprintf(image_path, sizeof(image_path), "%s", arg + strlen(OPT_IMAGE));
    1056. } else if (!memcmp(OPT_ROOT, arg, strlen(OPT_ROOT))) {
    1057. snprintf(root_path, sizeof(root_path), "%s", arg + strlen(OPT_ROOT));
    1058. } else {
    1059. LOGE("Unknown opt:%s", arg);
    1060. usage();
    1061. return -1;
    1062. }
    1063. }
    1064. if (!image_path[0]) {
    1065. snprintf(image_path, sizeof(image_path), "%s", DEFAULT_IMAGE_PATH);
    1066. }
    1067. switch (action) {
    1068. case ACTION_PACK: {
    1069. int file_num = argc;
    1070. const char **files = (const char **)argv;
    1071. if (!file_num) {
    1072. LOGE("No file to pack!");
    1073. return 0;
    1074. }
    1075. LOGD("try to pack %d files.", file_num);
    1076. return pack_image(file_num, files);
    1077. }
    1078. case ACTION_UNPACK: {
    1079. return unpack_image(argc > 0 ? argv[0] : DEFAULT_UNPACK_DIR);
    1080. }
    1081. case ACTION_TEST_LOAD: {
    1082. return test_load(argc, argv);
    1083. }
    1084. case ACTION_TEST_CHARGE: {
    1085. return test_charge(argc, argv);
    1086. }
    1087. }
    1088. /* not reach here. */
    1089. return -1;
    1090. }
    1091. /************unpack code****************/
    1092. static bool mkdirs(char *path)
    1093. {
    1094. char *tmp = path;
    1095. char *pos = NULL;
    1096. char buf[MAX_INDEX_ENTRY_PATH_LEN];
    1097. bool ret = true;
    1098. while ((pos = memchr(tmp, '/', strlen(tmp)))) {
    1099. strcpy(buf, path);
    1100. buf[pos - path] = '\0';
    1101. tmp = pos + 1;
    1102. LOGD("mkdir:%s", buf);
    1103. if (!mkdir(buf, 0755)) {
    1104. ret = false;
    1105. }
    1106. }
    1107. if (!ret)
    1108. LOGD("Failed to mkdir(%s)!", path);
    1109. return ret;
    1110. }
    1111. static bool dump_file(FILE *file, const char *unpack_dir,
    1112. index_tbl_entry entry)
    1113. {
    1114. LOGD("try to dump entry:%s", entry.path);
    1115. bool ret = false;
    1116. FILE *out_file = NULL;
    1117. long int pos = 0;
    1118. char path[MAX_INDEX_ENTRY_PATH_LEN * 2 + 1];
    1119. if (just_print) {
    1120. ret = true;
    1121. goto done;
    1122. }
    1123. pos = ftell(file);
    1124. snprintf(path, sizeof(path), "%s/%s", unpack_dir, entry.path);
    1125. mkdirs(path);
    1126. out_file = fopen(path, "wb");
    1127. if (!out_file) {
    1128. LOGE("Failed to create:%s", path);
    1129. goto end;
    1130. }
    1131. long int offset = entry.content_offset * BLOCK_SIZE;
    1132. fseek(file, offset, SEEK_SET);
    1133. if (offset != ftell(file)) {
    1134. LOGE("Failed to read content:%s", entry.path);
    1135. goto end;
    1136. }
    1137. char buf[BLOCK_SIZE];
    1138. int n;
    1139. int len = entry.content_size;
    1140. while (len > 0) {
    1141. n = len > BLOCK_SIZE ? BLOCK_SIZE : len;
    1142. if (!fread(buf, n, 1, file)) {
    1143. LOGE("Failed to read content:%s", entry.path);
    1144. goto end;
    1145. }
    1146. if (!fwrite(buf, n, 1, out_file)) {
    1147. LOGE("Failed to write:%s", entry.path);
    1148. goto end;
    1149. }
    1150. len -= n;
    1151. }
    1152. done:
    1153. ret = true;
    1154. end:
    1155. if (out_file)
    1156. fclose(out_file);
    1157. if (pos)
    1158. fseek(file, pos, SEEK_SET);
    1159. return ret;
    1160. }
    1161. static int unpack_image(const char *dir)
    1162. {
    1163. FILE *image_file = NULL;
    1164. bool ret = false;
    1165. char unpack_dir[MAX_INDEX_ENTRY_PATH_LEN];
    1166. if (just_print)
    1167. dir = ".";
    1168. snprintf(unpack_dir, sizeof(unpack_dir), "%s", dir);
    1169. if (!strlen(unpack_dir)) {
    1170. goto end;
    1171. } else if (unpack_dir[strlen(unpack_dir) - 1] == '/') {
    1172. unpack_dir[strlen(unpack_dir) - 1] = '\0';
    1173. }
    1174. mkdir(unpack_dir, 0755);
    1175. image_file = fopen(image_path, "rb");
    1176. char buf[BLOCK_SIZE];
    1177. if (!image_file) {
    1178. LOGE("Failed to open:%s", image_path);
    1179. goto end;
    1180. }
    1181. if (!fread(buf, BLOCK_SIZE, 1, image_file)) {
    1182. LOGE("Failed to read header!");
    1183. goto end;
    1184. }
    1185. memcpy(&header, buf, sizeof(header));
    1186. if (memcmp(header.magic, RESOURCE_PTN_HDR_MAGIC, sizeof(header.magic))) {
    1187. LOGE("Not a resource image(%s)!", image_path);
    1188. goto end;
    1189. }
    1190. /* switch for be. */
    1191. fix_header(&header);
    1192. printf("Dump header:\n");
    1193. printf("partition version:%d.%d\n", header.resource_ptn_version,
    1194. header.index_tbl_version);
    1195. printf("header size:%d\n", header.header_size);
    1196. printf("index tbl:\n\toffset:%d\tentry size:%d\tentry num:%d\n",
    1197. header.tbl_offset, header.tbl_entry_size, header.tbl_entry_num);
    1198. /* TODO: support header_size & tbl_entry_size */
    1199. if (header.resource_ptn_version != RESOURCE_PTN_VERSION ||
    1200. header.header_size != RESOURCE_PTN_HDR_SIZE ||
    1201. header.index_tbl_version != INDEX_TBL_VERSION ||
    1202. header.tbl_entry_size != INDEX_TBL_ENTR_SIZE) {
    1203. LOGE("Not supported in this version!");
    1204. goto end;
    1205. }
    1206. printf("Dump Index table:\n");
    1207. index_tbl_entry entry;
    1208. int i;
    1209. for (i = 0; i < header.tbl_entry_num; i++) {
    1210. /* TODO: support tbl_entry_size */
    1211. if (!fread(buf, BLOCK_SIZE, 1, image_file)) {
    1212. LOGE("Failed to read index entry:%d!", i);
    1213. goto end;
    1214. }
    1215. memcpy(&entry, buf, sizeof(entry));
    1216. if (memcmp(entry.tag, INDEX_TBL_ENTR_TAG, sizeof(entry.tag))) {
    1217. LOGE("Something wrong with index entry:%d!", i);
    1218. goto end;
    1219. }
    1220. /* switch for be. */
    1221. fix_entry(&entry);
    1222. printf("entry(%d):\n\tpath:%s\n\toffset:%d\tsize:%d\n", i, entry.path,
    1223. entry.content_offset, entry.content_size);
    1224. if (!dump_file(image_file, unpack_dir, entry)) {
    1225. goto end;
    1226. }
    1227. }
    1228. printf("Unack %s to %s successed!\n", image_path, unpack_dir);
    1229. ret = true;
    1230. end:
    1231. if (image_file)
    1232. fclose(image_file);
    1233. return ret ? 0 : -1;
    1234. }
    1235. /************unpack code end****************/
    1236. /************pack code****************/
    1237. static inline size_t get_file_size(const char *path)
    1238. {
    1239. LOGD("try to get size(%s)...", path);
    1240. struct stat st;
    1241. if (stat(path, &st) < 0) {
    1242. LOGE("Failed to get size:%s", path);
    1243. return -1;
    1244. }
    1245. LOGD("path:%s, size:%ld", path, st.st_size);
    1246. return st.st_size;
    1247. }
    1248. static int write_file(int offset_block, const char *src_path,
    1249. char hash[], int hash_size)
    1250. {
    1251. LOGD("try to write file(%s) to offset:%d...", src_path, offset_block);
    1252. char *buf = NULL;
    1253. int ret = -1;
    1254. size_t file_size;
    1255. FILE *src_file = fopen(src_path, "rb");
    1256. if (!src_file) {
    1257. LOGE("Failed to open:%s", src_path);
    1258. goto end;
    1259. }
    1260. file_size = get_file_size(src_path);
    1261. if (file_size < 0) {
    1262. goto end;
    1263. }
    1264. buf = calloc(file_size, 1);
    1265. if (!buf)
    1266. goto end;
    1267. if (!fread(buf, file_size, 1, src_file))
    1268. goto end;
    1269. if (!write_data(offset_block, buf, file_size))
    1270. goto end;
    1271. if (hash_size == 20)
    1272. sha1_csum((const unsigned char *)buf, file_size,
    1273. (unsigned char *)hash);
    1274. else if (hash_size == 32)
    1275. sha256_csum((const unsigned char *)buf, file_size,
    1276. (unsigned char *)hash);
    1277. else
    1278. goto end;
    1279. ret = file_size;
    1280. end:
    1281. if (src_file)
    1282. fclose(src_file);
    1283. if (buf)
    1284. free(buf);
    1285. return ret;
    1286. }
    1287. static bool write_header(const int file_num)
    1288. {
    1289. LOGD("try to write header...");
    1290. memcpy(header.magic, RESOURCE_PTN_HDR_MAGIC, sizeof(header.magic));
    1291. header.resource_ptn_version = RESOURCE_PTN_VERSION;
    1292. header.index_tbl_version = INDEX_TBL_VERSION;
    1293. header.header_size = RESOURCE_PTN_HDR_SIZE;
    1294. header.tbl_offset = header.header_size;
    1295. header.tbl_entry_size = INDEX_TBL_ENTR_SIZE;
    1296. header.tbl_entry_num = file_num;
    1297. /* switch for le. */
    1298. resource_ptn_header hdr = header;
    1299. fix_header(&hdr);
    1300. return write_data(0, &hdr, sizeof(hdr));
    1301. }
    1302. static bool write_index_tbl(const int file_num, const char **files)
    1303. {
    1304. LOGD("try to write index table...");
    1305. bool ret = false;
    1306. bool foundFdt = false;
    1307. int offset =
    1308. header.header_size + header.tbl_entry_size * header.tbl_entry_num;
    1309. index_tbl_entry entry;
    1310. char hash[20]; /* sha1 */
    1311. int i;
    1312. memcpy(entry.tag, INDEX_TBL_ENTR_TAG, sizeof(entry.tag));
    1313. for (i = 0; i < file_num; i++) {
    1314. size_t file_size = get_file_size(files[i]);
    1315. if (file_size < 0)
    1316. goto end;
    1317. entry.content_size = file_size;
    1318. entry.content_offset = offset;
    1319. if (write_file(offset, files[i], hash, sizeof(hash)) < 0)
    1320. goto end;
    1321. memcpy(entry.hash, hash, sizeof(hash));
    1322. entry.hash_size = sizeof(hash);
    1323. LOGD("try to write index entry(%s)...", files[i]);
    1324. /* switch for le. */
    1325. fix_entry(&entry);
    1326. memset(entry.path, 0, sizeof(entry.path));
    1327. const char *path = files[i];
    1328. if (root_path[0]) {
    1329. if (!strncmp(path, root_path, strlen(root_path))) {
    1330. path += strlen(root_path);
    1331. if (path[0] == '/')
    1332. path++;
    1333. }
    1334. }
    1335. path = fix_path(path);
    1336. if (!strcmp(files[i] + strlen(files[i]) - strlen(DTD_SUBFIX), DTD_SUBFIX)) {
    1337. if (!foundFdt) {
    1338. /* use default path. */
    1339. LOGD("mod fdt path:%s -> %s...", files[i], FDT_PATH);
    1340. path = FDT_PATH;
    1341. foundFdt = true;
    1342. }
    1343. }
    1344. snprintf(entry.path, sizeof(entry.path), "%s", path);
    1345. offset += fix_blocks(file_size);
    1346. if (!write_data(header.header_size + i * header.tbl_entry_size, &entry,
    1347. sizeof(entry)))
    1348. goto end;
    1349. }
    1350. ret = true;
    1351. end:
    1352. return ret;
    1353. }
    1354. static int pack_image(int file_num, const char **files)
    1355. {
    1356. bool ret = false;
    1357. FILE *image_file = fopen(image_path, "wb");
    1358. if (!image_file) {
    1359. LOGE("Failed to create:%s", image_path);
    1360. goto end;
    1361. }
    1362. fclose(image_file);
    1363. /* prepare files */
    1364. int i = 0;
    1365. int pos = 0;
    1366. const char *tmp;
    1367. for (i = 0; i < file_num; i++) {
    1368. if (!strcmp(files[i] + strlen(files[i]) - strlen(DTD_SUBFIX), DTD_SUBFIX)) {
    1369. /* dtb files for kernel. */
    1370. tmp = files[pos];
    1371. files[pos] = files[i];
    1372. files[i] = tmp;
    1373. pos++;
    1374. } else if (!strcmp(fix_path(image_path), fix_path(files[i]))) {
    1375. /* not to pack image itself! */
    1376. tmp = files[file_num - 1];
    1377. files[file_num - 1] = files[i];
    1378. files[i] = tmp;
    1379. file_num--;
    1380. }
    1381. }
    1382. if (!write_header(file_num)) {
    1383. LOGE("Failed to write header!");
    1384. goto end;
    1385. }
    1386. if (!write_index_tbl(file_num, files)) {
    1387. LOGE("Failed to write index table!");
    1388. goto end;
    1389. }
    1390. printf("Pack to %s successed!\n", image_path);
    1391. ret = true;
    1392. end:
    1393. return ret ? 0 : -1;
    1394. }
    1395. /************pack code end****************/

    2.修改 scripts/Makefile ,让他能够编译改c文件

    hostprogs-always-$(CONFIG_ARCH_ROCKCHIP)        += resource_tool

    再次make,就没有错误了。

    但是问题是,仍然没有生成boot.img

    通过查看mkimg文件的流程,发现还缺少一个命令

    解决: 

    从原来的sdk拷贝一个过来,再次make,就成功生成了boot.img。

    mkbootimg是一个python脚本,内容如下:

    1. #!/usr/bin/env python
    2. # Copyright 2015, The Android Open Source Project
    3. #
    4. # Licensed under the Apache License, Version 2.0 (the "License");
    5. # you may not use this file except in compliance with the License.
    6. # You may obtain a copy of the License at
    7. #
    8. # http://www.apache.org/licenses/LICENSE-2.0
    9. #
    10. # Unless required by applicable law or agreed to in writing, software
    11. # distributed under the License is distributed on an "AS IS" BASIS,
    12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13. # See the License for the specific language governing permissions and
    14. # limitations under the License.
    15. from __future__ import print_function
    16. from argparse import ArgumentParser, FileType, Action
    17. from hashlib import sha1
    18. from os import fstat
    19. import re
    20. from struct import pack
    21. BOOT_IMAGE_HEADER_V3_PAGESIZE = 4096
    22. def filesize(f):
    23. if f is None:
    24. return 0
    25. try:
    26. return fstat(f.fileno()).st_size
    27. except OSError:
    28. return 0
    29. def update_sha(sha, f):
    30. if f:
    31. sha.update(f.read())
    32. f.seek(0)
    33. sha.update(pack('I', filesize(f)))
    34. else:
    35. sha.update(pack('I', 0))
    36. def pad_file(f, padding):
    37. pad = (padding - (f.tell() & (padding - 1))) & (padding - 1)
    38. f.write(pack(str(pad) + 'x'))
    39. def get_number_of_pages(image_size, page_size):
    40. """calculates the number of pages required for the image"""
    41. return (image_size + page_size - 1) / page_size
    42. def get_recovery_dtbo_offset(args):
    43. """calculates the offset of recovery_dtbo image in the boot image"""
    44. num_header_pages = 1 # header occupies a page
    45. num_kernel_pages = get_number_of_pages(filesize(args.kernel), args.pagesize)
    46. num_ramdisk_pages = get_number_of_pages(filesize(args.ramdisk), args.pagesize)
    47. num_second_pages = get_number_of_pages(filesize(args.second), args.pagesize)
    48. dtbo_offset = args.pagesize * (num_header_pages + num_kernel_pages +
    49. num_ramdisk_pages + num_second_pages)
    50. return dtbo_offset
    51. def write_header_v3(args):
    52. BOOT_IMAGE_HEADER_V3_SIZE = 1580
    53. BOOT_MAGIC = 'ANDROID!'.encode()
    54. args.output.write(pack('8s', BOOT_MAGIC))
    55. args.output.write(pack(
    56. '4I',
    57. filesize(args.kernel), # kernel size in bytes
    58. filesize(args.ramdisk), # ramdisk size in bytes
    59. (args.os_version << 11) | args.os_patch_level, # os version and patch level
    60. BOOT_IMAGE_HEADER_V3_SIZE))
    61. args.output.write(pack('4I', 0, 0, 0, 0)) # reserved
    62. args.output.write(pack('I', args.header_version)) # version of bootimage header
    63. args.output.write(pack('1536s', args.cmdline.encode()))
    64. pad_file(args.output, BOOT_IMAGE_HEADER_V3_PAGESIZE)
    65. def write_vendor_boot_header(args):
    66. VENDOR_BOOT_IMAGE_HEADER_V3_SIZE = 2112
    67. BOOT_MAGIC = 'VNDRBOOT'.encode()
    68. args.vendor_boot.write(pack('8s', BOOT_MAGIC))
    69. args.vendor_boot.write(pack(
    70. '5I',
    71. args.header_version, # version of header
    72. args.pagesize, # flash page size we assume
    73. args.base + args.kernel_offset, # kernel physical load addr
    74. args.base + args.ramdisk_offset, # ramdisk physical load addr
    75. filesize(args.vendor_ramdisk))) # vendor ramdisk size in bytes
    76. args.vendor_boot.write(pack('2048s', args.vendor_cmdline.encode()))
    77. args.vendor_boot.write(pack('I', args.base + args.tags_offset)) # physical addr for kernel tags
    78. args.vendor_boot.write(pack('16s', args.board.encode())) # asciiz product name
    79. args.vendor_boot.write(pack('I', VENDOR_BOOT_IMAGE_HEADER_V3_SIZE)) # header size in bytes
    80. if filesize(args.dtb) == 0:
    81. raise ValueError("DTB image must not be empty.")
    82. args.vendor_boot.write(pack('I', filesize(args.dtb))) # size in bytes
    83. args.vendor_boot.write(pack('Q', args.base + args.dtb_offset)) # dtb physical load address
    84. pad_file(args.vendor_boot, args.pagesize)
    85. def write_header(args):
    86. BOOT_IMAGE_HEADER_V1_SIZE = 1648
    87. BOOT_IMAGE_HEADER_V2_SIZE = 1660
    88. BOOT_MAGIC = 'ANDROID!'.encode()
    89. if args.header_version > 3:
    90. raise ValueError('Boot header version %d not supported' % args.header_version)
    91. elif args.header_version == 3:
    92. return write_header_v3(args)
    93. args.output.write(pack('8s', BOOT_MAGIC))
    94. final_ramdisk_offset = (args.base + args.ramdisk_offset) if filesize(args.ramdisk) > 0 else 0
    95. final_second_offset = (args.base + args.second_offset) if filesize(args.second) > 0 else 0
    96. args.output.write(pack(
    97. '10I',
    98. filesize(args.kernel), # size in bytes
    99. args.base + args.kernel_offset, # physical load addr
    100. filesize(args.ramdisk), # size in bytes
    101. final_ramdisk_offset, # physical load addr
    102. filesize(args.second), # size in bytes
    103. final_second_offset, # physical load addr
    104. args.base + args.tags_offset, # physical addr for kernel tags
    105. args.pagesize, # flash page size we assume
    106. args.header_version, # version of bootimage header
    107. (args.os_version << 11) | args.os_patch_level)) # os version and patch level
    108. args.output.write(pack('16s', args.board.encode())) # asciiz product name
    109. args.output.write(pack('512s', args.cmdline[:512].encode()))
    110. sha = sha1()
    111. update_sha(sha, args.kernel)
    112. update_sha(sha, args.ramdisk)
    113. update_sha(sha, args.second)
    114. if args.header_version > 0:
    115. update_sha(sha, args.recovery_dtbo)
    116. if args.header_version > 1:
    117. update_sha(sha, args.dtb)
    118. img_id = pack('32s', sha.digest())
    119. args.output.write(img_id)
    120. args.output.write(pack('1024s', args.cmdline[512:].encode()))
    121. if args.header_version > 0:
    122. args.output.write(pack('I', filesize(args.recovery_dtbo))) # size in bytes
    123. if args.recovery_dtbo:
    124. args.output.write(pack('Q', get_recovery_dtbo_offset(args))) # recovery dtbo offset
    125. else:
    126. args.output.write(pack('Q', 0)) # Will be set to 0 for devices without a recovery dtbo
    127. # Populate boot image header size for header versions 1 and 2.
    128. if args.header_version == 1:
    129. args.output.write(pack('I', BOOT_IMAGE_HEADER_V1_SIZE))
    130. elif args.header_version == 2:
    131. args.output.write(pack('I', BOOT_IMAGE_HEADER_V2_SIZE))
    132. if args.header_version > 1:
    133. # if filesize(args.dtb) == 0:
    134. # raise ValueError("DTB image must not be empty.")
    135. args.output.write(pack('I', filesize(args.dtb))) # size in bytes
    136. args.output.write(pack('Q', args.base + args.dtb_offset)) # dtb physical load address
    137. pad_file(args.output, args.pagesize)
    138. return img_id
    139. class ValidateStrLenAction(Action):
    140. def __init__(self, option_strings, dest, nargs=None, **kwargs):
    141. if 'maxlen' not in kwargs:
    142. raise ValueError('maxlen must be set')
    143. self.maxlen = int(kwargs['maxlen'])
    144. del kwargs['maxlen']
    145. super(ValidateStrLenAction, self).__init__(option_strings, dest, **kwargs)
    146. def __call__(self, parser, namespace, values, option_string=None):
    147. if len(values) > self.maxlen:
    148. raise ValueError(
    149. 'String argument too long: max {0:d}, got {1:d}'.format(self.maxlen, len(values)))
    150. setattr(namespace, self.dest, values)
    151. def write_padded_file(f_out, f_in, padding):
    152. if f_in is None:
    153. return
    154. f_out.write(f_in.read())
    155. pad_file(f_out, padding)
    156. def parse_int(x):
    157. return int(x, 0)
    158. def parse_os_version(x):
    159. match = re.search(r'^(\d{1,3})(?:\.(\d{1,3})(?:\.(\d{1,3}))?)?', x)
    160. if match:
    161. a = int(match.group(1))
    162. b = c = 0
    163. if match.lastindex >= 2:
    164. b = int(match.group(2))
    165. if match.lastindex == 3:
    166. c = int(match.group(3))
    167. # 7 bits allocated for each field
    168. assert a < 128
    169. assert b < 128
    170. assert c < 128
    171. return (a << 14) | (b << 7) | c
    172. return 0
    173. def parse_os_patch_level(x):
    174. match = re.search(r'^(\d{4})-(\d{2})(?:-(\d{2}))?', x)
    175. if match:
    176. y = int(match.group(1)) - 2000
    177. m = int(match.group(2))
    178. # 7 bits allocated for the year, 4 bits for the month
    179. assert 0 <= y < 128
    180. assert 0 < m <= 12
    181. return (y << 4) | m
    182. return 0
    183. def parse_cmdline():
    184. parser = ArgumentParser()
    185. parser.add_argument('--kernel', help='path to the kernel', type=FileType('rb'))
    186. parser.add_argument('--ramdisk', help='path to the ramdisk', type=FileType('rb'))
    187. parser.add_argument('--second', help='path to the 2nd bootloader', type=FileType('rb'))
    188. parser.add_argument('--dtb', help='path to dtb', type=FileType('rb'))
    189. recovery_dtbo_group = parser.add_mutually_exclusive_group()
    190. recovery_dtbo_group.add_argument('--recovery_dtbo', help='path to the recovery DTBO',
    191. type=FileType('rb'))
    192. recovery_dtbo_group.add_argument('--recovery_acpio', help='path to the recovery ACPIO',
    193. type=FileType('rb'), metavar='RECOVERY_ACPIO',
    194. dest='recovery_dtbo')
    195. parser.add_argument('--cmdline', help='extra arguments to be passed on the '
    196. 'kernel command line', default='', action=ValidateStrLenAction, maxlen=1536)
    197. parser.add_argument('--vendor_cmdline',
    198. help='kernel command line arguments contained in vendor boot',
    199. default='', action=ValidateStrLenAction, maxlen=2048)
    200. parser.add_argument('--base', help='base address', type=parse_int, default=0x10000000)
    201. parser.add_argument('--kernel_offset', help='kernel offset', type=parse_int, default=0x00008000)
    202. parser.add_argument('--ramdisk_offset', help='ramdisk offset', type=parse_int,
    203. default=0x01000000)
    204. parser.add_argument('--second_offset', help='2nd bootloader offset', type=parse_int,
    205. default=0x00f00000)
    206. parser.add_argument('--dtb_offset', help='dtb offset', type=parse_int, default=0x01f00000)
    207. parser.add_argument('--os_version', help='operating system version', type=parse_os_version,
    208. default=0)
    209. parser.add_argument('--os_patch_level', help='operating system patch level',
    210. type=parse_os_patch_level, default=0)
    211. parser.add_argument('--tags_offset', help='tags offset', type=parse_int, default=0x00000100)
    212. parser.add_argument('--board', help='board name', default='', action=ValidateStrLenAction,
    213. maxlen=16)
    214. parser.add_argument('--pagesize', help='page size', type=parse_int,
    215. choices=[2**i for i in range(11, 15)], default=2048)
    216. parser.add_argument('--id', help='print the image ID on standard output',
    217. action='store_true')
    218. parser.add_argument('--header_version', help='boot image header version', type=parse_int,
    219. default=0)
    220. parser.add_argument('-o', '--output', help='output file name', type=FileType('wb'))
    221. parser.add_argument('--vendor_boot', help='vendor boot output file name', type=FileType('wb'))
    222. parser.add_argument('--vendor_ramdisk', help='path to the vendor ramdisk', type=FileType('rb'))
    223. return parser.parse_args()
    224. def write_data(args, pagesize):
    225. write_padded_file(args.output, args.kernel, pagesize)
    226. write_padded_file(args.output, args.ramdisk, pagesize)
    227. write_padded_file(args.output, args.second, pagesize)
    228. if args.header_version > 0 and args.header_version < 3:
    229. write_padded_file(args.output, args.recovery_dtbo, pagesize)
    230. if args.header_version == 2:
    231. write_padded_file(args.output, args.dtb, pagesize)
    232. def write_vendor_boot_data(args):
    233. write_padded_file(args.vendor_boot, args.vendor_ramdisk, args.pagesize)
    234. write_padded_file(args.vendor_boot, args.dtb, args.pagesize)
    235. def main():
    236. args = parse_cmdline()
    237. if args.vendor_boot is not None:
    238. if args.header_version < 3:
    239. raise ValueError('--vendor_boot not compatible with given header version')
    240. if args.vendor_ramdisk is None:
    241. raise ValueError('--vendor_ramdisk missing or invalid')
    242. write_vendor_boot_header(args)
    243. write_vendor_boot_data(args)
    244. if args.output is not None:
    245. if args.kernel is None:
    246. raise ValueError('kernel must be supplied when creating a boot image')
    247. if args.second is not None and args.header_version > 2:
    248. raise ValueError('--second not compatible with given header version')
    249. img_id = write_header(args)
    250. if args.header_version > 2:
    251. write_data(args, BOOT_IMAGE_HEADER_V3_PAGESIZE)
    252. else:
    253. write_data(args, args.pagesize)
    254. if args.id and img_id is not None:
    255. # Python 2's struct.pack returns a string, but py3 returns bytes.
    256. if isinstance(img_id, str):
    257. img_id = [ord(x) for x in img_id]
    258. print('0x' + ''.join('{:02x}'.format(c) for c in img_id))
    259. if __name__ == '__main__':
    260. main()

    最后还有一个说明一下:

    logo.bmp和logo_kernel.bmp 我也是拷贝了一份的。

  • 相关阅读:
    树状数组。 数组修改某个元素的数值/求出前n个元素的和,需要在一百毫秒处理上百万个数字
    Ant Design Vue Pro去掉权限,直接进入系统
    java auth 随笔 0-shiro
    一个优质软件测试工程师简历,疯狂面试5家公司......
    【JAVA UI】HarmonyOS 定位的功能基本实现
    “蘑菇书“配套在线课程上线
    netty系列之:kequeue传输协议详解
    本地库覆盖glibc的API
    VMware找不到父磁盘 父虚拟磁盘在子虚拟磁盘创建之后被修改过。父虚拟磁盘的内容 ID 与子虚拟磁盘中对应的父内容 ID 不匹配
    CF696B Puzzles 题解
  • 原文地址:https://blog.csdn.net/zhaozhi0810/article/details/133761180