JFFS2 파일시스템의 CLEANMARKER 메세지에 대하여
- 작성자
- 고친과정
2010년 7월 20일 : 처음씀
1.1. JFFS2 파일시스템의 CLEANMARKER의 역할
JFFS2 파일시스템은 노드(Node)의 연속으로 배열된 Log-structured 방식의 파일시스템으로 설계되어 있습니다. 하나의 노드는 다음과 같은 형식으로 구성됩니다.
여기서 Node Type의 값이 0x2003인 경우가 CLEANMARKER로 정의됩니다. CLEANMARKER는 각각의 Erase block의 선두에 만들어지게 되는데 이것은 Erase block이 유효한가를 나타냅니다. Flash의 Erase block의 선두가 CLEANMARKER가 아니고 하나의 bit라도 0인 경우는 Bad block으로 간주하여 처리됩니다. Flash에 jffs2 파일시스템을 write 시에 Erase block이 모두 0FFH로 채우거나(즉, 값이 0인 bit가 없는 상태) CLEANMARKER를 Erase block의 선두에 저장해야 합니다. 만약 Bad block인 경우 jffs2 image는 그 block크기만큼 Shift되어 저장하게 되며 Bad block을 자연스럽게 인지할수 있게 됩니다.
이러한 CLEANMARKER는 JFFS1에서는 없는 사양이며 JFFS2에서 제시된 사양입니다.
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Magic Bitmask (=0x1985) | Node Type | ||||||||||||||
Total Node Length | |||||||||||||||
Node Header CRC |
여기서 Node Type의 값이 0x2003인 경우가 CLEANMARKER로 정의됩니다. CLEANMARKER는 각각의 Erase block의 선두에 만들어지게 되는데 이것은 Erase block이 유효한가를 나타냅니다. Flash의 Erase block의 선두가 CLEANMARKER가 아니고 하나의 bit라도 0인 경우는 Bad block으로 간주하여 처리됩니다. Flash에 jffs2 파일시스템을 write 시에 Erase block이 모두 0FFH로 채우거나(즉, 값이 0인 bit가 없는 상태) CLEANMARKER를 Erase block의 선두에 저장해야 합니다. 만약 Bad block인 경우 jffs2 image는 그 block크기만큼 Shift되어 저장하게 되며 Bad block을 자연스럽게 인지할수 있게 됩니다.
이러한 CLEANMARKER는 JFFS1에서는 없는 사양이며 JFFS2에서 제시된 사양입니다.
1.2. 문제해결
다음과 같은 메세지를 보는 경우는 실제 Flash의 Erase block size와 mkfs.jffs2를 이용해서 주어진 erase block size의 크기가 일치하지 않아서 발생합니다.
예를 들어서 Erase block size를 8KBytes로 가정하고 mkfs.jffs2로 image를 만든었다면 다음과 같이 만들게 될겁니다.
이것을 실제 Erase block size 가 64KBytes 인 Flash에 굽게 되면 다음과 같은 메세지가 나옵니다. 여기서 중요한것은 일정한 간격으로 Offset이 나오다가 실제 Erase block의 시작점에서는 해당 메세지가 없다는 점입니다. 아래의 경우는 Offset 00010000H 간격으로 해당 메세지가 없는것을 알수 있고 이는 곧 64KBytes 단위의 Erase block size 이어야 한다는 것을 알수 있습니다.
그래서 결국은 mkfs.jffs2는 다음과 같이 사용되어야 맞게 됩니다.
CLEANMARKER node found at 0x%08x, not first node in block (0x%08x)
예를 들어서 Erase block size를 8KBytes로 가정하고 mkfs.jffs2로 image를 만든었다면 다음과 같이 만들게 될겁니다.
mkfs.jffs2 -o myroot.jffs2 -e 8192 -d <rootfsEntry>
이것을 실제 Erase block size 가 64KBytes 인 Flash에 굽게 되면 다음과 같은 메세지가 나옵니다. 여기서 중요한것은 일정한 간격으로 Offset이 나오다가 실제 Erase block의 시작점에서는 해당 메세지가 없다는 점입니다. 아래의 경우는 Offset 00010000H 간격으로 해당 메세지가 없는것을 알수 있고 이는 곧 64KBytes 단위의 Erase block size 이어야 한다는 것을 알수 있습니다.
Empty flash at 0x00000ffc ends at 0x00001000 CLEANMARKER node found at 0x00001000, not first node in block (0x00000000) Empty flash at 0x00001ffc ends at 0x00002000 CLEANMARKER node found at 0x00002000, not first node in block (0x00000000) Empty flash at 0x00002f58 ends at 0x00003000 CLEANMARKER node found at 0x00003000, not first node in block (0x00000000) Empty flash at 0x00003f70 ends at 0x00004000 CLEANMARKER node found at 0x00004000, not first node in block (0x00000000) Empty flash at 0x00004f70 ends at 0x00005000 CLEANMARKER node found at 0x00005000, not first node in block (0x00000000) Empty flash at 0x00005ffc ends at 0x00006000 CLEANMARKER node found at 0x00006000, not first node in block (0x00000000) Empty flash at 0x00006ffc ends at 0x00007000 CLEANMARKER node found at 0x00007000, not first node in block (0x00000000) Empty flash at 0x00007ffc ends at 0x00008000 CLEANMARKER node found at 0x00008000, not first node in block (0x00000000) Empty flash at 0x00008ffc ends at 0x00009000 CLEANMARKER node found at 0x00009000, not first node in block (0x00000000) Empty flash at 0x00009ffc ends at 0x0000a000 CLEANMARKER node found at 0x0000a000, not first node in block (0x00000000) Empty flash at 0x0000affc ends at 0x0000b000 CLEANMARKER node found at 0x0000b000, not first node in block (0x00000000) Empty flash at 0x0000bffc ends at 0x0000c000 CLEANMARKER node found at 0x0000c000, not first node in block (0x00000000) Empty flash at 0x0000cffc ends at 0x0000d000 CLEANMARKER node found at 0x0000d000, not first node in block (0x00000000) Empty flash at 0x0000dffc ends at 0x0000e000 CLEANMARKER node found at 0x0000e000, not first node in block (0x00000000) Empty flash at 0x0000effc ends at 0x0000f000 CLEANMARKER node found at 0x0000f000, not first node in block (0x00000000) Empty flash at 0x00010ffc ends at 0x00011000 /* 이 시점에서 Offset 00010000H에 대한 메세지가 안보인다는 점이 우리가 인지해야 하는 부분입니다. */ CLEANMARKER node found at 0x00011000, not first node in block (0x00010000) Empty flash at 0x00011f90 ends at 0x00012000 CLEANMARKER node found at 0x00012000, not first node in block (0x00010000) Empty flash at 0x00012f40 ends at 0x00013000 CLEANMARKER node found at 0x00013000, not first node in block (0x00010000) Empty flash at 0x00013f64 ends at 0x00014000 CLEANMARKER node found at 0x00014000, not first node in block (0x00010000) Empty flash at 0x00014ffc ends at 0x00015000 CLEANMARKER node found at 0x00015000, not first node in block (0x00010000) Empty flash at 0x00015ffc ends at 0x00016000
그래서 결국은 mkfs.jffs2는 다음과 같이 사용되어야 맞게 됩니다.
mkfs.jffs2 -o myroot.jffs2 -s 4096 -e 65536 -d <rootfsEntry>
1.3. 참고자료
- http://www.linux-mtd.infradead.org/ (jffs2.pdf)
- JFFS 이미지 생성
$ mkfs.jffs2 -o usr.jffs -e 0x40000 -r ~/work/tmp/mystage3-rootfs
- '-o <생성 파일 이름>'
- '-e <Flash erase block size>'
- '-r <대상 디랙토리>'