운영체제 공룡책 CH 20. The Linux System

박지윤·2022년 8월 10일
0

OS

목록 보기
7/7

20.1 Linux History

Linux 란?

  • Unix의 한 버전
  • 최근에 대중적인 인기를 얻고 있는 운영체제
  • 휴대전화부터 슈퍼컴퓨터까지에 사용되고 있다.

✔ Linux의 개발
: 1991년 Linus Tovalds라는 핀란드 학생이 80386 프로세서를 위해 만든 커널로서
크기는 작지만 완전한 기능을 가지고 있었다.

✔ Linux 시스템은 초기에는 Unix 시스템 서비스의 일부만을 구현했지만 이제는 Unix의 대부분 기능을 포함하도록 발전했다.

✔ 초기에 Linux 개발은 커널 위주로 진행되었지만, 완벽한 운영체제를 만들기 위해서는 커널 이상의 많은 것들이 필요하고, 따라서 Linux 커널과 Linux 시스템을 구분하게 되었다.

Linux 커널은 Linux 공동체에 의해서 완전히 새로이 개발된 독창적인 소프트웨어이다.

Linux 시스템은 이렇게 작성된 커널 외에 완전히 새로 개발된 소프트웨어이다. 다른 개발 프로젝트로부터 가져온 소프트웨어나 다른 팀과의 협조를 통해 만들어진 것들을 포함한다.

✔ Linux가 발전해감에 따라 Linux 시스템 위에 또 다른 계층이 필요하게 되었고, Linux 배포본이 만들어졌다.

Linux 배포본은 Linux의 표준 요소와 함께 몇 가지 관리 툴들의 집합을 포함한다. 이 관리 툴에는 초기 Linux 설치와 이후의 시스템 업그레이드를 간단하게 하기 위한 것들과 시스템 내 다른 패키지들의 설치와 삭제를 다루는 것들 등이 포함된다.

20.2 Design Principles

Linux는 다중 사용자(multiuser), 다중 태스킹(multitasking) 시스템이며, Unix와 호환되는 툴들 전부를 가지고 있다.

✔ 초기의 Linux 개발은 개인들에 의해서 이루어졌기 때문에, 제한된 자원으로부터 가능한 한 많은 기능을 뽑아내려는 시도가 행해졌다. 오늘날 Linux는 몇백 GB 단위의 메모리와 몇 TB 단위의 디스크 공간을 지니 다중 처리 기계(multiprocessor machine)에서도 무리 없이 작동하지만, 여전히 16MB 이하의 메모리에서도 유용하게 사용할 수 있다.

✔ PC가 발전하고 메모리와 하드 디스크의 가격이 내려가면서, 최소 기능만 구현했던 Linux 커널도 좀 더 많은 Unix 기능을 갖추도록 확장되었다.

✔ 빠른 속력과 높은 효율은 Linux에 있어서 여전히 주요한 디자인 목표이지만, 표준화라는 세 번째 목표에 초점을 맞추어 가고 있다.

✔ Unix는 다양한 시스템에서 수행되는 대신 한 시스템에서 작성된 소스 코드가 다른 시스템에서 제대로 컴파일 되지 않거나 작동하지 않는 문제점이 있을 수 있다.

✔ 이러한 문제 때문에, Unix는 POSIX 표준을 준수하도록 디자인된다.

📌 POSIX 표준
운영제체의 여러 측면에 관한 명세의 집합
운영체제의 기본적인 기능들에 관한 것과, 프로세스 스레드나 실시간 동작(real-time operations)과 같은 확장된 기능들에 관한 것들이 있다.

20.2.1 Components of a Linux System

Linux 커널 코드는 세 개의 주요 부분으로 구성되어 있다.

  1. 커널: 가상 메모리와 프로세스 등을 포함하는 운영체제의 핵심을 다루는 부분
  2. 시스템 라이브러리: 응용 프로그램이 커널과 소통하는 함수들을 정의하며, 또한 커널 코드의 특권이 필요하지 않은 기능들을 구현한 함수들도 정의하고 있다. 가장 중요한 시스템 라이브러리는 C 라이브러리로 libc로 알려져있다.
  3. 시스템 유틸리티: 개별적이고 특수한 관리 기능을 수행하는 프로그램이다. 시스템 내에서 계속 돌아가면서 네트워크 연결 요청에 대한 응답, 터미널로부터의 로그인 요청 처리, 로그 파일들을 업데이트 하는 등의 일을 수행한다.

