컴퓨터를 만듭시다. 어때요~ 참 쉽죠? (25)

나빌레라의 이미지

#25. 위그드라실

위그드라실은 북유럽 신화에 나오는 세상을 떠 받치고 있는 거대한 나무다. 이 거대한 나무의 세 줄기에 인간 세상, 지하의 세상, 신들의 세상으로 뻗어 있다. 소프트웨어의 세계에서 위그드라실같은 존재가 운영체제다. 물론 어떤 임베디드 환경에서는 운영체제 없이 단일 펌웨어 만으로 동작하는 시스템도 있겠지만 일단 운영체제가 탑재된 환경에서는 시스템의 모든 제어는 운영체제를 통해서 이뤄진다.

웹 사이트를 돌아다니며 웹 서핑을 한다든가, 지금 나 처럼 워드프로세서를 띄워놓고 글을 쓴다든가, 게임을 한다든가하는 모든 일들은 운영체제가 먼저 동작하고 그 운영체제 위에서 동작하는 프로그램에 의해서 이뤄진다. 운영체제는 컴퓨터 시스템의 모든것을 지배하고 있고 컴퓨터 사용 환경을 가장 크게 결정짓는 요소라고 볼 수 있다. 쉽게 말해 윈도우를 운영체제로 쓰는 사람이 주로 사용하는 프로그램과 나 처럼 리눅스를 운영체제로 쓰는 사람이 주로 사용하는 프로그램은 그 목적이 같은 프로그램이라 할 지라도 서로 다른 프로그램을 쓰는 경우가 많다. 내가 이 이야기를 윈도우에서 쓰고 있다면 아래 한글이나 마이크로소프트 워드를 사용하고 있겠지만 리눅스에서 쓰고 있기에 오픈 오피스 워드로 작업하고 있다. 요즘은 크로스 플랫폼 프로그램들이 잘 나오고 있어서 윈도우에서도 오픈 오피스를 동일하게 사용할 수 있겠지만 크게 봤을 때 리눅스에서 사용하는 비중이 아무래도 높을 것이다. 단적인 예로 나는 리눅스에서 인터넷 익스플로어를 특별한 설정없이 사용할 수 없다. 강제로 사용하는 방법이 없는 것은 아니지만 윈도우 환경에서처럼 자연스럽게 잘 동작하게 하려면 상당한 노력이 필요하다.

이런 운영체제는 어떻게 만들어지는 것일까. 운영체제를 만드는 과정 자체는 일반 프로그램을 만드는 과정과 크게 다르지 않다. 다만 운영체제가 제공하는 많은 라이브러리를 사용하지 않고 자체적으로 만들어야 하며 컴파일, 링킹을 거쳐 만들어진 바이너리 파일이 운영체제 위에서 동작하는 실행 파일 형식이 아니라 cpu에서 바로 실행되는 기계어 파일이라는 점이 다르다.

운영체제를 만드는 방법 역시 그 자체만으로 아주 두꺼운 책을 쓸 수 있을 정도로 방대한 내용이다. 나 역시 얼마 전에 임베디드 운영체제를 만드는 방법에 대한 책을 냈다. 이 이야기를 읽는 분들 중 관심이 있다면 찾아서 구매해 주기 바란다. 생각보다 쉽게 찾을 수 있을 것이다.

이번에도 역시 운영체제에 대해서 큰 그림을 이야기하는 정도로 맞춰볼 생각이다.

