• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# JFFS2<a name="EN-US_TOPIC_0000001123521625"></a>
2
3-   [Basic Concepts](#section11411110155919)
4-   [Working Principles](#section23911025195913)
5-   [Development Guidelines](#section179711119014)
6
7## Basic Concepts<a name="section11411110155919"></a>
8
9Journalling Flash File System Version 2 \(JFFS2\) is a log-structured file system designed for Memory Technology Devices \(MTDs\).
10
11JFFS2 is used on the NOR flash memory of the OpenHarmony. JFFS2 is readable and writable, supports data compression, provides crash/power failure protection, and supports wear leveling. There are many differences between flash memory and disk media. Running a disk file system on a flash memory device will lead to performance and security problems. JFFS2 is a file system optimized for flash memory.
12
13## Working Principles<a name="section23911025195913"></a>
14
15This document does not include the physical layout of JFFS2 on storage devices and JFFS2 specifications. For details, see the  [official JFFS2 specification document](https://sourceware.org/jffs2/).
16
17The following describes several important mechanisms and features of JFFS2 that developers may concern.
18
191.  Mount mechanism and speed: According to the JFFS2 design, all files are divided into nodes of different sizes based on certain rules and stored on the flash memory device in sequence. In the mount process, all node information needs to be obtained and cached in the memory. Therefore, the mount speed is in linear proportion to the flash device capacity and the number of files. This is a native design issue of JFFS2. To increase the mount speed, you can select  **Enable JFFS2 SUMMARY**  during kernel compilation. If this option is selected, information required by the mount operation will be stored to the flash memory in advance. When the mount operation is performed, this information can be read and parsed quickly, ensuring relatively constant mount speed. However, this space-for-time practice consumes about 8% extra space.
202.  Wear leveling: Due to the physical attributes of flash memory devices, read and write operations can be performed only on blocks of a specific size. To prevent certain blocks from being severely worn, wear leveling is used on written blocks in JFFS2 to ensure relatively balanced writes on all blocks. This prolongs the overall service life of the flash memory devices.
213.  Garbage collection \(GC\) mechanism: When a deletion operation is performed in JFFS2, the physical memory is not released immediately. An independent GC thread performs GC operations such as space defragmentation and migration. However, GC in JFFS2 affects instantaneous read/write performance, like all GC mechanisms. In addition, JFFS2 reserves about three blocks in each partition for space defragmentation. The reserved space is invisible to users.
224.  Compression mechanism: The underlying layer automatically decompresses or compresses the data read or written each time in JFFS2. The actual I/O size is different from the read or write size requested by the user. You cannot estimate whether the write operation will succeed or not based on the size of the written data and the remaining space of the flash memory.
235.  Hard link mechanism: JFFS2 supports hard links. Multiple hard links of the same file occupy physical memory space of only one hard link. The physical space is released only when all hard links are deleted.
24
25## Development Guidelines<a name="section179711119014"></a>
26
27The development based on JFFS2 and NOR flash memory is similar to the development based on other file systems because the VFS shields the differences of specific file systems and the standard POSIX APIs are used as external APIs.
28
29The raw NOR flash device has no place to centrally manage and record partition information. Therefore, you need to transfer the partition information by using other configuration methods \(using the  **bootargs**  parameter during image burning\), call the corresponding API in the code to add partitions, and then mount the partitions.
30
31**Creating a JFFS2 Image**
32
33Use the  **mkfs.jffs2**  tool to create an image. The default page size is 4 KiB, and the default  **eraseblock**  size is 64 KiB. Modify the parameter values to match your development.
34
35```
36./mkfs.jffs2 -d rootfs/ -o rootfs.jffs2
37```
38
39**Table  1**  Command description \(run  **mkfs.jffs2 --help**  to view more details\)
40
41<a name="table1925613541465"></a>
42<table><thead align="left"><tr id="row325613545615"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p153851336772"><a name="p153851336772"></a><a name="p153851336772"></a>Command</p>
43</th>
44<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p43852366714"><a name="p43852366714"></a><a name="p43852366714"></a>Description</p>
45</th>
46</tr>
47</thead>
48<tbody><tr id="row125715410619"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p20385103615715"><a name="p20385103615715"></a><a name="p20385103615715"></a>-s</p>
49</td>
50<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1338510362717"><a name="p1338510362717"></a><a name="p1338510362717"></a>Specifies the page size. If this parameter is not specified, the default value <strong id="b3814183173513"><a name="b3814183173513"></a><a name="b3814183173513"></a>4KiB</strong> is used.</p>
51</td>
52</tr>
53<tr id="row787741814720"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p538673616710"><a name="p538673616710"></a><a name="p538673616710"></a>-e</p>
54</td>
55<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p6386123612719"><a name="p6386123612719"></a><a name="p6386123612719"></a>Specifies the <strong id="b56716452412"><a name="b56716452412"></a><a name="b56716452412"></a>eraseblock</strong> size. If this parameter is not specified, the default value <strong id="b17480133411354"><a name="b17480133411354"></a><a name="b17480133411354"></a>64KiB</strong> is used.</p>
56</td>
57</tr>
58<tr id="row1160020211719"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p83861361079"><a name="p83861361079"></a><a name="p83861361079"></a>-p</p>
59</td>
60<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1491185544517"><a name="p1491185544517"></a><a name="p1491185544517"></a>Specifies the image size. 0xFF is filled at the end of the image file to make the file to the specified size. If the size is not specified, 0xFF is filled to a value aligned with <strong id="b6777155933718"><a name="b6777155933718"></a><a name="b6777155933718"></a>eraseblock</strong>.</p>
61</td>
62</tr>
63<tr id="row151563245714"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p183864361579"><a name="p183864361579"></a><a name="p183864361579"></a>-d</p>
64</td>
65<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p238618361573"><a name="p238618361573"></a><a name="p238618361573"></a>Specifies the source directory of the file system image.</p>
66</td>
67</tr>
68<tr id="row1323210319714"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p103867369710"><a name="p103867369710"></a><a name="p103867369710"></a>-o</p>
69</td>
70<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1938603617710"><a name="p1938603617710"></a><a name="p1938603617710"></a>Specifies the image name.</p>
71</td>
72</tr>
73</tbody>
74</table>
75
76**Mounting a JFFS2 Partition**
77
78Call  **int mount\(const char \*source, const char \*target, const char \*filesystemtype, unsigned long mountflags, const void \*data\)**  to mount the device node and mount point.
79
80This function has the following parameters:
81
82-   **const char \*source**  specifies the device node.
83-   **const char \*target**  specifies the mount point.
84-   **const char \*filesystemtype**  specifies the file system type.
85-   **unsigned long mountflags**  specifies the mount flag, which is  **0**  by default.
86-   **const void \*data**  specifies the data, which is  **NULL**  by default.
87
88You can also run the  **mount**  command in  **shell**  to mount a JFFS2 partition. You do not need to specify the last two parameters.
89
90Run the following command:
91
92```
93OHOS # mount /dev/spinorblk1 /jffs1 jffs2
94```
95
96If the following information is displayed, the JFFS2 partition is mounted:
97
98```
99OHOS # mount /dev/spinorblk1 /jffs1 jffs2
100mount OK
101```
102
103Now, you can perform read and write operations on the NOR flash memory.
104
105**Unmounting a JFFS2 Partition**
106
107Call  **int umount\(const char \*target\)**  to unmount a partition. You only need to specify the correct mount point.
108
109Run the following command:
110
111```
112OHOS # umount /jffs1
113```
114
115If the following information is displayed, the JFFS2 partition is unmounted:
116
117```
118OHOS # umount /jffs1
119umount ok
120```
121
122