Commit 315674c6 authored by Luo Ji's avatar Luo Ji

[iot] Support dual bootloader in SPL

Move the A/B slot check to SPL, the A/B slot switch
workflow is just like what we have in libavb_ab.

Test: A/B select works fine on imx8m.

Change-Id: Ie3d827a9be0298b491bf2bc8d48833597fd70e90
Signed-off-by: default avatarLuo Ji <ji.luo@nxp.com>
parent a789184b
......@@ -4,6 +4,8 @@
*
* Aneesh V <aneesh@ti.com>
*
* Copyright 2018 NXP
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
......@@ -18,7 +20,7 @@
DECLARE_GLOBAL_DATA_PTR;
static int mmc_load_legacy(struct spl_image_info *spl_image, struct mmc *mmc,
int mmc_load_legacy(struct spl_image_info *spl_image, struct mmc *mmc,
ulong sector, struct image_header *header)
{
u32 image_size_sectors;
......@@ -44,7 +46,7 @@ static int mmc_load_legacy(struct spl_image_info *spl_image, struct mmc *mmc,
return 0;
}
static ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
ulong count, void *buf)
{
struct mmc *mmc = load->dev;
......@@ -52,6 +54,13 @@ static ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
return blk_dread(mmc_get_blk_desc(mmc), sector, count, buf);
}
#ifdef CONFIG_DUAL_BOOTLOADER
/* Pre-declaration of mmc_load_image_raw_sector_dual_uboot().
*/
extern int mmc_load_image_raw_sector_dual_uboot(struct spl_image_info *spl_image,
struct mmc *mmc);
#else
static int mmc_load_image_raw_sector(struct spl_image_info *spl_image,
struct mmc *mmc, unsigned long sector)
{
......@@ -96,6 +105,8 @@ end:
return 0;
}
#endif /* CONFIG_DUAL_BOOTLOADER */
int spl_mmc_get_device_index(u32 boot_device)
{
switch (boot_device) {
......@@ -309,10 +320,15 @@ int spl_mmc_load_image(struct spl_image_info *spl_image,
* 1 and 2 match up to boot0 / boot1 and 7 is user data
* which is the first physical partition (0).
*/
#ifdef CONFIG_DUAL_BOOTLOADER
/* Bootloader is stored in eMMC user partition for dual bootloader */
part = 0;
#else
part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
if (part == 7)
part = 0;
#endif
if (CONFIG_IS_ENABLED(MMC_TINY))
err = mmc_switch_part(mmc, part);
......@@ -341,8 +357,13 @@ int spl_mmc_load_image(struct spl_image_info *spl_image,
return err;
#endif
#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
#ifdef CONFIG_DUAL_BOOTLOADER
err = mmc_load_image_raw_sector_dual_uboot(spl_image,
mmc);
#else
err = mmc_load_image_raw_sector(spl_image, mmc,
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
#endif
if (!err)
return err;
#endif
......
......@@ -39,3 +39,4 @@ CONFIG_SPL_FIT=y
CONFIG_SPL_LOAD_FIT=y
CONFIG_CMD_FASTBOOT=y
CONFIG_ANDROID_BOOT_IMAGE=y
CONFIG_SPL_LIBDISK_SUPPORT=y
......@@ -39,3 +39,4 @@ CONFIG_SPL_LOAD_FIT=y
CONFIG_FASTBOOT=y
CONFIG_CMD_FASTBOOT=y
CONFIG_ANDROID_BOOT_IMAGE=y
CONFIG_SPL_LIBDISK_SUPPORT=y
......@@ -246,8 +246,10 @@ void part_print_efi(struct blk_desc *dev_desc)
printf("\tguid:\t%s\n", uuid);
}
#if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD)
/* Remember to free pte */
free(gpt_pte);
#endif
return;
}
......@@ -282,7 +284,9 @@ int part_get_info_efi(struct blk_desc *dev_desc, int part,
!is_pte_valid(&gpt_pte[part - 1])) {
debug("%s: *** ERROR: Invalid partition number %d ***\n",
__func__, part);
#if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD)
free(gpt_pte);
#endif
return -1;
}
......@@ -309,8 +313,14 @@ int part_get_info_efi(struct blk_desc *dev_desc, int part,
debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s\n", __func__,
info->start, info->size, info->name);
/* Remember to free pte */
#if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD)
/* Heap memory is very limited in SPL, if the dual bootloader is
* enabled, just load pte to dram instead of oc-ram. In such case,
* this part of memory shouldn't be freed. But in common routine,
* don't forget to free the memory after use.
*/
free(gpt_pte);
#endif
return 0;
}
......@@ -916,10 +926,17 @@ static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba,
}
if (validate_gpt_entries(pgpt_head, *pgpt_pte)) {
#if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD)
/* Heap memory is very limited in SPL, if the dual bootloader is
* enabled, just load pte to dram instead of oc-ram. In such case,
* this part of memory shouldn't be freed. But in common routine,
* don't forget to free the memory after use.
*/
free(*pgpt_pte);
#endif
return 0;
}
/* We're done, all's well */
return 1;
}
......@@ -953,10 +970,19 @@ static gpt_entry *alloc_read_gpt_entries(struct blk_desc *dev_desc,
(u32) le32_to_cpu(pgpt_head->sizeof_partition_entry),
(ulong)count);
/* Allocate memory for PTE, remember to FREE */
/* Allocate memory for PTE.
* Heap memory is very limited in SPL, if the dual bootloader is
* enabled, just load pte to dram instead of oc-ram. In such case,
* this part of memory shouldn't be freed. But in common routine,
* don't forget to free the memory after use.
*/
if (count != 0) {
#if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_SPL_BUILD)
pte = (gpt_entry *)CONFIG_SYS_SPL_PTE_RAM_BASE;
#else
pte = memalign(ARCH_DMA_MINALIGN,
PAD_TO_BLOCKSIZE(count, dev_desc));
#endif
}
if (count == 0 || pte == NULL) {
......@@ -964,13 +990,14 @@ static gpt_entry *alloc_read_gpt_entries(struct blk_desc *dev_desc,
__func__, (ulong)count);
return NULL;
}
/* Read GPT Entries from device */
blk = le64_to_cpu(pgpt_head->partition_entry_lba);
blk_cnt = BLOCK_CNT(count, dev_desc);
if (blk_dread(dev_desc, blk, (lbaint_t)blk_cnt, pte) != blk_cnt) {
printf("*** ERROR: Can't read GPT Entries ***\n");
#if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD)
free(pte);
#endif
return NULL;
}
return pte;
......
......@@ -44,7 +44,11 @@ obj-$(CONFIG_SH_SDHI) += sh_sdhi.o
ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_SPL_MMC_BOOT) += fsl_esdhc_spl.o
ifdef CONFIG_DUAL_BOOTLOADER
obj-y += mmc_write.o
else
obj-$(CONFIG_SPL_SAVEENV) += mmc_write.o
endif
else
obj-$(CONFIG_GENERIC_MMC) += mmc_write.o
endif
......
......@@ -56,7 +56,7 @@ static inline ulong mmc_bwrite(struct udevice *dev, lbaint_t start,
{
return 0;
}
#else
#elif !defined(CONFIG_DUAL_BOOTLOADER)
static inline unsigned long mmc_berase(struct blk_desc *block_dev,
lbaint_t start, lbaint_t blkcnt)
{
......@@ -68,6 +68,10 @@ static inline ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start,
{
return 0;
}
#else /* CONFIG_DUAL_BOOTLOADER && !CONFIG_BLK*/
ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
const void *src);
ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt);
#endif
#endif /* CONFIG_SPL_BUILD */
......
......@@ -40,6 +40,7 @@
#define CONFIG_SPL_BSS_MAX_SIZE 0x2000 /* 8 KB */
#define CONFIG_SYS_SPL_MALLOC_START 0x00182000
#define CONFIG_SYS_SPL_MALLOC_SIZE 0x2000 /* 8 KB */
#define CONFIG_SYS_SPL_PTE_RAM_BASE 0x41580000
#define CONFIG_SYS_ICACHE_OFF
#define CONFIG_SYS_DCACHE_OFF
......
......@@ -41,6 +41,7 @@
#define CONFIG_SPL_BSS_MAX_SIZE 0x2000 /* 8 KB */
#define CONFIG_SYS_SPL_MALLOC_START 0x00182000
#define CONFIG_SYS_SPL_MALLOC_SIZE 0x2000 /* 8 KB */
#define CONFIG_SYS_SPL_PTE_RAM_BASE 0x41580000
#define CONFIG_SYS_ICACHE_OFF
#define CONFIG_SYS_DCACHE_OFF
......
......@@ -33,8 +33,8 @@ AvbIOResult fsl_read_from_partition(AvbOps* ops, const char* partition,
/* multi block read version
* */
AvbIOResult fsl_read_from_partition_multi(AvbOps* ops, const char* partition,
int64_t offset, size_t num_bytes,
void* buffer, size_t* out_num_read);
int64_t offset, size_t num_bytes,
void* buffer, size_t* out_num_read);
/* Writes |num_bytes| from |bffer| at offset |offset| to partition
* with name |partition| (NUL-terminated UTF-8 string). If |offset|
......@@ -87,11 +87,11 @@ AvbIOResult fsl_write_ab_metadata(AvbABOps* ab_ops, const struct AvbABData* data
* true if trusted or false if untrusted.
*/
AvbIOResult fsl_validate_vbmeta_public_key_rpmb(AvbOps* ops,
const uint8_t* public_key_data,
size_t public_key_length,
const uint8_t* public_key_metadata,
size_t public_key_metadata_length,
bool* out_is_trusted);
const uint8_t* public_key_data,
size_t public_key_length,
const uint8_t* public_key_metadata,
size_t public_key_metadata_length,
bool* out_is_trusted);
/* Gets the rollback index corresponding to the slot given by
* |rollback_index_slot|. The value is returned in
......@@ -103,7 +103,7 @@ AvbIOResult fsl_validate_vbmeta_public_key_rpmb(AvbOps* ops,
* this number.
*/
AvbIOResult fsl_read_rollback_index_rpmb(AvbOps* ops, size_t rollback_index_slot,
uint64_t* out_rollback_index);
uint64_t* out_rollback_index);
/* Sets the rollback index corresponding to the slot given by
* |rollback_index_slot| to |rollback_index|. Returns
......@@ -115,7 +115,7 @@ AvbIOResult fsl_read_rollback_index_rpmb(AvbOps* ops, size_t rollback_index_slot
* this number.
*/
AvbIOResult fsl_write_rollback_index_rpmb(AvbOps* ops, size_t rollback_index_slot,
uint64_t rollback_index);
uint64_t rollback_index);
/* Gets whether the device is unlocked. The value is returned in
* |out_is_unlocked| (true if unlocked, false otherwise). Returns
......@@ -135,9 +135,9 @@ AvbIOResult fsl_read_is_device_unlocked(AvbOps* ops, bool* out_is_unlocked);
* Returns AVB_IO_RESULT_OK on success, otherwise an error code.
*/
AvbIOResult fsl_get_unique_guid_for_partition(AvbOps* ops,
const char* partition,
char* guid_buf,
size_t guid_buf_size);
const char* partition,
char* guid_buf,
size_t guid_buf_size);
/* Gets the size of a partition with the name in |partition|
* (NUL-terminated UTF-8 string). Returns the value in
......@@ -145,8 +145,8 @@ AvbIOResult fsl_get_unique_guid_for_partition(AvbOps* ops,
* Returns AVB_IO_RESULT_OK on success, otherwise an error code.
*/
AvbIOResult fsl_get_size_of_partition(AvbOps* ops,
const char* partition,
uint64_t* out_size_num_bytes);
const char* partition,
uint64_t* out_size_num_bytes);
/* check if the fastboot getvar cmd is for query [avb] bootctl's slot var
* cmd is the fastboot getvar's cmd in
* return true if it is a bootctl related cmd, false if it's not.
......@@ -193,32 +193,42 @@ AvbIOResult fsl_read_permanent_attributes(
* permanently read-only location (e.g. fuses) when a device is LOCKED. On
* success, returned AVB_IO_RESULT_OK and populates |hash|.
*/
AvbIOResult fsl_read_permanent_attributes_hash(
AvbAtxOps* atx_ops, uint8_t hash[AVB_SHA256_DIGEST_SIZE]);
AvbIOResult fsl_read_permanent_attributes_hash(AvbAtxOps* atx_ops,
uint8_t hash[AVB_SHA256_DIGEST_SIZE]);
/* Provides the key version of a key used during verification. This may be
* useful for managing the minimum key version.
*/
void fsl_set_key_version(AvbAtxOps* atx_ops,
size_t rollback_index_location,
uint64_t key_version);
size_t rollback_index_location,
uint64_t key_version);
/* This is the fast version of avb_ab_flow(), this function will
* not check another slot if one slot can pass the verify (or verify
* fail is acceptable). */
* fail is acceptable).
*/
AvbABFlowResult avb_ab_flow_fast(AvbABOps* ab_ops,
const char* const* requested_partitions,
AvbSlotVerifyFlags flags,
AvbHashtreeErrorMode hashtree_error_mode,
AvbSlotVerifyData** out_data);
const char* const* requested_partitions,
AvbSlotVerifyFlags flags,
AvbHashtreeErrorMode hashtree_error_mode,
AvbSlotVerifyData** out_data);
/* This is for legacy i.mx6/7 which don't enable A/B but want to
* verify boot/recovery with AVB */
AvbABFlowResult avb_single_flow(AvbABOps* ab_ops,
const char* const* requested_partitions,
AvbSlotVerifyFlags flags,
AvbHashtreeErrorMode hashtree_error_mode,
AvbSlotVerifyData** out_data);
const char* const* requested_partitions,
AvbSlotVerifyFlags flags,
AvbHashtreeErrorMode hashtree_error_mode,
AvbSlotVerifyData** out_data);
/* Avb verify flow for dual bootloader, only the slot chosen by SPL will
* be verified.
*/
AvbABFlowResult avb_flow_dual_uboot(AvbABOps* ab_ops,
const char* const* requested_partitions,
AvbSlotVerifyFlags flags,
AvbHashtreeErrorMode hashtree_error_mode,
AvbSlotVerifyData** out_data);
/* Program ATX perm_attr into RPMB partition */
int avb_atx_fuse_perm_attr(uint8_t *staged_buffer, uint32_t size);
......
......@@ -213,7 +213,8 @@ static inline int blk_get_device_part_str(const char *ifname,
#ifdef CONFIG_SPL_BUILD
# define part_print_ptr(x) NULL
# if defined(CONFIG_SPL_EXT_SUPPORT) || defined(CONFIG_SPL_FAT_SUPPORT) || \
defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION)
defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION) || \
defined(CONFIG_DUAL_BOOTLOADER)
# define part_get_info_ptr(x) x
# else
# define part_get_info_ptr(x) NULL
......
......@@ -55,6 +55,11 @@ config LIB_RAND
config AVB_ATX
bool "Enable AVB_ATX support"
config DUAL_BOOTLOADER
bool "Enable dual bootloader support"
help
Enable A/B bootloader select in SPL.
source lib/dhry/Kconfig
source lib/rsa/Kconfig
......
......@@ -16,7 +16,6 @@ obj-$(CONFIG_BZIP2) += bzip2/
obj-$(CONFIG_TIZEN) += tizen/
obj-$(CONFIG_FIT) += libfdt/
obj-$(CONFIG_CMD_DHRYSTONE) += dhry/
obj-$(CONFIG_AVB_SUPPORT) += avb/
obj-$(CONFIG_IMX_TRUSTY_OS) += trusty/ql-tipc/
obj-$(CONFIG_AES) += aes.o
obj-$(CONFIG_USB_TTY) += circbuf.o
......@@ -48,6 +47,7 @@ endif
obj-$(CONFIG_$(SPL_)RSA) += rsa/
obj-$(CONFIG_$(SPL_)SHA1) += sha1.o
obj-$(CONFIG_$(SPL_)SHA256) += sha256.o
obj-$(CONFIG_AVB_SUPPORT) += avb/
obj-$(CONFIG_SPL_SAVEENV) += qsort.o
obj-$(CONFIG_$(SPL_)OF_LIBFDT) += libfdt/
......
......@@ -10,7 +10,10 @@ subdir-ccflags-y += -I./lib/avb \
-Wno-unused-parameter \
-ffunction-sections \
-std=gnu99
obj-y += libavb/
ifndef CONFIG_SPL_BUILD
obj-y += libavb_ab/
obj-$(CONFIG_AVB_ATX) += libavb_atx/
endif
obj-y += libavb/
obj-y += fsl/
ccflags-y += -Werror
ifndef CONFIG_SPL_BUILD
obj-y += fsl_avb.o
obj-y += fsl_avbkey.o
obj-y += fsl_bootctl.o
obj-y += fsl_avb_ab_flow.o
obj-y += fsl_avb_sysdeps_uboot.o
endif
obj-y += utils.o
obj-y += fsl_avb_ab_flow.o
This diff is collapsed.
/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ * Copyright 2018 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
......@@ -10,9 +10,13 @@
#include "debug.h"
#include "utils.h"
/* get margin_pos struct from offset [to the partition start/end] and num_bytes to read/write */
/*
* get margin_pos struct from offset [to the partition start/end] and
* num_bytes to read/write
*/
int get_margin_pos(uint64_t part_start, uint64_t part_end, unsigned long blksz,
margin_pos_t *margin, int64_t offset, size_t num_bytes, bool allow_partial) {
margin_pos_t *margin, int64_t offset, size_t num_bytes,
bool allow_partial) {
long off;
if (margin == NULL)
return -1;
......@@ -22,21 +26,27 @@ int get_margin_pos(uint64_t part_start, uint64_t part_end, unsigned long blksz,
if (offset < 0) {
margin->blk_start = (offset + 1) / (uint64_t)blksz + part_end;
margin->start = (off = offset % (uint64_t)blksz) == 0 ? 0 : blksz + off; // offset == -1 means the last byte?, or start need -1
// offset == -1 means the last byte?, or start need -1
margin->start = (off = offset % (uint64_t)blksz) == 0 ?
0 : blksz + off;
if (offset + num_bytes - 1 >= 0) {
if (!allow_partial)
return -1;
margin->blk_end = part_end;
margin->end = blksz - 1;
} else {
margin->blk_end = (num_bytes + offset) / (uint64_t)blksz + part_end; // which blk the last byte is in
margin->end = (off = (num_bytes + offset - 1) % (uint64_t)blksz) == 0 ?
0 : blksz + off; // last byte
// which blk the last byte is in
margin->blk_end = (num_bytes + offset) /
(uint64_t)blksz + part_end;
margin->end = (off = (num_bytes + offset - 1) %
(uint64_t)blksz) == 0 ?
0 : blksz + off; // last byte
}
} else {
margin->blk_start = offset / (uint64_t)blksz + part_start;
margin->start = offset % (uint64_t)blksz;
margin->blk_end = (offset + num_bytes - 1) / (uint64_t)blksz + part_start ;
margin->blk_end = ((offset + num_bytes - 1) / (uint64_t)blksz) +
part_start ;
margin->end = (offset + num_bytes - 1) % (uint64_t)blksz;
if (margin->blk_end > part_end) {
if (!allow_partial)
......@@ -46,7 +56,7 @@ int get_margin_pos(uint64_t part_start, uint64_t part_end, unsigned long blksz,
}
}
VDEBUG("bs=%ld, be=%ld, s=%ld, e=%ld\n",
margin->blk_start, margin->blk_end, margin->start, margin->end);
margin->blk_start, margin->blk_end, margin->start, margin->end);
if (margin->blk_start > part_end || margin->blk_start < part_start)
return -1;
......@@ -56,3 +66,151 @@ int get_margin_pos(uint64_t part_start, uint64_t part_end, unsigned long blksz,
VDEBUG("bm=%ld\n", margin->multi);
return 0;
}
int read_from_partition_in_bytes(struct blk_desc *fs_dev_desc,
disk_partition_t *info, int64_t offset,
size_t num_bytes, void* buffer,
size_t* out_num_read)
{
unsigned char *bdata;
unsigned char *out_buf = (unsigned char *)buffer;
unsigned char *dst, *dst64 = NULL;
unsigned long blksz;
unsigned long s, cnt;
size_t num_read = 0;
lbaint_t part_start, part_end, bs, be, bm, blk_num;
margin_pos_t margin;
int ret;
if(buffer == NULL || out_num_read == NULL) {
printf("NULL pointer error!\n");
return -1;
}
blksz = fs_dev_desc->blksz;
part_start = info->start;
part_end = info->start + info->size - 1;
if (get_margin_pos((uint64_t)part_start, (uint64_t)part_end, blksz,
&margin, offset, num_bytes, true))
return -1;
bs = (lbaint_t)margin.blk_start;
be = (lbaint_t)margin.blk_end;
s = margin.start;
bm = margin.multi;
/* alloc a blksz mem */
bdata = (unsigned char *)memalign(ALIGN_BYTES, blksz);
if (bdata == NULL) {
printf("Failed to allocate memory!\n");
return -1;
}
/* support multi blk read */
while (bs <= be) {
if (!s && bm > 1) {
dst = out_buf;
/* for mmc blk read alignment */
dst64 = PTR_ALIGN(out_buf, 64);
if (dst64 != dst) {
dst = dst64;
bm--;
}
blk_num = bm;
cnt = bm * blksz;
bm = 0; /* no more multi blk */
} else {
blk_num = 1;
cnt = blksz - s;
if (num_read + cnt > num_bytes)
cnt = num_bytes - num_read;
dst = bdata;
}
if (!fs_dev_desc->block_read(fs_dev_desc, bs, blk_num, dst)) {
ret = -1;
goto fail;
}
if (dst == bdata)
memcpy(out_buf, bdata + s, cnt);
else if (dst == dst64)
memcpy(out_buf, dst, cnt); /* internal copy */
s = 0;
bs += blk_num;
num_read += cnt;
out_buf += cnt;
}
*out_num_read = num_read;
ret = 0;
fail:
free(bdata);
return ret;
}
int write_to_partition_in_bytes(struct blk_desc *fs_dev_desc,
disk_partition_t *info, int64_t offset,
size_t num_bytes,
void* buffer, size_t *out_num_write)
{
unsigned char *bdata;
unsigned char *in_buf = (unsigned char *)buffer;
unsigned long blksz;
unsigned long s, cnt;
size_t num_write = 0;
lbaint_t part_start, part_end, bs;
margin_pos_t margin;
int ret;
if(buffer == NULL || out_num_write == NULL) {
printf("NULL pointer error!\n");
return -1;
}
blksz = fs_dev_desc->blksz;
part_start = info->start;
part_end = info->start + info->size - 1;
if(get_margin_pos((uint64_t)part_start, (uint64_t)part_end, blksz,
&margin, offset, num_bytes, false))
return -1;
bs = (lbaint_t)margin.blk_start;
s = margin.start;
// alloc a blksz mem
bdata = (unsigned char *)memalign(ALIGN_BYTES, blksz);
if (bdata == NULL)
return -1;
while (num_write < num_bytes) {
memset(bdata, 0, blksz);
cnt = blksz - s;
if (num_write + cnt > num_bytes)
cnt = num_bytes - num_write;
if (!s || cnt != blksz) { //read blk first
if (!fs_dev_desc->block_read(fs_dev_desc, bs, 1,
bdata)) {
ret = -1;
goto fail;
}
}
memcpy(bdata + s, in_buf, cnt); //change data
if (!fs_dev_desc->block_write(fs_dev_desc, bs, 1, bdata)) {
ret = -1;
goto fail;
}
bs++;
num_write += cnt;
in_buf += cnt;
s = 0;
}
*out_num_write = num_write;
ret = 0;
fail:
free(bdata);
return ret;
}
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
* Copyright 2017 NXP
* Copyright 2018 NXP
*
* SPDX-License-Identifier: GPL-2.0+
*/
......@@ -26,6 +26,17 @@ struct margin_pos {
typedef struct margin_pos margin_pos_t;
int get_margin_pos(uint64_t part_start, uint64_t part_end, unsigned long blksz,
margin_pos_t *margin, int64_t offset, size_t num_bytes, bool allow_partial);
margin_pos_t *margin, int64_t offset, size_t num_bytes,
bool allow_partial);
int read_from_partition_in_bytes(struct blk_desc *fs_dev_desc,
disk_partition_t *info,
int64_t offset, size_t num_bytes,
void* buffer, size_t* out_num_read);
int write_to_partition_in_bytes(struct blk_desc *fs_dev_desc,
disk_partition_t *info, int64_t offset,
size_t num_bytes, void* buffer,
size_t *out_num_write);
#endif
ccflags-y += -DAVB_COMPILATION
ifndef CONFIG_SPL_BUILD
obj-y += avb_descriptor.o \
avb_kernel_cmdline_descriptor.o \
avb_sha512.o \
avb_vbmeta_image.o \
avb_chain_partition_descriptor.o \
avb_footer.o \
avb_property_descriptor.o \
avb_slot_verify.o \
avb_crc32.o \
avb_hash_descriptor.o \
avb_rsa.o \
avb_crypto.o \
avb_hashtree_descriptor.o \
avb_sha256.o \
avb_util.o \
avb_cmdline.o
avb_kernel_cmdline_descriptor.o \
avb_sha512.o \
avb_vbmeta_image.o \
avb_chain_partition_descriptor.o \
avb_footer.o \
avb_property_descriptor.o \
avb_slot_verify.o \
avb_hash_descriptor.o \
avb_rsa.o \
avb_crypto.o \
avb_hashtree_descriptor.o \
avb_sha256.o \
avb_util.o \
avb_cmdline.o
endif
obj-y += avb_crc32.o
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment