운영체제 CH.2

이지용·2024년 4월 11일

Chapter 2 운영체제 구조

운영체제는 그 속에서 프로그램이 실행되는 환경을 제공해준다.
운영체제를 살펴보기 위한 몇 가지 유리한 관점이 있다.
첫 번째 관점은 운영체제가 제공하는 서비스에 초점을 맞추는 것이다.
두 번째 관점은 운영체제가 사용자와 프로그래머에게 제공하는 인터페이스에 초점을 맞추는 것이다.
세 번째는 시스템의 구성요소와 그들의 상호 연결에 초점을 맞추는 것이다.
본 장에서 우리는 사용자, 프로그래머, 그리고 운영체제 설계자의 관점에서 바라본 운영체제의 세 가지 측면을 모두 살펴본다.

이 장의 목표

  • 운영체제에서 제공하는 서비스를 식별한다.
  • 운영체제 서비스를 제공하기 위해 시스템 콜을 사용하는 방법을 설명한다.
  • 운영체제 설계를 위한 모놀리식, 계층화, 마이크로 커널, 모듈 및 하이브리드 전략을 비교 및 대조한다.
  • 운영체제 부팅 프로세스를 설명한다.
  • 운영체제 성능을 모니터링하기 위한 도구를 적용한다.
  • Linux 커널과 상호작용하기 위한 커널 모듈을 설계하고 구현한다.

  • 운영체제 서비스를 바라보는 관점

2.1 운영체제 서비스

운영체제는 프로그램 실행 환경을 제공한다. 이러한 서비스는 프로그래머가 프로그래밍 작업을 더 쉽게 수행할 수 있도록 한다.

  • 사용자 인터페이스(User interface)
    거의 모든 운영체제는 사용자 인터페이스(UI)를 제공한다. 가장 일반적으로 그래픽 사용자 인터페이스(GUI)가 사용된다. 여기서 인터페이스는 윈도 시스템으로 I/O를 지시하고, 메뉴에서 선택하고, 화면을 선택하는 포인팅 장치인 마우스와 텍스트를 입력할 키보드를 가지고 있다.
    또 다른 옵션은 명령어 라인 인터페이스(CLI)이다. 이 인터페이스는 명령을 사용하며 이를 입력할 방법(예: 특정 옵션이 정해진 특정 형식으로 명령을 입력하기 위한 키보드)이 사용된다.
  • 프로그램 수행
    시스템은 프로그램을 메모리에 적재해 실행할 수 있어야 한다. 프로그램은 정상적이든, 혹은 비정상적이든 실행을 끝낼 수 있어야 한다.
  • 입출력 연산
    수행중인 프로그램은 입출력을 요구할 수 있다. 이러한 입출력에는 파일 혹은, 입출력 장치가 연관될 수 있다.
  • 파일 시스템 조작(file system manipulation)
    파일 시스템은 특히 중요한 분야이다. 명백히, 프로그램은 파일을 읽고 쓸 필요가 있다. 프로그램은 또한 이름에 의해 파일을 생성하고 삭제할 수 있고 지정된 파일을 찾을 수 있어야 하고 파일의 정보를 열거하고, 파일의 접근을 관리할 수 있어야 한다.
  • 통신(communication)
    한 프로세스가 다른 프로세스와 정보를 교환하는 두가지 방법이 있다. 첫 번째는 동일한 컴퓨터에서 수행되고 있는 프로세스들 사이에서 일어나고, 두 번째는 네트워크에 의해 함께 묶여 있는 서로 다른 컴퓨터 시스템 상에서 수행되는 프로세스들 사이에서 일어난다.
    통신은 공유 메모리를 통해서 구현될 수 있고, 메시지 전달(message passing)기법을 사용하여 구현될 수 있다. 메시지 전달 기법의 경우 정보의 패킷들이 운영체제에 의해 프로세스 사이를 이동한다.
  • 오류 탐지(error detection)
    운영체제는 모든 가능한 오류를 항상 의식하고 있어야 한다. 오류는 CPU, 메모리 하드웨어, 입출력 장치, 또는 사용자 프로그램에서 일어날 수 있다. 운영체제는 올바르고 일관성 있는 계산을 보장하기 위해 각 유형의 오류에 대해 적당한 조치를 해야한다. 디버깅 설비는 시스템을 효율적으로 사용할 수 있는 사용자와 프로그래머의 능력을 향상시킨다.