운영체제는 말 그대로 컴퓨터 시스템을 운영하는 프로그램이다. 그리고 제대로된 운영을 위해서는 안정적으로 동작해야 하고 빠르게 동작해야 하면서 시스템의 자원을 적게 소모해야하는 등 많은 조건을 만족시켜야할 필요가 있다. 또한 운영체제가 동작하는 시스템의 특성에 따라서 운영체제에서 해주어야 하는 기능도 결정된다. 범용으로 쓰는 PC에서는 운영체제가 해 주어야 할 일이 아주 많지만 MP3 플레이어 같은 작고 간단한 기계에 탑재되는 운영체제가 해 주어야 할 일은 PC의 그것보다 상대적으로 적다. 그래서 내가 이 이야기에서 말하는 운영체제의 기능들 중 어떤 기능은 특정 환경의 운영체제에서는 필요없는 경우도 있다. 예를 들어 일반 PC에서는 네트워크 관리 기능이 거의 필수적으로 필요할 테지만 이족 보행 로봇에 탑재되는 RTOS에는 네트워크 관리 기능이 꼭 필요한 기능은 아닐 것이다.

운영체제의 가장 기본적인 기능은 누가 뭐라해도 당연히 태스크 관리 기능이다. 프로세스 관리라고도 한다. 태스크와 쓰레드와 프로세스를 구분하는 기준은 운영체제 이론서마다 운영체제마다 모두 그 기준이 다르다. 나는 이 이야기에서 그냥 태스크라고 말하고 그 기준은 운영체제에서 동작하는 개별적인 프로그램이라고 정리하겠다. 요즘 운영체제는 기본적으로 여러개의 프로그램이 동시에 동작하는 것을 지원하다. 흔히 멀티 태스킹 운영체제라고 한다. 대부분의 프로그램들은 사실상 대부분의 시간을 사용자의 입력을 대기하거나 디스크 입출력을 대기하는데 사용한다. CPU의 성능은 점점 좋아지고 있기 때문에 이렇게 프로그램이 입출력에 대기하고 있는 동안 CPU는 계속 놀고 있게된다. 이 CPU의 노는 시간에 CPU에게 일을 시키기 위해 등장한 방법이 멀티 태스킹이다. 운영체제 안에서 동작하고 있는 프로그램들이 CPU를 차지하는 시간을 짧게 끊어서 돌아가며 쓰도록 하는 것이다. 멀티 태스킹에서 태스크가 CPU를 점유하는 방식도 선점형이니 비 선점형이니 하는 여러 방법이 있고, 태스크가 CPU를 점유하는 순서도 우선 순위를 줘서 하는 방법 그냥 순서대로 돌리는 방법 등 여러 이론이 있다. 운영체제는 이런 여러 가지 방법 중에서 몇 가지를 골라서 지원해 주는 것이다. 그러기 위해서 동작 중인 태스크를 추상화해서 관리할 수 있는 수단이 필요하고 이것이 태스크 관리 기능이다.

동작 중인 태스크에 대한 자료구조를 정의한다. 자료구조에는 해당 태스크가 동작 중이던 직전 상태의 레지스터 정보와 CPU 상태 정보가 필수로 들어가고 부가적으로 해당 태스크의 우선 순위 정보나 동작 시간 정보 같은것들은 운영체제의 설계 정책에 따라 포함된다.

태스크 관리 기능과 연결되어서 운영체제의 성능을 좌우하는 기능 중 하나가 스케줄링 기능이다. 멀티 태스킹에서 운영체제 위에 돌아가는 태스크들은 운영체제의 정책에 따라 CPU를 점유한다.

여기서 CPU를 점유한다는 말은 태스크 추상화 자료 구조에 있는 레지스터 정보와 CPU 상태 정보가 실제로 CPU에 저장된다는 말이다. CPU를 점유하고 다시 다른 태스크에서 CPU를 넘겨주기 전에 CPU에 있던 레지스터 값과 상태 값은 다시 메모리로 저장된다. 다음에 다시 CPU를 점유할 차례가 오면 이 메모리에 저장되어 있던 값이 CPU로 옮겨지는 것이다.

