5959#include <boot_verifier.h>
6060#include <image_verify.h>
6161#include <decompress.h>
62+ #include <lz4.h>
63+ #include <lz4frame.h>
6264#include <platform/timer.h>
6365#include <sys/types.h>
6466#if USE_RPMB_FOR_DEVINFO
@@ -1576,6 +1578,56 @@ void get_recovery_dtbo_info(uint32_t *dtbo_size, void **dtbo_buf)
15761578 return ;
15771579}
15781580
1581+ int decompress_lz4f (const unsigned char * src , unsigned int srcSize , unsigned char * dst , unsigned int dstCapacity )
1582+ {
1583+ if (!src || srcSize <= 0 || !dst || dstCapacity <= 0 ) {
1584+ dprintf (CRITICAL , "Invalid parameters for LZ4F decompression\n" );
1585+ return -1 ;
1586+ }
1587+
1588+ int result = -1 ;
1589+ LZ4F_decompressOptions_t opts ;
1590+ memset (& opts , 0 , sizeof (opts ));
1591+ opts .stableDst = 1 ;
1592+
1593+ LZ4F_dctx * dctx ;
1594+ {
1595+ size_t const dctxStatus = LZ4F_createDecompressionContext (& dctx , LZ4F_VERSION );
1596+ if (LZ4F_isError (dctxStatus )) {
1597+ dprintf (CRITICAL , "LZ4F_dctx creation error: %s\n" , LZ4F_getErrorName (dctxStatus ));
1598+ }
1599+ }
1600+
1601+ if (dctx ) {
1602+ size_t dstSize = dstCapacity ;
1603+ size_t srcConsumed = srcSize ;
1604+ size_t const rc = LZ4F_decompress (dctx ,
1605+ dst ,
1606+ & dstSize ,
1607+ src ,
1608+ & srcConsumed ,
1609+ & opts );
1610+ if (LZ4F_isError (rc )) {
1611+ dprintf (CRITICAL , "LZ4F_decompress error: %s\n" , LZ4F_getErrorName (rc ));
1612+ } else {
1613+ if (rc != 0 || srcConsumed != srcSize ) {
1614+ dprintf (CRITICAL , "LZ4F_decompress did not consume all input data: "
1615+ "consumed %zu, expected %d\n" , srcConsumed , srcSize );
1616+ } else if (dstSize > dstCapacity ) {
1617+ dprintf (CRITICAL , "Decompressed size exceeds destination capacity: "
1618+ "dstSize %zu, dstCapacity %d\n" , dstSize , dstCapacity );
1619+ } else {
1620+ dprintf (INFO , "LZ4F decompression successful: "
1621+ "dstSize %zu, srcSize %d\n" , dstSize , srcSize );
1622+ }
1623+ result = (int )dstSize ;
1624+ }
1625+ }
1626+
1627+ LZ4F_freeDecompressionContext (dctx );
1628+ return result ;
1629+ }
1630+
15791631int boot_linux_from_mmc (void )
15801632{
15811633 boot_img_hdr * hdr = (void * ) buf ;
@@ -2110,6 +2162,25 @@ int boot_linux_from_mmc(void)
21102162 #if DEVICE_TREE
21112163 if (dt_size ) {
21122164 dt_table_offset = ((uint32_t )image_addr + page_size + kernel_actual + ramdisk_actual + second_actual );
2165+
2166+ if (* ((uint32_t * )dt_table_offset ) == LZ4F_MAGICNUMBER ) {
2167+ dprintf (INFO , "found LZ4F compressed dtb\n" );
2168+ out_addr = out_addr ? out_addr + out_len : (unsigned char * )(image_addr + imagesize_actual + page_size );
2169+ out_avai_len = out_avai_len ? out_avai_len - out_len : target_get_max_flash_size () - imagesize_actual - page_size ;
2170+ dprintf (INFO , "decompressing lz4f dtb: start\n" );
2171+ int rc = decompress_lz4f (
2172+ (unsigned char * )dt_table_offset ,
2173+ dt_size ,
2174+ out_addr ,
2175+ out_avai_len );
2176+ if (rc >= 0 ) {
2177+ out_len = rc ;
2178+ dt_table_offset = (uint32_t )out_addr ;
2179+ dt_size = out_len ;
2180+ }
2181+ dprintf (INFO , "decompressing lz4f dtb: done\n" );
2182+ }
2183+
21132184 table = (struct dt_table * ) dt_table_offset ;
21142185
21152186 if (dev_tree_validate (table , hdr -> page_size , & dt_hdr_size ) != 0 ) {
@@ -3065,6 +3136,7 @@ int copy_dtb(uint8_t *boot_image_start, unsigned int scratch_offset)
30653136 unsigned int dtb_size = 0 ;
30663137 unsigned int out_avai_len = 0 ;
30673138 unsigned char * out_addr = NULL ;
3139+ unsigned int out_len = 0 ;
30683140 unsigned char * best_match_dt_addr = NULL ;
30693141 int rc ;
30703142
@@ -3091,7 +3163,27 @@ int copy_dtb(uint8_t *boot_image_start, unsigned int scratch_offset)
30913163 }
30923164
30933165 /* offset now point to start of dt.img */
3094- table = (struct dt_table * )(boot_image_start + dt_image_offset );
3166+ unsigned int dt_table_offset = ((uint32_t )boot_image_start + dt_image_offset );
3167+
3168+ if (* ((uint32_t * )dt_table_offset ) == LZ4F_MAGICNUMBER ) {
3169+ dprintf (INFO , "found LZ4F compressed dtb\n" );
3170+ out_addr = (unsigned char * )target_get_scratch_address () + scratch_offset ;
3171+ out_avai_len = target_get_max_flash_size () - scratch_offset ;
3172+ dprintf (INFO , "decompressing lz4f dtb: start\n" );
3173+ int rc = decompress_lz4f (
3174+ (unsigned char * )dt_table_offset ,
3175+ dt_size ,
3176+ out_addr ,
3177+ out_avai_len );
3178+ if (rc >= 0 ) {
3179+ out_len = rc ;
3180+ dt_table_offset = (uint32_t )out_addr ;
3181+ dt_size = out_len ;
3182+ }
3183+ dprintf (INFO , "decompressing lz4f dtb: done\n" );
3184+ }
3185+
3186+ table = (struct dt_table * )dt_table_offset ;
30953187
30963188 if (dev_tree_validate (table , hdr -> page_size , & dt_hdr_size ) != 0 ) {
30973189 dprintf (CRITICAL , "ERROR: Cannot validate Device Tree Table \n" );
@@ -3114,8 +3206,8 @@ int copy_dtb(uint8_t *boot_image_start, unsigned int scratch_offset)
31143206 best_match_dt_addr = (unsigned char * )boot_image_start + dt_image_offset + dt_entry .offset ;
31153207 if (is_gzip_package (best_match_dt_addr , dt_entry .size ))
31163208 {
3117- out_addr = (unsigned char * )target_get_scratch_address () + scratch_offset ;
3118- out_avai_len = target_get_max_flash_size () - scratch_offset ;
3209+ out_addr = out_addr ? out_addr + out_len : (unsigned char * )target_get_scratch_address () + scratch_offset ;
3210+ out_avai_len = out_avai_len ? out_avai_len - out_len : target_get_max_flash_size () - scratch_offset ;
31193211 dprintf (INFO , "decompressing dtb: start\n" );
31203212 rc = decompress (best_match_dt_addr ,
31213213 dt_entry .size , out_addr , out_avai_len ,
0 commit comments