사용자에 도움을 주는 것이 목적이 아니라 시스템 자체의 효율적인 동작을 보장하기 위한 운영체제 기능들도 존재한다. 다수의 프로세스가 사용하는 시스템에서는 프로세스들 간에 컴퓨터 자원을 공유하게 함으로써 효율성을 얻을 수 있다.

  • 자원할당
    다수의 프로세스나 다수의 작업이 동시에 실행될 때, 그들 각각에 자원을 할당해 주어야 한다. 운영체제는 여러가지 다른 종류의 자원을 관리한다. 어떤 것(CPU 사이클, 메인 메모리, 파일 저장장치)들은 특수한 할당 코드를 가질 수 있지만, 다른것(입출력 장치)들은 훨씬 일반적인 요청과 방출 코드를 가질 수 있다.
  • 기록 작성(logging, accounting)
    어떤 프로그램이 어떤 종류의 컴퓨터 자원을 얼마나 많이 사용하는지를 추적한다.
  • 보호와 보안
    다중 사용자 컴퓨터 시스템 또는 네트워크로 연결된 컴퓨터 시스템에 저장된 정보의 소유자는 그 정보의 사용을 통제하길 원한다. 서로 다른 여러 프로세스가 병행하게 수행될 때, 한 프로세스가 다른 프로세스나 운영체제 자체를 방해해서는 안 된다.
    보호는 시스템 자원에 대한 모든 접근이 통제되도록 보장하는 것을 필요로 한다.
    보안은 각 사용자가 자원에 대한 접근을 원할 때 통상 패스워드를 사용해서 시스템에게 자기 자신을 인증하는 것으로부터 시작된다. 보안은 네트워크 어댑터 등과 같은 외부 입출력 장치들을 부적합한 접근 시도로부터 지키고, 침입의 탐지를 위해 모든 접속을 기록하는 것으로 범위를 넓힌다. 만약 시스템이 보호되고 보안이 유지되려면, 시스템 전체에 걸쳐 예방책(precaution)이 제정되어야 한다. 하나의 사슬은 가장 약한 연결고리만큼 강한 법이다.

2.2 사용자와 운영체제 인터페이스

2.2.1 명령 인터프리터, 명령어 라인 인터페이스(CLI)

운영체제 대부분은 명령 인터프리터를 프로세스가 시작되거나 사용자가 처음 로그온 할 때 수행되는 특수한 프로그램으로 취급한다. 선택할 수 있는 여러 명령 인터프리터를 제공하는 시스템에서 이 해석기는 셸(shell)이라고 불린다. 명령 인터프리터의 중요한 기능은 사용자가 지정한 명령을 가져와서 그것을 수행하는 것이다.
두 가지 일반적인 방식이 있는데, 한가지 방법은 명령 인터프리터 자체가 명령을 실행할 코드를 가지는 경우이다. 예를 들면, 한 파일을 삭제하기 위한 명령은 명령 인터프리터가 자신의 코드의 한 부분으로 분기하고, 그 코드 부분이 매개변수를 설정하고 적절한 시스템 콜을 한다.
다른 방법은 시스템 프로그램에 의해 대부분의 명령을 구현하는 것이다. 이러한 경우 명령 인터프리터는 전혀 그 명령을 알지 못하고 단지 메모리에 적재되어 실행될 파일을 식별하기 위해 명령을 사용한다.

2.2.2 그래픽 기반 사용자 인터페이스(GUI)

