사전 Multics
구현체

Multics

gabury1고친 사람 github-actions[bot]

Multics 는 컴퓨터 한 대를 여러 사람이 동시에 나눠 쓰게 해 주던 운영체제입니다. 계산 능력을 전기처럼 늘 공급하겠다는 목표로 만들었습니다. 지금은 도는 곳이 없습니다. 그래도 그 설계는 유닉스를 거쳐 오늘날 운영체제의 뼈대로 남았습니다.

쉽고 빠른 이해

Multics 는 비싼 컴퓨터 한 대를 여러 사람이 각자 단말기 앞에서 동시에 쓰게 해 줍니다. 연구자 여럿이 저마다 단말기로 붙어 프로그램을 짜고 바로 고쳐 보는 모습이 그 쓰임입니다.

이게 없던 때는 작업을 맡기고 결과가 나올 때까지 몇 시간씩 기다렸습니다. 여럿이 한 컴퓨터를 같이 쓰려면 서로의 파일과 메모리를 지켜 주는 장치도 있어야 했습니다.

  1. 프로세서 시간을 잘게 쪼개 사용자들에게 돌아가며 나눠 줍니다
  2. 파일을 메모리처럼 붙여 두고 주소로 바로 읽고 씁니다
  3. 운영체제 핵심을 여러 겹으로 감싸 사용자 프로그램이 함부로 못 건드리게 합니다

대가는 무게입니다. 많은 기능을 한 시스템에 담아 크고 복잡했습니다. 전용 기계에서만 돌았습니다. 그 무게를 덜어 낸 작은 운영체제가 유닉스입니다.

상세

Multics 는 Multiplexed Information and Computing Service 의 줄임말입니다. 우리말로 옮기면 「여럿이 함께 쓰는 정보·계산 서비스」쯤 됩니다.

이 절은 Multics 가 왜 나왔는지부터 봅니다. 그다음 Multics 가 한 시스템에 묶은 설계 다섯을 하나씩 봅니다. 파일을 읽는 방식, 파일에 이름과 권한을 붙이는 방식, 프로그램끼리 잇는 방식, 운영체제를 지키는 방식, 운영체제를 짠 언어입니다. 끝으로 이 설계가 유닉스로 어떻게 넘어갔는지, Multics 가 무엇을 대가로 치렀는지를 봅니다.

배치 처리에서 시분할로

Multics 이전의 큰 컴퓨터는 대개 배치 처리 방식으로 돌았습니다. 배치 처리는 사용자들이 맡긴 작업을 한 줄로 세워 하나씩 끝까지 돌리는 방식입니다. 프로그램을 맡기면 몇 시간 뒤에야 결과 출력을 받았습니다. 오타 하나를 고치는 데 하루가 가기도 했습니다.

시분할은 이 기다림을 없애려고 나온 방식입니다. 시분할은 CPU(Central Processing Unit, 중앙 처리 장치) 시간을 아주 잘게 쪼개 여러 사용자에게 돌아가며 나눠 줍니다. 한 사람 몫이 짧게 자주 돌아오므로 각자는 컴퓨터를 혼자 쓰는 것처럼 느낍니다. 사용자는 단말기 앞에 앉아 명령을 치고 바로 답을 받습니다.

Multics 는 시분할을 한 걸음 더 밀었습니다. 계산 능력을 전기나 전화처럼 늘 켜 두고 필요한 만큼 끌어다 쓰는 공공 서비스로 만들려 했습니다. 이 생각을 컴퓨터 유틸리티(computer utility)라고 불렀습니다.

공공 서비스가 되려면 두 가지가 필요했습니다. 하나는 멈추지 않는 것입니다. Multics 는 시스템을 끄지 않고 프로세서나 메모리를 빼고 더할 수 있게 설계했습니다. 다른 하나는 수많은 사용자의 데이터를 서로에게서 지키는 것입니다. 아래 소절에서 볼 접근 제어 목록과 보호 링이 이 둘째 요구에서 나왔습니다.

세 기관이 함께 만든 시스템

Multics 설계는 1965년에 공동 프로젝트로 시작했습니다. 참여한 곳은 셋입니다. MIT(Massachusetts Institute of Technology, 매사추세츠 공과대학)의 연구 그룹, 미국 전화 회사의 연구소인 벨 연구소, 컴퓨터를 만들던 GE(General Electric, 제너럴 일렉트릭)입니다.

하드웨어는 GE 가 맡았습니다. GE 는 자기 회사 컴퓨터를 고쳐 Multics 용 기계인 GE-645 를 만들었습니다. 이 기계는 Multics 가 메모리를 다루는 방식을 하드웨어로 받쳐 줬습니다. 그 방식은 다음 소절에서 봅니다.