커널

  • Linux 운영체제의 핵심으로, 프로세스를 관리하고 스레드를 수행하는 데 필요한 모든 지원 기능들과, 하드웨어 자원들에 대한 중재되고 보호된 액세스를 대행해 주는 등의 서비스를 제공한다.
  • 커널 모드 : 모든 커널 코드는 프로세서에서 특권 모드로 수행되어 컴퓨터의 모든 자원에 대한 모든 접근 권한을 갖는다.
  • 사용자 모드 : Linux에서는 사용자 모드의 코드가 커널에 포함될 수 없다. 운영체제 자체에서 지원하는 코드라고 해도 커널 모드에서 반드시 동작해야 할 필요가 없는 코드들이 수행된다.
  • Linux는 커널이 단일화된 실행 파일로 생성되는 형태를 유지하고 있다.
    ➡ 성능 향상을 위한 것인데, 모든 커널 코드와 자료구조를 하나의 주소 공간에 유지함으로써 시스템 콜을 호출하거나 하드웨어 인터럽트 발생 시 문맥 교환(context switch)이 필요하지 않다.

시스템 라이브러리

  • 응용 프로그램이 커널에 대한 시스템 콜을 할 수 있게 한다.
  • 시스템 콜을 하게 되면 특권을 가지고 있지 않은 사용자 모드에서 특권을 지닌 커널 모드로 전환하게 된다.
  • 기본적인 시스템 콜이 제공하는 것보다 훨씬 다양한 파일 입/출력 기능을 제공하기도 한다.

Linux 시스템 - 시스템 유틸리티, 사용자 유틸리티

  • 시스템 유틸리티 : 네트워크 인터페이스의 설정, 시스템에 사용자를 추가하거나 제거하는 일 등 시스템을 초기화하고 관리하는 데 필요한 모든 프로그램을 포함한다.
  • 사용자 유틸리티 : 시스템의 기본 작동을 위해 필요하지만 상향된 특권이 필요하지 않다.
    ex) 쉘(shell)

20.3 Kernel Modules

✔ Linux 커널은 요구가 발생할 때마다 커널 코드의 임의의 부분을 모듈 단위로 적재하고 메모리에서 제거할 수 있다.

📌 커널 모듈을 사용하는 것이 편리한 이유

  • 커널 개발 시에 새로운 기능을 적재하기 위해 커널 전체를 재컴파일하고 새로 링크하고 새로 적재하는 작업을 반복할 필요가 없다.
  • 새로운 드라이버를 커널 모듈로 작성한다면, 새로운 드라이버만 따로 재컴파일하고 이미 작동하고 있는 커널에 적재하여 훨씬 효율적이다. 또한 이 드라이버를 입수한 다른 사용자들 역시 전체 커널 소스를 새로 컴파일하고 링크하고 적재하는 작업을 할 필요가 없어진다.
  • 커널 모듈 덕분에 Linux에서는 필요하지 않은 장치 드라이버는 제외하고 표준적인 최소 커널의 Linux 커널의 Linux 시스템을 설치할 수 있다.

✔ Linux는 모듈을 지원하는 네 개의 컴포넌트가 있다.

  1. 모듈 관리(module management) 시스템
    : 모듈이 메모리에 적재되고 커널의 나머지 부분과 소통할 수 있도록 하는 부분
  2. 모듈 로더와 언로더(unloader)
    : 사용자 모드 유틸리티로 모듈 관리 시스템과 협력하여 모듈을 메모리에 적재한다.
  3. 장치 드라이버 등록(driver registration) 시스템
    : 새로운 장치 드라이버의 존재를 커널의 다른 부분에 알리게 한다.
  4. 충돌 해결 기법(conflict-resolution mechanism)
    : 서로 다른 장치 드라이버들이 하드웨어 자원을 예약하는 것을 도와주고 이들 자원을 다른 드라이버가 상충하게 사용하는 것을 막아준다.

20.4 Process Management