운영체제와 접촉하는 두번째 방식은 사용자 친화적인 그래픽 기반 사용자 인터페이스를 통하는 방식이다. 사용자는 마우스를 움직여 마우스 포인터를 아이콘에 위치시킨다. 마우스 버튼을 누름으로써 프로그램을 호출하거나 파일 혹은 디렉터리(폴더)를 선택할 수 있다.

2.2.4 인터페이스의 선택

많은 시스템들은 GUI와 CLI 모두 포함하고 있다.

시스템 콜(System Calls)

시스템 콜은 운영체제에 의해 사용가능하게 된 서비스에 대한 인터페이스를 제공한다. 이러한 호출은 일반적으로 C와 C++ 언어로 작성된 함수 형태로 제공된다.

  • 시스템 콜이 사용되는 방법의 예

2.3.2 응용 프로그래밍 인터페이스 (Application Programming Interface)

위의 그림처럼 간단한 프로그램이라도 매우 많은 시스템 콜을 수행한다. 응용 프로그래머는 대부분 직접 시스템 콜을 호출하지 않고, API를 통해 프로그램들에 접근한다.API는 각 함수에 전달되어야 할 매개 변수들과 프로그래머가 기대할 수 있는 반환값을 포함하여 응용 프로그래머가 사용 가능한 함수의 집합을 명시한다.
응용 프로그래머가 사용 가능한 가장 흔한 API 세가지는 Windows API, POSIX 기반 API, Java API가 있다.
실제 시스템 콜을 사용하지 않고 API에 따라 프로그래밍 하는 데에는 몇가지 이유가 있다. API에 따라 프로그램을 설계하면 프로그램이 같은 API를 지원하는 어느 시스템에서건 컴파일 되고 실행된다는 것을 기대할 수 있다. 또한 API는 시스템 콜을 더욱 단순하게 사용할 수 있게 해주고 사용할 때, 자세한 세부사항을 알지 못해도 되기 때문이다.

시스템 콜 인터페이스는 API 함수의 호출을 가로채어 필요한 운영체제 시스템 콜을 부른다. 통상 각 시스템 콜에는 번호가 할당되고 시스템 콜 인터페이스는 이 번호에 따라 색인되는 테이블을 유지한다. 시스템 콜 인터페이스는 의도하는 시스템 콜을 부르고 시스템 콜의 상태와 반환값을 돌려준다.
호출자는 시스템 콜이 어떻게 구현되고 실행 중 무슨 작업을 하는지 아무것도 알 필요가 없다. 호출자는 단지 API를 준수하고 시스템 콜의 결과로서 운영체제가 무엇을 할 것인지만 이해하면 된다. 따라서 운영체제 인터페이스에 대한 대부분의 자세한 내용은 API에 의해 프로그래머로부터 숨겨진다.

  • open() 시스템 콜을 호출하는 user application의 처리

종종, 단순히 원하는 시스템 콜이 무엇인지보다 더 많은 정보가 요구될 수 있다. 필요한 정보의 유형과 양은 특정 운영체제와 호출에 따라 다양하다. 예를 들어 입력으로 사용될 파일을 전달해야 할 수도 있고, 데이터를 저장할 메모리 버퍼의 주소와 길이를 명시해야 할 수도 있다.
운영체제에 매개변수를 전달하기 위해서 세가지 방법이 있다.
가장 간단한 방법은 매개변수를 레지스터 내에 전달하는 방법이다. 하지만 어떤 경우엔 레지스터보다 많은 매개변수가 있을 수 있다.
이러한 경우 매개변수는 메모리 내의 블록이나 테이블에 저장되고 블록의 주소가 레지스터 내에 매개변수르 전달된다.
매개변수는 프로그램에 의해 스택에 push 될 수 있고, 운영체제에 의해 꺼내진다.(pop off)
일부 운영체제는 블록이나 스택 방법을 선호하는데, 이 접근법은 전달되는 매개변수들의 개수나 길이를 제한하지 않기 때문이다.