벨 연구소는 1969년 4월에 프로젝트에서 빠졌습니다. 1970년에는 GE 가 컴퓨터 사업을 하니웰에 팔았습니다. 그 뒤로는 하니웰이 Multics 를 이어 팔았습니다.

Multics 는 그 뒤로도 30년 가까이 여러 기관에서 돌았습니다. 마지막까지 남은 시스템은 캐나다 국방부가 핼리팩스에서 돌리던 것이었습니다. 이 시스템은 2000년 10월 말에 꺼졌습니다. 그 뒤로 운영 중인 Multics 는 없습니다.

파일과 메모리를 하나로 다루는 세그먼트

Multics 는 파일과 메모리의 구분을 지웠습니다. 이 소절은 프로그램이 파일 하나를 읽는 장면으로 그 구분이 어떻게 사라지는지를 봅니다.

먼저 오늘날 흔한 방식입니다. 프로그램이 운영체제에 일을 부탁하는 호출을 시스템 콜이라고 합니다. 프로그램은 파일을 직접 만지지 못합니다. 파일을 연 뒤 읽기 시스템 콜로 내용을 메모리 버퍼에 복사해 와야 다룰 수 있습니다.

Multics 는 이 복사 단계를 없앴습니다. 여기서 쓰는 단위가 세그먼트(segment)입니다. 세그먼트는 이름이 붙은 데이터 덩어리입니다. Multics 에서는 파일 하나가 곧 세그먼트 하나입니다. 메모리를 이런 덩어리 단위로 나눠 다루는 방식을 세그멘테이션이라고 합니다.

프로그램이 볼 수 있는 메모리 주소의 범위를 주소 공간이라고 합니다. 프로그램이 파일을 쓰겠다고 하면 Multics 는 그 세그먼트를 프로그램의 주소 공간에 붙입니다. 붙인 뒤에는 메모리를 읽듯 주소로 바로 읽고 씁니다. 읽기 호출도 버퍼 복사도 없습니다.

이 방식을 단일 수준 저장소(single-level store)라고 부릅니다. 프로그램 눈에는 디스크와 메모리가 한 층으로 보인다는 뜻입니다. 파일을 따로 읽어 오는 코드가 사라집니다.

세그먼트 전체가 메모리에 올라올 필요는 없습니다. 세그먼트는 다시 같은 크기의 페이지로 쪼개집니다. 프로그램이 건드린 페이지만 디스크에서 메모리로 올라옵니다. 이렇게 같은 크기 조각 단위로 필요한 것만 메모리에 올리는 방식을 페이징이라고 합니다.

프로그램 코드도 세그먼트라서 데이터 파일과 같은 주소 공간에 붙습니다. 아래 그림은 report 라는 데이터 파일을 주소 공간에 붙인 모습입니다. 프로그램은 report 세그먼트 전체를 가진 것처럼 씁니다. 메모리에 올라와 있는 것은 그중 건드린 페이지뿐입니다.

flowchart TD
    subgraph 주소공간["프로그램의 주소 공간"]
        S1["세그먼트 · 프로그램 코드"]
        S2["세그먼트 · 데이터 파일 report"]
    end
    subgraph 페이지["report 세그먼트의 페이지"]
        P1["페이지 1 · 메모리에 올라옴"]
        P2["페이지 2 · 디스크에만 있음"]
        P3["페이지 3 · 메모리에 올라옴"]
    end
    S2 --> P1
    S2 --> P2
    S2 --> P3

이 설계는 지금도 남아 있습니다. 유닉스 계열의 mmap 시스템 콜은 파일을 주소 공간에 붙여 메모리처럼 읽게 해 줍니다. 다만 Multics 에서는 이 붙이기가 파일을 쓰는 기본 방식이었습니다. 유닉스의 기본은 읽기 시스템 콜이고, mmap 은 나중에 따로 더해진 선택지입니다.

디렉토리 트리와 파일 권한

Multics 가 파일에 이름을 붙이는 방식과, 누가 그 파일을 볼 수 있는지 정하는 방식을 이 소절에서 봅니다. 지금 우리가 쓰는 폴더 구조와 파일 권한이 여기서 나왔습니다.

Multics 는 파일을 나무 모양으로 묶었습니다. 디렉토리는 다른 파일과 디렉토리의 이름을 담는 특별한 파일입니다. 디렉토리 안에 디렉토리를 둘 수 있으므로 맨 위 루트에서 가지가 뻗어 나갑니다.

루트에서 그 파일까지 거치는 디렉토리 이름을 차례로 이은 것이 경로 이름입니다. Multics 는 이름 사이를 > 로 갈랐습니다. 유닉스는 같은 방식을 받아 / 로 가릅니다. /home/kim/memo 같은 경로가 그 후손입니다.

