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

2023-11-03 16:21

本文主要是介绍解决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脚本内容如下:

#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd.set -eusage() {cat >&2 << USAGE
usage: $0 [-h] --dtb DTBoptional arguments:-h, --help            show this help message and exit--dtb DTB             the dtb file name
USAGE
}# Parse command-line arguments
while [ $# -gt 0 ]; docase $1 in--dtb)DTB=$2shift 2;;-h)usageexit 0;;--help)usageexit 0;;*)shift;;esac
donesrctree=${srctree-"."}
objtree=${objtree-"."}
if [ "${ARCH}" == "" ]; thenif [ "$($srctree/scripts/config --state CONFIG_ARM)" == "y" ]; thenARCH=armelseARCH=arm64fi
fiLOGO_PATH=${srctree}/logo.bmp
[ -f ${LOGO_PATH} ] && LOGO=logo.bmpLOGO_KERNEL_PATH=${srctree}/logo_kernel.bmp
[ -f ${LOGO_KERNEL_PATH} ] && LOGO_KERNEL=logo_kernel.bmpKERNEL_IMAGE_PATH=${objtree}/arch/${ARCH}/boot/Image
KERNEL_IMAGE_ARG="--kernel ${KERNEL_IMAGE_PATH}"
if [ "${ARCH}" == "arm" ]; thenDTB_PATH=${objtree}/arch/arm/boot/dts/${DTB}ZIMAGE=zImage
elseDTB_PATH=${objtree}/arch/arm64/boot/dts/rockchip/${DTB}ZIMAGE=Image.lz4
fi
KERNEL_ZIMAGE_PATH=${objtree}/arch/${ARCH}/boot/${ZIMAGE}
KERNEL_ZIMAGE_ARG="--kernel ${KERNEL_ZIMAGE_PATH}"
if [ ! -f ${DTB_PATH} ]; thenecho "No dtb" >&2usageexit 1
fiOUT=out
ITB=${BOOT_IMG}
ITS=${OUT}/boot.its
MKIMAGE=${MKIMAGE-"mkimage"}
MKIMAGE_ARG="-E -p 0x800"make_boot_img()
{RAMDISK_IMG_PATH=${objtree}/ramdisk.img[ -f ${RAMDISK_IMG_PATH} ] && RAMDISK_IMG=ramdisk.img && RAMDISK_ARG="--ramdisk ${RAMDISK_IMG_PATH}"${srctree}/scripts/mkbootimg \${KERNEL_IMAGE_ARG} \${RAMDISK_ARG} \--second resource.img \-o boot.img && \echo "  Image:  boot.img (with Image ${RAMDISK_IMG} resource.img) is ready";${srctree}/scripts/mkbootimg \${KERNEL_ZIMAGE_ARG} \${RAMDISK_ARG} \--second resource.img \-o zboot.img && \echo "  Image:  zboot.img (with ${ZIMAGE} ${RAMDISK_IMG} resource.img) is ready"
}
make_boot_multi_dtb_img()
{RAMDISK_IMG_PATH=${objtree}/ramdisk.img[ -f ${RAMDISK_IMG_PATH} ] && RAMDISK_IMG=ramdisk.img && RAMDISK_ARG="--ramdisk ${RAMDISK_IMG_PATH}"${srctree}/scripts/mkbootimg \${KERNEL_IMAGE_ARG} \${RAMDISK_ARG} \--second resource_multi_dtb.img \-o boot.img && \echo "  Image:  boot.img (with Image ${RAMDISK_IMG} resource_multi_dtb.img) is ready";${srctree}/scripts/mkbootimg \${KERNEL_ZIMAGE_ARG} \${RAMDISK_ARG} \--second resource_multi_dtb.img \-o zboot.img && \echo "  Image:  zboot.img (with ${ZIMAGE} ${RAMDISK_IMG} resource_multi_dtb.img) is ready"
}repack_boot_img()
{${srctree}/scripts/repack-bootimg \--boot_img ${BOOT_IMG} --out ${OUT} \${KERNEL_IMAGE_ARG} \--second resource.img \--dtb ${DTB_PATH} \-o boot.img &&echo "  Image:  boot.img (${BOOT_IMG} + Image) is ready";${srctree}/scripts/repack-bootimg \--boot_img ${BOOT_IMG} --out ${OUT} \${KERNEL_ZIMAGE_ARG} \--second resource.img \--dtb ${DTB_PATH} \-o zboot.img && \echo "  Image:  zboot.img (${BOOT_IMG} + ${ZIMAGE}) is ready"
}repack_multi_dtb_boot_img()
{${srctree}/scripts/repack-bootimg \--boot_img ${BOOT_IMG} --out ${OUT} \${KERNEL_IMAGE_ARG} \--second resource_multi_dtb.img \--dtb ${DTB_PATH} \-o boot.img &&echo "  Image:  boot.img (${BOOT_IMG} + Image + resource_multi_dtb) is ready";${srctree}/scripts/repack-bootimg \--boot_img ${BOOT_IMG} --out ${OUT} \${KERNEL_ZIMAGE_ARG} \--second resource_multi_dtb.img \--dtb ${DTB_PATH} \-o zboot.img && \echo "  Image:  zboot.img (${BOOT_IMG} + ${ZIMAGE}) is ready"
}check_mkimage()
{MKIMAGE=$(type -p ${MKIMAGE} || true)if [ -z "${MKIMAGE}" ]; then# Doesn't existecho '"mkimage" command not found - U-Boot images will not be built' >&2exit 1;fi
}unpack_itb()
{rm -rf ${OUT}mkdir -p ${OUT}for NAME in $(fdtget -l ${ITB} /images)do# generate imageNODE="/images/${NAME}"OFFS=$(fdtget -ti ${ITB} ${NODE} data-position)SIZE=$(fdtget -ti ${ITB} ${NODE} data-size)if [ -z ${OFFS} ]; thencontinue;fiif [ ${SIZE} -ne 0 ]; thendd if=${ITB} of=${OUT}/${NAME} bs=${SIZE} count=1 skip=${OFFS} iflag=skip_bytes >/dev/null 2>&1elsetouch ${OUT}/${NAME}fidone[ ! -f ${OUT}/kernel ] && echo "FIT ${ITB} no kernel" >&2 && exit 1 || true
}gen_its()
{TMP_ITB=${OUT}/boot.tmp# add placeholdercp ${ITB} ${TMP_ITB}for NAME in $(fdtget -l ${ITB} /images); dofdtput -t s ${TMP_ITB} /images/${NAME} data "/INCBIN/(${NAME})"donedtc -I dtb -O dts ${TMP_ITB} -o ${ITS} >/dev/null 2>&1rm -f ${TMP_ITB}# fixup placeholder: data = "/INCBIN/(...)"; -> data = /incbin/("...");sed -i "s/\"\/INCBIN\/(\(.*\))\"/\/incbin\/(\"\1\")/" ${ITS}# removesed -i "/memreserve/d"		${ITS}sed -i "/timestamp/d"		${ITS}sed -i "/data-size/d"		${ITS}sed -i "/data-position/d"	${ITS}sed -i "/value/d"		${ITS}sed -i "/hashed-strings/d"	${ITS}sed -i "/hashed-nodes/d"	${ITS}sed -i "/signer-version/d"	${ITS}sed -i "/signer-name/d"		${ITS}
}gen_itb()
{[ -f ${OUT}/fdt ] && cp -a ${DTB_PATH} ${OUT}/fdt && FDT=" + ${DTB}"[ -f ${OUT}/resource ] && cp -a resource.img ${OUT}/resource && RESOURCE=" + resource.img"COMP=$(fdtget ${ITB} /images/kernel compression)case "${COMP}" ingzip)	EXT=".gz";;lz4)	EXT=".lz4";;bzip2)	EXT=".bz2";;lzma)	EXT=".lzma";;lzo)	EXT=".lzo";;esaccp -a ${KERNEL_IMAGE_PATH}${EXT} ${OUT}/kernel && \${MKIMAGE} ${MKIMAGE_ARG} -f ${ITS} boot.img >/dev/null && \echo "  Image:  boot.img (FIT ${BOOT_IMG} + Image${EXT}${FDT}${RESOURCE}) is ready";if [ "${EXT}" == "" ] && [ -f ${KERNEL_ZIMAGE_PATH} ]; thencp -a ${KERNEL_ZIMAGE_PATH} ${OUT}/kernel && \${MKIMAGE} ${MKIMAGE_ARG} -f ${ITS} zboot.img >/dev/null && \echo "  Image:  zboot.img (FIT ${BOOT_IMG} + zImage${FDT}${RESOURCE}) is ready";fi
}repack_itb()
{check_mkimageunpack_itbgen_itsgen_itb
}# Create U-Boot FIT Image use ${BOOT_ITS}
make_fit_boot_img()
{ITS=${OUT}/boot.itscheck_mkimagemkdir -p ${OUT}rm -f ${OUT}/fdt ${OUT}/kernel ${OUT}/resource ${ITS}cp -a ${BOOT_ITS} ${ITS}cp -a ${DTB_PATH} ${OUT}/fdtcp -a ${KERNEL_ZIMAGE_PATH} ${OUT}/kernelcp -a resource.img ${OUT}/resourceif [ "${ARCH}" == "arm64" ]; thensed -i -e 's/arch = ""/arch = "arm64"/g' -e 's/compression = ""/compression = "lz4"/' ${ITS}elsesed -i -e 's/arch = ""/arch = "arm"/g' -e 's/compression = ""/compression = "none"/' ${ITS}fiFIT_DESC=$(${MKIMAGE} ${MKIMAGE_ARG} -f ${ITS} boot.img | grep "FIT description" | sed 's/FIT description: //')echo "  Image:  boot.img (${FIT_DESC}) is ready";
}if [ -x ${srctree}/scripts/bmpconvert ]; thenif [ -f ${LOGO_PATH} ]; then${srctree}/scripts/bmpconvert ${LOGO_PATH};fiif [ -f ${LOGO_KERNEL_PATH} ]; then${srctree}/scripts/bmpconvert ${LOGO_KERNEL_PATH};fi
fiif [ "${srctree}" != "${objtree}" ]; thenif [ -f ${LOGO_PATH} ]; thencp -a ${LOGO_PATH} ${objtree}/;fiif [ -f ${LOGO_KERNEL_PATH} ]; thencp -a ${LOGO_KERNEL_PATH} ${objtree}/;fi
fi
scripts/resource_tool ${DTB_PATH} ${LOGO} ${LOGO_KERNEL} >/dev/null
echo "  Image:  resource.img (with ${DTB} ${LOGO} ${LOGO_KERNEL}) is ready"if [ -f "${BOOT_IMG}" ]; thenif file -L -p -b ${BOOT_IMG} | grep -q 'Device Tree Blob' ; thenrepack_itb;elif [ -x ${srctree}/scripts/repack-bootimg ]; thenif [[ $MULTI_DTB = "true" ]] ; thenecho "  ready to build multi dtb boot.img";repack_multi_dtb_boot_img;elserepack_boot_img;fifi
elif [ -f "${BOOT_ITS}" ]; thenmake_fit_boot_img;
elif [ -x ${srctree}/scripts/mkbootimg ]; thenif [[ $MULTI_DTB = "true" ]] ; thenecho "  ready to build multi dtb boot.img";make_boot_multi_dtb_img;elsemake_boot_img;fi
fi