2.3.3 시스템 콜의 유형

시스템 콜은 다섯가지의 중요한 범주, 즉 프로세스 제어, 파일 조작, 장치 조작, 정보 유지 보수, 통신과 보호 등으로 묶을 수 있다.

시스템 서비스(System Services)

논리적인 컴퓨터 계층 구조를 다시 생각해보자. 최하위 수준은 하드웨어, 다음은 운영체제, 그 다음은 시스템 서비스, 그리고 마지막으로 응용프로그램이다. 시스템 서비스는 시스템 유틸리티로도 알려진, 프로그램 개발과 실행을 위해 더 편리한 환경을 제공한다. 이들은 다음 몇가지 범주로 분류할 수 있다.

  • 파일 관리
  • 상태 정보
  • 파일 변경
  • 프로그래밍언어 지원
  • 프로그램 적재와 수행
  • 통신
  • 백그라운드 서비스

사용자 대부분이 보는 운영체제의 관점은 실제의 시스템 콜에 의해서 보다는 시스템 프로그램과 응용에 의해서 정의된다.

2.7 운영체제 설계 및 구현(Operating system design and implementation)

이 절에서는 운영체제를 설계하고 구현할 때 우리가 당면하는 문제점을 논의한다. 물론 이들 설계 문제점에 대한 완전한 해결책은 없지만 성공적인 접근 방법들이 있다.

2.7.1 설계 목표(Design goals)

시스템을 설계하는 데에 첫째 문제점은 시스템의 목표와 세부사항을 정의하는 것이다. 시스템 설계는 최상위 수준에서는 하드웨어와 시스템 유형의 선택에 의해 영향을 받을 것이다.
목적은 크게 사용자 목적과 시스템 목적 두가지로 나눌 수 있다.

  • 사용자 목적
    시스템은 사용하기 쉽고 편리하며, 배우기 쉽고, 믿을 수 있고 안전하고 신속해야 한다.
  • 시스템 목적
    운영체제는 설계, 구현, 유지 보수가 쉬워야 하며, 또한 적응성, 신뢰성, 무오류, 효율성을 가져아 한다.

요약하면 운영체제에 대한 요구를 정의하는 문제를 해결하는 유일한 해법은 없다.

2.7.2 기법과 정책(Mechanisms and policies)

한가지 중요한 원칙은 기법(mechanism)으로부터 정책(policy)를 분리하는 것이다.

  • 기법(mechanism)
    어떤 일을 어떻게 할 것인가를 결정하는 것
  • 정책(policy)
    무엇을 할 것인가를 결정하는 것

정책과 기법의 분리는 융통성을 위해 아주 중요하다.

Policy는 상황에 따라서 잘 변하는 가변적인 것이다. 만약, Policy와 Mechanism을 잘 분리해서 설계하지 못했다면, Policy가 변할 때마다 Mechanism도 계속해서 변해야 한다.
하지만, 잘 분리해서 설계해놓았다면, Policy가 아무리 변해도 Mechanism은 수정할 필요가 없는 것이다.

2.7.3 구현(Implementation)

운영체제의 설계가 완료되면 구현되어야 한다. 초기 운영체제는 어셈블리 언어로 작성되었지만 이제 대부분은 C 또는 C++과 같은 고급언어로 작성된다.

2.8 운영체제 구조

2.8.1 모놀리식 구조(Monolithic structure)

운영체제를 구성하는 가장 간단한 구조는 구조가 아예 없는 것이다. 즉, 커널의 모든 기능을 단일 주소 공간에서 실행되는 단일 정적 이진 파일에 넣는 것이다.
모놀리식 커널의 명백한 단순성에도 불구하고 이 구조는 구현 및 확장하기 어렵다.
그러나 모놀리식 커널은 성능 면에서 뚜렷한 이점이 있다. 시스템 콜 인터페이스에는 오버헤드가 거의 없고 커널안에서의 통신 속도가 빠르다.