여럿이 한 컴퓨터를 쓰면 남의 파일을 함부로 못 보게 막아야 합니다. 그래서 Multics 는 파일마다 누가 무엇을 할 수 있는지를 목록으로 적어 둡니다. 이 목록이 접근 제어 목록(ACL, Access Control List)입니다. 사용자마다 읽기와 쓰기 같은 권한을 따로 줄 수 있습니다.

유닉스는 이것을 단순하게 줄였습니다. 소유자, 그룹, 나머지 세 부류에게 읽기·쓰기·실행 권한만 줍니다. 리눅스 같은 요즘 시스템은 그것으로 모자랄 때 ACL 을 다시 얹어 씁니다.

실행 중에 이어 붙이는 동적 링크

이 소절은 프로그램이 남이 짠 함수를 부를 때 그 둘을 언제 잇는지를 봅니다.

부르는 코드와 불리는 코드를 이어 주는 일을 링크라고 합니다. 예전에는 실행하기 전에 링커가 필요한 코드를 전부 모아 한 파일로 붙였습니다. 이것이 정적 링크입니다.

Multics 는 이 잇기를 실행 중으로 미뤘습니다. 프로그램은 다른 세그먼트의 함수를 이름으로만 적어 둡니다. 그 함수를 처음 부르는 순간 Multics 가 이름에 맞는 세그먼트를 찾아 주소를 이어 줍니다. 두 번째 호출부터는 이어 둔 주소로 바로 갑니다.

이 방식을 동적 링크라고 부릅니다. 이름으로 찾아가는 세그먼트는 메모리에 한 벌만 있습니다. 같은 함수를 부르는 프로그램이 여럿이어도 모두 그 한 벌에 이어집니다. 그래서 여러 프로그램이 같은 코드 한 벌을 나눠 씁니다.

리눅스의 .so 파일이나 윈도우의 .dll 파일 같은 공유 라이브러리도 같은 방식입니다.

동적 링크에도 대가가 있습니다. 첫 호출마다 이름을 찾는 비용이 듭니다. 불리는 쪽 코드가 바뀌면 부르는 쪽의 동작도 모르는 사이에 바뀝니다. 부르는 쪽은 한 줄도 안 고쳤는데 결과가 뜻하지 않게 달라질 수 있습니다.

보호 링

이 소절은 사용자 프로그램이 운영체제 핵심을 망가뜨리지 못하게 막는 방식을 봅니다. 지금 CPU 가 운영체제와 일반 프로그램의 권한을 가르는 방식이 여기서 나왔습니다.

Multics 는 권한을 여러 겹의 동심원으로 나눴습니다. 이 동심원 하나하나를 보호 링(protection ring)이라고 부릅니다. 안쪽 링일수록 권한이 큽니다. 맨 안쪽에는 운영체제의 핵심이 있습니다. 사용자 프로그램은 바깥쪽 링에서 돕니다.

바깥 링의 코드는 안쪽 링의 데이터를 직접 못 건드립니다. 안쪽 기능을 쓰려면 미리 정해 둔 입구를 거쳐야 합니다. 이 입구를 게이트(gate)라고 부릅니다. 시스템은 호출이 게이트로 들어오는지 검사합니다. 아무 주소로나 뛰어드는 호출은 막힙니다.

아래 그림은 여러 겹 가운데 두 겹만 그렸습니다. 바깥쪽 링이 안쪽 링을 감쌉니다. 게이트는 안쪽 링의 경계에 난 입구입니다.

flowchart TD
    subgraph 바깥["바깥쪽 링 · 권한이 작다"]
        U["사용자 프로그램"]
        subgraph 안["안쪽 링 · 권한이 크다"]
            G["게이트 · 정해 둔 입구"]
            K["운영체제 핵심"]
        end
    end
    U --> G
    G --> K

오늘날 CPU 는 대개 이 설계를 두 겹으로 줄여 씁니다. 운영체제가 도는 커널 모드와 일반 프로그램이 도는 사용자 모드입니다. x86 CPU 는 링을 넷 둡니다. 운영체제는 대개 그중 둘만 씁니다.

프로그램이 시스템 콜을 부르면 정해진 입구를 거쳐 커널 모드로 넘어갑니다. Multics 의 게이트와 같은 구조입니다.

고급 언어로 짠 운영체제

이 소절은 Multics 를 무슨 언어로 짰는지를 봅니다. 이 선택이 뒤의 운영체제들까지 바꿨습니다.

당시 운영체제는 대개 어셈블리어로 짰습니다. 어셈블리어는 CPU 명령어를 거의 하나씩 받아 적는 언어입니다. 기계가 바뀌면 처음부터 다시 짜야 합니다. 코드가 길어 읽고 고치기도 어렵습니다.