错误提示3:没有resource_tool命令

解决:

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

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

resource_tool.c原文如下:

// SPDX-License-Identifier: GPL-2.0+
/** (C) Copyright 2008-2015 Fuzhou Rockchip Electronics Co., Ltd*/#include <errno.h>
#include <memory.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <time.h>/*** \brief	   SHA-1 context structure*/
typedef struct
{unsigned long total[2];	/*!< number of bytes processed	*/unsigned long state[5];	/*!< intermediate digest state	*/unsigned char buffer[64];	/*!< data block being processed */
}
sha1_context;/** 32-bit integer manipulation macros (big endian)*/
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(n,b,i) {				\(n) = ( (unsigned long) (b)[(i)    ] << 24 )	\| ( (unsigned long) (b)[(i) + 1] << 16 )	\| ( (unsigned long) (b)[(i) + 2] <<  8 )	\| ( (unsigned long) (b)[(i) + 3]       );	\
}
#endif
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n,b,i) {				\(b)[(i)    ] = (unsigned char) ( (n) >> 24 );	\(b)[(i) + 1] = (unsigned char) ( (n) >> 16 );	\(b)[(i) + 2] = (unsigned char) ( (n) >>  8 );	\(b)[(i) + 3] = (unsigned char) ( (n)       );	\
}
#endif/** SHA-1 context setup*/
static
void sha1_starts (sha1_context * ctx)
{ctx->total[0] = 0;ctx->total[1] = 0;ctx->state[0] = 0x67452301;ctx->state[1] = 0xEFCDAB89;ctx->state[2] = 0x98BADCFE;ctx->state[3] = 0x10325476;ctx->state[4] = 0xC3D2E1F0;
}static void sha1_process(sha1_context *ctx, const unsigned char data[64])
{unsigned long temp, W[16], A, B, C, D, E;GET_UINT32_BE (W[0], data, 0);GET_UINT32_BE (W[1], data, 4);GET_UINT32_BE (W[2], data, 8);GET_UINT32_BE (W[3], data, 12);GET_UINT32_BE (W[4], data, 16);GET_UINT32_BE (W[5], data, 20);GET_UINT32_BE (W[6], data, 24);GET_UINT32_BE (W[7], data, 28);GET_UINT32_BE (W[8], data, 32);GET_UINT32_BE (W[9], data, 36);GET_UINT32_BE (W[10], data, 40);GET_UINT32_BE (W[11], data, 44);GET_UINT32_BE (W[12], data, 48);GET_UINT32_BE (W[13], data, 52);GET_UINT32_BE (W[14], data, 56);GET_UINT32_BE (W[15], data, 60);#define S(x,n)	((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))#define R(t) (						\temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^	\W[(t - 14) & 0x0F] ^ W[ t      & 0x0F],	\( W[t & 0x0F] = S(temp,1) )			\
)#define P(a,b,c,d,e,x)	{				\e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);	\
}A = ctx->state[0];B = ctx->state[1];C = ctx->state[2];D = ctx->state[3];E = ctx->state[4];#define F(x,y,z) (z ^ (x & (y ^ z)))
#define K 0x5A827999P (A, B, C, D, E, W[0]);P (E, A, B, C, D, W[1]);P (D, E, A, B, C, W[2]);P (C, D, E, A, B, W[3]);P (B, C, D, E, A, W[4]);P (A, B, C, D, E, W[5]);P (E, A, B, C, D, W[6]);P (D, E, A, B, C, W[7]);P (C, D, E, A, B, W[8]);P (B, C, D, E, A, W[9]);P (A, B, C, D, E, W[10]);P (E, A, B, C, D, W[11]);P (D, E, A, B, C, W[12]);P (C, D, E, A, B, W[13]);P (B, C, D, E, A, W[14]);P (A, B, C, D, E, W[15]);P (E, A, B, C, D, R (16));P (D, E, A, B, C, R (17));P (C, D, E, A, B, R (18));P (B, C, D, E, A, R (19));#undef K
#undef F#define F(x,y,z) (x ^ y ^ z)
#define K 0x6ED9EBA1P (A, B, C, D, E, R (20));P (E, A, B, C, D, R (21));P (D, E, A, B, C, R (22));P (C, D, E, A, B, R (23));P (B, C, D, E, A, R (24));P (A, B, C, D, E, R (25));P (E, A, B, C, D, R (26));P (D, E, A, B, C, R (27));P (C, D, E, A, B, R (28));P (B, C, D, E, A, R (29));P (A, B, C, D, E, R (30));P (E, A, B, C, D, R (31));P (D, E, A, B, C, R (32));P (C, D, E, A, B, R (33));P (B, C, D, E, A, R (34));P (A, B, C, D, E, R (35));P (E, A, B, C, D, R (36));P (D, E, A, B, C, R (37));P (C, D, E, A, B, R (38));P (B, C, D, E, A, R (39));#undef K
#undef F#define F(x,y,z) ((x & y) | (z & (x | y)))
#define K 0x8F1BBCDCP (A, B, C, D, E, R (40));P (E, A, B, C, D, R (41));P (D, E, A, B, C, R (42));P (C, D, E, A, B, R (43));P (B, C, D, E, A, R (44));P (A, B, C, D, E, R (45));P (E, A, B, C, D, R (46));P (D, E, A, B, C, R (47));P (C, D, E, A, B, R (48));P (B, C, D, E, A, R (49));P (A, B, C, D, E, R (50));P (E, A, B, C, D, R (51));P (D, E, A, B, C, R (52));P (C, D, E, A, B, R (53));P (B, C, D, E, A, R (54));P (A, B, C, D, E, R (55));P (E, A, B, C, D, R (56));P (D, E, A, B, C, R (57));P (C, D, E, A, B, R (58));P (B, C, D, E, A, R (59));#undef K
#undef F#define F(x,y,z) (x ^ y ^ z)
#define K 0xCA62C1D6P (A, B, C, D, E, R (60));P (E, A, B, C, D, R (61));P (D, E, A, B, C, R (62));P (C, D, E, A, B, R (63));P (B, C, D, E, A, R (64));P (A, B, C, D, E, R (65));P (E, A, B, C, D, R (66));P (D, E, A, B, C, R (67));P (C, D, E, A, B, R (68));P (B, C, D, E, A, R (69));P (A, B, C, D, E, R (70));P (E, A, B, C, D, R (71));P (D, E, A, B, C, R (72));P (C, D, E, A, B, R (73));P (B, C, D, E, A, R (74));P (A, B, C, D, E, R (75));P (E, A, B, C, D, R (76));P (D, E, A, B, C, R (77));P (C, D, E, A, B, R (78));P (B, C, D, E, A, R (79));#undef K
#undef Fctx->state[0] += A;ctx->state[1] += B;ctx->state[2] += C;ctx->state[3] += D;ctx->state[4] += E;
}#undef P
#undef R
#undef S/** SHA-1 process buffer*/
static
void sha1_update(sha1_context *ctx, const unsigned char *input,unsigned int ilen)
{int fill;unsigned long left;if (ilen <= 0)return;left = ctx->total[0] & 0x3F;fill = 64 - left;ctx->total[0] += ilen;ctx->total[0] &= 0xFFFFFFFF;if (ctx->total[0] < (unsigned long) ilen)ctx->total[1]++;if (left && ilen >= fill) {memcpy ((void *) (ctx->buffer + left), (void *) input, fill);sha1_process (ctx, ctx->buffer);input += fill;ilen -= fill;left = 0;}while (ilen >= 64) {sha1_process (ctx, input);input += 64;ilen -= 64;}if (ilen > 0) {memcpy ((void *) (ctx->buffer + left), (void *) input, ilen);}
}static const unsigned char sha1_padding[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};/** SHA-1 final digest*/
static
void sha1_finish (sha1_context * ctx, unsigned char output[20])
{unsigned long last, padn;unsigned long high, low;unsigned char msglen[8];high = (ctx->total[0] >> 29)| (ctx->total[1] << 3);low = (ctx->total[0] << 3);PUT_UINT32_BE (high, msglen, 0);PUT_UINT32_BE (low, msglen, 4);last = ctx->total[0] & 0x3F;padn = (last < 56) ? (56 - last) : (120 - last);sha1_update (ctx, (unsigned char *) sha1_padding, padn);sha1_update (ctx, msglen, 8);PUT_UINT32_BE (ctx->state[0], output, 0);PUT_UINT32_BE (ctx->state[1], output, 4);PUT_UINT32_BE (ctx->state[2], output, 8);PUT_UINT32_BE (ctx->state[3], output, 12);PUT_UINT32_BE (ctx->state[4], output, 16);
}/** Output = SHA-1( input buffer )*/
static
void sha1_csum(const unsigned char *input, unsigned int ilen,unsigned char *output)
{sha1_context ctx;sha1_starts (&ctx);sha1_update (&ctx, input, ilen);sha1_finish (&ctx, output);
}typedef struct {uint32_t total[2];uint32_t state[8];uint8_t buffer[64];
} sha256_context;static
void sha256_starts(sha256_context * ctx)
{ctx->total[0] = 0;ctx->total[1] = 0;ctx->state[0] = 0x6A09E667;ctx->state[1] = 0xBB67AE85;ctx->state[2] = 0x3C6EF372;ctx->state[3] = 0xA54FF53A;ctx->state[4] = 0x510E527F;ctx->state[5] = 0x9B05688C;ctx->state[6] = 0x1F83D9AB;ctx->state[7] = 0x5BE0CD19;
}static void sha256_process(sha256_context *ctx, const uint8_t data[64])
{uint32_t temp1, temp2;uint32_t W[64];uint32_t A, B, C, D, E, F, G, H;GET_UINT32_BE(W[0], data, 0);GET_UINT32_BE(W[1], data, 4);GET_UINT32_BE(W[2], data, 8);GET_UINT32_BE(W[3], data, 12);GET_UINT32_BE(W[4], data, 16);GET_UINT32_BE(W[5], data, 20);GET_UINT32_BE(W[6], data, 24);GET_UINT32_BE(W[7], data, 28);GET_UINT32_BE(W[8], data, 32);GET_UINT32_BE(W[9], data, 36);GET_UINT32_BE(W[10], data, 40);GET_UINT32_BE(W[11], data, 44);GET_UINT32_BE(W[12], data, 48);GET_UINT32_BE(W[13], data, 52);GET_UINT32_BE(W[14], data, 56);GET_UINT32_BE(W[15], data, 60);#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))#define F0(x,y,z) ((x & y) | (z & (x | y)))
#define F1(x,y,z) (z ^ (x & (y ^ z)))#define R(t)					\
(						\W[t] = S1(W[t - 2]) + W[t - 7] +	\S0(W[t - 15]) + W[t - 16]	\
)#define P(a,b,c,d,e,f,g,h,x,K) {		\temp1 = h + S3(e) + F1(e,f,g) + K + x;	\temp2 = S2(a) + F0(a,b,c);		\d += temp1; h = temp1 + temp2;		\
}A = ctx->state[0];B = ctx->state[1];C = ctx->state[2];D = ctx->state[3];E = ctx->state[4];F = ctx->state[5];G = ctx->state[6];H = ctx->state[7];P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98);P(H, A, B, C, D, E, F, G, W[1], 0x71374491);P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF);P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5);P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B);P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1);P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4);P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5);P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98);P(H, A, B, C, D, E, F, G, W[9], 0x12835B01);P(G, H, A, B, C, D, E, F, W[10], 0x243185BE);P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174);P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA);P(A, B, C, D, E, F, G, H, R(24), 0x983E5152);P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D);P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8);P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147);P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351);P(B, C, D, E, F, G, H, A, R(31), 0x14292967);P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85);P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);P(F, G, H, A, B, C, D, E, R(35), 0x53380D13);P(E, F, G, H, A, B, C, D, R(36), 0x650A7354);P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);P(B, C, D, E, F, G, H, A, R(39), 0x92722C85);P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B);P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);P(E, F, G, H, A, B, C, D, R(44), 0xD192E819);P(D, E, F, G, H, A, B, C, R(45), 0xD6990624);P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585);P(B, C, D, E, F, G, H, A, R(47), 0x106AA070);P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116);P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08);P(G, H, A, B, C, D, E, F, R(50), 0x2748774C);P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE);P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F);P(G, H, A, B, C, D, E, F, R(58), 0x84C87814);P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208);P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2);ctx->state[0] += A;ctx->state[1] += B;ctx->state[2] += C;ctx->state[3] += D;ctx->state[4] += E;ctx->state[5] += F;ctx->state[6] += G;ctx->state[7] += H;
}#undef P
#undef R
#undef F1
#undef F0
#undef S3
#undef S2
#undef S1
#undef S0
#undef ROTR
#undef SHRstatic
void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length)
{uint32_t left, fill;if (!length)return;left = ctx->total[0] & 0x3F;fill = 64 - left;ctx->total[0] += length;ctx->total[0] &= 0xFFFFFFFF;if (ctx->total[0] < length)ctx->total[1]++;if (left && length >= fill) {memcpy((void *) (ctx->buffer + left), (void *) input, fill);sha256_process(ctx, ctx->buffer);length -= fill;input += fill;left = 0;}while (length >= 64) {sha256_process(ctx, input);length -= 64;input += 64;}if (length)memcpy((void *) (ctx->buffer + left), (void *) input, length);
}static uint8_t sha256_padding[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};static
void sha256_finish(sha256_context * ctx, uint8_t digest[32])
{uint32_t last, padn;uint32_t high, low;uint8_t msglen[8];high = ((ctx->total[0] >> 29)| (ctx->total[1] << 3));low = (ctx->total[0] << 3);PUT_UINT32_BE(high, msglen, 0);PUT_UINT32_BE(low, msglen, 4);last = ctx->total[0] & 0x3F;padn = (last < 56) ? (56 - last) : (120 - last);sha256_update(ctx, sha256_padding, padn);sha256_update(ctx, msglen, 8);PUT_UINT32_BE(ctx->state[0], digest, 0);PUT_UINT32_BE(ctx->state[1], digest, 4);PUT_UINT32_BE(ctx->state[2], digest, 8);PUT_UINT32_BE(ctx->state[3], digest, 12);PUT_UINT32_BE(ctx->state[4], digest, 16);PUT_UINT32_BE(ctx->state[5], digest, 20);PUT_UINT32_BE(ctx->state[6], digest, 24);PUT_UINT32_BE(ctx->state[7], digest, 28);
}/** Output = SHA-256( input buffer ).*/
static
void sha256_csum(const unsigned char *input, unsigned int ilen,unsigned char *output)
{sha256_context ctx;sha256_starts(&ctx);sha256_update(&ctx, input, ilen);sha256_finish(&ctx, output);
}/* #define DEBUG */static bool g_debug =
#ifdef DEBUGtrue;
#elsefalse;
#endif /* DEBUG */#define LOGE(fmt, args...)                                                     \fprintf(stderr, "E/%s(%d): " fmt "\n", __func__, __LINE__, ##args)
#define LOGD(fmt, args...)                                                     \do {                                                                         \if (g_debug)                                                               \fprintf(stderr, "D/%s(%d): " fmt "\n", __func__, __LINE__, ##args);      \} while (0)/* sync with ./board/rockchip/rk30xx/rkloader.c #define FDT_PATH */
#define FDT_PATH "rk-kernel.dtb"
#define DTD_SUBFIX ".dtb"#define DEFAULT_IMAGE_PATH "resource.img"
#define DEFAULT_UNPACK_DIR "out"
#define BLOCK_SIZE 512#define RESOURCE_PTN_HDR_SIZE 1
#define INDEX_TBL_ENTR_SIZE 1#define RESOURCE_PTN_VERSION 0
#define INDEX_TBL_VERSION 0#define RESOURCE_PTN_HDR_MAGIC "RSCE"
typedef struct {char magic[4]; /* tag, "RSCE" */uint16_t resource_ptn_version;uint16_t index_tbl_version;uint8_t header_size;    /* blocks, size of ptn header. */uint8_t tbl_offset;     /* blocks, offset of index table. */uint8_t tbl_entry_size; /* blocks, size of index table's entry. */uint32_t tbl_entry_num; /* numbers of index table's entry. */
} resource_ptn_header;#define INDEX_TBL_ENTR_TAG "ENTR"
#define MAX_INDEX_ENTRY_PATH_LEN	220
#define MAX_HASH_LEN			32typedef struct {char tag[4]; /* tag, "ENTR" */char path[MAX_INDEX_ENTRY_PATH_LEN];char hash[MAX_HASH_LEN]; /* hash data */uint32_t hash_size;	 /* 20 or 32 */uint32_t content_offset; /* blocks, offset of resource content. */uint32_t content_size;   /* bytes, size of resource content. */
} index_tbl_entry;#define OPT_VERBOSE "--verbose"
#define OPT_HELP "--help"
#define OPT_VERSION "--version"
#define OPT_PRINT "--print"
#define OPT_PACK "--pack"
#define OPT_UNPACK "--unpack"
#define OPT_TEST_LOAD "--test_load"
#define OPT_TEST_CHARGE "--test_charge"
#define OPT_IMAGE "--image="
#define OPT_ROOT "--root="#define VERSION "2014-5-31 14:43:42"typedef struct {char path[MAX_INDEX_ENTRY_PATH_LEN];uint32_t content_offset; /* blocks, offset of resource content. */uint32_t content_size;   /* bytes, size of resource content. */void *load_addr;
} resource_content;typedef struct {int max_level;int num;int delay;char prefix[MAX_INDEX_ENTRY_PATH_LEN];
} anim_level_conf;#define DEF_CHARGE_DESC_PATH "charge_anim_desc.txt"#define OPT_CHARGE_ANIM_DELAY "delay="
#define OPT_CHARGE_ANIM_LOOP_CUR "only_current_level="
#define OPT_CHARGE_ANIM_LEVELS "levels="
#define OPT_CHARGE_ANIM_LEVEL_CONF "max_level="
#define OPT_CHARGE_ANIM_LEVEL_NUM "num="
#define OPT_CHARGE_ANIM_LEVEL_PFX "prefix="static char image_path[MAX_INDEX_ENTRY_PATH_LEN] = "\0";static int fix_blocks(size_t size)
{return (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
}static const char *fix_path(const char *path)
{if (!memcmp(path, "./", 2)) {return path + 2;}return path;
}static uint16_t switch_short(uint16_t x)
{uint16_t val;uint8_t *p = (uint8_t *)(&x);val = (*p++ & 0xff) << 0;val |= (*p & 0xff) << 8;return val;
}static uint32_t switch_int(uint32_t x)
{uint32_t val;uint8_t *p = (uint8_t *)(&x);val = (*p++ & 0xff) << 0;val |= (*p++ & 0xff) << 8;val |= (*p++ & 0xff) << 16;val |= (*p & 0xff) << 24;return val;
}static void fix_header(resource_ptn_header *header)
{/* switch for be. */header->resource_ptn_version = switch_short(header->resource_ptn_version);header->index_tbl_version = switch_short(header->index_tbl_version);header->tbl_entry_num = switch_int(header->tbl_entry_num);
}static void fix_entry(index_tbl_entry *entry)
{/* switch for be. */entry->content_offset = switch_int(entry->content_offset);entry->content_size = switch_int(entry->content_size);
}static int inline get_ptn_offset(void)
{return 0;
}static bool StorageWriteLba(int offset_block, void *data, int blocks)
{bool ret = false;FILE *file = fopen(image_path, "rb+");if (!file)goto end;int offset = offset_block * BLOCK_SIZE;fseek(file, offset, SEEK_SET);if (offset != ftell(file)) {LOGE("Failed to seek %s to %d!", image_path, offset);goto end;}if (!fwrite(data, blocks * BLOCK_SIZE, 1, file)) {LOGE("Failed to write %s!", image_path);goto end;}ret = true;
end:if (file)fclose(file);return ret;
}static bool StorageReadLba(int offset_block, void *data, int blocks)
{bool ret = false;FILE *file = fopen(image_path, "rb");if (!file)goto end;int offset = offset_block * BLOCK_SIZE;fseek(file, offset, SEEK_SET);if (offset != ftell(file)) {goto end;}if (!fread(data, blocks * BLOCK_SIZE, 1, file)) {goto end;}ret = true;
end:if (file)fclose(file);return ret;
}static bool write_data(int offset_block, void *data, size_t len)
{bool ret = false;if (!data)goto end;int blocks = len / BLOCK_SIZE;if (blocks && !StorageWriteLba(offset_block, data, blocks)) {goto end;}int left = len % BLOCK_SIZE;if (left) {char buf[BLOCK_SIZE] = "\0";memcpy(buf, data + blocks * BLOCK_SIZE, left);if (!StorageWriteLba(offset_block + blocks, buf, 1))goto end;}ret = true;
end:return ret;
}/**********************load test************************/
static int load_file(const char *file_path, int offset_block, int blocks);static int test_load(int argc, char **argv)
{if (argc < 1) {LOGE("Nothing to load!");return -1;}const char *file_path;int offset_block = 0;int blocks = 0;if (argc > 0) {file_path = (const char *)fix_path(argv[0]);argc--, argv++;}if (argc > 0) {offset_block = atoi(argv[0]);argc--, argv++;}if (argc > 0) {blocks = atoi(argv[0]);}return load_file(file_path, offset_block, blocks);
}static void free_content(resource_content *content)
{if (content->load_addr) {free(content->load_addr);content->load_addr = 0;}
}static void tests_dump_file(const char *path, void *data, int len)
{FILE *file = fopen(path, "wb");if (!file)return;fwrite(data, len, 1, file);fclose(file);
}static bool load_content(resource_content *content)
{if (content->load_addr)return true;int blocks = fix_blocks(content->content_size);content->load_addr = malloc(blocks * BLOCK_SIZE);if (!content->load_addr)return false;if (!StorageReadLba(get_ptn_offset() + content->content_offset,content->load_addr, blocks)) {free_content(content);return false;}tests_dump_file(content->path, content->load_addr, content->content_size);return true;
}static bool load_content_data(resource_content *content, int offset_block,void *data, int blocks)
{if (!StorageReadLba(get_ptn_offset() + content->content_offset + offset_block,data, blocks)) {return false;}tests_dump_file(content->path, data, blocks * BLOCK_SIZE);return true;
}static bool get_entry(const char *file_path, index_tbl_entry *entry)
{bool ret = false;char buf[BLOCK_SIZE];resource_ptn_header header;if (!StorageReadLba(get_ptn_offset(), buf, 1)) {LOGE("Failed to read header!");goto end;}memcpy(&header, buf, sizeof(header));if (memcmp(header.magic, RESOURCE_PTN_HDR_MAGIC, sizeof(header.magic))) {LOGE("Not a resource image(%s)!", image_path);goto end;}/* test on pc, switch for be. */fix_header(&header);/* TODO: support header_size & tbl_entry_size */if (header.resource_ptn_version != RESOURCE_PTN_VERSION ||header.header_size != RESOURCE_PTN_HDR_SIZE ||header.index_tbl_version != INDEX_TBL_VERSION ||header.tbl_entry_size != INDEX_TBL_ENTR_SIZE) {LOGE("Not supported in this version!");goto end;}int i;for (i = 0; i < header.tbl_entry_num; i++) {/* TODO: support tbl_entry_size */if (!StorageReadLba(get_ptn_offset() + header.header_size + i * header.tbl_entry_size,buf, 1)) {LOGE("Failed to read index entry:%d!", i);goto end;}memcpy(entry, buf, sizeof(*entry));if (memcmp(entry->tag, INDEX_TBL_ENTR_TAG, sizeof(entry->tag))) {LOGE("Something wrong with index entry:%d!", i);goto end;}if (!strncmp(entry->path, file_path, sizeof(entry->path)))break;}if (i == header.tbl_entry_num) {LOGE("Cannot find %s!", file_path);goto end;}/* test on pc, switch for be. */fix_entry(entry);printf("Found entry:\n\tpath:%s\n\toffset:%d\tsize:%d\n", entry->path,entry->content_offset, entry->content_size);ret = true;
end:return ret;
}static bool get_content(resource_content *content)
{bool ret = false;index_tbl_entry entry;if (!get_entry(content->path, &entry))goto end;content->content_offset = entry.content_offset;content->content_size = entry.content_size;ret = true;
end:return ret;
}static int load_file(const char *file_path, int offset_block, int blocks)
{printf("Try to load:%s", file_path);if (blocks) {printf(", offset block:%d, blocks:%d\n", offset_block, blocks);} else {printf("\n");}bool ret = false;resource_content content;snprintf(content.path, sizeof(content.path), "%s", file_path);content.load_addr = 0;if (!get_content(&content)) {goto end;}if (!blocks) {if (!load_content(&content)) {goto end;}} else {void *data = malloc(blocks * BLOCK_SIZE);if (!data)goto end;if (!load_content_data(&content, offset_block, data, blocks)) {goto end;}}ret = true;
end:free_content(&content);return ret;
}/**********************load test end************************/
/**********************anim test************************/static bool parse_level_conf(const char *arg, anim_level_conf *level_conf)
{memset(level_conf, 0, sizeof(anim_level_conf));char *buf = NULL;buf = strstr(arg, OPT_CHARGE_ANIM_LEVEL_CONF);if (buf) {level_conf->max_level = atoi(buf + strlen(OPT_CHARGE_ANIM_LEVEL_CONF));} else {LOGE("Not found:%s", OPT_CHARGE_ANIM_LEVEL_CONF);return false;}buf = strstr(arg, OPT_CHARGE_ANIM_LEVEL_NUM);if (buf) {level_conf->num = atoi(buf + strlen(OPT_CHARGE_ANIM_LEVEL_NUM));if (level_conf->num <= 0) {return false;}} else {LOGE("Not found:%s", OPT_CHARGE_ANIM_LEVEL_NUM);return false;}buf = strstr(arg, OPT_CHARGE_ANIM_DELAY);if (buf) {level_conf->delay = atoi(buf + strlen(OPT_CHARGE_ANIM_DELAY));}buf = strstr(arg, OPT_CHARGE_ANIM_LEVEL_PFX);if (buf) {snprintf(level_conf->prefix, sizeof(level_conf->prefix), "%s",buf + strlen(OPT_CHARGE_ANIM_LEVEL_PFX));} else {LOGE("Not found:%s", OPT_CHARGE_ANIM_LEVEL_PFX);return false;}LOGD("Found conf:\nmax_level:%d, num:%d, delay:%d, prefix:%s",level_conf->max_level, level_conf->num, level_conf->delay,level_conf->prefix);return true;
}static int test_charge(int argc, char **argv)
{const char *desc;if (argc > 0) {desc = argv[0];} else {desc = DEF_CHARGE_DESC_PATH;}resource_content content;snprintf(content.path, sizeof(content.path), "%s", desc);content.load_addr = 0;if (!get_content(&content)) {goto end;}if (!load_content(&content)) {goto end;}char *buf = (char *)content.load_addr;char *end = buf + content.content_size - 1;*end = '\0';LOGD("desc:\n%s", buf);int pos = 0;while (1) {char *line = (char *)memchr(buf + pos, '\n', strlen(buf + pos));if (!line)break;*line = '\0';LOGD("splite:%s", buf + pos);pos += (strlen(buf + pos) + 1);}int delay = 900;int only_current_level = false;anim_level_conf *level_confs = NULL;int level_conf_pos = 0;int level_conf_num = 0;while (true) {if (buf >= end)break;const char *arg = buf;buf += (strlen(buf) + 1);LOGD("parse arg:%s", arg);if (!memcmp(arg, OPT_CHARGE_ANIM_LEVEL_CONF,strlen(OPT_CHARGE_ANIM_LEVEL_CONF))) {if (!level_confs) {LOGE("Found level conf before levels!");goto end;}if (level_conf_pos >= level_conf_num) {LOGE("Too many level confs!(%d >= %d)", level_conf_pos, level_conf_num);goto end;}if (!parse_level_conf(arg, level_confs + level_conf_pos)) {LOGE("Failed to parse level conf:%s", arg);goto end;}level_conf_pos++;} else if (!memcmp(arg, OPT_CHARGE_ANIM_DELAY,strlen(OPT_CHARGE_ANIM_DELAY))) {delay = atoi(arg + strlen(OPT_CHARGE_ANIM_DELAY));LOGD("Found delay:%d", delay);} else if (!memcmp(arg, OPT_CHARGE_ANIM_LOOP_CUR,strlen(OPT_CHARGE_ANIM_LOOP_CUR))) {only_current_level =!memcmp(arg + strlen(OPT_CHARGE_ANIM_LOOP_CUR), "true", 4);LOGD("Found only_current_level:%d", only_current_level);} else if (!memcmp(arg, OPT_CHARGE_ANIM_LEVELS,strlen(OPT_CHARGE_ANIM_LEVELS))) {if (level_conf_num) {goto end;}level_conf_num = atoi(arg + strlen(OPT_CHARGE_ANIM_LEVELS));if (!level_conf_num) {goto end;}level_confs =(anim_level_conf *)malloc(level_conf_num * sizeof(anim_level_conf));LOGD("Found levels:%d", level_conf_num);} else {LOGE("Unknown arg:%s", arg);goto end;}}if (level_conf_pos != level_conf_num || !level_conf_num) {LOGE("Something wrong with level confs!");goto end;}int i = 0, j = 0;for (i = 0; i < level_conf_num; i++) {if (!level_confs[i].delay) {level_confs[i].delay = delay;}if (!level_confs[i].delay) {LOGE("Missing delay in level conf:%d", i);goto end;}for (j = 0; j < i; j++) {if (level_confs[j].max_level == level_confs[i].max_level) {LOGE("Dup level conf:%d", i);goto end;}if (level_confs[j].max_level > level_confs[i].max_level) {anim_level_conf conf = level_confs[i];memmove(level_confs + j + 1, level_confs + j,(i - j) * sizeof(anim_level_conf));level_confs[j] = conf;}}}printf("Parse anim desc(%s):\n", desc);printf("only_current_level=%d\n", only_current_level);printf("level conf:\n");for (i = 0; i < level_conf_num; i++) {printf("\tmax=%d, delay=%d, num=%d, prefix=%s\n", level_confs[i].max_level,level_confs[i].delay, level_confs[i].num, level_confs[i].prefix);}end:free_content(&content);return 0;
}/**********************anim test end************************/
/**********************append file************************/static const char *PROG = NULL;
static resource_ptn_header header;
static bool just_print = false;
static char root_path[MAX_INDEX_ENTRY_PATH_LEN] = "\0";static void version(void)
{printf("%s (cjf@rock-chips.com)\t" VERSION "\n", PROG);
}static void usage(void)
{printf("Usage: %s [options] [FILES]\n", PROG);printf("Tools for Rockchip's resource image.\n");version();printf("Options:\n");printf("\t" OPT_PACK "\t\t\tPack image from given files.\n");printf("\t" OPT_UNPACK "\t\tUnpack given image to current dir.\n");printf("\t" OPT_IMAGE "path""\t\tSpecify input/output image path.\n");printf("\t" OPT_PRINT "\t\t\tJust print informations.\n");printf("\t" OPT_VERBOSE "\t\tDisplay more runtime informations.\n");printf("\t" OPT_HELP "\t\t\tDisplay this information.\n");printf("\t" OPT_VERSION "\t\tDisplay version information.\n");printf("\t" OPT_ROOT "path""\t\tSpecify resources' root dir.\n");
}static int pack_image(int file_num, const char **files);
static int unpack_image(const char *unpack_dir);enum ACTION {ACTION_PACK,ACTION_UNPACK,ACTION_TEST_LOAD,ACTION_TEST_CHARGE,
};int main(int argc, char **argv)
{PROG = fix_path(argv[0]);enum ACTION action = ACTION_PACK;argc--, argv++;while (argc > 0 && argv[0][0] == '-') {/* it's a opt arg. */const char *arg = argv[0];argc--, argv++;if (!strcmp(OPT_VERBOSE, arg)) {g_debug = true;} else if (!strcmp(OPT_HELP, arg)) {usage();return 0;} else if (!strcmp(OPT_VERSION, arg)) {version();return 0;} else if (!strcmp(OPT_PRINT, arg)) {just_print = true;} else if (!strcmp(OPT_PACK, arg)) {action = ACTION_PACK;} else if (!strcmp(OPT_UNPACK, arg)) {action = ACTION_UNPACK;} else if (!strcmp(OPT_TEST_LOAD, arg)) {action = ACTION_TEST_LOAD;} else if (!strcmp(OPT_TEST_CHARGE, arg)) {action = ACTION_TEST_CHARGE;} else if (!memcmp(OPT_IMAGE, arg, strlen(OPT_IMAGE))) {snprintf(image_path, sizeof(image_path), "%s", arg + strlen(OPT_IMAGE));} else if (!memcmp(OPT_ROOT, arg, strlen(OPT_ROOT))) {snprintf(root_path, sizeof(root_path), "%s", arg + strlen(OPT_ROOT));} else {LOGE("Unknown opt:%s", arg);usage();return -1;}}if (!image_path[0]) {snprintf(image_path, sizeof(image_path), "%s", DEFAULT_IMAGE_PATH);}switch (action) {case ACTION_PACK: {int file_num = argc;const char **files = (const char **)argv;if (!file_num) {LOGE("No file to pack!");return 0;}LOGD("try to pack %d files.", file_num);return pack_image(file_num, files);}case ACTION_UNPACK: {return unpack_image(argc > 0 ? argv[0] : DEFAULT_UNPACK_DIR);}case ACTION_TEST_LOAD: {return test_load(argc, argv);}case ACTION_TEST_CHARGE: {return test_charge(argc, argv);}}/* not reach here. */return -1;
}/************unpack code****************/
static bool mkdirs(char *path)
{char *tmp = path;char *pos = NULL;char buf[MAX_INDEX_ENTRY_PATH_LEN];bool ret = true;while ((pos = memchr(tmp, '/', strlen(tmp)))) {strcpy(buf, path);buf[pos - path] = '\0';tmp = pos + 1;LOGD("mkdir:%s", buf);if (!mkdir(buf, 0755)) {ret = false;}}if (!ret)LOGD("Failed to mkdir(%s)!", path);return ret;
}static bool dump_file(FILE *file, const char *unpack_dir,index_tbl_entry entry)
{LOGD("try to dump entry:%s", entry.path);bool ret = false;FILE *out_file = NULL;long int pos = 0;char path[MAX_INDEX_ENTRY_PATH_LEN * 2 + 1];if (just_print) {ret = true;goto done;}pos = ftell(file);snprintf(path, sizeof(path), "%s/%s", unpack_dir, entry.path);mkdirs(path);out_file = fopen(path, "wb");if (!out_file) {LOGE("Failed to create:%s", path);goto end;}long int offset = entry.content_offset * BLOCK_SIZE;fseek(file, offset, SEEK_SET);if (offset != ftell(file)) {LOGE("Failed to read content:%s", entry.path);goto end;}char buf[BLOCK_SIZE];int n;int len = entry.content_size;while (len > 0) {n = len > BLOCK_SIZE ? BLOCK_SIZE : len;if (!fread(buf, n, 1, file)) {LOGE("Failed to read content:%s", entry.path);goto end;}if (!fwrite(buf, n, 1, out_file)) {LOGE("Failed to write:%s", entry.path);goto end;}len -= n;}
done:ret = true;
end:if (out_file)fclose(out_file);if (pos)fseek(file, pos, SEEK_SET);return ret;
}static int unpack_image(const char *dir)
{FILE *image_file = NULL;bool ret = false;char unpack_dir[MAX_INDEX_ENTRY_PATH_LEN];if (just_print)dir = ".";snprintf(unpack_dir, sizeof(unpack_dir), "%s", dir);if (!strlen(unpack_dir)) {goto end;} else if (unpack_dir[strlen(unpack_dir) - 1] == '/') {unpack_dir[strlen(unpack_dir) - 1] = '\0';}mkdir(unpack_dir, 0755);image_file = fopen(image_path, "rb");char buf[BLOCK_SIZE];if (!image_file) {LOGE("Failed to open:%s", image_path);goto end;}if (!fread(buf, BLOCK_SIZE, 1, image_file)) {LOGE("Failed to read header!");goto end;}memcpy(&header, buf, sizeof(header));if (memcmp(header.magic, RESOURCE_PTN_HDR_MAGIC, sizeof(header.magic))) {LOGE("Not a resource image(%s)!", image_path);goto end;}/* switch for be. */fix_header(&header);printf("Dump header:\n");printf("partition version:%d.%d\n", header.resource_ptn_version,header.index_tbl_version);printf("header size:%d\n", header.header_size);printf("index tbl:\n\toffset:%d\tentry size:%d\tentry num:%d\n",header.tbl_offset, header.tbl_entry_size, header.tbl_entry_num);/* TODO: support header_size & tbl_entry_size */if (header.resource_ptn_version != RESOURCE_PTN_VERSION ||header.header_size != RESOURCE_PTN_HDR_SIZE ||header.index_tbl_version != INDEX_TBL_VERSION ||header.tbl_entry_size != INDEX_TBL_ENTR_SIZE) {LOGE("Not supported in this version!");goto end;}printf("Dump Index table:\n");index_tbl_entry entry;int i;for (i = 0; i < header.tbl_entry_num; i++) {/* TODO: support tbl_entry_size */if (!fread(buf, BLOCK_SIZE, 1, image_file)) {LOGE("Failed to read index entry:%d!", i);goto end;}memcpy(&entry, buf, sizeof(entry));if (memcmp(entry.tag, INDEX_TBL_ENTR_TAG, sizeof(entry.tag))) {LOGE("Something wrong with index entry:%d!", i);goto end;}/* switch for be. */fix_entry(&entry);printf("entry(%d):\n\tpath:%s\n\toffset:%d\tsize:%d\n", i, entry.path,entry.content_offset, entry.content_size);if (!dump_file(image_file, unpack_dir, entry)) {goto end;}}printf("Unack %s to %s successed!\n", image_path, unpack_dir);ret = true;
end:if (image_file)fclose(image_file);return ret ? 0 : -1;
}/************unpack code end****************/
/************pack code****************/static inline size_t get_file_size(const char *path)
{LOGD("try to get size(%s)...", path);struct stat st;if (stat(path, &st) < 0) {LOGE("Failed to get size:%s", path);return -1;}LOGD("path:%s, size:%ld", path, st.st_size);return st.st_size;
}static int write_file(int offset_block, const char *src_path,char hash[], int hash_size)
{LOGD("try to write file(%s) to offset:%d...", src_path, offset_block);char *buf = NULL;int ret = -1;size_t file_size;FILE *src_file = fopen(src_path, "rb");if (!src_file) {LOGE("Failed to open:%s", src_path);goto end;}file_size = get_file_size(src_path);if (file_size < 0) {goto end;}buf = calloc(file_size, 1);if (!buf)goto end;if (!fread(buf, file_size, 1, src_file))goto end;if (!write_data(offset_block, buf, file_size))goto end;if (hash_size == 20)sha1_csum((const unsigned char *)buf, file_size,(unsigned char *)hash);else if (hash_size == 32)sha256_csum((const unsigned char *)buf, file_size,(unsigned char *)hash);elsegoto end;ret = file_size;
end:if (src_file)fclose(src_file);if (buf)free(buf);return ret;
}static bool write_header(const int file_num)
{LOGD("try to write header...");memcpy(header.magic, RESOURCE_PTN_HDR_MAGIC, sizeof(header.magic));header.resource_ptn_version = RESOURCE_PTN_VERSION;header.index_tbl_version = INDEX_TBL_VERSION;header.header_size = RESOURCE_PTN_HDR_SIZE;header.tbl_offset = header.header_size;header.tbl_entry_size = INDEX_TBL_ENTR_SIZE;header.tbl_entry_num = file_num;/* switch for le. */resource_ptn_header hdr = header;fix_header(&hdr);return write_data(0, &hdr, sizeof(hdr));
}static bool write_index_tbl(const int file_num, const char **files)
{LOGD("try to write index table...");bool ret = false;bool foundFdt = false;int offset =header.header_size + header.tbl_entry_size * header.tbl_entry_num;index_tbl_entry entry;char hash[20];	/* sha1 */int i;memcpy(entry.tag, INDEX_TBL_ENTR_TAG, sizeof(entry.tag));for (i = 0; i < file_num; i++) {size_t file_size = get_file_size(files[i]);if (file_size < 0)goto end;entry.content_size = file_size;entry.content_offset = offset;if (write_file(offset, files[i], hash, sizeof(hash)) < 0)goto end;memcpy(entry.hash, hash, sizeof(hash));entry.hash_size = sizeof(hash);LOGD("try to write index entry(%s)...", files[i]);/* switch for le. */fix_entry(&entry);memset(entry.path, 0, sizeof(entry.path));const char *path = files[i];if (root_path[0]) {if (!strncmp(path, root_path, strlen(root_path))) {path += strlen(root_path);if (path[0] == '/')path++;}}path = fix_path(path);if (!strcmp(files[i] + strlen(files[i]) - strlen(DTD_SUBFIX), DTD_SUBFIX)) {if (!foundFdt) {/* use default path. */LOGD("mod fdt path:%s -> %s...", files[i], FDT_PATH);path = FDT_PATH;foundFdt = true;}}snprintf(entry.path, sizeof(entry.path), "%s", path);offset += fix_blocks(file_size);if (!write_data(header.header_size + i * header.tbl_entry_size, &entry,sizeof(entry)))goto end;}ret = true;
end:return ret;
}static int pack_image(int file_num, const char **files)
{bool ret = false;FILE *image_file = fopen(image_path, "wb");if (!image_file) {LOGE("Failed to create:%s", image_path);goto end;}fclose(image_file);/* prepare files */int i = 0;int pos = 0;const char *tmp;for (i = 0; i < file_num; i++) {if (!strcmp(files[i] + strlen(files[i]) - strlen(DTD_SUBFIX), DTD_SUBFIX)) {/* dtb files for kernel. */tmp = files[pos];files[pos] = files[i];files[i] = tmp;pos++;} else if (!strcmp(fix_path(image_path), fix_path(files[i]))) {/* not to pack image itself! */tmp = files[file_num - 1];files[file_num - 1] = files[i];files[i] = tmp;file_num--;}}if (!write_header(file_num)) {LOGE("Failed to write header!");goto end;}if (!write_index_tbl(file_num, files)) {LOGE("Failed to write index table!");goto end;}printf("Pack to %s successed!\n", image_path);ret = true;
end:return ret ? 0 : -1;
}/************pack code end****************/

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

hostprogs-always-$(CONFIG_ARCH_ROCKCHIP)        += resource_tool

再次make,就没有错误了。

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

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

解决: 

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

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

#!/usr/bin/env python
# Copyright 2015, The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.from __future__ import print_functionfrom argparse import ArgumentParser, FileType, Action
from hashlib import sha1
from os import fstat
import re
from struct import packBOOT_IMAGE_HEADER_V3_PAGESIZE = 4096def filesize(f):if f is None:return 0try:return fstat(f.fileno()).st_sizeexcept OSError:return 0def update_sha(sha, f):if f:sha.update(f.read())f.seek(0)sha.update(pack('I', filesize(f)))else:sha.update(pack('I', 0))def pad_file(f, padding):pad = (padding - (f.tell() & (padding - 1))) & (padding - 1)f.write(pack(str(pad) + 'x'))def get_number_of_pages(image_size, page_size):"""calculates the number of pages required for the image"""return (image_size + page_size - 1) / page_sizedef get_recovery_dtbo_offset(args):"""calculates the offset of recovery_dtbo image in the boot image"""num_header_pages = 1 # header occupies a pagenum_kernel_pages = get_number_of_pages(filesize(args.kernel), args.pagesize)num_ramdisk_pages = get_number_of_pages(filesize(args.ramdisk), args.pagesize)num_second_pages = get_number_of_pages(filesize(args.second), args.pagesize)dtbo_offset = args.pagesize * (num_header_pages + num_kernel_pages +num_ramdisk_pages + num_second_pages)return dtbo_offsetdef write_header_v3(args):BOOT_IMAGE_HEADER_V3_SIZE = 1580BOOT_MAGIC = 'ANDROID!'.encode()args.output.write(pack('8s', BOOT_MAGIC))args.output.write(pack('4I',filesize(args.kernel),                          # kernel size in bytesfilesize(args.ramdisk),                         # ramdisk size in bytes(args.os_version << 11) | args.os_patch_level,  # os version and patch levelBOOT_IMAGE_HEADER_V3_SIZE))args.output.write(pack('4I', 0, 0, 0, 0))           # reservedargs.output.write(pack('I', args.header_version))   # version of bootimage headerargs.output.write(pack('1536s', args.cmdline.encode()))pad_file(args.output, BOOT_IMAGE_HEADER_V3_PAGESIZE)def write_vendor_boot_header(args):VENDOR_BOOT_IMAGE_HEADER_V3_SIZE = 2112BOOT_MAGIC = 'VNDRBOOT'.encode()args.vendor_boot.write(pack('8s', BOOT_MAGIC))args.vendor_boot.write(pack('5I',args.header_version,                            # version of headerargs.pagesize,                                  # flash page size we assumeargs.base + args.kernel_offset,                 # kernel physical load addrargs.base + args.ramdisk_offset,                # ramdisk physical load addrfilesize(args.vendor_ramdisk)))                 # vendor ramdisk size in bytesargs.vendor_boot.write(pack('2048s', args.vendor_cmdline.encode()))args.vendor_boot.write(pack('I', args.base + args.tags_offset)) # physical addr for kernel tagsargs.vendor_boot.write(pack('16s', args.board.encode())) # asciiz product nameargs.vendor_boot.write(pack('I', VENDOR_BOOT_IMAGE_HEADER_V3_SIZE)) # header size in bytesif filesize(args.dtb) == 0:raise ValueError("DTB image must not be empty.")args.vendor_boot.write(pack('I', filesize(args.dtb)))   # size in bytesargs.vendor_boot.write(pack('Q', args.base + args.dtb_offset)) # dtb physical load addresspad_file(args.vendor_boot, args.pagesize)def write_header(args):BOOT_IMAGE_HEADER_V1_SIZE = 1648BOOT_IMAGE_HEADER_V2_SIZE = 1660BOOT_MAGIC = 'ANDROID!'.encode()if args.header_version > 3:raise ValueError('Boot header version %d not supported' % args.header_version)elif args.header_version == 3:return write_header_v3(args)args.output.write(pack('8s', BOOT_MAGIC))final_ramdisk_offset = (args.base + args.ramdisk_offset) if filesize(args.ramdisk) > 0 else 0final_second_offset = (args.base + args.second_offset) if filesize(args.second) > 0 else 0args.output.write(pack('10I',filesize(args.kernel),                          # size in bytesargs.base + args.kernel_offset,                 # physical load addrfilesize(args.ramdisk),                         # size in bytesfinal_ramdisk_offset,                           # physical load addrfilesize(args.second),                          # size in bytesfinal_second_offset,                            # physical load addrargs.base + args.tags_offset,                   # physical addr for kernel tagsargs.pagesize,                                  # flash page size we assumeargs.header_version,                            # version of bootimage header(args.os_version << 11) | args.os_patch_level)) # os version and patch levelargs.output.write(pack('16s', args.board.encode())) # asciiz product nameargs.output.write(pack('512s', args.cmdline[:512].encode()))sha = sha1()update_sha(sha, args.kernel)update_sha(sha, args.ramdisk)update_sha(sha, args.second)if args.header_version > 0:update_sha(sha, args.recovery_dtbo)if args.header_version > 1:update_sha(sha, args.dtb)img_id = pack('32s', sha.digest())args.output.write(img_id)args.output.write(pack('1024s', args.cmdline[512:].encode()))if args.header_version > 0:args.output.write(pack('I', filesize(args.recovery_dtbo)))   # size in bytesif args.recovery_dtbo:args.output.write(pack('Q', get_recovery_dtbo_offset(args))) # recovery dtbo offsetelse:args.output.write(pack('Q', 0)) # Will be set to 0 for devices without a recovery dtbo# Populate boot image header size for header versions 1 and 2.if args.header_version == 1:args.output.write(pack('I', BOOT_IMAGE_HEADER_V1_SIZE))elif args.header_version == 2:args.output.write(pack('I', BOOT_IMAGE_HEADER_V2_SIZE))if args.header_version > 1:# if filesize(args.dtb) == 0:#     raise ValueError("DTB image must not be empty.")args.output.write(pack('I', filesize(args.dtb)))   # size in bytesargs.output.write(pack('Q', args.base + args.dtb_offset)) # dtb physical load addresspad_file(args.output, args.pagesize)return img_idclass ValidateStrLenAction(Action):def __init__(self, option_strings, dest, nargs=None, **kwargs):if 'maxlen' not in kwargs:raise ValueError('maxlen must be set')self.maxlen = int(kwargs['maxlen'])del kwargs['maxlen']super(ValidateStrLenAction, self).__init__(option_strings, dest, **kwargs)def __call__(self, parser, namespace, values, option_string=None):if len(values) > self.maxlen:raise ValueError('String argument too long: max {0:d}, got {1:d}'.format(self.maxlen, len(values)))setattr(namespace, self.dest, values)def write_padded_file(f_out, f_in, padding):if f_in is None:returnf_out.write(f_in.read())pad_file(f_out, padding)def parse_int(x):return int(x, 0)def parse_os_version(x):match = re.search(r'^(\d{1,3})(?:\.(\d{1,3})(?:\.(\d{1,3}))?)?', x)if match:a = int(match.group(1))b = c = 0if match.lastindex >= 2:b = int(match.group(2))if match.lastindex == 3:c = int(match.group(3))# 7 bits allocated for each fieldassert a < 128assert b < 128assert c < 128return (a << 14) | (b << 7) | creturn 0def parse_os_patch_level(x):match = re.search(r'^(\d{4})-(\d{2})(?:-(\d{2}))?', x)if match:y = int(match.group(1)) - 2000m = int(match.group(2))# 7 bits allocated for the year, 4 bits for the monthassert 0 <= y < 128assert 0 < m <= 12return (y << 4) | mreturn 0def parse_cmdline():parser = ArgumentParser()parser.add_argument('--kernel', help='path to the kernel', type=FileType('rb'))parser.add_argument('--ramdisk', help='path to the ramdisk', type=FileType('rb'))parser.add_argument('--second', help='path to the 2nd bootloader', type=FileType('rb'))parser.add_argument('--dtb', help='path to dtb', type=FileType('rb'))recovery_dtbo_group = parser.add_mutually_exclusive_group()recovery_dtbo_group.add_argument('--recovery_dtbo', help='path to the recovery DTBO',type=FileType('rb'))recovery_dtbo_group.add_argument('--recovery_acpio', help='path to the recovery ACPIO',type=FileType('rb'), metavar='RECOVERY_ACPIO',dest='recovery_dtbo')parser.add_argument('--cmdline', help='extra arguments to be passed on the ''kernel command line', default='', action=ValidateStrLenAction, maxlen=1536)parser.add_argument('--vendor_cmdline',help='kernel command line arguments contained in vendor boot',default='', action=ValidateStrLenAction, maxlen=2048)parser.add_argument('--base', help='base address', type=parse_int, default=0x10000000)parser.add_argument('--kernel_offset', help='kernel offset', type=parse_int, default=0x00008000)parser.add_argument('--ramdisk_offset', help='ramdisk offset', type=parse_int,default=0x01000000)parser.add_argument('--second_offset', help='2nd bootloader offset', type=parse_int,default=0x00f00000)parser.add_argument('--dtb_offset', help='dtb offset', type=parse_int, default=0x01f00000)parser.add_argument('--os_version', help='operating system version', type=parse_os_version,default=0)parser.add_argument('--os_patch_level', help='operating system patch level',type=parse_os_patch_level, default=0)parser.add_argument('--tags_offset', help='tags offset', type=parse_int, default=0x00000100)parser.add_argument('--board', help='board name', default='', action=ValidateStrLenAction,maxlen=16)parser.add_argument('--pagesize', help='page size', type=parse_int,choices=[2**i for i in range(11, 15)], default=2048)parser.add_argument('--id', help='print the image ID on standard output',action='store_true')parser.add_argument('--header_version', help='boot image header version', type=parse_int,default=0)parser.add_argument('-o', '--output', help='output file name', type=FileType('wb'))parser.add_argument('--vendor_boot', help='vendor boot output file name', type=FileType('wb'))parser.add_argument('--vendor_ramdisk', help='path to the vendor ramdisk', type=FileType('rb'))return parser.parse_args()def write_data(args, pagesize):write_padded_file(args.output, args.kernel, pagesize)write_padded_file(args.output, args.ramdisk, pagesize)write_padded_file(args.output, args.second, pagesize)if args.header_version > 0 and args.header_version < 3:write_padded_file(args.output, args.recovery_dtbo, pagesize)if args.header_version == 2:write_padded_file(args.output, args.dtb, pagesize)def write_vendor_boot_data(args):write_padded_file(args.vendor_boot, args.vendor_ramdisk, args.pagesize)write_padded_file(args.vendor_boot, args.dtb, args.pagesize)def main():args = parse_cmdline()if args.vendor_boot is not None:if args.header_version < 3:raise ValueError('--vendor_boot not compatible with given header version')if args.vendor_ramdisk is None:raise ValueError('--vendor_ramdisk missing or invalid')write_vendor_boot_header(args)write_vendor_boot_data(args)if args.output is not None:if args.kernel is None:raise ValueError('kernel must be supplied when creating a boot image')if args.second is not None and args.header_version > 2:raise ValueError('--second not compatible with given header version')img_id = write_header(args)if args.header_version > 2:write_data(args, BOOT_IMAGE_HEADER_V3_PAGESIZE)else:write_data(args, args.pagesize)if args.id and img_id is not None:# Python 2's struct.pack returns a string, but py3 returns bytes.if isinstance(img_id, str):img_id = [ord(x) for x in img_id]print('0x' + ''.join('{:02x}'.format(c) for c in img_id))if __name__ == '__main__':main()

最后还有一个说明一下:

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

这篇关于解决linux5.15编译时不生成boot.img 的问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/339409

相关文章

IDEA自动生成注释模板的配置教程

《IDEA自动生成注释模板的配置教程》本文介绍了如何在IntelliJIDEA中配置类和方法的注释模板,包括自动生成项目名称、包名、日期和时间等内容,以及如何定制参数和返回值的注释格式,需要的朋友可以... 目录项目场景配置方法类注释模板定义类开头的注释步骤类注释效果方法注释模板定义方法开头的注释步骤方法注

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

如何解决idea的Module:‘:app‘platform‘android-32‘not found.问题

《如何解决idea的Module:‘:app‘platform‘android-32‘notfound.问题》:本文主要介绍如何解决idea的Module:‘:app‘platform‘andr... 目录idea的Module:‘:app‘pwww.chinasem.cnlatform‘android-32

在Spring Boot中浅尝内存泄漏的实战记录

《在SpringBoot中浅尝内存泄漏的实战记录》本文给大家分享在SpringBoot中浅尝内存泄漏的实战记录,结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录使用静态集合持有对象引用,阻止GC回收关键点:可执行代码:验证:1,运行程序(启动时添加JVM参数限制堆大小):2,访问 htt

Python如何自动生成环境依赖包requirements

《Python如何自动生成环境依赖包requirements》:本文主要介绍Python如何自动生成环境依赖包requirements问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录生成当前 python 环境 安装的所有依赖包1、命令2、常见问题只生成当前 项目 的所有依赖包1、

kali linux 无法登录root的问题及解决方法

《kalilinux无法登录root的问题及解决方法》:本文主要介绍kalilinux无法登录root的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,... 目录kali linux 无法登录root1、问题描述1.1、本地登录root1.2、ssh远程登录root2、

SpringBoot应用中出现的Full GC问题的场景与解决

《SpringBoot应用中出现的FullGC问题的场景与解决》这篇文章主要为大家详细介绍了SpringBoot应用中出现的FullGC问题的场景与解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录Full GC的原理与触发条件原理触发条件对Spring Boot应用的影响示例代码优化建议结论F

MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录

《MySQL中查询VARCHAR类型JSON数据的问题记录》在数据库设计中,有时我们会将JSON数据存储在VARCHAR或TEXT类型字段中,本文将详细介绍如何在MySQL中有效查询存储为V... 目录一、问题背景二、mysql jsON 函数2.1 常用 JSON 函数三、查询示例3.1 基本查询3.2

MySQL中动态生成SQL语句去掉所有字段的空格的操作方法

《MySQL中动态生成SQL语句去掉所有字段的空格的操作方法》在数据库管理过程中,我们常常会遇到需要对表中字段进行清洗和整理的情况,本文将详细介绍如何在MySQL中动态生成SQL语句来去掉所有字段的空... 目录在mysql中动态生成SQL语句去掉所有字段的空格准备工作原理分析动态生成SQL语句在MySQL

如何配置Spring Boot中的Jackson序列化

《如何配置SpringBoot中的Jackson序列化》在开发基于SpringBoot的应用程序时,Jackson是默认的JSON序列化和反序列化工具,本文将详细介绍如何在SpringBoot中配置... 目录配置Spring Boot中的Jackson序列化1. 为什么需要自定义Jackson配置?2.