From 23aef2d7b4804bc880f3663c405f13d5769dcc8d Mon Sep 17 00:00:00 2001 From: guohao15 Date: Thu, 25 Apr 2024 18:37:56 +0800 Subject: [PATCH] romfs:extend romfs to enable write part3 add romfs_mkfs to support autoformat && forceformat Signed-off-by: guohao15 --- fs/romfs/fs_romfs.c | 47 ++++++++++--- fs/romfs/fs_romfs.h | 2 + fs/romfs/fs_romfsutil.c | 142 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 171 insertions(+), 20 deletions(-) diff --git a/fs/romfs/fs_romfs.c b/fs/romfs/fs_romfs.c index 4797f7b2cd..3cbcddf287 100644 --- a/fs/romfs/fs_romfs.c +++ b/fs/romfs/fs_romfs.c @@ -1124,6 +1124,18 @@ static int romfs_bind(FAR struct inode *blkdriver, FAR const void *data, goto errout_with_mount; } +#ifdef CONFIG_FS_ROMFS_WRITEABLE + if (data && strstr(data, "rw") && strstr(data, "forceformat")) + { + ret = romfs_mkfs(rm); + if (ret < 0) + { + ferr("ERROR: romfs_mkfs failed: %d\n", ret); + goto errout_with_buffer; + } + } +#endif + /* Then complete the mount by getting the ROMFS configuratrion from * the ROMF header */ @@ -1131,8 +1143,29 @@ static int romfs_bind(FAR struct inode *blkdriver, FAR const void *data, ret = romfs_fsconfigure(rm, data); if (ret < 0) { - ferr("ERROR: romfs_fsconfigure failed: %d\n", ret); - goto errout_with_buffer; +#ifdef CONFIG_FS_ROMFS_WRITEABLE + if (data && strstr(data, "rw") && strstr(data, "autoformat")) + { + ret = romfs_mkfs(rm); + if (ret < 0) + { + ferr("ERROR: romfs_format failed: %d\n", ret); + goto errout_with_buffer; + } + + ret = romfs_fsconfigure(rm, data); + if (ret < 0) + { + ferr("ERROR: romfs_fsconfigure failed: %d\n", ret); + goto errout_with_buffer; + } + } + else +#endif + { + ferr("ERROR: romfs_fsconfigure failed: %d\n", ret); + goto errout_with_buffer; + } } /* Mounted! */ @@ -1141,10 +1174,7 @@ static int romfs_bind(FAR struct inode *blkdriver, FAR const void *data, return OK; errout_with_buffer: - if (!rm->rm_xipbase) - { - fs_heap_free(rm->rm_buffer); - } + fs_heap_free(rm->rm_devbuffer); errout_with_mount: nxrmutex_destroy(&rm->rm_lock); @@ -1231,10 +1261,7 @@ static int romfs_unbind(FAR void *handle, FAR struct inode **blkdriver, /* Release the mountpoint private data */ - if (!rm->rm_xipbase) - { - fs_heap_free(rm->rm_buffer); - } + fs_heap_free(rm->rm_devbuffer); #ifdef CONFIG_FS_ROMFS_CACHE_NODE romfs_freenode(rm->rm_root); diff --git a/fs/romfs/fs_romfs.h b/fs/romfs/fs_romfs.h index b066d0adf2..5906f68e83 100644 --- a/fs/romfs/fs_romfs.h +++ b/fs/romfs/fs_romfs.h @@ -154,6 +154,7 @@ struct romfs_mountpt_s uint32_t rm_cachesector; /* Current sector in the rm_buffer */ FAR uint8_t *rm_xipbase; /* Base address of directly accessible media */ FAR uint8_t *rm_buffer; /* Device sector buffer, allocated if rm_xipbase==0 */ + FAR uint8_t *rm_devbuffer; /* Device sector buffer, allocated for write if rm_xipbase != 0 */ #ifdef CONFIG_FS_ROMFS_WRITEABLE struct list_node rm_sparelist; /* The list of spare space */ #endif @@ -231,6 +232,7 @@ int romfs_datastart(FAR struct romfs_mountpt_s *rm, void romfs_freenode(FAR struct romfs_nodeinfo_s *node); #endif #ifdef CONFIG_FS_ROMFS_WRITEABLE +int romfs_mkfs(FAR struct romfs_mountpt_s *rm); void romfs_free_sparelist(FAR struct list_node *list); #endif diff --git a/fs/romfs/fs_romfsutil.c b/fs/romfs/fs_romfsutil.c index a040e97385..c8d73dc786 100644 --- a/fs/romfs/fs_romfsutil.c +++ b/fs/romfs/fs_romfsutil.c @@ -408,7 +408,7 @@ static FAR struct romfs_sparenode_s * romfs_alloc_sparenode(uint32_t start, uint32_t end) { FAR struct romfs_sparenode_s *node; - node = kmm_malloc(sizeof(struct romfs_sparenode_s)); + node = fs_heap_malloc(sizeof(struct romfs_sparenode_s)); if (node == NULL) { ferr("romfs_alloc_sparenode: no memory\n"); @@ -474,7 +474,7 @@ static int romfs_alloc_spareregion(FAR struct list_node *list, /* Delete the node */ list_delete(&node->node); - kmm_free(node); + fs_heap_free(node); return 0; } else if (start == node->start) @@ -514,6 +514,78 @@ static int romfs_alloc_spareregion(FAR struct list_node *list, end); return -ENOENT; } + +/**************************************************************************** + * Name: romfs_devwrite32 + * + * Description: + * Write the big-endian 32-bit value to the mount device buffer + * + ****************************************************************************/ + +static void romfs_devwrite32(FAR struct romfs_mountpt_s *rm, + int ndx, uint32_t value) +{ + /* Write the 32-bit value to the specified index in the buffer */ + + rm->rm_devbuffer[ndx] = (uint8_t)(value >> 24) & 0xff; + rm->rm_devbuffer[ndx + 1] = (uint8_t)(value >> 16) & 0xff; + rm->rm_devbuffer[ndx + 2] = (uint8_t)(value >> 8) & 0xff; + rm->rm_devbuffer[ndx + 3] = (uint8_t)(value & 0xff); +} + +/**************************************************************************** + * Name: romfs_hwwrite + * + * Description: + * Write the specified number of sectors to the block device + * + ****************************************************************************/ + +static int romfs_hwwrite(FAR struct romfs_mountpt_s *rm, FAR uint8_t *buffer, + uint32_t sector, unsigned int nsectors) +{ + FAR struct inode *inode = rm->rm_blkdriver; + ssize_t ret = -ENODEV; + + if (inode->u.i_bops->write) + { + ret = inode->u.i_bops->write(inode, buffer, sector, nsectors); + } + + if (ret == (ssize_t)nsectors) + { + ret = OK; + } + + return ret; +} + +/**************************************************************************** + * Name: romfs_devcachewrite + * + * Description: + * Write the specified sector for specified offset into the sector cache. + * + ****************************************************************************/ + +static int romfs_devcachewrite(FAR struct romfs_mountpt_s *rm, + uint32_t sector) +{ + int ret; + + ret = romfs_hwwrite(rm, rm->rm_devbuffer, sector, 1); + if (ret == OK) + { + rm->rm_cachesector = sector; + } + else + { + rm->rm_cachesector = (uint32_t)-1; + } + + return ret; +} #endif /**************************************************************************** @@ -800,6 +872,14 @@ int romfs_hwconfigure(FAR struct romfs_mountpt_s *rm) rm->rm_cachesector = (uint32_t)-1; + /* Allocate the device cache buffer for normal sector accesses */ + + rm->rm_devbuffer = fs_heap_malloc(rm->rm_hwsectorsize); + if (!rm->rm_devbuffer) + { + return -ENOMEM; + } + if (inode->u.i_bops->ioctl) { ret = inode->u.i_bops->ioctl(inode, BIOC_XIPBASE, @@ -816,14 +896,9 @@ int romfs_hwconfigure(FAR struct romfs_mountpt_s *rm) } } - /* Allocate the device cache buffer for normal sector accesses */ - - rm->rm_buffer = fs_heap_malloc(rm->rm_hwsectorsize); - if (!rm->rm_buffer) - { - return -ENOMEM; - } + /* The device cache buffer for normal sector accesses */ + rm->rm_buffer = rm->rm_devbuffer; return OK; } @@ -843,7 +918,7 @@ void romfs_free_sparelist(FAR struct list_node *list) list_for_every_entry_safe(list, node, tmp, struct romfs_sparenode_s, node) { list_delete(&node->node); - kmm_free(node); + fs_heap_free(node); } } #endif @@ -1343,3 +1418,50 @@ int romfs_datastart(FAR struct romfs_mountpt_s *rm, return -EINVAL; /* Won't get here */ #endif } + +#ifdef CONFIG_FS_ROMFS_WRITEABLE + +/**************************************************************************** + * Name: romfs_mkfs + * + * Description: + * Format the romfs filesystem + * + ****************************************************************************/ + +int romfs_mkfs(FAR struct romfs_mountpt_s *rm) +{ + /* Write the magic number at that identifies this as a ROMFS filesystem */ + + memcpy(rm->rm_devbuffer + ROMFS_VHDR_ROM1FS, ROMFS_VHDR_MAGIC, + ROMFS_VHDR_SIZE); + + /* Init the ROMFS volume to zero */ + + romfs_devwrite32(rm, ROMFS_VHDR_SIZE, 0); + + /* Write the volume name */ + + memcpy(rm->rm_devbuffer + ROMFS_VHDR_VOLNAME, "romfs", 6); + + /* Write the root node . */ + + romfs_devwrite32(rm, 0x20 + ROMFS_FHDR_NEXT, 0x40 | RFNEXT_DIRECTORY); + romfs_devwrite32(rm, 0x20 + ROMFS_FHDR_INFO, 0x20); + romfs_devwrite32(rm, 0x20 + ROMFS_FHDR_SIZE, 0); + romfs_devwrite32(rm, 0x20 + ROMFS_FHDR_CHKSUM, 0); + memcpy(rm->rm_devbuffer + 0x20 + ROMFS_FHDR_NAME, ".", 2); + + /* Write the root node .. */ + + romfs_devwrite32(rm, 0x40 + ROMFS_FHDR_NEXT, RFNEXT_HARDLINK); + romfs_devwrite32(rm, 0x40 + ROMFS_FHDR_INFO, 0x20); + romfs_devwrite32(rm, 0x40 + ROMFS_FHDR_SIZE, 0); + romfs_devwrite32(rm, 0x40 + ROMFS_FHDR_CHKSUM, 0); + memcpy(rm->rm_devbuffer + 0x40 + ROMFS_FHDR_NAME, "..", 3); + + /* Write the buffer to sector zero */ + + return romfs_devcachewrite(rm, 0); +} +#endif