Multics 는 운영체제 대부분을 고급 언어인 PL/I(Programming Language One)로 짰습니다. 어셈블리어로 짠 것은 일부뿐입니다. 이렇게 큰 시스템도 고급 언어로 짤 수 있다는 것을 보였습니다.

유닉스가 이 길을 이었습니다. 유닉스는 처음에 어셈블리어로 짰다가 C 언어로 다시 짰습니다. 지금은 운영체제를 고급 언어로 짜는 것이 당연한 일입니다.

유닉스로 이어진 길

이 소절은 Multics 에서 나온 사람들이 무엇을 들고 나갔는지를 봅니다. 아래 표 하나로 받은 것과 줄인 것을 견줍니다.

Multics 에 참여한 벨 연구소 사람 가운데 Ken Thompson 과 Dennis Ritchie 가 있었습니다. 벨 연구소가 빠진 뒤 이들은 훨씬 작은 운영체제를 따로 만들었습니다. 그것이 유닉스입니다.

유닉스(Unix)라는 이름도 Multics 를 비튼 말장난에서 왔습니다. 「여럿」을 뜻하는 Multi- 를 「하나」를 뜻하는 Uni- 로 바꿨습니다.

명령을 받아 프로그램을 띄워 주는 프로그램을 셸이라고 합니다. Multics 는 셸을 운영체제 핵심 안에 넣지 않고 보통 프로그램으로 따로 뒀습니다. 유닉스도 이 구조를 받았습니다.

설계 Multics 유닉스
파일 이름 디렉토리 트리 · > 로 가름 디렉토리 트리 · / 로 가름
파일 읽기 세그먼트를 주소 공간에 붙여 메모리처럼 읽기·쓰기 시스템 콜로 복사
권한 사용자마다 ACL 소유자·그룹·나머지 세 부류
보호 여러 겹의 링 커널과 사용자 두 겹
셸 핵심 밖의 보통 프로그램 핵심 밖의 보통 프로그램
짠 언어 PL/I C

표를 보면 유닉스는 뼈대를 받았습니다. 무게는 덜어 냈습니다. 디렉토리 트리와 셸처럼 쓰기 쉬운 설계는 가져갔습니다.

특수한 하드웨어가 있어야 하는 세그먼트는 파일을 쓰는 기본 방식으로 삼지 않았습니다. 파일을 주소 공간에 붙이는 mmap 은 나중에 선택지로 따로 들어왔습니다. 여러 겹의 링은 두 겹으로 줄였습니다. 그래서 유닉스는 작은 컴퓨터에서도 돌았습니다.

Multics 가 치른 대가

Multics 는 처음부터 많은 것을 한 시스템에 담으려 했습니다. 그만큼 크고 복잡했습니다. 개발은 계획보다 길어졌습니다. 벨 연구소가 빠진 것도 결과가 더디게 나왔기 때문입니다.

하드웨어도 무거웠습니다. 세그먼트와 페이징과 링을 하드웨어가 받쳐 줘야 했습니다. 그래서 그 기능을 갖춘 전용 기계에서만 돌았습니다. 다른 기계로 옮기기 어려웠습니다.

지금 Multics 를 만나는 곳

지금 Multics 를 새로 쓸 일은 없습니다. 이름은 운영체제의 내력을 읽을 때 나옵니다. mmap, 공유 라이브러리, 커널 모드, ACL, 디렉토리 경로가 왜 지금 모양인지 따라가면 Multics 에 닿습니다. 백엔드 개발자가 서버에서 매일 쓰는 것들입니다.

관련 항목

Multics 가 속하는 상위 분류

운영체제 · 시분할 · 메인프레임 · 컴퓨터 유틸리티 · 다중 사용자 시스템

Multics 를 만든 기관과 사람

MIT · 벨 연구소 · Honeywell · Fernando Corbató · Ken Thompson · Dennis Ritchie

Multics 가 돌던 하드웨어와 그 기능

GE-645 · 세그멘테이션 · 페이징 · 가상 메모리 · 주소 공간

Multics 가 한 시스템에 묶은 설계

단일 수준 저장소 · 동적 링크 · 보호 링 · 접근 제어 목록 · 계층형 파일 시스템 · 파일 시스템 · 디렉토리 · 경로 이름

Multics 설계가 남은 오늘날의 기능

mmap · 메모리 맵 파일 · 공유 라이브러리 · 정적 링크 · 링커 · 커널 모드 · 사용자 모드 · 시스템 콜 · 셸

Multics 에서 갈라져 나온 운영체제 계보

유닉스 · 유닉스 계열 · Linux · BSD

Multics 와 견주는 시분할 운영체제

CTSS · TOPS-10 · TENEX · VMS

운영체제를 짜는 언어

어셈블리어 · 고급 언어 · C · 시스템 프로그래밍

다른 이름: 멀틱스 · MULTICS · Multiplexed Information and Computing Service