diff --git a/build/configs/common_download.sh b/build/configs/common_download.sh index ee26baca62..c59982c041 100755 --- a/build/configs/common_download.sh +++ b/build/configs/common_download.sh @@ -113,6 +113,7 @@ function get_executable_name() loadparam) echo "$1";; common) echo "${COMMON_BIN_NAME}";; zoneinfo) echo "zoneinfo.img";; + resource) echo "${RESOURCE_BIN_NAME}";; rom) echo "romfs.img";; bootparam) if [[ ! -n "${BOOTPARAM}" ]];then diff --git a/build/configs/rtl8730e/rtl8730e_download.sh b/build/configs/rtl8730e/rtl8730e_download.sh index 5ab56c6219..9803d79f00 100755 --- a/build/configs/rtl8730e/rtl8730e_download.sh +++ b/build/configs/rtl8730e/rtl8730e_download.sh @@ -49,6 +49,9 @@ function pre_download() if test -f "${BIN_PATH}/${COMMON_BIN_NAME}"; then cp -p ${BIN_PATH}/${COMMON_BIN_NAME} ${IMG_TOOL_PATH}/${COMMON_BIN_NAME} fi + if test -f "${BIN_PATH}/${RESOURCE_BIN_NAME}"; then + cp -p ${BIN_PATH}/${RESOURCE_BIN_NAME} ${IMG_TOOL_PATH}/${RESOURCE_BIN_NAME} + fi if test -f "${SMARTFS_BIN_PATH}"; then cp -p ${SMARTFS_BIN_PATH} ${IMG_TOOL_PATH}/${CONFIG_ARCH_BOARD}_smartfs.bin fi @@ -141,6 +144,9 @@ function post_download() if test -f "${SMARTFS_BIN_PATH}"; then [ -e ${CONFIG_ARCH_BOARD}_smartfs.bin ] && rm ${CONFIG_ARCH_BOARD}_smartfs.bin fi + if test -f "${RESOURCE_BIN_PATH}"; then + [ -e ] && rm ${RESOURCE_BIN_PATH} + fi if test -f "${BOOTPARAM}.bin"; then [ -e ${BOOTPARAM}.bin ] && rm ${BOOTPARAM}.bin fi diff --git a/framework/src/binary_manager/binary_manager_update.c b/framework/src/binary_manager/binary_manager_update.c index 8722999915..d03143e5be 100644 --- a/framework/src/binary_manager/binary_manager_update.c +++ b/framework/src/binary_manager/binary_manager_update.c @@ -53,6 +53,9 @@ binmgr_result_type_e binary_manager_set_bootparam(uint8_t type, binary_setbp_res #ifdef CONFIG_SUPPORT_COMMON_BINARY && !BM_CHECK_GROUP(type, BINARY_COMMON) #endif +#endif +#ifdef CONFIG_RESOURCE_FS + && !BM_CHECK_GROUP(type, BINARY_RESOURCE) #endif ) { bmdbg("Invalid parameter %u\n", type); diff --git a/os/Makefile.unix b/os/Makefile.unix index 3c691c7216..629f630de1 100644 --- a/os/Makefile.unix +++ b/os/Makefile.unix @@ -555,6 +555,11 @@ endif ifeq ($(CONFIG_BINARY_SIGNING),y) $(Q) $(call MAKE_USER_SIGNING) endif +endif +ifeq ($(CONFIG_RESOURCE_FS),y) + $(Q) $(TOPDIR)/../tools/fs/mkromfsimg.sh $(TOPDIR)/../resource ../build/output/bin/resourcefs.img + $(Q) $(TOPDIR)/tools/mkbinheader.py $(OUTBIN_DIR)/resourcefs.img resource + $(Q) $(TOPDIR)/tools/mkchecksum.py $(OUTBIN_DIR)/resourcefs.img endif $(Q) echo "Start the Board Specific Work for Binary" $(Q) $(call MAKE_BOARD_SPECIFIC_BIN, $(BIN_EXE), $(BIN_EXT)) @@ -789,7 +794,7 @@ endif romfs: ifeq ($(CONFIG_FS_ROMFS),y) - $(Q) ../tools/fs/mkromfsimg.sh + $(Q) $(TOPDIR)/../tools/fs/mkromfsimg.sh $(TOPDIR)/../tools/fs/contents-romfs ../build/output/bin/romfs.img endif # tools/compression/mkcompresstool.sh diff --git a/os/board/common/partitions.c b/os/board/common/partitions.c index 8e41b6f7a9..ea9a5e1db1 100644 --- a/os/board/common/partitions.c +++ b/os/board/common/partitions.c @@ -54,7 +54,21 @@ #endif #include "common.h" -#define FS_PATH_MAX 15 +#define FS_PATH_MAX 16 + +#ifdef CONFIG_AUTOMOUNT_USERFS +#ifdef CONFIG_USERFS_MNTPT +#define USERFS_MNTPT CONFIG_USERFS_MNTPT +#else +#define USERFS_MNTPT "/mnt" +#endif + +#ifdef CONFIG_USERFS_EXT_MNTPT +#define USERFS_EXT_MNTPT CONFIG_USERFS_EXT_MNTPT +#else +#define USERFS_EXT_MNTPT "/ext" +#endif +#endif /* CONFIG_AUTOMOUNT_USERFS */ #ifdef CONFIG_FLASH_PARTITION @@ -155,7 +169,13 @@ static int type_specific_initialize(int minor, FAR struct mtd_dev_s *mtd_part, c save_timezone_partno = true; } #endif -#endif /* CONFIG_MTD_FTL */ +#ifdef CONFIG_RESOURCE_FS + else if (!strncmp(types, "resource,", 9)) { + do_ftlinit = true; + tagno = MTD_FTL; + } +#endif +#endif #ifdef CONFIG_MTD_CONFIG else if (!strncmp(types, "config,", 7)) { @@ -251,6 +271,33 @@ static void configure_partition_name(FAR struct mtd_dev_s *mtd_part, const char } #endif +#ifdef CONFIG_RESOURCE_FS +static int make_resource_mtd_partition(struct mtd_dev_s *mtd, off_t partoffset, off_t nblocks, uint16_t partno) +{ + int ret; + char fs_devname[FS_PATH_MAX]; + FAR struct mtd_dev_s *mtd_part; + uint16_t resource_partno; + + /* Set part num to avoid duplication */ + resource_partno = partno + RESOURCE_DEVNUM_OFFSET; + + mtd_part = mtd_partition(mtd, partoffset, nblocks, resource_partno); + + if (!mtd_part) { + printf("ERROR: failed to create partition.\n"); + return ERROR; + } + + if (ftl_initialize(resource_partno, mtd_part)) { + printf("ERROR: failed to initialise mtd ftl errno :%d\n", errno); + return ERROR; + } + + return OK; +} +#endif + int configure_mtd_partitions(struct mtd_dev_s *mtd, int minor, partition_info_t *partinfo) { int ret; @@ -275,7 +322,7 @@ int configure_mtd_partitions(struct mtd_dev_s *mtd, int minor, partition_info_t return ERROR; #endif } - g_partno = 0; + if (!mtd || !part_data.types || !part_data.sizes || !partinfo) { printf("ERROR: Invalid partition data is NULL\n"); return ERROR; @@ -292,6 +339,11 @@ int configure_mtd_partitions(struct mtd_dev_s *mtd, int minor, partition_info_t return ERROR; } + /* Initialize partinfo data */ + partinfo->smartfs_partno = -1; + partinfo->romfs_partno = -1; + partinfo->timezone_partno = -1; + partoffset = 0; types = part_data.types; sizes = part_data.sizes; @@ -335,13 +387,30 @@ int configure_mtd_partitions(struct mtd_dev_s *mtd, int minor, partition_info_t #endif } #endif +#ifdef CONFIG_RESOURCE_FS + if (!strncmp(types, "resource,", 9)) { + int nblocks = geo.erasesize / geo.blocksize; + /* Make mtd dev to access resource fs. It starts from offset + erasesize (4K). */ + ret = make_resource_mtd_partition(mtd, partoffset + (geo.erasesize / 1024), partsize / geo.blocksize - nblocks, g_partno); + if (ret != OK) { + printf("ERROR: fail to make resource mtd part.\n"); + } + } +#endif #ifdef CONFIG_MTD_PARTITION_NAMES configure_partition_name(mtd_part, (const char **)&names, &index, part_name); -#if defined(CONFIG_BINARY_MANAGER) && defined(CONFIG_APP_BINARY_SEPARATION) +#ifdef CONFIG_BINARY_MANAGER +#ifdef CONFIG_APP_BINARY_SEPARATION if (!strncmp(types, "bin,", 4)) { binary_manager_register_upart(part_name, g_partno, partsize, partoffset * geo.blocksize); } #endif +#ifdef CONFIG_RESOURCE_FS + if (!strncmp(types, "resource,", 9)) { + binary_manager_register_respart(g_partno, partsize, partoffset * geo.blocksize); + } +#endif +#endif #endif partoffset += partsize / geo.blocksize; @@ -349,7 +418,6 @@ int configure_mtd_partitions(struct mtd_dev_s *mtd, int minor, partition_info_t move_to_next_part((const char **)&types); g_partno++; } - return OK; } @@ -365,47 +433,53 @@ void automount_fs_partition(partition_info_t *partinfo) } #ifdef CONFIG_AUTOMOUNT_USERFS /* Initialize and mount user partition (if we have) */ - snprintf(fs_devname, FS_PATH_MAX, "/dev/smart%dp%d", partinfo->minor, partinfo->smartfs_partno); -#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS - ret = mksmartfs(fs_devname, 1, false); -#else - ret = mksmartfs(fs_devname, false); -#endif - if (ret != OK) { - printf("ERROR: mksmartfs on %s failed errno : %d\n", fs_devname, errno); - } else { - char *mountpath; - if (partinfo->minor == 0) { - mountpath = "/mnt"; - } else { - mountpath = "/ext"; - } - ret = mount(fs_devname, mountpath, "smartfs", 0, NULL); + if (partinfo->smartfs_partno != -1) { + snprintf(fs_devname, FS_PATH_MAX, "/dev/smart%dp%d", partinfo->minor, partinfo->smartfs_partno); + #ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS + ret = mksmartfs(fs_devname, 1, false); + #else + ret = mksmartfs(fs_devname, false); + #endif if (ret != OK) { - printf("ERROR: mounting '%s' failed, errno %d\n", fs_devname, get_errno()); + printf("ERROR: mksmartfs on %s failed errno : %d\n", fs_devname, errno); } else { - printf("%s is mounted successfully @ %s \n", fs_devname, mountpath); + char *mountpath; + if (partinfo->minor == 0) { + mountpath = USERFS_MNTPT; + } else { + mountpath = USERFS_EXT_MNTPT; + } + ret = mount(fs_devname, mountpath, "smartfs", 0, NULL); + if (ret != OK) { + printf("ERROR: mounting '%s' failed, errno %d\n", fs_devname, get_errno()); + } else { + printf("%s is mounted successfully @ %s \n", fs_devname, mountpath); + } } } #endif #ifdef CONFIG_AUTOMOUNT_ROMFS - snprintf(fs_devname, FS_PATH_MAX, "/dev/mtdblock%d", partinfo->romfs_partno); - ret = mount(fs_devname, "/rom", "romfs", 0, NULL); - if (ret != OK) { - printf("ERROR: mounting '%s'(ROMFS) failed, errno %d\n", fs_devname, get_errno()); - } else { - printf("%s is mounted successfully @ %s \n", fs_devname, "/rom"); + if (partinfo->romfs_partno != -1) { + snprintf(fs_devname, FS_PATH_MAX, "/dev/mtdblock%d", partinfo->romfs_partno); + ret = mount(fs_devname, "/rom", "romfs", 0, NULL); + if (ret != OK) { + printf("ERROR: mounting '%s'(ROMFS) failed, errno %d\n", fs_devname, get_errno()); + } else { + printf("%s is mounted successfully @ %s \n", fs_devname, "/rom"); + } } #endif /* CONFIG_AUTOMOUNT_ROMFS */ #ifdef CONFIG_LIBC_ZONEINFO_ROMFS - snprintf(fs_devname, FS_PATH_MAX, "/dev/mtdblock%d", partinfo->timezone_partno); - ret = mount(fs_devname, CONFIG_LIBC_TZDIR, "romfs", MS_RDONLY, NULL); - if (ret != OK) { - printf("ROMFS ERROR: timezone mount failed, errno %d\n", get_errno()); - } else { - printf("%s is mounted successfully @ %s \n", fs_devname, CONFIG_LIBC_TZDIR); + if (partinfo->romfs_partno != -1) { + snprintf(fs_devname, FS_PATH_MAX, "/dev/mtdblock%d", partinfo->timezone_partno); + ret = mount(fs_devname, CONFIG_LIBC_TZDIR, "romfs", MS_RDONLY, NULL); + if (ret != OK) { + printf("ROMFS ERROR: timezone mount failed, errno %d\n", get_errno()); + } else { + printf("%s is mounted successfully @ %s \n", fs_devname, CONFIG_LIBC_TZDIR); + } } #endif /* CONFIG_LIBC_ZONEINFO_ROMFS */ #endif /* CONFIG_AUTOMOUNT_USERFS, CONFIG_AUTOMOUNT_ROMFS, CONFIG_LIBC_ZONEINFO_ROMFS */ diff --git a/os/fs/Kconfig b/os/fs/Kconfig index 85006a1b26..e9561e755c 100644 --- a/os/fs/Kconfig +++ b/os/fs/Kconfig @@ -26,6 +26,22 @@ config FS_WRITABLE bool default y +config RESOURCE_FS + bool "Support Resource fs" + select FS_ROMFS + default y + +if RESOURCE_FS +config RESOURCE_BINARY_VERSION + string "Resource binary version (YYMMDD)" + default 240421 + ---help--- + This config indicates resource binary version which has a "YYMMDD" format. + It is included in resource binary header and used to check the latest binary. + So it should be set to a higher value than versions of old binaries if you want to make the binary the latest version. + +endif + source fs/aio/Kconfig source fs/semaphore/Kconfig source fs/mqueue/Kconfig diff --git a/os/include/tinyara/binary_manager.h b/os/include/tinyara/binary_manager.h index a4b20cb9c7..5823d7c92d 100644 --- a/os/include/tinyara/binary_manager.h +++ b/os/include/tinyara/binary_manager.h @@ -59,8 +59,15 @@ #endif #define KERNEL_BIN_COUNT 2 -#define BINARY_COUNT (USER_BIN_COUNT + KERNEL_BIN_COUNT) +#define RESOURCE_DEVNUM_OFFSET 30 +#define RESOURCE_HEADER_SIZE 4096 +#define RESOURCE_BIN_COUNT 2 +#ifdef CONFIG_RESOURCE_FS +#define BINARY_COUNT (USER_BIN_COUNT + KERNEL_BIN_COUNT + RESOURCE_BIN_COUNT) +#else +#define BINARY_COUNT (USER_BIN_COUNT + KERNEL_BIN_COUNT) +#endif /* Kernel version has "YYMMDD" format */ #define KERNEL_BIN_VER_MIN 101 /* YYMMDD : 000101 */ #define KERNEL_BIN_VER_MAX 991231 /* YYMMDD : 991231 */ @@ -68,12 +75,13 @@ /* The lenght of user or kernel partition path */ #define BINARY_PATH_LEN 16 -/* Binary Type : Kernel, Common, User app */ +/* Binary Type : Kernel, Common, User app, Resource */ enum binary_type_e { BINARY_KERNEL = 0, BINARY_COMMON = 1, BINARY_USERAPP = 2, - BINARY_TYPE_MAX = 3, + BINARY_RESOURCE = 3, + BINARY_TYPE_MAX = 4, }; /* Macros for binary grouping used for request to set bootparam */ @@ -175,6 +183,14 @@ struct common_binary_header_s { } __attribute__((__packed__)); typedef struct common_binary_header_s common_binary_header_t; +struct resource_binary_header_s { + uint32_t crc_hash; + uint16_t header_size; + uint32_t version; + uint32_t bin_size; +} __attribute__((__packed__)); +typedef struct resource_binary_header_s resource_binary_header_t; + /* The structure of binary update information for kernel or user binaries */ struct binary_setbp_result_s { int result[BINARY_TYPE_MAX]; @@ -280,6 +296,8 @@ typedef struct binmgr_getinfo_all_response_s binmgr_getinfo_all_response_t; void binary_manager_register_kpart(int part_num, int part_size, int part_offset); void binary_manager_register_bppart(int part_num, int part_size); void binary_manager_register_upart(char *name, int part_num, int part_size, int part_offset); +void binary_manager_register_respart(int part_num, int part_size, int part_offset); +int binary_manager_mount_resource(void); void binary_manager_deinit_modules(void); #ifdef __cplusplus diff --git a/os/kernel/binary_manager/Make.defs b/os/kernel/binary_manager/Make.defs index 8e07e8b3d8..526bdf736c 100644 --- a/os/kernel/binary_manager/Make.defs +++ b/os/kernel/binary_manager/Make.defs @@ -27,6 +27,10 @@ ifeq ($(CONFIG_USE_BP),y) CSRCS += binary_manager_bootparam.c endif +ifeq ($(CONFIG_RESOURCE_FS),y) +CSRCS += binary_manager_resource.c +endif + ifeq ($(CONFIG_APP_BINARY_SEPARATION),y) CSRCS += binary_manager_load.c binary_manager_callback.c binary_manager_deinit.c ifeq ($(CONFIG_BINMGR_RECOVERY),y) diff --git a/os/kernel/binary_manager/binary_manager.c b/os/kernel/binary_manager/binary_manager.c index b95f8dd7d5..e53f9921e4 100644 --- a/os/kernel/binary_manager/binary_manager.c +++ b/os/kernel/binary_manager/binary_manager.c @@ -137,6 +137,13 @@ int binary_manager(int argc, char *argv[]) goto errout_with_nobinary; } +#ifdef CONFIG_RESOURCE_FS + if (binary_manager_mount_resource() != OK) { + bmdbg("Fail to mount resource\n"); + goto errout_with_nobinary; + } +#endif + #ifdef CONFIG_APP_BINARY_SEPARATION if (binary_manager_get_ucount() <= 0) { is_found_ubin = false; diff --git a/os/kernel/binary_manager/binary_manager.h b/os/kernel/binary_manager/binary_manager.h index 90d27b72fc..70aae69cbe 100644 --- a/os/kernel/binary_manager/binary_manager.h +++ b/os/kernel/binary_manager/binary_manager.h @@ -99,6 +99,9 @@ #endif #define BINMGR_LOADING_TRYCNT 2 +/* Partition Name - first partition : "A", second partition : "B" */ +#define GET_PARTNAME(part_idx) ((part_idx == 0) ? "A" : "B") + /* Loading thread cmd types */ enum loading_thread_cmd { LOADCMD_LOAD = 0, @@ -164,6 +167,16 @@ struct binmgr_kinfo_s { }; typedef struct binmgr_kinfo_s binmgr_kinfo_t; +/* Resource binary data type in resource table */ +struct binmgr_resinfo_s { + bool is_mounted; + uint8_t inuse_idx; + uint32_t part_count; + part_info_t part_info[RESOURCE_BIN_COUNT]; + uint32_t version; +}; +typedef struct binmgr_resinfo_s binmgr_resinfo_t; + /* User bootparam data */ struct binmgr_userbp_s { char name[BIN_NAME_MAX]; @@ -182,6 +195,7 @@ struct binmgr_bpdata_s { uint8_t app_count; binmgr_userbp_t app_data[CONFIG_NUM_APPS + 1]; #endif + uint8_t resource_active_idx; } __attribute__((__packed__)); typedef struct binmgr_bpdata_s binmgr_bpdata_t; @@ -285,6 +299,12 @@ int binary_manager_get_inactive_path(int requester_pid, char *bin_name); void binary_manager_update_bootparam(int requester_pid, uint8_t type); void binary_manager_reset_board(int reboot_reason); int binary_manager_update_kernel_binary(void); +#ifdef CONFIG_RESOURCE_FS +binmgr_resinfo_t *binary_manager_get_resdata(void); +bool binary_manager_scan_resource(void); +int binary_manager_unmount_resource(void); +int binary_manager_check_resource_update(void); +#endif /**************************************************************************** * Binary Manager Main Thread diff --git a/os/kernel/binary_manager/binary_manager_bootparam.c b/os/kernel/binary_manager/binary_manager_bootparam.c index e772bf4c70..46745e7efe 100644 --- a/os/kernel/binary_manager/binary_manager_bootparam.c +++ b/os/kernel/binary_manager/binary_manager_bootparam.c @@ -298,6 +298,24 @@ void binary_manager_update_bootparam(int requester_pid, uint8_t type) } } +#ifdef CONFIG_RESOURCE_FS + if (BM_CHECK_GROUP(type, BINARY_RESOURCE)) { + /* Update bootparam if new resource binary exists */ + ret = binary_manager_check_resource_update(); + if (ret == BINMGR_OK) { + /* Update index for inactive partition */ + update_bp_data.resource_active_idx ^= 1; + } else if (ret == BINMGR_ALREADY_UPDATED || ret == BINMGR_NOT_FOUND) { + bmdbg("No resource binary to update\n"); + is_all_updatable = false; + response_msg.data.result[BINARY_RESOURCE] = BINMGR_ALREADY_UPDATED; + } else { + bmdbg("Fail to check resource update, %d\n", ret); + goto send_response; + } + } +#endif + #ifdef CONFIG_APP_BINARY_SEPARATION need_update = false; diff --git a/os/kernel/binary_manager/binary_manager_getinfo.c b/os/kernel/binary_manager/binary_manager_getinfo.c index 30913584e0..c063c99d89 100644 --- a/os/kernel/binary_manager/binary_manager_getinfo.c +++ b/os/kernel/binary_manager/binary_manager_getinfo.c @@ -119,6 +119,9 @@ void binary_manager_get_info_with_name(int requester_pid, char *bin_name) #ifdef CONFIG_APP_BINARY_SEPARATION int bin_idx; uint32_t bin_count; +#endif +#ifdef CONFIG_RESOURCE_FS + binmgr_resinfo_t *resinfo; #endif binmgr_kinfo_t *kerinfo; char q_name[BIN_PRIVMQ_LEN]; @@ -144,6 +147,19 @@ void binary_manager_get_info_with_name(int requester_pid, char *bin_name) } response_msg.result = BINMGR_OK; } +#ifdef CONFIG_RESOURCE_FS + if (!strncmp("resource", bin_name, BIN_NAME_MAX)) { + resinfo = binary_manager_get_resdata(); + strncpy(response_msg.data.name, "resource", BIN_NAME_MAX); + response_msg.data.version = resinfo->version; + if (resinfo->part_count > 1) { + response_msg.data.available_size = resinfo->part_info[resinfo->inuse_idx ^ 1].size; + } else { + response_msg.data.available_size = -1; + } + response_msg.result = BINMGR_OK; + } +#endif #ifdef CONFIG_APP_BINARY_SEPARATION else { bin_count = binary_manager_get_ucount(); @@ -173,6 +189,9 @@ void binary_manager_get_info_all(int requester_pid) #ifdef CONFIG_APP_BINARY_SEPARATION int bin_idx; uint32_t bin_count; +#endif +#ifdef CONFIG_RESOURCE_FS + binmgr_resinfo_t *resinfo; #endif int result_idx; char q_name[BIN_PRIVMQ_LEN]; @@ -214,6 +233,18 @@ void binary_manager_get_info_all(int requester_pid) response_msg.data.bin_info[result_idx].version = BIN_VER(bin_idx, BIN_USEIDX(bin_idx)); result_idx++; } +#endif +#ifdef CONFIG_RESOURCE_FS + /* Get kernel data */ + resinfo = binary_manager_get_resdata(); + strncpy(response_msg.data.bin_info[result_idx].name, "resource", BIN_NAME_MAX); + response_msg.data.bin_info[result_idx].version = resinfo->version; + if (resinfo->part_count > 1) { + response_msg.data.bin_info[result_idx].available_size = resinfo->part_info[resinfo->inuse_idx ^ 1].size; + } else { + response_msg.data.bin_info[result_idx].available_size = -1; + } + result_idx++; #endif if (response_msg.result == BINMGR_OK) { response_msg.data.bin_count = result_idx; @@ -226,6 +257,9 @@ static int binary_manager_get_path(int requester_pid, char *bin_name, bool inact { #ifdef CONFIG_APP_BINARY_SEPARATION int bin_idx; +#endif +#ifdef CONFIG_RESOURCE_FS + binmgr_resinfo_t *resinfo; #endif binmgr_kinfo_t *kerinfo; char q_name[BIN_PRIVMQ_LEN]; @@ -248,7 +282,18 @@ static int binary_manager_get_path(int requester_pid, char *bin_name, bool inact } goto send_result; } - +#ifdef CONFIG_RESOURCE_FS + if (!strncmp("resource", bin_name, BIN_NAME_MAX)) { + resinfo = binary_manager_get_resdata(); + if (resinfo->part_count > 1) { + response_msg.result = BINMGR_OK; + snprintf(response_msg.binpath, BINARY_PATH_LEN, BINMGR_DEVNAME_FMT, resinfo->part_info[resinfo->inuse_idx ^ inactive].devnum); + } else { + response_msg.result = BINMGR_NOT_FOUND; + } + goto send_result; + } +#endif #ifdef CONFIG_APP_BINARY_SEPARATION bin_idx = binary_manager_get_index_with_name(bin_name); if (bin_idx < 0) { diff --git a/os/kernel/binary_manager/binary_manager_load.c b/os/kernel/binary_manager/binary_manager_load.c index 82ca2be2a4..9bb41ce9f2 100644 --- a/os/kernel/binary_manager/binary_manager_load.c +++ b/os/kernel/binary_manager/binary_manager_load.c @@ -69,9 +69,6 @@ extern struct binary_s *g_lib_binp; #define BINARY_COMP_TYPE "[Un-compressed Binary]" #endif -/* Partition Name - first partition : "A", second partition : "B" */ -#define GET_PARTNAME(part_idx) ((part_idx == 0) ? "A" : "B") - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -488,6 +485,13 @@ static int loadingall_thread(int argc, char *argv[]) return BINMGR_OPERATION_FAIL; } +#ifdef CONFIG_RESOURCE_FS + ret = binary_manager_mount_resource(); + if (ret != OK) { + bmdbg("ERROR: resourcefs mount failed\n"); + } +#endif + #ifdef CONFIG_SUPPORT_COMMON_BINARY ret = binary_manager_load(BM_CMNLIB_IDX); if (ret < 0) { @@ -498,7 +502,6 @@ static int loadingall_thread(int argc, char *argv[]) load_cnt = 0; bin_count = binary_manager_get_ucount(); - /* Load the binaries with high priority directly */ for (bin_idx = 1; bin_idx <= bin_count; bin_idx++) { if (BIN_LOAD_PRIORITY(bin_idx, BIN_USEIDX(bin_idx)) == BINARY_LOADPRIO_HIGH) { @@ -580,6 +583,13 @@ static int reloading_thread(int argc, char *argv[]) } #endif +#ifdef CONFIG_RESOURCE_FS + ret = binary_manager_unmount_resource(); + if (ret != OK) { + return BINMGR_OPERATION_FAIL; + } +#endif + /* Deinitialize modules in kernel */ binary_manager_deinit_modules(); @@ -640,6 +650,13 @@ static int update_thread(int argc, char *argv[]) } #endif +#ifdef CONFIG_RESOURCE_FS + ret = binary_manager_unmount_resource(); + if (ret != OK) { + return BINMGR_OPERATION_FAIL; + } +#endif + /* Deinitialize modules in kernel */ binary_manager_deinit_modules(); diff --git a/os/kernel/binary_manager/binary_manager_resource.c b/os/kernel/binary_manager/binary_manager_resource.c new file mode 100644 index 0000000000..78f438dc66 --- /dev/null +++ b/os/kernel/binary_manager/binary_manager_resource.c @@ -0,0 +1,267 @@ +/**************************************************************************** + * + * Copyright 2024 Samsung Electronics All Rights Reserved. + * + * 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. + * + ****************************************************************************/ +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include + +#include + +#include "binary_manager/binary_manager.h" + +/**************************************************************************** + * Private Definitions + ****************************************************************************/ +#define RESOURCE_MOUNTPT "/res" + +/* Data for Resource partitions */ +static binmgr_resinfo_t resource_info; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: binary_manager_get_resdata + * + * Description: + * This function gets a resource data. + * + ****************************************************************************/ +binmgr_resinfo_t *binary_manager_get_resdata(void) +{ + return &resource_info; +} + +/**************************************************************************** + * Name: binary_manager_register_resource + * + * Description: + * This function registers a partition of resource. + * + ****************************************************************************/ +void binary_manager_register_respart(int part_num, int part_size, int part_offset) +{ + if (part_num < 0 || part_size <= 0 || part_offset < 0 || resource_info.part_count >= RESOURCE_BIN_COUNT) { + bmdbg("Invalid resource partition : num %d, size %d, offset %d\n", part_num, part_size, part_offset); + return; + } + + resource_info.is_mounted = false; + resource_info.part_info[resource_info.part_count].size = part_size; + resource_info.part_info[resource_info.part_count].devnum = part_num; + resource_info.part_info[resource_info.part_count].address = CONFIG_FLASH_START_ADDR + part_offset; + + bmdbg("[RESOURCE %d] part num %d size %d, address 0x%x\n", resource_info.part_count, part_num, part_size, CONFIG_FLASH_START_ADDR + part_offset); + + resource_info.part_count++; +} + +/**************************************************************************** + * Name: binary_manager_scan_resource + * + * Description: + * This function scans resource binaries and update information. + * + ****************************************************************************/ +bool binary_manager_scan_resource(void) +{ + int ret; + resource_binary_header_t header_data; + char filepath[BINARY_PATH_LEN]; + +#ifdef CONFIG_USE_BP + binmgr_bpdata_t *bp_data; + if (binary_manager_update_bpinfo() == BINMGR_OK) { + bp_data = binary_manager_get_bpdata(); + /* Verify running resource binary based on bootparam */ + snprintf(filepath, BINARY_PATH_LEN, BINMGR_DEVNAME_FMT, resource_info.part_info[bp_data->resource_active_idx].devnum); + ret = binary_manager_read_header(BINARY_RESOURCE, filepath, &header_data, false); + if (ret == OK) { + /* Update inuse index and resource version */ + resource_info.inuse_idx = bp_data->resource_active_idx; + resource_info.version = header_data.version; + bmvdbg("Resource version [%u] %u\n", resource_info.inuse_idx, resource_info.version); + return true; + } + } +#else + uint32_t latest_ver = 0; + + for (int part_idx = 0; part_idx < resource_info.part_count; part_idx++) { + snprintf(filepath, BINARY_PATH_LEN, BINMGR_DEVNAME_FMT, resource_info.part_info[part_idx].devnum); + ret = binary_manager_read_header(BINARY_RESOURCE, filepath, &header_data, true); + if (ret == OK && latest_ver < header_data.version) { + /* Update latest version and inuse index */ + resource_info.version = header_data.version; + resource_info.inuse_idx = part_idx; + latest_ver = header_data.version; + } + } + + /* Found valid binary */ + if (resource_info.version != 0) { + bmvdbg("Resource version [%u] %u\n", resource_info.inuse_idx, resource_info.version); + return true; + } +#endif + bmdbg("Failed to find valid resource\n"); + return false; +} + +/**************************************************************************** + * Name: binary_manager_mount_resource + * + * Description: + * This function mounts resourcefs. + * + ****************************************************************************/ +int binary_manager_mount_resource(void) +{ + int ret; + int inuse_idx; + int bin_count; + bool need_update_bp = false; + char devpath[BINARY_PATH_LEN]; + char fs_devpath[BINARY_PATH_LEN]; + resource_binary_header_t resource_header_data; + + if (resource_info.is_mounted) { + bmvdbg("RESOURCEFS is already mounted\n"); + return OK; + } + + bin_count = resource_info.part_count; + inuse_idx = resource_info.inuse_idx; + + do { + /* Read header data and Check crc */ + snprintf(devpath, BINARY_PATH_LEN, BINMGR_DEVNAME_FMT, resource_info.part_info[inuse_idx].devnum); + ret = binary_manager_read_header(BINARY_RESOURCE, devpath, &resource_header_data, true); + if (ret == BINMGR_OK) { + bmvdbg("Resource Header Checking Success\n"); + snprintf(fs_devpath, BINARY_PATH_LEN, BINMGR_DEVNAME_FMT, resource_info.part_info[inuse_idx].devnum + RESOURCE_DEVNUM_OFFSET); + ret = mount(fs_devpath, RESOURCE_MOUNTPT, "romfs", MS_RDONLY, NULL); + if (ret != OK) { + printf("ROMFS ERROR: resourcefs mount failed, errno %d\n", get_errno()); + } else { + resource_info.is_mounted = true; + printf("%s is mounted successfully @ %s \n", fs_devpath, RESOURCE_MOUNTPT); + bmdbg("Mount resource success! [Version: %d] [Partition: %s] \n", resource_info.version, GET_PARTNAME(inuse_idx)); + break; + } + } + + bmdbg("Invalid Resource header[%d] devpath : %s\n", inuse_idx, devpath); + + /* Check if a binary exists in another partition. */ + if (--bin_count > 0) { + inuse_idx ^= 1; +#ifdef CONFIG_USE_BP + need_update_bp = true; +#endif + bmdbg("Try to read another partition %d\n", resource_info.part_info[inuse_idx].devnum); + continue; + } else { + bmvdbg("No valid Resource binary\n"); + return ERROR; + } + } while (bin_count > 0); + +#ifdef CONFIG_USE_BP + if (need_update_bp) { + /* Update boot param data because the binary not written to bootparam is loaded */ + binmgr_bpdata_t update_bp_data; + memcpy(&update_bp_data, binary_manager_get_bpdata(), sizeof(binmgr_bpdata_t)); + update_bp_data.version++; + update_bp_data.resource_active_idx ^= 1; + ret = binary_manager_write_bootparam(&update_bp_data); + if (ret == BINMGR_OK) { + binary_manager_set_bpdata(&update_bp_data); + bmvdbg("Update bootparam SUCCESS\n"); + } else { + bmdbg("Fail to update bootparam to recover, %d\n", ret); + } + } +#endif + return OK; +} + +/**************************************************************************** + * Name: binary_manager_unmount_resource + * + * Description: + * This function unmounts resourcefs. + * + ****************************************************************************/ +int binary_manager_unmount_resource(void) +{ + int ret; + + /* Unmont current resource */ + ret = unmount(RESOURCE_MOUNTPT); + if (ret != OK) { + bmdbg("ERROR: resourcefs unmount failed, errno %d\n", get_errno()); + return ERROR; + } + + resource_info.is_mounted = false; + bmvdbg("%s is unmounted successfully \n", RESOURCE_MOUNTPT); + + return OK; +} + +/************************************************************************************* +* Name: binary_manager_check_resource_update +* +* Description: +* This function checks that new resource binary exists on inactive partition +* and verifies the update is needed by comparing running version with new version. +* +*************************************************************************************/ +int binary_manager_check_resource_update(void) +{ + int ret; + int inactive_partidx; + char filepath[BINARY_PATH_LEN]; + resource_binary_header_t header_data; + + inactive_partidx = resource_info.inuse_idx ^ 1; + + /* Verify resource binary on the partition without running binary */ + snprintf(filepath, BINARY_PATH_LEN, BINMGR_DEVNAME_FMT, resource_info.part_info[inactive_partidx].devnum); + ret = binary_manager_read_header(BINARY_RESOURCE, filepath, (void *)&header_data, true); + if (ret == BINMGR_OK) { +#ifdef CONFIG_BINMGR_UPDATE_SAME_VERSION + if (resource_info.version <= header_data.version) { +#else + if (resource_info.version < header_data.version) { +#endif + /* Need to update bootparam and reboot */ + bmvdbg("Found new resource binary in inactive partition %d\n", resource_info.part_info[inactive_partidx].devnum); + return BINMGR_OK; + } else { + bmdbg("Latest version is running, version %d\n", resource_info.version); + return BINMGR_ALREADY_UPDATED; + } + } + return ret; +} diff --git a/os/kernel/binary_manager/binary_manager_verify.c b/os/kernel/binary_manager/binary_manager_verify.c index 3c4c3343d9..1b05f24fd6 100644 --- a/os/kernel/binary_manager/binary_manager_verify.c +++ b/os/kernel/binary_manager/binary_manager_verify.c @@ -69,8 +69,7 @@ static int binary_manager_verify_header_data(int type, void *header_input) return ERROR; } bmvdbg("User binary header : %u %u %u %u %s %u %u %u\n", header_data->header_size, header_data->bin_type, header_data->bin_size, header_data->loading_priority, header_data->bin_name, header_data->bin_ver, header_data->bin_ramsize, header_data->kernel_ver); - } else { - /* Verify header data */ + } else if (type == BINARY_COMMON) { common_binary_header_t *header_data = (common_binary_header_t *)header_input; if (header_data->header_size == 0 || header_data->bin_size == 0 ||\ header_data->version < BM_VERSION_DATE_MIN || header_data->version > BM_VERSION_DATE_MAX) { @@ -78,6 +77,14 @@ static int binary_manager_verify_header_data(int type, void *header_input) return ERROR; } bmvdbg("Common binary header : headersize %u, binsize %u, version %u\n", header_data->header_size, header_data->bin_size, header_data->version); + } else { + resource_binary_header_t *header_data = (resource_binary_header_t *)header_input; + if (header_data->header_size == 0 || header_data->bin_size == 0 ||\ + header_data->version < BM_VERSION_DATE_MIN || header_data->version > BM_VERSION_DATE_MAX) { + bmdbg("Invalid resource header data : headersize %u, binsize %u, version %u\n", header_data->header_size, header_data->bin_size, header_data->version); + return ERROR; + } + bmvdbg("Resource binary header : headersize %u, binsize %u, version %u\n", header_data->header_size, header_data->bin_size, header_data->version); } return OK; @@ -109,13 +116,15 @@ int binary_manager_read_header(int type, char *devpath, void *header_data, bool bmdbg("Invalid parameter, type %d\n", type); return BINMGR_INVALID_PARAM; } - + if (type == BINARY_KERNEL) { header_size = sizeof(kernel_binary_header_t); } else if (type == BINARY_USERAPP) { header_size = sizeof(user_binary_header_t); } else if (type == BINARY_COMMON) { header_size = sizeof(common_binary_header_t); + } else if (type == BINARY_RESOURCE) { + header_size = sizeof(resource_binary_header_t); } memset(header_data, 0, header_size); @@ -128,7 +137,7 @@ int binary_manager_read_header(int type, char *devpath, void *header_data, bool } #ifdef CONFIG_BINARY_SIGNING - if (type != BINARY_KERNEL) { + if (type == BINARY_USERAPP || type == BINARY_COMMON) { ret = lseek(fd, USER_SIGN_PREPEND_SIZE, SEEK_SET); if (ret < 0) { bmdbg("Fail to set offset to skip signing header, errno : %d\n", errno); @@ -166,6 +175,10 @@ int binary_manager_read_header(int type, char *devpath, void *header_data, bool crc_bufsize = CMNLIB_CRC_BUFSIZE; bin_size = ((common_binary_header_t *)header_data)->bin_size; crc_hash = ((common_binary_header_t *)header_data)->crc_hash; + } else if (type == BINARY_RESOURCE) { + crc_bufsize = ((resource_binary_header_t *)header_data)->bin_size; + bin_size = RESOURCE_HEADER_SIZE - header_size + ((resource_binary_header_t *)header_data)->bin_size; + crc_hash = ((resource_binary_header_t *)header_data)->crc_hash; } size_t max_bufsize = kmm_get_largest_freenode_size() / 2; crc_bufsize = crc_bufsize < max_bufsize ? crc_bufsize : max_bufsize; diff --git a/os/tools/check_package_header.py b/os/tools/check_package_header.py index f19e2ea02d..ca98d1d791 100644 --- a/os/tools/check_package_header.py +++ b/os/tools/check_package_header.py @@ -148,6 +148,10 @@ print("\tStack Size : " + str(stk_size[0])) print("\tKernel Version : " + str(kernel_ver[0])) +elif "resource" in target : + print("=== Resource Package Header Information ===") + sys.exit(1) + else : print("!!!Not Supported Package. Please Check the package!!!") VERIFY_SUCCESS = False diff --git a/os/tools/check_package_size.py b/os/tools/check_package_size.py index a698e584cb..02dc456c42 100755 --- a/os/tools/check_package_size.py +++ b/os/tools/check_package_size.py @@ -37,6 +37,7 @@ CONFIG_APP_BINARY_SEPARATION = util.get_value_from_file(cfg_file, "CONFIG_APP_BINARY_SEPARATION=").rstrip('\n') CONFIG_SUPPORT_COMMON_BINARY = util.get_value_from_file(cfg_file, "CONFIG_SUPPORT_COMMON_BINARY=").rstrip('\n') +CONFIG_RESOURCE_FS = util.get_value_from_file(cfg_file, "CONFIG_RESOURCE_FS=").rstrip('\n') INTERNAL_PARTITION_NAME_LIST = util.get_value_from_file(cfg_file, "CONFIG_FLASH_PART_NAME=") INTERNAL_PARTITION_SIZE_LIST = util.get_value_from_file(cfg_file, "CONFIG_FLASH_PART_SIZE=") @@ -68,6 +69,10 @@ def validate_binary_size(bin_type, part_size): PARTITION_SIZE = part_size used_ratio = 0 + # Calculate the used ratio + if PARTITION_SIZE != 0 : + used_ratio = round(float(BINARY_SIZE) / float(PARTITION_SIZE) * 100, 2) + # Calculate the used ratio if PARTITION_SIZE != 0 : used_ratio = round(float(BINARY_SIZE) / float(PARTITION_SIZE) * 100, 2) @@ -142,6 +147,8 @@ def check_binary_size(bin_name): check_binary_size("APP2") if CONFIG_SUPPORT_COMMON_BINARY == "y" : check_binary_size("COMMON") +if CONFIG_RESOURCE_FS == "y" : + check_binary_size("RESOURCE") if FAIL_TO_BUILD == True : # Stop to build, because there is mismatched size problem. diff --git a/os/tools/convert_binary.py b/os/tools/convert_binary.py index cd9659171c..0c92e99526 100755 --- a/os/tools/convert_binary.py +++ b/os/tools/convert_binary.py @@ -86,6 +86,12 @@ if common_bin_name != common_trpk_name : shutil.copyfile(output_folder + '/' + common_bin_name, output_folder + '/' + common_trpk_name) +# Convert resource binary to name stored in .bininfo +if util.check_config_existence(cfg_file, 'CONFIG_RESOURCE_FS') == True : + resource_bin_name = "resourcefs.img" + resource_trpk_name = util.get_binname_from_bininfo("RESOURCE") + if resource_bin_name != resource_trpk_name : + shutil.copyfile(output_folder + '/' + resource_bin_name, output_folder + '/' + resource_trpk_name) ############################################################################ # Convert kernel binary format to hex or srec diff --git a/os/tools/mkbinheader.py b/os/tools/mkbinheader.py index 2e1679fc92..6a8f6c241a 100755 --- a/os/tools/mkbinheader.py +++ b/os/tools/mkbinheader.py @@ -363,6 +363,62 @@ def make_common_binary_header(): fp.write(struct.pack('H', 0)) fp.write(data) +############################################################################ +# +# Resource binary header information : +# +# The total size is 4096 bytes but CRC value (4 bytes) will be prepended later. +# So now it makes header with (4096 - 4) bytes. +# +---------------------------------------------------------------------------------+ +# | Header size | Binary Version | Binary Size | Padding | +# | (2bytes) | (4bytes) | (4bytes) | (4096 - 14 bytes) | +# +---------------------------------------------------------------------------------+ +# +# parameter information : +# +# argv[1] is file path of binary file. +# argv[2] is binary type. +# +########################################################################### +def make_resource_binary_header(): + + SIZE_OF_TOTAL = 4096 + SIZE_OF_HEADERSIZE = 2 + SIZE_OF_BINVER = 4 + SIZE_OF_BINSIZE = 4 + + # Calculate binary header size + header_size = SIZE_OF_HEADERSIZE + SIZE_OF_BINVER + SIZE_OF_BINSIZE + + remain_size = SIZE_OF_TOTAL - header_size - 4 + + # Get binary version + bin_ver = util.get_value_from_file(cfg_path, "CONFIG_RESOURCE_BINARY_VERSION=").replace('"','').replace('\n','') + if bin_ver == 'None' : + print("Error : Not Found config for resource binary version, CONFIG_RESOURCE_BINARY_VERSION") + sys.exit(1) + bin_ver = int(bin_ver) + if bin_ver < 101 or bin_ver > 991231 : + print("Error : Invalid Resource Binary Version, ",bin_ver,".") + print(" Please check CONFIG_RESOURCE_BINARY_VERSION with 'YYMMDD' format in (101, 991231)") + sys.exit(1) + + with open(file_path, 'rb') as fp: + # binary data copy to 'data' + data = fp.read() + file_size = fp.tell() + fp.close() + + fp = open(file_path, 'wb') + + # Generate binary with header data + fp.write(struct.pack('H', header_size)) + fp.write(struct.pack('I', int(bin_ver))) + fp.write(struct.pack('I', file_size)) + # Add padding for total size 4 Kbytes + fp.write(b'\xff' * remain_size) + fp.write(data) + ############################################################################ # # Generate headers for binary types @@ -381,6 +437,8 @@ def make_common_binary_header(): make_user_binary_header() elif binary_type == 'common' : make_common_binary_header() +elif binary_type == 'resource' : + make_resource_binary_header() else : # Not supported. print("Error : Not supported Binary Type") sys.exit(1) diff --git a/os/tools/mkbootparam.py b/os/tools/mkbootparam.py index 9da956978d..37b3f39344 100755 --- a/os/tools/mkbootparam.py +++ b/os/tools/mkbootparam.py @@ -46,10 +46,14 @@ # | Checksum | BP Version | BP Format Version | Active Idx | First Address | Second Address | # | (4bytes) | (4bytes) | (4bytes) | (1byte) | (4bytes) | (4bytes) | # +------------------------------------------------------------------------------------------ -# ----------------------------------------------------------------------------------------------------------------------+ -# | App Count | App1 Name | App1 Active Idx | App2 Name | App2 Active Idx | App# ... | Reserved | -# | (1byte) | (16 bytes) | (1 bytes) | (16 bytes) | (1 bytes) | (## bytes) |(4Kbytes - (21 + @)bytes) | -# ----------------------------------------------------------------------------------------------------------------------+ +# -------------------------------------------------------------------------------------------- +# | App Count | App1 Name | App1 Active Idx | App2 Name | App2 Active Idx | App# ... | +# | (1byte) | (16 bytes) | (1 bytes) | (16 bytes) | (1 bytes) | (## bytes) | +# -------------------------------------------------------------------------------------------- +# ------------------------------------------------------------------+ +# | Resource Active Idx | Reserved | +# | (1 byte) | (4Kbytes - (23 + @)bytes) | +# ------------------------------------------------------------------+ # * The "Checksum" is crc32 value for data from "BP Version" to "Second Address". # * The "BP Version" is a version to check the latest of boot parameters. # * The "BP Format Version" is a version to manage the format of boot parameters. @@ -62,6 +66,10 @@ # - All user app have 2 partitions. # - If the value is 0, "First partition" will be loaded or is loaded. # - If the value is 1, "Second partition" will be loaded or is loaded. +# * The "Resource Active Idx" is a index indicating which partition to use for resource. +# - All resource have 2 partitions. +# - If the value is 0, "First partition" will be mounted. +# - If the value is 1, "Second partition" will be mounted. # ########################################################################################### @@ -131,13 +139,16 @@ def make_bootparam(): else: user_file_list = [] - app_data_size = 0 + total_app_data_size = 0 user_app_count = len(user_file_list) if user_app_count > 0: SIZE_OF_BINCOUNT = 1 SIZE_OF_BINNAME = 16 SIZE_OF_BINIDX = 1 - app_data_size = SIZE_OF_BINCOUNT + (user_app_count * (SIZE_OF_BINNAME + SIZE_OF_BINIDX)) + TOTAL_APP_COUNT = int(util.get_value_from_file(config_file_path, "CONFIG_NUM_APPS=")) + 1 + + total_app_data_size = SIZE_OF_BINCOUNT + TOTAL_APP_COUNT * (SIZE_OF_BINNAME + SIZE_OF_BINIDX) + remain_app_data_size = (TOTAL_APP_COUNT - user_app_count) * (SIZE_OF_BINNAME + SIZE_OF_BINIDX) with open(bootparam_file_path, 'a') as fp: # User Data @@ -145,10 +156,18 @@ def make_bootparam(): for user_file in user_file_list: fp.write('{:{}{}.{}}'.format(user_file, '<', SIZE_OF_BINNAME, SIZE_OF_BINNAME - 1).replace(' ','\0')) fp.write(struct.pack('B', INITIAL_ACTIVE_IDX)) + fp.write(b'\xff' * remain_app_data_size) + + # Resource Data + resource_data_size = 0 + if (util.check_config_existence(config_file_path, "CONFIG_RESOURCE_FS")) : + resource_data_size = 1 + with open(bootparam_file_path, 'a') as fp: + fp.write(struct.pack('B', INITIAL_ACTIVE_IDX)) # Fill remaining space with '0xff' with open(bootparam_file_path, 'a') as fp: - remain_size = SIZE_OF_BPx - (kernel_data_size + app_data_size) + remain_size = SIZE_OF_BPx - (kernel_data_size + total_app_data_size + resource_data_size) fp.write(b'\xff' * remain_size) # Add checksum for BP1 diff --git a/os/tools/set_bininfo.py b/os/tools/set_bininfo.py index fc5031a9c5..66528a9b8f 100755 --- a/os/tools/set_bininfo.py +++ b/os/tools/set_bininfo.py @@ -39,8 +39,8 @@ def save_bininfo(bin_name) : f.write('APP2_BIN_NAME=' + bin_name + '\n') elif ("common" in bin_name) : f.write('COMMON_BIN_NAME=' + bin_name + '\n') - elif ("bootparam" in bin_name) : - f.write('BOOTPARAM_BIN_NAME=' + bin_name + '\n') + elif ("resource" in bin_name) : + f.write('RESOURCE_BIN_NAME=' + bin_name + '\n') else : f.write('KERNEL_BIN_NAME=' + bin_name + '\n') @@ -84,6 +84,8 @@ def save_bininfo(bin_name) : COMMON_BIN_NAME = 'common_' + BOARD_TYPE + '_' + COMMON_BIN_VER save_bininfo(COMMON_BIN_NAME + '.' + TARGET_EXT_NAME) -# Set the boot parameter bin name as "bootparam.bin" -if util.check_config_existence(cfg_file, 'CONFIG_USE_BP') == True : - save_bininfo('bootparam' + '.' + BP_EXT_NAME) +# Set the resource bin name as "resource_[board]_[version]" +if util.check_config_existence(cfg_file, 'CONFIG_RESOURCE_FS') == True : + RESOURCE_BIN_VER = util.get_value_from_file(cfg_file, "CONFIG_RESOURCE_BINARY_VERSION=").replace('"','').rstrip('\n') + RESOURCE_BIN_NAME = 'resource_' + BOARD_TYPE + '_' + RESOURCE_BIN_VER + save_bininfo(RESOURCE_BIN_NAME + '.' + TARGET_EXT_NAME) diff --git a/resource/README.txt b/resource/README.txt new file mode 100644 index 0000000000..4ee78abdda --- /dev/null +++ b/resource/README.txt @@ -0,0 +1,5 @@ +Please put resources like audio files, images in /resource folder. +They would be located in "/res" folder on board. +For examples, + /resource/hello.txt -> /res/hello.txt + /resource/audio/sample.wav -> /res/audio/sample.wav \ No newline at end of file diff --git a/tools/fs/mkromfsimg.sh b/tools/fs/mkromfsimg.sh index 8794b90b09..d4f0dc7101 100755 --- a/tools/fs/mkromfsimg.sh +++ b/tools/fs/mkromfsimg.sh @@ -57,17 +57,11 @@ echo "Making romfs.img..." FSTOOL_PATH=`test -d ${0%/*} && cd ${0%/*}; pwd` # When location of this script is changed, only OS_PATH should be changed together!!! -OS_PATH=${FSTOOL_PATH}/../../os -BIN_PATH=${OS_PATH}/../build/output/bin -CONTENTS_PATH=${FSTOOL_PATH}/contents-romfs -ROMFS_IMG=${BIN_PATH}/romfs.img -# Sanity checks +CONTENTS_PATH=$1 +ROMFS_IMG=$2 -if [ ! -d "${CONTENTS_PATH}" ]; then - echo "ERROR: Directory ${CONTENTS_PATH} does not exist" - exit 1 -fi +# Sanity checks genromfs -h 1>/dev/null 2>&1 || { \ echo "Host executable genromfs not available in PATH"; \ @@ -75,9 +69,15 @@ genromfs -h 1>/dev/null 2>&1 || { \ exit 1; \ } -# Now we are ready to make the ROMFS image +if [ ! -d "${CONTENTS_PATH}" ]; then + # If directory doesn't exist, it doesn't create ROMFS image without error return + + echo "Directory ${CONTENTS_PATH} does not exist" +else + # Now we are ready to make the ROMFS image -genromfs -f ${ROMFS_IMG} -d ${CONTENTS_PATH} -x .gitignore -V "TinyAraROMVol" || { echo "genromfs failed" ; exit 1 ; } + genromfs -f ${ROMFS_IMG} -d ${CONTENTS_PATH} -x .gitignore -x README.txt -V "TinyAraROMVol" || { echo "genromfs failed" ; exit 1 ; } -# And, finally, create the header file -echo "${ROMFS_IMG} was made." + # And, finally, create the header file + echo "${ROMFS_IMG} was made." +fi