태스크가 CPU를 점유하는 순서를 정해주는 정책이 스케줄링 정책이다. 일반적으로 가장 쉽게 구현할 수 있는 스케줄링 방법은 아무 조건도 이유도 없이 운영체제 위의 태스크를 순서대로 하나씩 동작시키는 방법이다. 흔히 라운드로빈 방식이라고 한다. 라운드로빈 방식의 문제점은 어떤 조건에서는 어떤 태스크가 급하게 실행되어야 하는데, 라운드로빈에 의해 순서가 오지 않으면 해당 태스크는 실행이 되지 않기 때문에 시스템 전체의 응답성이 떨어지는 점이다. 이 문제점을 해결하기 위해서 우선 순위 스케줄링이라는 방식이 대두되었다. 각 태스크 별로 우선 순위를 할당해 놓고, 우선 순위가 낮은 태스크가 실행 중에 있는데, 우선 순위가 높은 태스크가 실행되어야 할 조건이 온다면 우선 순위가 낮은 태스크는 그 즉시 실행이 중단되고 우선 순위가 높은 태스크가 동작되는 방식이다. 이 방식에도 두 가지 분류가 있다. 하나는 정적 우선 순위 방식이고 다른 하나는 동적 우선 순위 방식이다. 정적 우선 순위 방식은 태스크가 처음 실행되는 시점에서 우선 순위를 할당 받고 이 우선 순위는 태스크가 끝날 때까지 변하지 않는 방식이다. 동적 우선 순위 방식은 태스크가 동작하는 도중에라도 운영체제에 의해서 우선 순위가 계속 바뀌는 방식이다. 당연히 정적 우선 순위 방식이 복잡도가 덜하다.

태스크 관리 기능외에 또 꼭 필요한 기능은 시스템 자원 관리 기능이다. 임베디드 시스템을 포함한 컴퓨터 시스템에는 여러가지 자원이 연결되어 있다. 그 중 가장 중요한 자원은 누가 뭘라고 해도 메모리다. 태스크의 실행 코드, 데이터, 운영체제의 많은 자료 구조들. 컴퓨터의 모든 정보는 모두 메모리에 저장되어있다. 지난 이야기에서 CPU를 만들 때도 메모리는 빠지지 않았다. 메모리가 없으면 컴퓨터는 제대로 된 동작을 할 수 없다. 그러므로 운영체제는 이 메모리를 효율적으로 그리고 빠르게 관리할 수 있는 기능이 필요하다.

일반적으로 메모리 자원은 한정되어 있으나 시스템에서 동작하는 프로그램들은 더 많은 메모리를 요구하는 경향이 강하다. 운영체제는 한정된 메모리 자원은 프로그램들에게 서로 겹치거나 충돌되지 않게 잘 할당해야 하며 할당된 메모리 역시 잘 관리해야 한다. 그리고 한정된 메모리를 효율적으로 관리하기 위한 방법으로 하드웨어의 지원하에 MMU 등을 사용해서 가상 메모리를 구현하기도 한다. 덕분에 프로그램들은 메모리의 한계를 그다지 생각하지 않고 동작할 수 있게 되었고 운영체제는 한층더 복잡해 졌다.

운영체제는 주변 장치들도 제어해야 한다. 대부분의 운영체제는 디바이스 드라이버라는 형식으로 주변 장치 제어를 지원한다. 주변 장치 제조 업체에서는 지원하고자 하는 운영체제의 디바이스 드라이버를 작성하고 운영체제 사용자들은 그 디바이스 드라이버를 자신의 시스템에 설치해서 주변 장치를 사용하는 것이다. 디바이스 드라이버를 만들기 위한 방법은 운영체제마다 모두 다르다. 응용 프로그램은 디바이스 드라이버를 통해서 주변 장치를 제어하기 위해서 운영체제가 정해놓은 방법을 따라야한다. 그래서 같은 목적을 가진 다른 주변 장치를 사용하더라도 디바이스 드라이버만 달라질 뿐이지 그것을 사용하는 응용 프로그램은 변경을 하지 않아도 잘 동작한다. 일반적으로 디바이스 드라이버를 작성하는 방법은 응용 프로그램을 만드는 방법에 비해서 난이도가 조금 높다. 관련 자료도 부족한 편이고 하드웨어와 소프트웨어의 특징을 모두 다 잘 알고 있는 사람이 만들 수 있기 때문이다.