2.8.2 계층적 접근(Layered approach)

시스템의 한 부분을 변경하면 다른 부분에 광범위한 영향을 줄 수 있으므로 이에 대한 대안으로 느슨하게 결합된 시스템을 설계할 수 있다. 이러한 시스템은 기능이 특정 기능 및 한정된 기능을 가진 개별적이며 작은 구성요소로 나뉜다.
이 모듈 방식의 장점은 한 구성요소의 변경이 해당 구성요소에만 영향을 미치고 다른 구성요소에는 영향을 미치지 않으므로 시스템 구현자가 시스템의 내부 작동을 더 자유롭게 생성하고 변경할 수 있다는 것이다.
계층적 접근 방식에선 운영체제가 여러개의 층으로 나뉘어진다.

  • layered approach

최하위 층은 하드웨어이고 최상위 층은 사용자 인터페이스이다.
운영체제 층은 데이터와 이를 조작하는 연산으로 구성된 추상된 객체의 구현이다.

계층적 접근 방식의 주된 장점은 구현과 디버깅의 간단함에 있다.
층들은 단지 자신의 하위층의 서비스와 기능들만을 사용하도록 선택된다. 이러한 접근 방법은 시스템의 검증과 디버깅 작업을 단순화한다.
예시로 첫 번째 층은 그 아래의 층만을 사용하여 이 층의 기능을 구현하기 때문에 나머지 시스템에 아무런 신경을 쓰지 않고 디버깅 할 수 있다.
각 층은 자신보다 하위 수준의 층에 의해 제공된 연산들만 사용해 구현한다. 한 층은 이러한 연산들이 어떻게 구현되는지 알 필요가 없고, 다만 이러한 연산이 무엇을 하는지만 알면 된다.
단점으로는 각 계층의 기능을 적절히 정의해야 한다는 문제가 있고, 시스템의 전반적인 성능이 운영체제 서비스를 얻기 위해 사용자 프로그램이 여러 계츠을 통과해야 하는 오버헤드로 인해 열악하다.

마이크로커널

2.8.4 모듈(Modules)

운영체제를 설계하는 데 이용되는 최근 기술 중 최선책은 아마도 모듈(LKM) 기법의 사용일 것이다. 이 접근법에서는 커널은 핵심적인 구성요소의 집합을 가지고 있고 부팅 때 또는 실행 중에 부가적인 서비스들을 모듈을 통하여 링크할 수 있다.
설계의 주안점은 커널은 핵심 서비스를 제공하고 다른 서비스들은 커널이 실행되는 동안 동적으로 구현하는 것이다.
전체적인 결과는 커널의 각 부분이 정의되고 보호된 인터페이스를 가진다는 점에서 계층 구조를 닮았다. 그러나 모듈에서 임의의 다른 모듈을 호출할 수 있다는 점에서 계층 구조보다 유연하다.(계층구조는 자신의 하위층 밖에 호출할 수 없었음)

  • 솔라리스 모듈

+추가

가상머신(virtual machine)

가상 머신은 논리적 결론에 도달하기 위해 계층화된 접근 방식을 취한다.
가상 머신은 하드웨어와 운영 체제 커널을 모두 하드웨어인 것처럼 취급한다.
가상 머신은 기본 하드웨어와 동일한 인터페이스를 제공합니다.
운영 체제 호스트는 프로세스에 자체 프로세서와(가상 메모리)가 있는 것처럼 착각을 일으킨다.

단점

실행하기 어렵다.

  • 기본 머신의 정확한 복제본을 제공해야한다.
  • 일반적으로 사용자 모드에서 실행되며 가상 사용자 모드와 가상 커널 모드를 생성한다.

시간이 문제가 될 수 있다.

  • 실제 머신보다 느리다.

하드웨어 지원이 필요하다.

  • 가상 머신 구조

0개의 댓글