✔ 운영체제는 사용자의 모든 요청을 프로세스라는 context 속에서 처리한다.
✔ Unix에서는 하나의 프로그램이 수행되는데 필요한 모든 정보를 프로세스가 그 context 속에 모두 포함하고 있지만, Linux에서는 이러한 정보를 프로세스의 식별(identity), 프로세스의 환경(environment), 프로세스의 문맥(context)로 구분할 수 있다.

  • 프로세스 식별 (process identity)
    프로세스 식별을 위해 제공되는 요소들
    • 프로세스 ID (PID)
    • 신임장(credentials)
    • 퍼스낼리티(personality)
    • 이름공간(namespace)
  • 프로세스 환경 (process environment)
    프로세스의 환경은 부모 프로세스로부터 상속받게 되며 두 개의 벡터로 구성된다
    • 인자 벡터 (argument vector)
      프로그램을 실행하는데 필요한 사용자 명령어의 인자들이며, 관습저그올 그 프로그램 이름으로 시작한다.
    • 환경 벡터 (environment vector)
      "이름=값" 형태의 쌍들의 목록이며, 지명된 환경 변수와 그에 대응하는 값을 서로 연관시킨다.
  • 프로세스 문맥 (process context)
    수행 중인 프로그램의 상태를 나타내며, 프로그램이 실행되는 동안 끊임없이 변화한다.
    • 스케줄링 문맥 (scheduling context)
    • 어카운팅 (accounting)
    • 파일 테이블 (file-table)
    • 파일-시스템 문맥 (file-system context)
    • 신호 핸들러 테이블 (signal-handler table)
    • 가상-메모리 문맥 (virtual-memory context)

20.5 Scheduling

✔ Linux는 모든 UNIX 시스템과 마찬가지로 선점 가능 다중 태스킹(preemptive multitasking)을 지원하고, 이러한 시스템에서는 프로세스 스케줄러가 언제 어느 스레드를 수행할지 결정한다.

20.5.1 Thread Scheduling

✔ 스레드 스케줄러는 버전 2.5에서 크게 개선되었는데, 시스템 내 태스크나 처리기의 개수에 상관없이 상수 시간에 실행되는 (O(1)로 알려진) 스케줄러를 제공할 수 있었다.
하지만 확장성은 향상하지만 대화형 성능이나 공평성을 개선하지 못했다.

✔ 버전 2.6에서는 CFS(Completely Fair Schedular, 완전 공평 스케줄러)가 만들어졌다.

📌 CFS

  • 전통적인 UNIX 프로세스 스케줄러와 크게 다르다.
  • 공평한 스케줄링이라는 새로운 스케줄링 알고리즘을 도입하여, 정통적 의미의 타임 슬라이스(스레드에 주어진 시간의 길이)를 없앤다. 대신 모든 스레드는 처리기 시간의 비율을 할당받는다. 그 할당의 실제 길이는 수행 가능한 스레드의 수에 좌우된다.
  • CFS는 단순한 알고리즘으로 문제를 해결하며, 큰 서버에서 처리량 성능을 훼손하지 않으면서 휴대장치와 같은 대화형 작업 부하에 좋은 성능을 발휘한다.

20.5.2 Real-time Scheduling

✔ Linux의 실시간 스케줄링은 연성 실시간 방식이다. 스케줄러는 실시간 스레드의 상대적인 우선순위에 대해서는 엄격한 보장을 제공하나, 일단 스레드가 실행 가능하게 된 후 그 실시간 스레드가 얼마나 빨리 스케줄 될지에 대해서는 보장하지 않는다.

20.6 Memory Management

Linux에서 메모리 관리는 두 부분으로 나누어진다.

  • 물리 메모리를 할당하고 반납하는 것
  • 가상 메모리를 다루는 것

20.6.1 Management of Physical Memory

✔ 특정 하드웨어의 특성 때문에 Linux는 물리 메모리를 네 종류의 zone으로 구분한다.

  • ZONE_DMA
  • ZONE_DMA32
  • ZONE_NORMAL
  • ZONE_HIGHMEM

(이 zone들은 아키텍처에 따라 다르다.)

✔ Linux 커널에서 물리 메모리 주 관리자는 페이지 할당기(page allocator)이다.
각 zone은 자신의 할당기를 가지고 있는데, 이 할당기는 zone의 모든 물리 페이지들의 할당과 반납을 담당하고 있고, 요청에 따라서는 물리적으로 연속된 페이지들의 영역을 할당해 줄 수 있다.

✔ 페이지 할당기는 사용 가능한 물리 페이지들의 정보를 얻기 위해 buddy 시스템을 이용하는데, 이는 인접한 할당 가능한 메모리 단위들을 함께 짝지어 주는 것에서 비롯된다.

