파일시스템

유닉스의 첫 출발은 파일시스템 구현에서 시작되었다. 파일시스템이란 디스크에 파일을 저장하고 관리하는 작업을 맡는 소프트웨어이다.

전자식 컴퓨터가 처음 등장했을 때, 외부의 데이터를 입력하고 출력하는 수단은 주로 펀치카드였다. 간단한 데이터는 콘솔이라고 불리는 계기판에서 스위치 조작을 통해 입력하기도 했고 출력은 전구를 통해 확인하기도 했지만, 많은 양의 데이터는 펀치카드 혹은 펀치테이프를 통해 입출력이 이루어졌다. 펀치카드는 그 자체가 하나의 저장장치 역할을 했다. 구멍이 뚫린 종이는 영구적으로 그 데이터가 유지되기 때문이다.

자기테이프가 등장하면서 데이터를 지우고 다시 쓸 수 있는 상황이 되었다. 자기테이프는 대량의 데이터를 저장할 수 있었으므로 하나의 자기테이프 내에 다른 용도의 데이터들을 저장하고 싶은 욕구는 당연했을 것이다. 다른 용도의 데이터 뭉치들을 구별할 필요성이 생겼고, 사무 환경에서 흔히 쓰는 용어였던 ‘파일’이 자연스럽게 사용되기 시작했다.

자기테이프는 순차적인 접근에 적합했으므로, 하나의 자기테이프에 저장되는 여러 개의 파일들은 순차적으로 위치하는 것이 합리적이었다. 1950년대 말에 자기디스크가 등장했다. 아마도 처음에는 자기테이프처럼 사용되었을 것이다. 하지만 임의접근이 가능하다는 장점을 살리기 위해서는 새로운 패러다임이 필요해졌다.


자기디스크에 가장 먼저 반응한 것은 데이터베이스였다. 찰스 바크먼​15​은 자기디스크를 사용해서 최초의 네트워크형 데이터베이스를 구현했다. 데이터베이스는 ‘레코드’라는 단위로 데이터를 관리한다. 따라서 파일시스템과 직접적인 관련은 없었다.

평면적으로 관리되던 파일들에 계층 구조를 부여한 첫 번째 시도는 멀틱스였다. 우리가 익숙해하는 디렉토리 구조가 멀틱스에서 처음 시도되었다. 그런데 멀틱스는 가상 메모리virtual memory 개념을 일반 데이터 파일에까지 확대 적용했다. 가상 메모리란, 실제 장착된 물리적 메모리보다 더 큰 메모리 공간이 있는 것처럼 사용하는 것을 말한다. 즉, 컴퓨터에 장착된 메모리는 1MByte인데 응용 프로그램에서는 마치 64MByte가 있는 것처럼 사용하게 해준다. 이것이 가능한 이유는, 운영체제에서 약간의 장난을 치기 때문이다. 응용 프로그램이 1M를 넘어가는 주소에 접근하면 이를 알아채고 그 위치에 해당하는 프로그램 코드를 물리적 메모리에 올려 놓는다. 당연히 그 물리적 메모리 자리에 있었던 기존의 코드는 날아가지만 당장은 사용하지 않을 코드이므로 상관없다. 그런데 이렇게 동작하려면, 물리적 메모리 위에 올라와 있는 코드가 프로그램 상에서는 어떤 주소에 해당하는지를 항상 관리해 주어야 하고, 프로그램이 접근하는 주소가 물리적 메모리에 해당하는지를 확인하는 작업을 누군가 해주어야 한다. 운영체제가 그런 일을 담당한다. 가상 메모리의 장점은 물리적 메모리의 크기와는 무관하게 응용 프로그램이 마음껏 메모리 공간을 사용할 수 있다는 점이다.

멀틱스는 가상 메모리를 파일 접근에까지 확대하려 했다. 파일을 프로세서의 메모리 공간에 대응시킨 것이다. 이렇게 하면 파일의 내용을 읽고 싶을 때, 일반 메모리 접근 명령을 사용하면 된다.​**​ 하지만 멀틱스의 이런 파일 시스템은 결국 제대로 구현되지 못했다. 응용 프로그램이 수행될 때, 메모리 주소가 물리적 메모리에 존재하지 않음을 감지하는 것은 비교적 쉬웠지만, 어떤 파일이 메모리 공간에 존재하지 않음을 감지하는 일은 구현하기가 어려웠다.​5,11​


켄 톰슨은 멀틱스에서 가상 메모리와 계층적 파일 시스템이라는 개념을 모두 빌려왔지만, 가상 메모리는 응용 프로그램의 메모리 접근에만 적용했다. 가상 메모리는 페이징 시스템 형식으로 구현되었다. 페이징 시스템이란, 메모리 공간을 페이지page라는 일정 크기로 쪼개어 관리하는 것을 말한다. 페이징 시스템이라는 개념이 유닉스에서 처음 등장한 것은 아니다. 이미 1960년대 초에 등장하여 여러 운영체제에서 사용되었다.

계층적 파일 시스템은 멀틱스에서 처음 제안되었지만 현실적으로 처음 구현된 것은 유닉스라고 보아도 무방할 듯싶다. 우리가 일상적으로 사용하는 ‘디렉토리’ 혹은 ‘폴더’라는 개념이 유닉스에서 처음 만들어진 셈이다. 참고로 마이크로소프트는 1970년대 말에 IBM PC용 유닉스인 제닉스Xenix를 만들었고, 이때의 경험으로 인해 유닉스의 계층적 파일 시스템을 MS-DOS에 도입했다.​9​


유닉스의 파일 시스템에서 주목할 점 중 하나는 입출력 장치를 마치 파일인 것처럼 다룬 것이다. 이는 데니스 리치의 아이디어로 알려진다. 입출력 장치의 대표적인 예를 들자면, 프린터를 들 수 있겠다. 프린터에 뭔가를 출력하려고 할 때 운영체제로부터 아무런 도움을 받지 않는다면, 프로그래머는 프린터를 제어하기 위해 프린터 고유의 명령어를 참조해서 프로그램을 작성해야 한다. 만약, 다른 프린터를 지원해야 한다면 이 새로운 프린터의 고유 명령어를 다시 참조해야 하고 별도의 프로그램을 작성해야 한다.

유닉스에서는 프린터가 하나의 파일로 간주되며 이 파일에 뭔가를 쓰면, 결국 프린터에 출력이 이루어지도록 해준다. 따라서 응용 프로그래머는 프린터마다 별도의 프로그램을 작성해야 할 필요가 없어진다. 그렇다면 각 프린터마다 고유한 명령어를 실제로 처리하는 작업은 누가 할까? 이것은 이른바 디바이스 드라이버device driver라는 별도의 시스템 프로그램으로 해결한다. 프린터에 해당하는 파일(예: /dev/printer)에 뭔가를 쓰면write, 그 프린터에 해당하는 디바이스 드라이버로 데이터가 넘어간 후, 해당 프린터의 고유 명령어를 통해 프린터에 데이터가 전달되는 셈이다.

1 2 3 4 5 6 7