메모리나 주변 장치에 대한 접근 제어 방법도 제공한다. 여러 태스크가 하나의 주변 장치 혹은 같은 메모리 주소에 대해서 쓰기 동작을 할 경우 데이터가 깨져서 앞서 동작했던 태스크가 실행에 문제를 일으키는 경우가 생길 수 있기 때문이다. 그래서 주변 장치나 메모리에 대해서 배타적으로 접근할 수 있는 방법이 필요하다. 이런 방법과 수단을 제공하는 것 역시 운영체제의 역할이다.

그외에 시스템의 전원 관리 같은 기능도 운영체제의 주요 기능중 하나다. 데스크톱 PC에서도 중요하겠지만 노트북 PC 환경이나 저전력이 더욱 중요한 임베디드 환경 같은 경우에는 운영체제의 전원 관리 기능은 운영체제 전체의 성능을 결정짓는 요소중 하나가 되기도 한다. 운영체제의 전원 관리 기능은 어떤 면에서 태스크 관리 기능과도 깊은 연관이 있다. 동작 중인 태스크들이 모두 특별한 연산없이 입출력 대기 상태에 있다면 잠시 시스템을 저전력 모드로 바꿔놓을 수 있을 것이다. 그러다가 사용자의 입력같은 인터럽트가 들어오면 시스템을 다시 동작시키는 등의 관리 기능은 태스크 관리 기능과 잘 연결되어야 한다. 마찬가지로 디바이스 드라이버 관련 정책을 정의할 때 저전력 모드에서 디바이스 드라이버를 어떻게 해야 할지 등을 제조사에서 결정할 수 있도록 인터페이스를 만들어 두는 것같은 작업도 필요하다.

운영체제는 방대하다. 운영체제에 대한 간단한 소개글 정도로 이번 이야기를 썻다. 중요한것은 운영체제가 어떤것이다라는 것이 아니라 내가 이끌어온 이 이야기를 통해서 운영체제 역시 프로그램이고 프로그램인 만큼 이 이야기에서 했던 프로그래밍 언어로 만들 수 있다라는 것을 강조하고 싶다. 또한 프로그래밍 언어는 어셈블리어로 만들 수 있고, 어셈블리어는 하드웨어와 연결되며 그 하드웨어는 결국 게이트의 집합일 따름이며, 게이트는 플립플랍의 집합, 플립플랍은 트랜지스터 혹은 릴레이 스위치의 집합이고 릴레이 스위치는 전선과 스위치로 만들 수 있다는 것을 말하고 싶은 것이다.

이제 내가 하고 싶었던 이야기는 모두 끝났다. 지금까지 이 두서없고 허접한 이야기를 읽어주신 많은 분께 진심으로 감사의 마음을 전한다.

댓글

세벌의 이미지

질문 있어요...글 내용 중...
단적인 예로 나는 리눅스에서 인터넷 익스플로어를 특별한 설정없이 사용할 수 없다.
어떻게 하면 가능한지요?

http://sebul.sarang.net/

octaphial의 이미지

"단적인 예로 나는 리눅스에서 인터넷 익스플로어를 특별한 설정없이 사용할 수 ***없다***." "있다"가 아니네요.

세벌의 이미지

제가 잘못 봤네요. 보기는 "없다"를 보면서 생각은 "있다" 라고 하다니... 복사 붙이기를 하면서도...

http://sebul.sarang.net/

kimback100의 이미지

완전 생초보

수박겉핡기가 되어버렸습니다. 중간에 헐렁헐렁 넘어가다보니 그만......ㅉㅉㅉㅉㅉㅉㅉ

완전 생초보

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.