저장 장치(raw storage)라는 것은 기실 바이트들이 연속적으로 놓여있는 공간일 뿐이다.
그런데 사람이나 프로그램이 그런 바이트 덩어리를 직접 다루기는 어렵기 때문에, “파일” 이라는 단위로 나눠서 이름을 붙이고, 여러 파일을 “디렉토리” 라는 폴더 구조로 관리한다.
즉, 파일과 디렉토리라는 논리적 개념이 바로 파일 추상화이다.
Mapping
추상화 기법을 통해 얻은 논리적 공간이 의미를 가지려면 실제 공간에 매핑되어야 한다. (More precisely, group homomorphism - 군 동형 사상)
OS에서 배웠던 메모리 개념을 떠올려 보자. 이때 가상(논리) 메모리 주소를 물리 메모리 공간으로 매핑하는 주소 변환하는 과정에 대해 배웠다. 이는 논리 공간과 실제 공간 간의 매핑의 다른 예시이다.
즉, 가상 메모리가 ‘가상 주소 (page) → 페이지 테이블 → 물리 메모리 (frame)’ 의 매핑 구조를 가졌듯이,
파일 시스템은 ‘파일 이름 (file) → 파일 테이블 → 디스크 (blocks)’ 의 매핑 구조를 갖는다.
유의할 점은, 페이지와 프레임은 일대일 매핑 관계지만, 파일과 블록은 하나의 파일에 여러 블록이 연결될 수 있음으로써, 파일의 크기가 자유롭게 이뤄진다. (윈도우에서 폴더 속성을 들어가 보면, 디스크 할당 크기와 파일 크기가 다를 때가 있었는데 그 이유를 알것 같다.)
이러한 추상화를 통해 프로세스(유저)는 데이터를 더 쉽게 다룰 수 있게 된다.
+ Privileged Instruction / MMIO와의 관계
앞서 배운 개념과 혼동할 수 있기 때문에 정확히 구분하고 넘어가려 한다.
CPU는 반드시 메모리(RAM)에서만 데이터를 읽을 수 있다.
따라서 프로세스가 파일에 접근한다는 것은 결국 내부적으로 CPU를 통해 RAM에 저장된 데이터에 접근하는 것이다. 이전 시간에 다뤘던 부분은 IO 접근의 구체적인 메커니즘을 CPU가 바라보는 메모리 관점에서 배웠던 것이다.
File Descriptor
파일 접근 시에 커널은 파일 디스크립터를 통해 접근한다.
파일 디스크립터는 작은 정수로 정의되는데, open file table의 인덱스를 가리킨다.
‘작은’ 정수인 이유는 테이블이 프로세스마다 정의되기 때문이다.
테이블이 프로세스마다 정의될 수 있는 이유는 무엇일까?
그것은 파일을 열 때, 프로세스가 이용되기 때문이다.
예컨대 텍스트 파일은 텍스트 뷰어로 열거나 코드 뷰어로 열거나 할 수 있다. 또한 이미지 파일이나 비디오 파일 등 다양한 파일 들은 프로세스를 통해 열린다.
이런식으로 구분함으로써 프로세스간의 프로텍트 도메인을 지킬 수 있다.