[PATCH 21/26] test: spl: Add functions to create filesystems

Sean Anderson seanga2 at gmail.com
Thu Oct 12 06:11:30 CEST 2023


On 10/11/23 23:41, Simon Glass wrote:
> Hi Sean,
> 
> On Wed, 11 Oct 2023 at 18:56, Sean Anderson <seanga2 at gmail.com> wrote:
>>
>> Add some functions for creating fat/ext2 filesystems with a single file and
>> a test for them. Filesystems require block devices, and it is easiest to
>> just use MMC for this. To get an MMC, we must also pull in the test device
>> tree.
>>
>> Signed-off-by: Sean Anderson <seanga2 at gmail.com>
>> ---
>>
>>   arch/sandbox/cpu/start.c         |   9 +-
>>   configs/sandbox_noinst_defconfig |   7 +
>>   include/ext4fs.h                 |   1 +
>>   include/ext_common.h             |  14 ++
>>   include/test/spl.h               |   3 +
>>   test/image/Kconfig               |  11 ++
>>   test/image/Makefile              |   1 +
>>   test/image/spl_load.c            |   1 +
>>   test/image/spl_load_fs.c         | 305 +++++++++++++++++++++++++++++++
>>   9 files changed, 350 insertions(+), 2 deletions(-)
>>   create mode 100644 test/image/spl_load_fs.c
> 
> Reviewed-by: Simon Glass <sjg at chromium.org>
> 
> Wow there is a lot going on in this patch. It might be good to split it.

OK.

