Introduction to romfs technology of AliOS Things

1 Overview

romfs is mainly used on Linux and some Unix-like systems. It has the characteristics of small size, good reliability, and high performance. It is very suitable for use in the stage of constructing the smallest kernel. AliOS Things also provides the romfs function, which is mainly used in scenarios such as read-only file systems and minimal systems in the microkernel stage.

The main features and uses of romfs are as follows:

  • Small size, saving resources, can be used when constructing the smallest kernel.
  • Read-only file system to prevent file content from being tampered with.
  • Files are stored in order, with high reading performance.
  • No need to write, simple operation and high reliability.
  • It can be driven independently and can be loaded independently.

 

2. Data storage of romfs

The romfs provided in AliOS Things packs files, directories and other data in a read-only code segment. Therefore, the romfs file system does not have a separate mirror, but is included in the kernel mirror. After the system starts, the user can access the data of the romfs file system through a specified data structure.

mkromfs.pyThe tool is a supporting conversion tool of romfs, which can convert directory tree data into a C language structure ( struct romfs_dirent), and users can access file data by accessing this type of structure variable.

The definition of the structure is as follows:

struct romfs_dirent
{
    uint32_t         type;  /* dirent type */
    const char       *name; /* dirent name */
    const uint8_t    *data; /* file date ptr */
    size_t           size;  /* file size */
};

Among them, type indicates the type, name, data pointer, data size and other information of an entry (each entry corresponds to a file or directory item).

The data and size pointed to by the entry differ depending on the type.

For example, a file type entry, its data pointer points to a binary array, the content of the array is the binary content of the file, and its size is the length of the file;

If it is a directory type entry, its data pointer points to a struct romfs_direntstructure, that is, the next directory record, size indicates the number of members in the directory record, and so on.

 

For example, the file and directory structure that needs to be packaged into romfs are as follows:

Screenshot 2020-12-11 20.19.51.png

After conversion by mkromfs.py tool, the generated C language file (components/fs/romfs/romfs.c) is as follows:

/* Generated by mkromfs. Edit with caution. */
#include "romfs_def.h"

static const uint8_t _romfs_root_README[] = {
    0x48,0x65,0x6c,0x6c,0x6f,0x20,0x48,0x61,0x61,0x73,0x0a
};

static const uint8_t _romfs_root_bin_README[] = {
    0x48,0x65,0x6c,0x6c,0x6f,0x77,0x6f,0x72,0x6c,0x64,0x0a
};

static const struct romfs_dirent _romfs_root_bin[] = {
    {ROMFS_DIRENT_FILE, "README", (uint8_t *)_romfs_root_bin_README, sizeof(_romfs_root_bin_README)/sizeof(_romfs_root_bin_README[0])}
};

static const struct romfs_dirent _romfs_root[] = {
    {ROMFS_DIRENT_FILE, "README", (uint8_t *)_romfs_root_README, sizeof(_romfs_root_README)/sizeof(_romfs_root_README[0])},
    {ROMFS_DIRENT_DIR, "bin", (uint8_t *)_romfs_root_bin, sizeof(_romfs_root_bin)/sizeof(_romfs_root_bin[0])}
};

const struct romfs_dirent romfs_root = {
    ROMFS_DIRENT_DIR, "/", (uint8_t *)_romfs_root, sizeof(_romfs_root)/sizeof(_romfs_root[0])
};

which is:

(1) Root directory information of romfs is recorded in a romfs_rootglobal variable named . This variable is a struct romfs_direnttype of structure variable, which records the following data of the root directory: type (DIR), name ("/"), data pointer (point to _romfs_rootvariable), data size.

(2) Through the data pointer, you can continue to access the members under the root directory (that is, the bin directory and the REAMDE file). For members in the root directory, each entry is a struct romfs_direnttype of structure variable.

(3) Through the first entry in _romfs_root, you can access the information of REAMDE files. The data pointer of the entry points to a named _romfs_root_REAMDEstructure variable whose type is FILE. _romfs_root_REAMDEThe content of the README file in the root directory (ie the binary data of the "Helloworld" string) is stored in it.

