Chap2. 컴퓨터 시스템과 운영체제 1,2절
1. 컴퓨터 시스템과 하드웨어
1-1 컴퓨터 시스템의 범위
컴퓨터 시스템은 3개의 층이 있다.
<컴퓨터 시스템의 계층 구조에서 알 수 있는 것>
- 사용자는 응용 프로그램이나 운영체제 패키지에 포함된 GUI와 도구 프로그램을 통해 컴퓨터를 활용한다.
- 하드웨어들은 모두! 운영체제의 독점 지배 받는다.
- 모든 사용자나 응용프로그램은 직접 하드웨어에 접근할 수 없다. 반드시 운영체제를 통해 접근한다.
- 운영체제는 하드웨어와 응용소프트웨어 사이의 중계 역할 한다.
-> 운영체제의 본질은 사용자로부터 하드웨어를 숨겨주는 것. (사용자가 하드웨어에 대한 구체적인 내용을 몰라도 컴퓨터를 사용할 수 있도록.)
1-2 컴퓨터 하드웨어
일반적인 컴퓨터 하드웨어 구성은 다음과 같다.
- CPU ( Central Processing unit)
- 프로그램코드(기계명령. 그냥 명령이 아니라 기계명령.) 실행하는 중앙처리장치. 전원 공급시 작동시작, 메모리에 적재된 프로그램 실행
- 컴퓨터 시스템 전체에서 master은 cpu 하나다. 야 디스크! 이거빨리 저장해. 야 메모리! 나한테 프로그램코드랑 데이터 줘. 야 프린터! 인쇄해! 등등 slave는 시키지 않으면 일을 안함.
- PC -> 프로그램 카운터. 지금 다음에 처리할 명령의 메모리주소를 저장하고있는 PC(program coounter)
- CPU가 버스로 100번지 손들어! 하면 다들 명령을 전달받는다. 다 듣고 나서, 어? 나부르네 하고 100번지에 있던 메모리가 응답한다.
- CPU 안에는 임시기억장치, 레지스터가 있음. 148236+3278513 하면 숫자들 먼저 기억한다음에 계산을 해야됨. 그 숫자들을 임시 기억.
- ROM - read only memory -> 처음에는 아무것도 없는 빈공간인데, rom write 라고 하는 곳에 롬을 넣어서 굽는다고 표현. 프로그램 하나를 구우면 영구적으로 프로그램 하나가 들어가 있다. 전원을 켜자마자, rom
- BIOS - 바이오스 롬 안에 들어가 있는 프로그램 코드인데, 메모리에 555 적어봣다가 잘 적혔는지 읽어봤다가... 마지막에는 하드웨어의 첫번째 섹터를 메모리에 올린다. 그럼 cpu는 그걸 처음으로 수행한다.
- cpu는 절대 쉴 수가 없다. 전원공급 되면. 의미없는 일이라도 하고 있는 중이다.
- 클럭 - cpu에게 일을 시키는 놈이 cpu에 주는 신호. 메모리에게도 감.
- 메모리
- CPU에 의해 실행되는 프로그램 코드와 데이터가 적재되는 공간.
- 반도체 메모리 RAM이 사용된다, 프로그램은 실행되기 위해 반드시! 메모리에 적재되어야 한다.
- 캐시 메모리
- 배경 : CPU의 발전속도가 메모리 발전속도보다 빨라 느린 메모리 때문에 CPU가 대기하는 시간을 줄이려고 탄생.
- 프로그램 실행 속도(메모리가 너무 느려서 떨어지는 프로그램 실행속도)를 높이기 위해 CPU와 메모리 사이에 빠른 캐시 메모리 사용.
- 옵칩 캐시(off-chip cache) - 초기에 시스템 버스에 연결되는 방식으로 사용됨
- 온칩 캐시(on-chip cache) - 이후 캐시메모리를 아에 CPU 내부에 둠. CPU의 보다 빠른 사용을 위해.\
- 비싸서 소량만 사용한다.
- 캐시메모리가 있는 컴터에서, CPU는 캐시 메모리로부터만 명령과 데이터 읽어 실행함. 메모리에서 캐시메모리로 프로그램코드와 데이터 한번 복사되고 실행됨.
- 캐시 메모리의 용량은 매우 작음. -> 현재 실행할코드, 데이터 일부분만 저장됨
- 용량이 작아도 for문 하나 가지고 있으면 10만번 돈다 생각하면 한동안 계속 돈다. 캐시메모리는 용량이 작아도 매우 효율적이다.
- 장치들
- 키보드, 프린터, 스캐너, 마우스, 디스플레이, 네트워크장치, 입출력장치, 디스크, SSD, USB메모리 등 저장 장치들 이 있다.
- 버스
- 컴퓨터 하드웨어들이 서로 데이터를 주고받기 위해 0과 1의 디지털 신호가 지나가는 여러 가닥의 선의 다발. (CPU,캐시메모리,메모리 등)
- 버스라기보단, 도시와 마을들 연결하는 도로에 가까움 -> 자동차들은 0과 1의 디지털정보.
- 종류는 세개, 주소버스- 주소신호가 지나다니는 버스()
- 주소=> 메모리나, 입출력 장치나 저장장치 내에 있는 레지스터들에 대한 번지이며 0번지에서 시작한다.
- 데이터버스 - 데이터신호가 지나다니는 버스(코드나 데이터가 지나다님. -> 양방향 버스)
- 제어 버스 - 제어신호가 지나다니는 버스(인터럽트 신호, 메모리 읽기/쓰기신호, 클럭신호 등)
- 시스템버스와 입출력 버스
- 시스템버스 : CPU, 캐시메모리, 메모리 등 빠르게 작동하는 하드웨어들 사이에 신호를 전송하기 위한 버스 (고속도로)-> 빠른 애들끼리만 쓰는 도로
- 입출력버스 : 상대적으로 느린 입출력장치들로부터 입출력 데이터를 전송하기 위한 버스이다.(일반도로-시내버스, 자전거, 오토바이, 자동차 트럭 등 다양한 차들이 섞여 속도를 내지 않고 다니도록 규정함) -> 느린 애들만 쓰는 도로
- 시스템버스나 입출력 버스 모두 각각 주소버스, 데이터버스, 제어버스로 구성된다.
- 입출력 제어 장치 및 시스템 제어 회로
- 입출력장치들을 제어하기위한 여러 하드웨어 회로 포함.
- 입출력 장치에게 명령을 내리고 메모리와 입출력 장치 사이, CPU와 입출력장치 사이에 데이터가 전달되도록 중계.
- 장치들이 입출력 완료했을 때 발생시키는 인터럽트신호 받아 CPU에 전달하는 인터럽트 제어장치, CPU의 개입없이 입출력장치와 메모리 사이의 데이터 직접 전송하는 DMAC, 등이 포함된다.
1-3 CPU와 메모리의 관계
32비트 컴퓨터, 32비트 CPU, 32비트 운영체제 할때 32비트는 무슨 뜻일까?
우선 32비트 CPU란 32개의 주소선을 가진 CPU라는 뜻. 이 32개의 주소선은 주소버스와 연결된다.
CPU가, 32개의 주소선을 통해 주소를 출력한다.
-> 32비트의 주소가 주소버스를 통해 메모리에게 전달된다. (주소선의 한가닥=한비트 전달됨 / 주소버스는 시스템버스)
-> 메모리는 주소 버스를 총해 주소를 전달받고 해당 주소의 데이터를 데이터버스에 내놓는다. (데이터버스도 시스템버스)
-> CPU는 자신의 데이터 선을 통해 데이터값을 CPU내부로 읽어들인다.
==> 메모리가 데이터버스에 cpu가 요청한 데이터 내놓는 속도가 느린 경우 cpu는 주소를 발생시키고 오래 기다려야 함.
32개의 주소선을 가진 CPU가 액세스할 수 있는 주소의 범위 : 2의 32제곱 개의 서로 다른 주소
( 0 ) ~ (2의 32제곱 -1 번지)
한 번지의 크기는 1바이트이므로, 32비트 CPU가 액세스할 수 있는 메모리의 최대 범위는 2의 32제곱 바이트 = 4GB 이다!!
그러므로 32비트 CPU를 가진 컴퓨터에서 사용할 수 있는 메모리 최대 크기는 4GB이다
4GB이상의 메모리는 설치한다해도 32비트 CPU로는 접근할 수 없다!프로그램을 아무리 크게 작성한다고 해도 코드와 데이터 등 프로그램이 활용할 수 있는 메모리는 4GB를 넘을 수 없다는 뜻.
->근데 함정은 4GB에서 운영체제공간 제외하고 나머지만큼이 프로그램이 활용가능한 최대공간임.
->윈도우는 4GB중 2GB, 리눅스는 3GB로 설정되어있다.
==> 32비트 운영체제는 32비트의 주소체계로 관리하는 운영체제이다.!!!
1-4 CPU 기계명령
CPU 명령은 CPU가 해석하고 실행할 수 있는 기계명령이다. (C나 JAVA와는 다름)
기계명령은 인텔같이 CPU를 설계하는 기업이 CPU를 설계할 때 결정하고, CPU마다 명령 개수, 명령형태가 다르다.
아래 그림은 "hello" 를 출력하는 C프로그램 hello.c를 비주얼 스튜디오에서 컴파일한 것을 정리함.
C프로그램을 어떤 CPU를 대상으로 컴파일 했는지에 따라 기계어가 달라지므로 컴파일된 코드는 다른 CPU에서 호환성이 없다.
1-5 CPU의 일생
CPU는 쉬지 않는다. 전원이 켜지고 나서부터 전원꺼질때 까지 계속 뭔가를 실행한다.
바로 CPU의 기계명령들을 실행한다. 프로그램은 연속적으로 나열된 기계명령어들의 집합이다
이 프로그램(기계명령)들이 저장되는 장치는 메모리이고 명령어가 실행되는 장치는 CPU내부이다.
CPU의 명령 사이클
-> CPU가 한개의 명령을 처리하는 세부 과정이다.
명령을 실행하기 위해, CPU는 명령을 메모리로부터 읽어오는 작업부터 시작한다.
mov eax, [300] ; ->메모리 300번지의 데이터를 읽어 eax레지스터에 저장해라. 라고 했다하자.
이 명령이 메모리 100번지에 있다고 하자. 그러므로 현재 CPU의 PC 레지스터에는 100이 들어있다.
- 1. CPU는 PC레지스터에 저장된 주소 100을 주소 버스에 싣는다.
- 2. 메모리는 주소버스로부터 주소 100을 받고, 100번지에 저장된 데이터( mov eax, [300] )를 데이터버스에 싣는다.
- 3. CPU는 데이터 버스에 담긴 바이너리값들을 IR레지스터에 저장하고, PC는 다음 명령의 번지로 수정된다.
- 4. CPU는 연산에 필요한 데이터를 읽기 위해 데이터의 주소 300을 주소 버스에 싣는다.
- 5. 메모리는 300번지에 저장된 값 50을 데이터버스에 싣는다.
- 6. CPU는 데이터버스로부터 50을 CPU내부의 임시 레지스터에 저장한다.
- 7. CPU는 명령을 해석하고 명령을 실행한다. 명령실행 결과 50이 eax레지스터에 저장된다.
CPU의 레지스터 종류
- PC - 다음 실행할 기계명령의 메모리주소를 저장하는 레지스터 (주소만. 명령은 메모리안에 있음. IR에도하나잇음)
- IR - 실행하기 위해 메모리에서 읽어온 명령이 저장된 레지스터
- SP - 스택영역 꼭대기 메모리주소를 저장하는 레지스터
- 데이터레지스터들 - 연산에 사용될 데이터들을 저장하는 레지스터들
- 상태레지스터 - CPU의 상태정보나 인터럽트 금지 등 제어정보를 가지는 레지스터
- 기타 레지스터들 - 페이지 테이블이 저장된 메모리주소를 가리키는 레지스터 등 운영체제의 실행을 도움.
1-6 스택(STACK)은 어디에 있는가?
운영체제는 프로그램을 실행 시킬 때 마다 프로그램에게 각 4개의 공간을 부여한다.
- 코드 공간 - 프로그램 코드가 적재됨
- 데이터 공간 - 프로그램의 전역변수 적재됨
- 힙 공간 - 동적할당 받아 메모리를 사용할 수 있도록 놔둔 공간
- 스택 공간 - 함수 호출될 때 매개변수, 지역변수, 함수가 실행 마치고 돌아갈 코드공간의 주소, (함수 코드가 의도적으로 스택에 저장한 값 -> 함수에서 스택을 만들었을때 라는 건가...?) 등을 저장.
코드공간의 프로그램코드를 실행 하다가, 함수가 호출되면 스택공간으로 가서 복작복작하다가 다시 코드공간으로 넘어감.
각 프로그램 마다 각자 스택이 할당된다. 스택은 별거 없고 그냥 함수관련 정보들을 저장하고 있는 메모리공간이다.
CPU의 SP(STACK POINTER)가 현재실행중인 프로그램의 스택 영역 꼭대기 주소를 가리킨다.
1-7 컨텍스트
컨텍스트는 '어떤 프로그램이 실행되고 있을 때의 상황'을 말한다.
그 상황은 프로그램이 진행되는 동안 CPU의 레지스터들과 메모리에 있다.
이때 메모리 위에는 하나의 프로그램마다 운영체제가 부여한 1. 코드공간, 2. 데이터공간, 3. 힙공간, 4. 스택공간이 있다.
CPU의 레지스터에는,
PC 레지스터 - 현재 실행중인 코드의 메모리주소
데이터 레지스터 - 이전에 실행된 결과나 현재 실행에 사용될 데이터 값들
상태 레지스터 - 현재 CPU의 상태정보
SP 레지스터 - 스택의 탑 주소
가 저장된다.
이때, 현재 실행중인 프로그램에서 다른 프로그램으로 넘어가려 할 때 메모리에는 계속 실행중인 프로그램들이 올라가 있으므로 메모리에 있는 컨텍스트정보는 놔두고, CPU안의 레지스터는 당장 다른 프로그램이 사용해야 하기 때문에 레지스터 안의 값을 메모리의 특정 영역에 저장한다. 이 영역을 프로세스 제어 블록이라 하며, 운영체제의 커널 안에 있다.
메모리 위에는 운영체제공간과 응용프로그램공간, 등이 있는데, CPU의 레지스터 정보는 운영체제 공간 안에>> 커널 안에 >>프로세스 제어블록 안에 저장 된다.
예를 들어, 시분할 운영체제에서 A프로그램을 작동시키다가 정해진 타임 슬라이스 후에 B프로그램을 작동시키려 한다.
그때, A프로그램이 진행되던 상황을 저장해놓지 않는다면 CPU가 한바퀴를 돌고와서 다시 A를 처리하는데 (CPU의 성능은 그때나 지금이나 같을것이므로 ) 첫번째에 처리했던 곳 까지 딱 끝내고 다시 다음 프로그램으로 넘어갈 것이다. (이게 무한반복이겠다.)
무튼 그래서 컨텍스트 스위칭에서는 현재 실행중인 A의 컨텍스트를 운영체제커널의 프로세스 제어블록 안에 저장해두고, B의 이전 컨텍스트를 CPU로 다시 불러온다.
컨텍스트 스위칭 이후에, CPU의 PC - 프로그램 B가 실행을 재개할 코드의 주소 가리키고,
SP - 프로그램 B의 스택영역(톱주소) 가리킨다.
1-8 멀티코어 CPU
원래 전통적인 의미의 cpu는 1개의 제어장치, 1개의 ALU(산술논리연산장치), 여러개의 레지스터들을 갖추고 프로그램을 실행하는 프로세서이다. 1가지의 프로그램만 실행시킬 수 있다.
그러나, 멀티코어 CPU라는 것이 개발 되었는데, 그러면 여기서 코어란 뭐냐.
코어 하나는 다음과 같다. 코어 하나에 독립적으로 프로세싱에 필요한 레지스터들을 모두 가지고 있고, ALU(산술논리연산장치), 제어장치까지도 가지고 있다. 또 외부 버스와 연결되는 인터페이스 장치도 가지고 있다.
즉, 코어는 독립적으로 하나의 프로세스를 처리할 수 있고, 전통적인 의미의 CPU와 같다. 멀티코어 CPU는 CPU안에 전통적의미의 CPU인 코어 여러개가 들어가 있는 것이다.
인텔의 i7 CPU는 4개의 코어를 가지고 있고, 4개의 프로그램을 동시에 실행할 수 있다.
2. 컴퓨터 시스템과 운영체제
2-1 컴퓨터 시스템의 계층 구조
컴퓨터 시스템이 이렇게 계층구조를 갖는 이유는 계층간의 독립성을 확보하기 위함이다.
사용자는 운영체제, 하드웨어에 대해 몰라도 응용프로그램을 통해 컴퓨터를 활용할 수 있고 응용프로그램도 컴퓨터 하드웨어 타입이나 제어방법에 대해 구체적으로 몰라도 개발 할 수 있다.
1. 운영체제와 응용프로그램 사이의 관계
-> 운영체제의 역할이기도 한데, 운영체제는 응용프로그램이 직접 하드웨어를 다루지 못하도록 차단한다.
응용프로그램이 하드웨어에 접근하기 위해서는 반드시 운영체제에게 시스템호출 함수를 이용해서 서비스를 요청해야한다. 시스템호출 외 하드웨어에 응용프로그램이 접근 할 수 있는 방법은 없다.
왜 하드웨어를 독점적으로 관리할까? -> 응용프로그램 간의 자원충돌을 막기 위함이다. 두 응용프로그램이 같은 디스크에 데이터를 저장한다던지, 한 응용프로그램이 읽고있는 파일을 다른 응용프로그램이 지워버리거나 할 수 있다. 이런 사태를 막기 위해 운영체제는 독점적으로 모든 컴퓨터 하드웨어를 조작한다.
2. 운영체제와 사용자의 관계
3. 운영체제와 하드웨어의 관계
2-2 운영체제의 전체 기능
2-3 운영체제와 커널
운영체제는 도구/GUI 소프트웨어, 커널, 디바이스 드라이버 들로 구성되는 소프트웨어이다.
점선으로 묶어진 것이 운영체제이다.
1. 도구 소프트웨어
- 파이 탐색기, 제어판, 장치 관리자, 작업관리자, 윈도우 파워쉘 등 (리눅스에는 쉘 있음.)
- 사용자가 컴퓨터를 편하게 사용할 수 있도록 함, 운영체제 패키지에 포함되어 같이 설치됨.
2. GUI
- 윈도우 바탕화면
3. 커널
- 부팅 후에 메모리의 운영체제 공간에 상주한다.
- 프로세스와 스레드 관리 , 메모리 관리
- 파일생성, 삭제, 파일 입출력 등 파일 및 파일시스템 관리
- 디바이스 드라이버를 호출하여 장치 입출력
- 커널코드는 함수의 형태로 존재.
- 응용프로그램은 원래 함수호출 이라는 방식을 통해서 응용프로그램 내에 작성한 함수나 라이브러리에 포함된 함수 호출한다. 하지만, 응용프로그램은 함수호출 방법으로 커널 호출하지 못함.
- 왜냐. 응용프로그램은 일단 커널 코드에 들어있는 함수의 이름을 알 수도 없고, 알아도 응용프로그램과 커널 코드는 링크(link)될 수 없다.
- 응용프로그램에서 커널에 있는 함수를 쓸 방법은 유일하게 시스템호출이라는 방법밖에 없다.
4. 디바이스 드라이버
- 장치를 직접 제어하는 소프트웨어
- 장치마다 전담 디바이스 드라이버가 꼭 잇음
- 마우스드라이버 : 마우스움직임, 클릭 인지 / 키보드드라이버 : 키보드장치로부터 사용자가 입력한 키를 알아오는 드라이버 / 그래픽드라이버 : 디스플레이 해상도 조정 등 그래픽 장치 제어, 디스플레이 출력 담당 / 디스크드라이버 : 디스크장치를 제어하여 디스크 블록을 읽고 씀. / 프린터드라이버도있음
- 과거에는 모든 디바이스 드라이버들이 커널 영역에서 실행되었음. 현대는 커널영역에서 디바이스드라이버가 잘못 작성되면 시스템 심각하게 손상입음. 그래서 커널 밖에 사용자공간에서 실행되는 디바이스 드라이버 허용함.
- but 대부분의 디바이스드라이버는 커널영역의 메모리에 적재됨.
2-4 운영체제 커널 인터페이스 : 시스템 호출과 인터럽트
운영체제가 하드웨어와 응용프로그램 사이의 중계역할을 위해 다음 두가지 인터페이스를 둔다.
- 시스템호출 = 커널과 응용프로그램 사이의 인터페이스
- 인터럽트 = 커널과 하드웨어장치의 인터페이스
시스템호출
- 응용 프로그램에서 커널코드(커널에 작성된 함수)를 실행하는 기법.
응용프로그램은 커널에 작성된 함수를 직접 호출할 수는 없다. 왜냐하면 함수의 이름도 모르고 위치도 모르며, 보다 근본적인 이유는 커널이 있는 메모리에 접근할 권한도 없기 때문이다.
그래서 운영체제는 패키지를 통해 응용프로그램을 대신하여 커널 함수에 접근하는 시스템 호출 라이브러리를 제공한다. 응용프로그램이 커널의 기능을 활용하려면 시스템 호출 라이브러리에 들어 있는 시스템 호출 함수를 호출하면 된다.
일반적으로 라이브러리는 다음 두 종류가 있다.
표준 라이브러리(운영체제와 무관) | 시스템 호출 라이브러리(운영체제 커널 관련) |
printf(), strcmp(), scanf() 같이 복잡한 기능 미리 작성, 응용프로그램에서 활용. 사용자가 쉽게 응용프로그램 작성할 수 있도록함. |
여기 라이브러리의 함수들은 시스템 호출 과정을 통해 응용프로그램이 커널코드를 불러 활용할 수 있도록 함. 운영체제를 만드는 기업이나 개발자가 작성, 배포하는것이 원칙! 시스템호출 함수들은 시스템 호출을 일으키는 기계명령을 실행하여 CPU가 커널코드와 데이터가 적재된 메모리 영역을 액세스하는 권한을 가지도록하고, 커널에 작성된 함수를 실행시킨다. 시스템 호출'은 응용프로그램이 커널 코드(커널함수)를 활용할 수 있는 유일한 관문이다. 다른 방법은 없다. |
인터럽트
-> 하드웨어 장치들이 CPU에게 하드웨어신호(인터럽트신호)를 물리적으로 발생시켜, 입출력 완료나 타이머 완료 등을 CPU에게 알리는 방법.
CPU가 인터럽트 신호를 받으면, 즉시 하던 일을 멈추고 인터럽트의 요청을 처리하는 코드(인터럽트 서비스 루틴)를 실행한다.
이 인터럽트 서비스 루틴이라는 코드는 커널 코드나 디바이스 드라이버 내에 작성된다.
EX) 사용자가 키보드의 키를 누르는 순간 CPU에 인터럽트가 발생, CPU는 하던 일을 멈추고 키보드 인터럽트 루틴을 실행한다. 인터럽트 서비스 루틴의 코드가 키 값을 읽어 커널 영역에 만들어 놓은 키 입력 버퍼나 키 입력을 기다리는 응용프로그램의 버퍼로 전달한다. CPU는 인터럽트 서비스 루틴의 실행을 마친 후 그 전에 실행하던 코드로 돌아간다.
운영체제는 인터럽트라는 방법을 통해 운영체제가 입출력장치에 지시한 작업의 완료나, 예고없는 데이터의 도착, 키보드와 마우스의 입력, 부족한 배터리 경고 등 장치와 관련된 모든 이벤트 처리함.