>>
>> diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
>> index 2c8a72590b5..f5728e6e7ee 100644
>> --- a/arch/sandbox/cpu/start.c
>> +++ b/arch/sandbox/cpu/start.c
>> @@ -13,6 +13,7 @@
>>   #include <log.h>
>>   #include <os.h>
>>   #include <sort.h>
>> +#include <spl.h>
>>   #include <asm/getopt.h>
>>   #include <asm/global_data.h>
>>   #include <asm/io.h>
>> @@ -202,10 +203,14 @@ static int sandbox_cmdline_cb_test_fdt(struct sandbox_state *state,
>>   {
>>          char buf[256];
>>          char *fname;
>> +       char *relname;
>>          int len;
>>
>> -       len = state_get_rel_filename("arch/sandbox/dts/test.dtb", buf,
>> -                                    sizeof(buf));
>> +       if (spl_phase() < PHASE_BOARD_F)
> 
> I think <= PHASE_SPL is better since you care about whether it is in
> SPL or not. I did send a patch to check for SPL, but I don't think it
> is merged yet.

Fine by me.

>> +               relname = "../arch/sandbox/dts/test.dtb";
>> +       else
>> +               relname = "arch/sandbox/dts/test.dtb";
>> +       len = state_get_rel_filename(relname, buf, sizeof(buf));
>>          if (len < 0)
>>                  return len;
>>
>> diff --git a/configs/sandbox_noinst_defconfig b/configs/sandbox_noinst_defconfig
>> index 908155be8a3..0a542cfb6aa 100644
>> --- a/configs/sandbox_noinst_defconfig
>> +++ b/configs/sandbox_noinst_defconfig
>> @@ -6,10 +6,12 @@ CONFIG_NR_DRAM_BANKS=1
>>   CONFIG_ENV_SIZE=0x2000
>>   CONFIG_DEFAULT_DEVICE_TREE="sandbox"
>>   CONFIG_DM_RESET=y
>> +CONFIG_SPL_MMC=y
>>   CONFIG_SPL_SERIAL=y
>>   CONFIG_SPL_DRIVERS_MISC=y
>>   CONFIG_SPL_SYS_MALLOC_F_LEN=0x8000
>>   CONFIG_SPL=y
>> +CONFIG_SPL_FS_FAT=y
>>   CONFIG_SYS_LOAD_ADDR=0x0
>>   CONFIG_PCI=y
>>   CONFIG_SANDBOX_SPL=y
>> @@ -39,7 +41,9 @@ CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y
>>   CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0xa000000
>>   CONFIG_SPL_SYS_MALLOC_SIZE=0x4000000
>>   CONFIG_SPL_ENV_SUPPORT=y
>> +CONFIG_SPL_FS_EXT4=y
>>   CONFIG_SPL_I2C=y
>> +CONFIG_SPL_MMC_WRITE=y
>>   CONFIG_SPL_RTC=y
>>   CONFIG_CMD_CPU=y
>>   CONFIG_CMD_LICENSE=y
>> @@ -97,6 +101,7 @@ CONFIG_AMIGA_PARTITION=y
>>   CONFIG_OF_CONTROL=y
>>   CONFIG_SPL_OF_CONTROL=y
>>   CONFIG_SPL_OF_PLATDATA=y
>> +CONFIG_SPL_OF_REAL=y
>>   CONFIG_ENV_IS_NOWHERE=y
>>   CONFIG_ENV_IS_IN_EXT4=y
>>   CONFIG_ENV_EXT4_INTERFACE="host"
>> @@ -159,6 +164,7 @@ CONFIG_CROS_EC_SPI=y
>>   CONFIG_P2SB=y
>>   CONFIG_PWRSEQ=y
>>   CONFIG_SPL_PWRSEQ=y
>> +CONFIG_FS_LOADER=y
>>   CONFIG_MMC_SANDBOX=y
>>   CONFIG_SPI_FLASH_SANDBOX=y
>>   CONFIG_SPI_FLASH_ATMEL=y
>> @@ -220,6 +226,7 @@ CONFIG_SYSRESET=y
>>   CONFIG_SPL_SYSRESET=y
>>   CONFIG_DM_THERMAL=y
>>   CONFIG_TIMER=y
>> +CONFIG_SPL_TIMER=y
>>   CONFIG_TIMER_EARLY=y
>>   CONFIG_SANDBOX_TIMER=y
>>   CONFIG_USB=y
> 
> I think these would be better in their own patch

Surprisingly, MMC_WRITE actually depends on SPL_TIMER. I didn't check on the exact
dependency, but presumably there is some poll/timeout loop in the MMC write code.

>> diff --git a/include/ext4fs.h b/include/ext4fs.h
>> index cb5d9cc0a5c..dd66d27f776 100644
>> --- a/include/ext4fs.h
>> +++ b/include/ext4fs.h
>> @@ -31,6 +31,7 @@
>>   struct disk_partition;
>>
>>   #define EXT4_INDEX_FL          0x00001000 /* Inode uses hash tree index */
>> +#define EXT4_TOPDIR_FL         0x00020000 /* Top of directory hierarchies*/
>>   #define EXT4_EXTENTS_FL                0x00080000 /* Inode uses extents */
>>   #define EXT4_EXT_MAGIC                 0xf30a
>>   #define EXT4_FEATURE_RO_COMPAT_GDT_CSUM        0x0010
>> diff --git a/include/ext_common.h b/include/ext_common.h
>> index 30a0c248414..b09bbde116a 100644
>> --- a/include/ext_common.h
>> +++ b/include/ext_common.h
>> @@ -35,6 +35,16 @@ struct cmd_tbl;
>>   #define EXT2_PATH_MAX                          4096
>>   /* Maximum nesting of symlinks, used to prevent a loop.  */
>>   #define        EXT2_MAX_SYMLINKCNT             8
>> +/* Maximum file name length */
>> +#define EXT2_NAME_LEN 255
>> +
>> +/*
>> + * Revision levels
>> + */
>> +#define EXT2_GOOD_OLD_REV      0       /* The good old (original) format */
>> +#define EXT2_DYNAMIC_REV       1       /* V2 format w/ dynamic inode sizes */
>> +
>> +#define EXT2_GOOD_OLD_INODE_SIZE 128
>>
>>   /* Filetype used in directory entry.  */
>>   #define        FILETYPE_UNKNOWN                0
>> @@ -48,6 +58,10 @@ struct cmd_tbl;
>>   #define FILETYPE_INO_DIRECTORY         0040000
>>   #define FILETYPE_INO_SYMLINK           0120000
>>   #define EXT2_ROOT_INO                  2 /* Root inode */
>> +#define EXT2_BOOT_LOADER_INO           5 /* Boot loader inode */
>> +
>> +/* First non-reserved inode for old ext2 filesystems */
>> +#define EXT2_GOOD_OLD_FIRST_INO        11
>>
>>   /* The size of an ext2 block in bytes.  */
>>   #define EXT2_BLOCK_SIZE(data)     (1 << LOG2_BLOCK_SIZE(data))
> 
> Again I think these ext2 changes would be better in their own patch

OK.

FWIW These are really only used by this patch.

--Sean

>> diff --git a/include/test/spl.h b/include/test/spl.h
>> index a2f8d77b88f..7ae32a1020b 100644
>> --- a/include/test/spl.h
>> +++ b/include/test/spl.h
>> @@ -114,4 +114,7 @@ SPL_TEST(func##_##type, flags)
>>   /* More than a couple blocks, and will not be aligned to anything */
>>   #define SPL_TEST_DATA_SIZE     4099
>>
>> +/* Flags necessary for accessing DM devices */
>> +#define DM_FLAGS (UT_TESTF_DM | UT_TESTF_SCAN_FDT)
>> +
>>   #endif /* TEST_SPL_H */
>> diff --git a/test/image/Kconfig b/test/image/Kconfig
>> index 70ffe0ff276..963c86cc290 100644
>> --- a/test/image/Kconfig
>> +++ b/test/image/Kconfig
>> @@ -10,6 +10,17 @@ config SPL_UT_LOAD
>>
>>   if SPL_UT_LOAD
>>
>> +config SPL_UT_LOAD_FS
>> +       bool "Unit tests for filesystems"
>> +       depends on SANDBOX && SPL_OF_REAL
>> +       depends on FS_LOADER
>> +       depends on SPL_FS_FAT
>> +       depends on SPL_FS_EXT4
>> +       depends on SPL_MMC_WRITE
>> +       default y
>> +       help
>> +         Test filesystems in SPL.
>> +
>>   config SPL_UT_LOAD_OS
>>          bool "Test loading from the host OS"
>>          depends on SANDBOX && SPL_LOAD_FIT
>> diff --git a/test/image/Makefile b/test/image/Makefile
>> index 1f62d54453c..9427e69bd3b 100644
>> --- a/test/image/Makefile
>> +++ b/test/image/Makefile
>> @@ -3,4 +3,5 @@
>>   # Copyright 2021 Google LLC
>>
>>   obj-$(CONFIG_SPL_UT_LOAD) += spl_load.o
>> +obj-$(CONFIG_SPL_UT_LOAD_FS) += spl_load_fs.o
>>   obj-$(CONFIG_SPL_UT_LOAD_OS) += spl_load_os.o
>> diff --git a/test/image/spl_load.c b/test/image/spl_load.c
>> index ca3777cab37..4338da417ce 100644
>> --- a/test/image/spl_load.c
>> +++ b/test/image/spl_load.c
>> @@ -4,6 +4,7 @@
>>    */
>>
>>   #include <common.h>
>> +#include <dm.h>
>>   #include <image.h>
>>   #include <imx_container.h>
>>   #include <mapmem.h>
>> diff --git a/test/image/spl_load_fs.c b/test/image/spl_load_fs.c
>> new file mode 100644
>> index 00000000000..8cd90b73518
>> --- /dev/null
>> +++ b/test/image/spl_load_fs.c
>> @@ -0,0 +1,305 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2023 Sean Anderson <seanga2 at gmail.com>
>> + */
>> +
>> +#include <common.h>
>> +#include <blk.h>
>> +#include <ext_common.h>
>> +#include <ext4fs.h>
>> +#include <fat.h>
>> +#include <fs.h>
>> +#include <memalign.h>
>> +#include <asm/io.h>
>> +#include <linux/stat.h>
>> +#include <test/spl.h>
>> +#include <test/ut.h>
>> +
>> +/**
>> + * create_ext2() - Create an "ext2" filesystem with a single file
>> + * @dst: The location of the new filesystem; MUST be zeroed
>> + * @size: The size of the file
>> + * @filename: The name of the file
>> + * @data_offset: Filled with the offset of the file data from @dst
>> + *
>> + * Budget mke2fs. We use 1k blocks (to reduce overhead) with a single block
>> + * group, which limits us to 8M of data. Almost every feature which increases
>> + * complexity (checksums, hash tree directories, etc.) is disabled. We do cheat
>> + * a little and use extents from ext4 to save having to deal with indirects, but
>> + * U-Boot doesn't care.
>> + *
>> + * If @dst is %NULL, nothing is copied.
>> + *
>> + * Return: The size of the filesystem in bytes
>> + */
>> +static size_t create_ext2(void *dst, size_t size, const char *filename,
>> +                         size_t *data_offset)
>> +{
>> +       u32 super_block = 1;
>> +       u32 group_block = 2;
>> +       u32 block_bitmap_block = 3;
>> +       u32 inode_bitmap_block = 4;
>> +       u32 inode_table_block = 5;
>> +       u32 root_block = 6;
>> +       u32 file_block = 7;
>> +
>> +       u32 root_ino = EXT2_ROOT_INO;
>> +       u32 file_ino = EXT2_BOOT_LOADER_INO;
>> +
>> +       u32 block_size = EXT2_MIN_BLOCK_SIZE;
>> +       u32 inode_size = sizeof(struct ext2_inode);
>> +
>> +       u32 file_blocks = (size + block_size - 1) / block_size;
>> +       u32 blocks = file_block + file_blocks;
>> +       u32 inodes = block_size / inode_size;
>> +       u32 filename_len = strlen(filename);
>> +       u32 dirent_len = ALIGN(filename_len, sizeof(struct ext2_dirent)) +
>> +                           sizeof(struct ext2_dirent);
>> +
>> +       struct ext2_sblock *sblock = dst + super_block * block_size;
>> +       struct ext2_block_group *bg = dst + group_block * block_size;
>> +       struct ext2_inode *inode_table = dst + inode_table_block * block_size;
>> +       struct ext2_inode *root_inode = &inode_table[root_ino - 1];
>> +       struct ext2_inode *file_inode = &inode_table[file_ino - 1];
>> +       struct ext4_extent_header *ext_block = (void *)&file_inode->b;
>> +       struct ext4_extent *extent = (void *)(ext_block + 1);
>> +       struct ext2_dirent *dot = dst + root_block * block_size;
>> +       struct ext2_dirent *dotdot = dot + 2;
>> +       struct ext2_dirent *dirent = dotdot + 2;
>> +       struct ext2_dirent *last = ((void *)dirent) + dirent_len;
>> +
>> +       /* Make sure we fit in one block group */
>> +       if (blocks > block_size * 8)
>> +               return 0;
>> +
>> +       if (filename_len > EXT2_NAME_LEN)
>> +               return 0;
>> +
>> +       if (data_offset)
>> +               *data_offset = file_block * block_size;
>> +
>> +       if (!dst)
>> +               goto out;
>> +
>> +       sblock->total_inodes = cpu_to_le32(inodes);
>> +       sblock->total_blocks = cpu_to_le32(blocks);
>> +       sblock->first_data_block = cpu_to_le32(super_block);
>> +       sblock->blocks_per_group = cpu_to_le32(blocks);
>> +       sblock->fragments_per_group = cpu_to_le32(blocks);
>> +       sblock->inodes_per_group = cpu_to_le32(inodes);
>> +       sblock->magic = cpu_to_le16(EXT2_MAGIC);
>> +       /* Done mostly so we can pretend to be (in)compatible */
>> +       sblock->revision_level = cpu_to_le32(EXT2_DYNAMIC_REV);
>> +       /* Not really accurate but it doesn't matter */
>> +       sblock->first_inode = cpu_to_le32(EXT2_GOOD_OLD_FIRST_INO);
>> +       sblock->inode_size = cpu_to_le32(inode_size);
>> +       sblock->feature_incompat = cpu_to_le32(EXT4_FEATURE_INCOMPAT_EXTENTS);
>> +
>> +       bg->block_id = cpu_to_le32(block_bitmap_block);
>> +       bg->inode_id = cpu_to_le32(inode_bitmap_block);
>> +       bg->inode_table_id = cpu_to_le32(inode_table_block);
>> +
>> +       /*
>> +        * All blocks/inodes are in-use. I don't want to have to deal with
>> +        * endianness, so just fill everything in.
>> +        */
>> +       memset(dst + block_bitmap_block * block_size, 0xff, block_size * 2);
>> +
>> +       root_inode->mode = cpu_to_le16(S_IFDIR | 0755);
>> +       root_inode->size = cpu_to_le32(block_size);
>> +       root_inode->nlinks = cpu_to_le16(3);
>> +       root_inode->blockcnt = cpu_to_le32(1);
>> +       root_inode->flags = cpu_to_le32(EXT4_TOPDIR_FL);
>> +       root_inode->b.blocks.dir_blocks[0] = root_block;
>> +
>> +       file_inode->mode = cpu_to_le16(S_IFREG | 0644);
>> +       file_inode->size = cpu_to_le32(size);
>> +       file_inode->nlinks = cpu_to_le16(1);
>> +       file_inode->blockcnt = cpu_to_le32(file_blocks);
>> +       file_inode->flags = cpu_to_le32(EXT4_EXTENTS_FL);
>> +       ext_block->eh_magic = cpu_to_le16(EXT4_EXT_MAGIC);
>> +       ext_block->eh_entries = cpu_to_le16(1);
>> +       ext_block->eh_max = cpu_to_le16(sizeof(file_inode->b) /
>> +                                       sizeof(*ext_block) - 1);
>> +       extent->ee_len = cpu_to_le16(file_blocks);
>> +       extent->ee_start_lo = cpu_to_le16(file_block);
>> +
>> +       /* I'm not sure we need these, but it can't hurt */
>> +       dot->inode = cpu_to_le32(root_ino);
>> +       dot->direntlen = cpu_to_le16(2 * sizeof(*dot));
>> +       dot->namelen = 1;
>> +       dot->filetype = FILETYPE_DIRECTORY;
>> +       memcpy(dot + 1, ".", dot->namelen);
>> +
>> +       dotdot->inode = cpu_to_le32(root_ino);
>> +       dotdot->direntlen = cpu_to_le16(2 * sizeof(*dotdot));
>> +       dotdot->namelen = 2;
>> +       dotdot->filetype = FILETYPE_DIRECTORY;
>> +       memcpy(dotdot + 1, "..", dotdot->namelen);
>> +
>> +       dirent->inode = cpu_to_le32(file_ino);
>> +       dirent->direntlen = cpu_to_le16(dirent_len);
>> +       dirent->namelen = filename_len;
>> +       dirent->filetype = FILETYPE_REG;
>> +       memcpy(dirent + 1, filename, filename_len);
>> +
>> +       last->direntlen = block_size - dirent_len;
>> +
>> +out:
>> +       return (size_t)blocks * block_size;
>> +}
>> +
>> +/**
>> + * create_fat() - Create a FAT32 filesystem with a single file
>> + * @dst: The location of the new filesystem; MUST be zeroed
>> + * @size: The size of the file
>> + * @filename: The name of the file
>> + * @data_offset: Filled with the offset of the file data from @dst
>> + *
>> + * Budget mkfs.fat. We use FAT32 (so I don't have to deal with FAT12) with no
>> + * info sector, and a single one-sector FAT. This limits us to 64k of data
>> + * (enough for anyone). The filename must fit in 8.3.
>> + *
>> + * If @dst is %NULL, nothing is copied.
>> + *
>> + * Return: The size of the filesystem in bytes
>> + */
>> +static size_t create_fat(void *dst, size_t size, const char *filename,
>> +                        size_t *data_offset)
>> +{
>> +       u16 boot_sector = 0;
>> +       u16 fat_sector = 1;
>> +       u32 root_sector = 2;
>> +       u32 file_sector = 3;
>> +
>> +       u16 sector_size = 512;
>> +       u32 file_sectors = (size + sector_size - 1) / sector_size;
>> +       u32 sectors = file_sector + file_sectors;
>> +
>> +       char *ext;
>> +       size_t filename_len, ext_len;
>> +       int i;
>> +
>> +       struct boot_sector *bs = dst + boot_sector * sector_size;
>> +       struct volume_info *vi = (void *)(bs + 1);
>> +       __le32 *fat = dst + fat_sector * sector_size;
>> +       struct dir_entry *dirent = dst + root_sector * sector_size;
>> +
>> +       /* Make sure we fit in the FAT */
>> +       if (sectors > sector_size / sizeof(u32))
>> +               return 0;
>> +
>> +       ext = strchr(filename, '.');
>> +       if (ext) {
>> +               filename_len = ext - filename;
>> +               ext++;
>> +               ext_len = strlen(ext);
>> +       } else {
>> +               filename_len = strlen(filename);
>> +               ext_len = 0;
>> +       }
>> +
>> +       if (filename_len > 8 || ext_len > 3)
>> +               return 0;
>> +
>> +       if (data_offset)
>> +               *data_offset = file_sector * sector_size;
>> +
>> +       if (!dst)
>> +               goto out;
>> +
>> +       bs->sector_size[0] = sector_size & 0xff;
>> +       bs->sector_size[1] = sector_size >> 8;
>> +       bs->cluster_size = 1;
>> +       bs->reserved = cpu_to_le16(fat_sector);
>> +       bs->fats = 1;
>> +       bs->media = 0xf8;
>> +       bs->total_sect = cpu_to_le32(sectors);
>> +       bs->fat32_length = cpu_to_le32(1);
>> +       bs->root_cluster = cpu_to_le32(root_sector);
>> +
>> +       vi->ext_boot_sign = 0x29;
>> +       memcpy(vi->fs_type, FAT32_SIGN, sizeof(vi->fs_type));
>> +
>> +       memcpy(dst + 0x1fe, "\x55\xAA", 2);
>> +
>> +       fat[0] = cpu_to_le32(0x0ffffff8);
>> +       fat[1] = cpu_to_le32(0x0fffffff);
>> +       fat[2] = cpu_to_le32(0x0ffffff8);
>> +       for (i = file_sector; file_sectors > 1; file_sectors--, i++)
>> +               fat[i] = cpu_to_le32(i + 1);
>> +       fat[i] = cpu_to_le32(0x0ffffff8);
>> +
>> +       for (i = 0; i < sizeof(dirent->nameext.name); i++) {
>> +               if (i < filename_len)
>> +                       dirent->nameext.name[i] = toupper(filename[i]);
>> +               else
>> +                       dirent->nameext.name[i] = ' ';
>> +       }
>> +
>> +       for (i = 0; i < sizeof(dirent->nameext.ext); i++) {
>> +               if (i < ext_len)
>> +                       dirent->nameext.ext[i] = toupper(ext[i]);
>> +               else
>> +                       dirent->nameext.ext[i] = ' ';
>> +       }
>> +
>> +       dirent->start = cpu_to_le16(file_sector);
>> +       dirent->size = cpu_to_le32(size);
>> +
>> +out:
>> +       return sectors * sector_size;
>> +}
>> +
>> +typedef size_t (*create_fs_t)(void *, size_t, const char *, size_t *);
>> +
>> +static int spl_test_fs(struct unit_test_state *uts, const char *test_name,
>> +                      create_fs_t create)
>> +{
>> +       const char *filename = CONFIG_SPL_FS_LOAD_PAYLOAD_NAME;
>> +       struct blk_desc *dev_desc;
>> +       char *data_write, *data_read;
>> +       void *fs;
>> +       size_t fs_size, fs_data, fs_blocks, data_size = SPL_TEST_DATA_SIZE;
>> +       loff_t actread;
>> +
>> +       fs_size = create(NULL, data_size, filename, &fs_data);
>> +       ut_assert(fs_size);
>> +       fs = calloc(fs_size, 1);
>> +       ut_assertnonnull(fs);
>> +
>> +       data_write = fs + fs_data;
>> +       generate_data(data_write, data_size, test_name);
>> +       ut_asserteq(fs_size, create(fs, data_size, filename, NULL));
>> +
>> +       dev_desc = blk_get_devnum_by_uclass_id(UCLASS_MMC, 0);
>> +       ut_assertnonnull(dev_desc);
>> +       ut_asserteq(512, dev_desc->blksz);
>> +       fs_blocks = fs_size / dev_desc->blksz;
>> +       ut_asserteq(fs_blocks, blk_dwrite(dev_desc, 0, fs_blocks, fs));
>> +
>> +       /* We have to use malloc so we can call virt_to_phys */
>> +       data_read = malloc_cache_aligned(data_size);
>> +       ut_assertnonnull(data_read);
>> +       ut_assertok(fs_set_blk_dev_with_part(dev_desc, 0));
>> +       ut_assertok(fs_read("/" CONFIG_SPL_FS_LOAD_PAYLOAD_NAME,
>> +                           virt_to_phys(data_read), 0, data_size, &actread));
>> +       ut_asserteq(data_size, actread);
>> +       ut_asserteq_mem(data_write, data_read, data_size);
>> +
>> +       free(data_read);
>> +       free(fs);
>> +       return 0;
>> +}
>> +
>> +static int spl_test_ext(struct unit_test_state *uts)
>> +{
>> +       return spl_test_fs(uts, __func__, create_ext2);
>> +}
>> +SPL_TEST(spl_test_ext, DM_FLAGS);
>> +
>> +static int spl_test_fat(struct unit_test_state *uts)
>> +{
>> +       return spl_test_fs(uts, __func__, create_fat);
>> +}
>> +SPL_TEST(spl_test_fat, DM_FLAGS);
>> --
>> 2.37.1
>>
> 
> Regards,
> Simon



More information about the U-Boot mailing list