(4) Through _romfs_rootthe second entry, you can access the information in the bin directory. The data pointer of the entry points to a _romfs_root_binstructure variable named (DIR). _romfs_root_binThe data information in the bin directory is stored in.

(5) The _romfs_root_binstructure contains an entry, which is FILE type data, corresponding to the README file in the bin directory.

 

In summary, its working principle and basic process are as follows:

  1. The user prepares the directory to be packaged, which can contain files and subdirectories.
  2. Through the supporting mkromfs.pytools, the data in the packaging directory is converted into C language code, and the code is added to the romfs component for compilation.

Note : At present, the mkromfs packaging function has been integrated into the compilation process, that is, it will be automatically packaged during the compilation process, and there is no need to handle it manually. You only need to copy the problems that need to be packaged to the components/fs/romfs/rootfsdirectory before compilation .

  1. Users (usually file system modules, and end users access romfs through the posix interface) romfs_rootaccess the root directory through variables.
  2. Through the entry information recorded in the root directory, gradually expand the romfs directory tree, you can access the file data in the root directory and its subdirectories accordingly

 

3. romfs file access

The romfs file system will be registered to the VFS virtual file system (mount path is /) during the system initialization phase . The application layer does not need to pay attention to the data structure introduced in the previous chapter, but access the directories and files in romfs through the standard posix interface.

 

The following figure shows the basic process of romfs file registration and access.

Screenshot 2020-12-11 21.13.19.png

The following example shows how to add logic to access romfs based on helloworld_demo.

 

1. Modify the application/example/helloworld_demo/aos.mk file and add the romfs component dependency.

diff --git a/application/example/helloworld_demo/aos.mk b/application/example/helloworld_demo/aos.mk
index 233896d..a5db41b 100644
--- a/application/example/helloworld_demo/aos.mk
+++ b/application/example/helloworld_demo/aos.mk
@@ -5,7 +5,7 @@ $(NAME)_VERSION := 1.0.1
 $(NAME)_SUMMARY := helloworld demo
 $(NAME)_SOURCES := maintask.c appdemo.c

-$(NAME)_COMPONENTS += osal_aos
+$(NAME)_COMPONENTS += osal_aos romfs

 GLOBAL_DEFINES += AOS_NO_WIFI

2. Modify the application/example/helloworld_demo/appdemo.c file, add romfs file test logic, and read /bin/READMEthe content of the file in romfs .

diff --git a/application/example/helloworld_demo/appdemo.c b/application/example/helloworld_demo/appdemo.c
index 50b153e..7c9462b 100644
--- a/application/example/helloworld_demo/appdemo.c
+++ b/application/example/helloworld_demo/appdemo.c
@@ -8,6 +8,9 @@
 #include "aos/init.h"
 #include "board.h"
 #include <k_api.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>

 int application_start(int argc, char *argv[])
 {
@@ -18,6 +21,19 @@ int application_start(int argc, char *argv[])
     //fd = board_lcd_create("name");
     //board_lcd_write(fd,buffer,len);

+    int fd, ret;
+    const char *file = "/bin/README";
+    char fcontent[64] = {0};
+
+    fd = open(file, O_RDONLY);
+    if (fd >= 0) {
+        ret = read(fd, fcontent, sizeof(fcontent));
+        if (ret > 0) {
+            printf("Content read from file %s: %s\r\n", file, fcontent);
+        }
+        close(fd);
+    }
+
     while(1) {
         printf("hello world! count %d \r\n", count++);

3. Compile and burn the firmware. After the system is running, you will see the following printout:

Content read from file /bin/README: Helloworld

Note : romfs is a read-only file system, files do not support writing.

 

4. Summary

This article introduces the use and characteristics of romfs, and focuses on the data storage method of romfs in AliOS Things and the method of accessing romfs data at the application layer.

To learn more about AliOS Things, please join our DingTalk developer group.

For more technology and solution introduction, please visit the Aliyun AIoT homepage https://iot.aliyun.com/

Guess you like

Origin blog.csdn.net/HaaSTech/article/details/111828361