✔ 각각의 할당 가능한 메모리 영역은 인접한 짝, 즉 buddy를 가지고 있는데, 할당된 두 짝이 모두 반납될(free up) 때마다 합쳐져서 더 큰 영역(buddy heap)을 형성한다.
✔ 역으로, 존재하는 작은 가용 영역을 할당해서 메모리 요청을 만족시켜줄 수 없으면 더 큰 가용 영역을 두 개로 쪼개서 그 요청을 만족시켜 줄 수 있다.

20.6.2 Virtual Memory

✔ Linux 가상 메모리 시스템은 실행 중인 프로세스들의 주소 공간으로 맵핑되는 메모리를 다룬다.
✔ Linux 가상 메모리 시스템은 요청시 가상 메모리 페이지를 만들고, 디스크로부터 페이지들을 적재하거나 다시 디스크로 방출(swapping)하는 일 등을 관리한다.

✔ 주소 공간의 논리적인 면

  • 주소 공간은 서로 겹쳐질 수 없는 영역의 집합으로 구성된다.
  • 각 영역은 연속적이면서 페이지 위치에 정렬된 주소 공간의 부분 집합이다.
  • 각 영역은 내부적으로 영역의 특성을 정의하는 하나의 vm_area_struct 자료구조에 의해 기술된다.

✔ 주소 공간의 물리적인 면

  • 프로세스의 하드웨어 페이지 테이블에 저장되어 있다.
  • 각각의 페이지 테이블 항목은 가상 메모리 상의 각 페이지가 현재 존재하는 위치 정보를 알려준다.

20.7 File System

Linux는 Unix 표준 파일 시스템 모델을 그대로 따른다.
Linux 커널은 여러 가지 다양한 파일의 구현 상세를 가상 파일 시스템(virtual FIle System, VFS)이라는 계층 밑으로 숨김으로써 겉으로는 간단한 파일 모델만을 사용자에게 제공한다.

✅ VFS

  • Linux VFS는 객체지향을 기본 원리로 고안되었다.
  • 파일 시스템의 객체를 무엇처럼 보이게 할 것인가를 결정하는 정의들의 집합, 이 객체들을 실제로 처리하는 소프트웨어 계층으로 구성된다.
  • VFS에 의해 정의되는 네 가지 주요 객체 유형
    • 아이노드 객체 (inode object) : 개별 파일을 표현한다.
    • 파일 객체 (file object) : 열린 파일을 표현한다.
    • 수퍼블록 객체 (superblock object) : 전체 파일 시스템을 표현한다.
    • 덴트리 객체 (dentry object) : 개별적인 디렉터리 항목을 표현한다.

20.8 Input and Output

✔ 일반 사용자에게 Linux의 입/출력 시스템은 UNIX와 비슷하다.
✔ 모든 I/O 장치 드라이버는 일반적인 파일과 동등하게 보이게 되어있다.
➡ 모든 장치(device)는 일반 파일을 다루는 방식으로 접근할 수 있다.

✔ 시스템의 관리자는 I/O 장치를 특수 파일 형태로 파일 시스템 내에 만들 수 있으며, 그러한 파일을 연 사용자는 바로 그 장치에 대해 읽기와 쓰기를 할 수 있다.
✔ 이러한 장치에 대해 사용자들의 접근을 통제하는 방법은 일반적인 파일 접근을 통제하는 것과 동일한 방식을 그대로 사용하게 되며, 관리자는 각 파일에 대한 접근 권한(rwx)를 설정함으로써 장치에 대한 접근을 제어할 수 있다.

✔ Linux에서는 모든 장치들을 세 가지로 분류할 수 있다.

  • 블록 장치 (block device)
    일반적으로 파일 시스템을 저장하는 데 사용된다.
    하드 디스크나 플로피디스크, CD-ROM, 블루 레이 디스크 및 플래시 메모리와 같이 완전히 독립되고 고정된 크기의 데이터 블록에 임의 접근(random access)을 한다.
  • 문자 장치 (character device)
    마우스나 키보드와 같은 대부분의 다른 장치들을 지칭한다.
    블록장치는 임의 접근을 허용하고, 문자 장치는 오직 순차적으로 접근된다.
    ex) 파일에서의 특정 위치를 검색하는 것은 DVD에서는 가능하지만 마우스와 같은 장치에서는 의미없음
  • 네트워크 장치 (network device)
    사용자는 네트워크 장치에 직접적으로 데이터를 전송할 수 없고, 대신에 커널의 네트워크 서브시스템과 연결을 설정한 후 이를 통해 간접적으로 통신해야 한다.

0개의 댓글