OS/OS 파헤치기!
2장 컴퓨터 구조
dp.
2010. 8. 16. 01:47
OS를 구체적으로 논하기에 앞서서 먼저 OS가 담겨질 컴퓨터 구조에 대한 개괄적인 이해를 하는 시간을 갖도록 하자
지금부터 그림을 그리도록하겠다. 초록 들판위, 한가운데 씨피유가 버티고 있고 그 주변에는 디바이스(주변기기)들이 널부러져 있다. 그 사이에는 컨트롤러 라고 하는 톨게이트 같이 생긴것이 떡하니 버티고 서있고 톨게이트를 지나 씨피유와 디바이스를 연결해주는 길이있는데 이는 버스(BUS)라고 불리운다. 어떻게 한폭의 그림이 그려졌는가?
대충 내부구조가 머리속에 그려졌다면 잠시 컴퓨터 OS의 동작 흐름을 잠시 살펴보도록 하자.
먼저 컴퓨터의 전원이 들어오는 순간, 제일먼저 Bootstrap 프로그램이라는 것이 실행이 된다. 본 프로그램은 초기화(씨피유내부의 빠르지만 작은 용량의 레지스터라 불리우는 기억소자의 초기화, 디바이스 컨트롤러의 초기화, 메모리의 초기화 등등)를 모조리 시켜버린다.
쉽게 생각해서 컴퓨터 처음켜서 로고나오고 다음화면으로 넘어가기까지!!! 보통... 이 5초도 안걸리는 시간안에 슈루룩~~ 다 해버리고 OS의 커널 영역으로 진입하게 된다. 이후!! 하염없이 기다린다.......................................... 언제까지? 누구를? .... 정답은 이벤트!
좀더 정확하게 말하자면 인터럽트를 기다린다고 할 수 있다.
인터럽트는 매우 중요한 의미를 가지고 있는 사건이다. 주로 씨피유가 뭔가에 열중하고 있을 때(놀고있는 것도 열중에 포함됨) 인터럽터를 걸어 줌으로 써 씨피유가 인터럽트를 걸은 녀석이 요구하는 일을 수행하게 만드는 것이다.
그러면 엄청나게 다양한 인터럽트의 경우를 OS는 어떻게 다 알아차려서 정확하게 거기에 맞는 응답을 ,처리를 해줄수 있을까? ... 그렇다 . 컴퓨터는 모든종료의 인터럽트에 대한 모든 해결법을 이미 준비해 놓은 것이다. 각 인터럽트는 각 서비스 루틴과 일종의 함수관계를 가지고 있고, 씨피유는 단지 중간에서 짝맞추기 게임을 하고 있는 것이다. 어때 이해가 쉽게 가는가?
인터럽트는 또한 하드웨어적인 컨트롤러 뿐만 아니라 소프트웨어가 발생시키기도 한다. 이를 트랩(Trap) 이라고 불리우기도 한다. 이는 '시스템콜' 이라는 형태로 씨피유에 도달하게 된다. 자기만의 OS를 만드는 방법중에 하나가 이렇게 자기만의 시스템콜을 만들어 OS 에 추가시켜 특정한 목적의 OS 를 제작할 수 도 있다.
이러한 인터럽트의 발생을 씨피유는 어떻게 알아차릴까? 바로 특정한 패턴! 의 전기 신호가 시스템 버스를 따라서 씨피유에게 전달됨으로 씨피유는 인터럽트의 발생을 알아차리게 된다. 하드웨어에서 발생하건 소프트웨어에서 발생하건 인터럽트가 발생하게 되면 씨피유는 그 즉히 하던일을 중단해 버리게 된다. 그리고 실행권한을 어떤 '메모리의 고정된 위치'로 던저 주게 된다. 그 위치는 인터럽트 서비스 루틴이 시작되는 지점이며 루틴이 완료된 다음에야 씨피유는 하던일을 계속하게 된다.
자 여기서 궁금한점이 있지않은가? 바로 위에 문단에 마지막 문장 '루틴이 완료된다음에야 씨피유는 하던일을 계속하게 된다.'
어떻게? 현재 1부터 100까지 세어가는 중 15에서 인터럽트를 만나서 잠깐 일을 처리하고 돌아와 16부터 다시 셈을 해 나가야되는데 15까지 셈을 한것을 어디에 저장하지? . 컴퓨터에는 내부적으로 현재 실행주소가 항상 저장이 되는 레지스터가 존재한다. 이곳의 내용을 잠시 특정한 메모리 공간에 저장해 놓았다가, 인터럽트 처리후 다시 불러오면 되겠네? .. 정답! 하나하나 과정을 말하면 복잡하니 개념을 이렇게 잡아두자. 인터럽트 발생시 현재의 내용을 특정메모리 영역에 고스란히 저장해 놓았다가 인터럽트 처리가 끝나면 다시 불러온다. 따라서 하나의 인터럽트 처리시 다른 인터럽트가 들어와 특정메모리 영역을 덮어 버리면 어떻게 되는것인가? 그렇게 이전에 내용은 지워저 버려서 감당할 수 없는 결과가 나오게 된다. 여기에 대한 해결방법 한번쯤 생각해보도록...
위의 설명이 길고 장황하지 않은가? 그만큼 중요하기 때문이다. 이러한 인터럽트를 처리하는 구체적인 방법들이 나름대로 존재하는데 , 직관적이며 대표적인 방법이 '인터럽트 벡터'를 이용하는 것이다. '인터럽트 벡터' 의 개념은 아무리 인터럽트가 많아도 유한개의 인터럽트 집합이 존재한다는 전제에서 각 인터럽트 핸들링 서비스 루틴이 들어있는 주소를 가르키는 포인터를 테이블 화 한것이 바로 인터럽트 벡터이다. 즉, 인터럽트와 그 인터럽트에 해당되는 서비스루틴의 주소를 매치 시켜놓은 테이블! 이 바로 인터럽트 벡터이다.
이러한 개념은 여러분들이 잘 아는 MS-DOS 와 UNIX ,LINUX 에 적용되어 있다. 인터럽트가 발생하면 테이블 한번 쭉 훑어 본뒤에 대응되는 서비스 루틴의 시작주소를 한방에 콜! 하는 방식이다.
뭐 여러가지 다른 인터럽트 처리 방법들이 있지만 궁금한사람은 책을 찾아 보도록....
그럼 인터럽트라고 다 같은 인터럽트냐? 아니다. 인터럽트도 나름대로 계보가 존재하기에 우선순위가 주어지게 된다. 인터럽트가 한꺼번에 여러개가 발생하게 되는 경우 일종의 큐(먼저들어오는 녀석이 먼저 실행되는 구조의 저장공간)에 담아서 보관하게 되는데, 우선순위가 높은 인터럽트는 낮은 인터럽트를 그냥 무시하게 된다. 심지어는 실행되고 있는 낮은 우선순위의 인터럽트를 밀어내기도 한다.
인터럽트가 발생하였을 때 씨피유가 모든 I/O에게 인터럽트 발생한게 너냐? 라고 물어서 알아내는 방법을 폴링 이라고 한다. 또한 인터럽트를 발생한 디바이스 자체가 자진해서 씨피유에게 알려오는 방법을 인터러브 드리븐 방식이라고 한다. 현대의 OS는 인터럽트 드리븐 방식이다.
I/O 이야기가 나온김에 잠시 언급하고 넘어가자면 먼저 컨트롤러에 대해 생각해 봐야한다. 초반에 그려두었던 그림이 생각가는가? 거기에서 컨트롤러를 떠 올려보자 . 기본적으로 하나의 주변기기에 하나의 컨트롤러가 달려있지만, 하나 이상의 주변기기를 달아줄 수도 있다. 그 대표적인 예가 바로 스커지(SCSI: Small Computer System Interface) 이다. 이 방식에서 최대 7개 이상의 디바이스들을 데이지 체인 방식으로(서로 꼬리에 꼬리를 물어 연결이 되어있는) 연결이 가능하였다. 이 스커지의 최대 특징은 바로 독립성에 있는 듯한데, 스커지 어뎁터에는 이미 또 한개의 입출력만을 전담하는 독립된 씨피유를 가지고 있기에 그만큼 씨피유에 부과될 인터럽트를 '내선에서~' 처리 가능하게 해주는 믿음직한 장치이다. 하지만 요즘은 씨피유의 능력이 워낙 뛰어나게 발전하여 입출력으로 인한 인터럽트는 껌으로 여긴다.
이러한 디바이스 컨트롤러는 결국 데이터를 주변 디바이스들간에 옮기는 책임을 전담하고 있는 장치이며, 버퍼를 가지고 있다. 입출력을 시작하기 위하여 일단 씨피유가 디바이스 컨트롤러 내부에 존재하는 레지스터안에 적당한 명령어와 데이터를 셋팅하게 된다. 그럼 디바이스 컨트롤러는 차례로 그 명령어들을 하나씩 읽어봄으로써 어떠한 조치를 취해야 하는지 판단하게 된다.
자, 여기서 잠깐 알아두고 넘어갈 포인트 ! 사용자에 의해 데이터 입출력이 시작되었을 때 사용권한에 대한 두 가지 경우가 발생하게 된다. 첫번째는 입출력의 과정이 모두 끝날때 까지 기다렸다가 씨피유의 사용권한이 유저에게 넘어가는 경우(이것을 동기적 I/O) 와 I/O가 시작된 것만 확인하고 바로 유저에게 사용권이 넘어가는 경우(비동기적I/O) 가 있다. 어떤경우와에 사용되는지 구현원리를 알고싶은 사람은 책을 찾아보도록...
I/O 라고 해서 다 똑같이 취급해서는 안되는 경우가 있다. 이러한 경우는 특수한 경우의 I/O 인데 대표적으로 DMA 가 바로 이 경우에 해당된다. 보통의 경우 씨피유가 중간에서 중재자 역할을 하게 되는데 이러한 중재자 역할이 초고속 디바이스인 메모리와의 데이터 교환에 있어서는 오히려 번거로운 존재가 되어 버린다. 따라서 일부 디바이스 드라이버는 DMA 컨트롤러의 레지스터에 소스 주소및 데스티네이션 주소, 그리고 단위전송 크기를 셋팅한 뒤 씨피유의 클럭을 찔끔찔끔 훔쳐내면서 원하는 디바이스와 메모리와의 데이터 교환을 직접 하도록 유도해 준다.
이러한 특수한 형태의 I/O의 예로 memory-mapped I/O 가 있다. 이는 램의 특정 영역이 디바이스 컨트롤러의 레지스터 들과 1:1 대응관계를 갖도록 먼저 약속을 하여 램에 전송할 데이터를 쇽쇽 넣어주게 되는 것이다. 램은 빠르니까...
오늘은 이만....대충 어렵지 않으리라 생각된다. 나도 정리를 하면서 세삼 다시 알아가는 것 같아 기분이 좋다 ㅎㅎ