우리는 컴퓨터를 사용할때 윈도우 탐색기와 같은 프로그램을 이용해서 파일을 찾고, 실행하고 복사하고 저장한다. 이것이 파일시스템을 사용하는 것이다. 윈도우 탐색기는 파일시스템을 사용할 수 있는 일종의 툴(Tool) 내지는 프로그램인 셈이다. 너무나 보편적인 기능이지만 과거 임베디드 세계에서는 파일 시스템은 그리 많이 사용되지 않았다.
파일 시스템이 많은 파일을 효율적으로 관리하기 위해 탄생했다는 것을 염두에 둔다면, 가벼운 임베디드 디바이스에서는 파일시스템을 사용할 이유가 별로 없다. RTOS를 사용하는 전통적인 임베디드 디바이스의 저장장치는 파일구조가 아닌 플래쉬(Flash Memory)의 블록 (Block) 단위로 데이터를 관리한다.
임베디드 세계에서도 리눅스Linux가 RTOS를 대체하면서부터는 파일시스템이 보편적으로 사용되게 되었다.
그래서 임베디드 기기의 파일시스템이라 하면, 통상 유닉스Unix나 리눅스의 파일 시스템을 말한다.
이 글에서는 리눅스를 기준으로 파일 시스템을 설명하고자 한다.
가장 먼저 알아야 할 두 개념을 살펴 보자
말 그대로 뿌리가 되는 파일 시스템이다, 가장 상위에 있는 파일 시스템으로 운영체제가 시작하면서 맨먼저 로딩하는 파일시스템을 말한다.
이 루트파일시스템의 최상위 디렉토리는 /로 표시한다. root directory라고 부른다.
이 루트파일시스템은 특정한 파일시스템 포멧(NTFS, EXT4, FAT32 등과 같은)을 말하는 것이 아니니 헷갈리지 말자. 루트파일시스템은 운영체제에서 사용하는 최상위의 파일 시스템으로 여러가지 포멧이 사용가능하다.
이 루트 디렉토리(/) 아래로 bin, proc, usr, home, mnt 등의 여러 서브 디렉토리들이 존재한다. 각각의 디렉토리들은 시스템에서 각기 다른 역할을 가지고 있다. 각각의 디렉토리에는 소프트웨어의 실행에 필요한 각종 라이브러리들과 실행파일들, 그리고 그 데이터 파일들이 존재한다.
마운트는 특정파일시스템을 로딩(Loading)하는 것을 말한다. 운영체제, 즉 리눅스가 시작하면서 가장 먼저 로딩하는 파일 시스템이 루트파일시스템이라는 이야기는 이미 했다. 운영체제가 루트파일 시스템을 로딩하는 것을 운영체제가 루트파일시스템을 마운트한다고 말한다. 임베디드 파일시스템에서 마운트는 한번 이상 이루어질 수 있다. 루트파일시스템의 서브디렉토리에 또다른 파일시스템을 마운트할수 있다는 얘기다. 대표적인 것이 /mnt 디렉토리다.
이 mnt 디렉토리 이름은 글자에서 알수 있듯이 mount의 약자다. 통상 이 디렉토리에 각종 파일 시스템들을 마운팅해서 사용한다. 마운팅하는 파일시스템은 오만가지다. 특정 플래쉬 메모리 장치에 들어있는 JFFS2 파일시스템이 될수도 있고, 하드디스크의 EXT4 파일 시스템이 될 수도, USB메모리스틱에 들어있는 FAT32 파일시스템이 될 수도, 아니면 네트워크를 통해 다른 PC의 디렉토리를 마운팅하는 NFS(Network File System)이 될 수 도 있다.
그럼 임베디드 세계에서 많이 사용되는 대표적인 파일 시스템 포멧에 대해서 간략히 살펴보자.
통상적으로 어떤 물리적인 매체이냐에 따라서 각각에 적합한 파일시스템 포멧이 사용된다.
예를 들어 소용량의 플래쉬 메모리의 경우에는 CramFS나 JFFS2가 보편적으로 사용된다. JFFS2는 읽기와 쓰기 모두 가능한 파일시스템이고, CramFS는 읽기만 가능한 read-only 파일시스템이다. 플래쉬메모리에 사용되는 또다른 대표적인 read-only 파일시스템으로 SquashFS이 있다. SquashFS의 경우 압축율이 좋은 것으로 알려져 있다. 플래쉬메모리의 타입에 따라서도 적합한 파일시스템을 나눌수 있다. JFFS2는 소용량의 NOR 플래쉬 메모리에 적합하고, YAFFS2 파일시스템은 NAND 플래쉬와 같은 상대적으로 고용량의 플래쉬메모리에 적합하다.
이런 차이가 나는 이유는 플래쉬메모리를 마운팅하는데 소요되는 시간과 해당 파일시스템이 RAM메모리에서 차지하는 크기와 관련이 있다. 플래쉬 메모리가 크면 클수록 마운팅에 걸리는 시간과 RAM에 적재하는 메모리 크기가 커지기 마련이다. YAFFS2는 JFFS2보다 RAM메모리를 상대적으로 적게 사용하는 특징이 있다.
JFFS2와 YAFFS2의 단점들을 보완한 파일시스템이 UBIFS로 근래 임베디드 세계에서 많이 쓰이는 파일시스템이다. 마운팅타임은 줄이고, RAM 메모리적재 역시 줄임으로써 1GB이상의 대용량 플래쉬메모리에 적합한 파일시스템으로 널리 사용되고 있다. UBIFS는 MTD(Memory Techonolgy Device)에 기반하고 있다. 쉽게 말해 리눅스계열과 같이 MTD를 지원하는 운영체제에서만 사용이 가능하다는 단점이 있다.
이상에서 살펴본 파일시스템들은 보통 소프트웨어 이미지(software binary image & files)와 데이터 둘다 저장하는데 사용이 된다. 따로 업데이트가 필요없는 소프트웨어 파일과 데이터의 경우에는 read-only 파일시스템을 사용하는 것이 현명한 선택일수도 있다. 파일 시스템내에 데이터를 변경하는 것이 필요하다면 읽기/쓰기 모두 지원되는 파일시스템을 써야 한다. 다른 대안으로는 소프트웨어를 위한 read-only 파일시스템을 하나 쓰고, 쓰기가 필요한 데이터용으로 별도의 파일시스템을 쓰는 방법도 많이 사용된다. 동영상 비디오 데이터를 녹화하든지 하는 대용량의 데이터를 빈번하게 읽고 쓰는 경우에는 EXT4와 같이 멀티미디어 데이터 처리에 적합한 파일 시스템을 별도의 공간에 사용하는 것이 좋다.
이상 소개한 플래쉬 메모리와 같은 비휘발성 저장장치에 사용되는 파일시스템 외에도 파일 시스템의 종류는 굉장히 많다. RAM 메모리에 사용되는 RAM DISK 파일시스템, 앞서 잠깐 언급한 네트워크를 통해 다른 저장소를 사용가능한 NFS, 리눅스/유닉스에서 디바이스 제어를 위해 사용하는 proc 파일시스템과 같은 운영체제전용 파일시스템까지 다양하다.
아래 그림은 리눅스의 설정메뉴(menuconfig)에서 파일시스템에 대한 항목들이다.
어마무시하게 많은 항목을 볼 수 있다. 임베디드 소프트웨어 개발자로서 우리가 할 일은 주로 사용되는 파일 시스템에 대해 기본지식을 갖추고, 필요한 상황에서 적절히 활용하는 것이다. 파일 시스템의 내부적인 핵심 구조조(Architecture)나 코어(Core)를 변경하는 일은 거의 없으니, 파일시스템을 마운트하고 해당 파일시스템에서 제공하는 툴의 활용 정도가 임베디드 소프트웨어 개발자가 다루는 전부라고 보면 된다.