3. 커널과 시스템 호출
3-1 응용프로그램의 자원 접근 문제
MS-DOS 같이 단일사용자/단일프로세스 운영체제를 사용하던 시절에는 시스템에 한번에 하나의 응용프로그램만 실행되었으니 응용프로그램이 컴퓨터 자원에 접근하는 것을 막을 필요가 없었다. 응용프로그램 간의 자원충돌이 일어나지 못한다는 이야기. (동시에 디스크의 같은 부분에 쓰거나 같은파일을 하나는 읽으면서 하나는 지우는 등 할 수가 없었다.)
하지만, 오늘날 다중사용자(서버컴퓨터, 메인프레임 컴퓨터라 생각하면 될듯) / 다중 프로세스 운영체제를 탑재한 컴퓨터들에서, 응용프로그램이 하드웨어에 직접 접근할 수 있도록 허락한다면 어떻게 될까?
-> 자원충돌은 물론이고, 하드웨어 중에 메모리에는 커널이 적재되어있잖아.... 메모리의 커널에 액세스하면 주요데이터 훼손하는 등 진짜 큰일 남...
- 그래서, 운영체제는 응용프로그램과 '커널' 의 메모리 영역을 확실히 구분하기 위해 메모리를 '사용자공간'과 '커널공간'으로 나눴음!!!
- 또, CPU의 실행모드를 사용자모드, 커널모드로 나눠서 응용프로그램은 사용자모드에서, 커널 코드는 커널모드에서 실행되게함!!!!
- 응용프로그램이 커널의 기능을 실행하기를 원할 경우 시스템호출을 해야만 하도록, 시스템호출 안하면 커널 손도못대게 했음.
3-2 사용자 공간과 커널 공간
운영체제는 CPU로 액세스할 수 있는 전체 메모리공간을 사용자공간과 커널공간으로 분리한다.
-> 두 공간에 적재되는 내용은 다르다.
- 사용자 공간 - 응용프로그램 적재됨, 응용프로그램의 변수가 만들어지고 동적할당 받는 공간
- 커널공간 - 커널코드와 데이터, 커널함수들이 실행될 때 필요한 스택공간, 디바이스 드라이버 등이 탑재된다.
왜 커널 사용자 공간 나누나?
-> 응용프로그램으로부터 커널 코드와 커널 데이터를 지키기 위해서이다. 응용프로그램은 기본적으로 믿을 수 없다.
(악의적인 개발자가 있을 수 있어 커널 코드와 데이터를 몰래 보거나 훼손할 수도 있음...)
(그리고 응용프로그램 개발자가 본의아니게 실수로 커널 데이터를 건드려 훼손시킬 수도 있음!)
그래서 바이러스 침범, 시스템훼손, 시스템 중단 등 심각한 문제가 발생할 수 있음.
-> 아예 메모리공간을 나눠서 커널에 응용프로그램이 접근도 못하게 막음.
사용자 공간 크기 의미
32비트 윈도우운영체제에서 사용자공간이 2GB이다 -> 응용프로그램의 크기가 최대 2GB로 제한된다는말.
응용프로그램의 코드영역, 데이터영역, 힙영역, 스택영역을 모두 합친 총 응용프로그램의 크기 !!!!!
사용자 공간과 커널 공간은 가상주소 공간이다.
4GB의 주소공간은 운영체제가 만들어주는 가상 주소공간이다. 실제 메모리공간이 아니다.
각 응용프로그램은 자기가 0~7FFFFFFF 번지인 2GB의 사용자공간을 독점적으로 사용하고, 나머지 2GB는 커널이 사용하고 있다고 착각하지.
BUT 실제는 운영체제는 가상주소 공간의 상위 2GB, 커널공간을 모든 응용프로그램이 공유하도록 한다.
-> 모든 응용프로그램은 각각 4GB의 주소공간(가상)을 받는다.
그중 사용자공간은 본인이 독점적으로 사용할 수 있고, 커널공간은 다른 응용프로그램과 공유한다.
그럼 여기서 의문이 두가지 들어야 한다.
Q1. 모든 응용프로그램이 가상주소 0번지부터 시작하는데 응용프로그램간 주소공간이 겹치지 않나?
- 각 응용프로그램의 가상 주소공간을 물리 메모리 공간으로 매핑시킬 때, 각 응용프로그램 마다 커널 공간에 매핑테이블을 두고 그것대로 사용자공간을 물리메모리 공간으로 매핑한다.
- 물리메모리를 여러 응용프로그램의 사용자공간이 나누어 쓴다. = 각 응용프로그램은 사용자공간중 일부만 사용한다.
- 커널공간도 물리 메모리에 매핑되어 각 응용프로그램의 매핑 테이블에 기록된다. -> 커널에 대한 매핑정보는 모든 응용프로그램이 동일하다. 당연히 커널공간 하나를 같이 나눠쓰니깐.
Q2. 컴퓨터에 장착된 물리 메모리(RAM)의 크기가 4GB보다 작으면 어떻게하나.
- 가상메모리기법 이용한다. (램의 일부를 하드 디스크에 저장하여 램의 빈 영역을 확보하는 기법)
응용프로그램과 개발자 모두 가상공간에서 산다.
- 프로그램코드와 데이터는 물리메모리의 빈곳에 저장되므로 어느 위치에 있을지는 아무도 모른다. 실행되는 시점에, 현재 실행되는 프로그램 개수, 물리메모리의 크기, 물리메모리의 빈 위치에 따라 프로그램 코드와 데이터가 어디 저장될지 정해진다.
- 하물며 CPU의 PC레지스터에 있는 주소도 물리메모리 주소가 아니다. 이 응용프로그램의 가상주소이다.
- 비주얼스튜디오의 디버거에서 보여주는 변수의 주소도 가상주소이다.
정리하면, 운영체제는 물리 메모리 주소를 각 응용프로그램에 줄 수 없으니,
0번지부터 있는 가상 주소공간을 모든 응용프로그램에게 제공하고,
모든 응용프로그램은 때문에 자신만의 사용자공간을 가지게 된다.
3-3 CPU의 사용자모드와 커널 모드
CPU는 반드시 사용자 모드 혹은 커널모드 중 하나에서 실행된다.
응용프로그램 : 사용자모드 // 커널코드 : 커널모드
사용자 모드인지 커널모드인지는 CPU내의 모드 레지스터에 저장되어 있다.
응용프로그램을 실행시킬 때 운영체제는 CPU모드를 사용자모드로 설정하고, 응용프로그램이 '시스템 호출'을 하면 그때 커널모드로 전환되며 커널 코드가 실행된다.
사용자모드 | 커널모드 | |
CPU의 메모리 액세스 범위 | 사용자공간에만 액세스가능. 커널공간 액세스불가. |
커널공간 액세스 가능 모든 메모리 공간에 액세스 가능 |
CPU의 하드웨어 액세스 여부 | 불가! | 모든 하드웨어 액세스 가능! |
CPU가 처리가능한 명령 | 특권명령을 제외한 모든 CPU명령 (특권명령 처리불가.) |
특권명령포함 모든 CPU명령 |
오류 발생 시 처리 | 사용자 프로그램만 실행종료. 시스템이 종료되지 않으므로 안전함. |
시스템에 심각한 오류가 발생한 것으로 시스템 종료. |
3-3-1 사용자 모드
- 사용자모드에서 프로그램은 사용자 공간만 접근 할 수 있고 커널공간은 접근할 수 없다.
- 만일 응용프로그램이(CPU가) 사용자 모드에서 실행하던 중 커널공간의 메모리 번지를 접근한다? -> 바로 시스템 예외(exception) 발생하고 응용프로그램 즉시 종료된다.
- 사용자모드에서 응용프로그램은(CPU는) 어떤 하드웨어(하드디스크, 입출력 장치 등)에도 접근할 수 없다.
- 사용자모드에서 응용프로그램은(CPU는) 다른 응용프로그램에 할당된 메모리도 접근할 수 없다.
- CPU는 사용자모드에서 특권명령으로 불리는 기계명령들을 실행할 수 없다.
- (만약 응용프로그램코드에 특권명령이 들어있어 사용자모드에서 특권명령 실행하게 되면, CPU는 바로 예외 발생 시키고 응용프로그램 종료시킨다.)
3-3-2 커널 모드
- CPU는 모든 메모리 공간 액세스 할 수 있다.
- 특권명령 실행할 수 있다.
- 어떤 하드웨어든 접근하고 제어할 수 있다.
- 커널모드는 특권모드 혹은 감독자 모드라고 불린다.
- 위 그림과 같이 모드레지스터가 커널모드로 설정이 되어 있어야 CPU는 권한을 갖고 커널모드에서만 액세스하거나 조작할 수 있는 것들을 수행한다.
3-3-3 사용자모드에서 커널모드로 전환
사용자모드에서 커널모드로 전환되는 경우는 시스템호출, 인터럽트 발생 이렇게 두가지이다!!!!!!
1. 시스템 호출
아래는 시스템 호출로 (사용자모드 -> 커널모드) 로 전환되는 모습이다.
응용프로그램이 시스템호출을 하면 CPU의 모드가 커널모드로 바뀌고(모드 레지스터 값 커널모드로 설정됨)
커널 코드가 실행된다.
- 응용프로그램에서 하드웨어를 직접 액세스 못한다. (시스템호출해야함) = 응용프로그램의 코드는 신뢰할 수 없기 때문이다. 오직 신뢰할 수 있는 커널코드만 하드웨어 액세스 가능하다.
- 파일에서 데이터 읽거나, 데이터를 네트워크 이용해 보내거나, 디스플레이에 텍스트를 출력하는 기능도 모두 커널에 작성되어 있다.
- 시스템호출을 일으키는 특별한 CPU기계명령이 실행되면 CPU는 (사용자모드->커널모드) 로 바뀐다.
- 시스템호출이 끝나고 시스템 호출을 종료하는 CPU기계명령에 의해 사용자모드로 바뀐다.
2. 인터럽트
- 입출력 장치나 저장장치가 CPU에게 인터럽트를 거는 경우 CPU는 자동으로 커널모드로 전환된다.
- CPU는 이 즉시 인터럽트 서비스 루틴을 실행한다.
- ex (유튜브 보는 도중 사용자가 F 누르면 CPU에 인터럽트 신호가 전달되고 자동으로 커널모드로 바뀌며, 키보드 인터럽트 루틴을 실행하여 전체화면으로 영상을 보여준다. 고 이해하면 될 듯.)
- 커널모드로 바뀌는 이유는? -> 인터럽트 서비스 루틴이 커널공간에 있기 때문이다.
- 인터럽트 서비스 루틴이 끝나면 CPU는 다시 사용자모드로 돌아가며, 응용프로그램의 실행을 계속함.
- ex (전체화면을 만들어 주고 나서 CPU는 다시 사용자모드, 유튜브 영상을 계속 보여준다.)
3-3-4 특권명령
특권명령은 다음 작업을 위해 CPU제조업체에서 특별히 설계한 CPU명령들이다.
I/O 명령
-> 컴퓨터 본체 내 하드웨어 혹은 입출력장치나 저장장치를 제어하고 읽기 쓰기에 사용되는 CPU 기계명령
1) 입출력장치들은 CPU가 액세스 할 수 있는 여러 개의 레지스터를 내장하고 있다. 이를 I/O 포트라고 부른다.
2) CPU는 I/O 포트에 값을 읽거나 쓰는 방식으로 입출력 장치를 제어하거나 값을 쓰거나 읽는다.
인텔 CPU의 예를 들면,
in eax, 300 ; I/O포트 300번지에서 값을 읽어 eax레지스터에 저장
out 301, eax ; eax레지스터에 있는 값을 I/O 포트 301번지에 쓰기
3) 위의 in, out 과 같은 I/O 명령들은 하드웨어 장치를 직접 접근하므로 커널모드에서 실행되어야 하는 특권명령이다.
Halt 명령
-> 커널이 현재 처리할 작업이 없을 때 실행하는 명령, CPU의 작동을 중지시키고 CPU 유휴상태로 만든다
1) Halt명령을 실행한 뒤, CPU는 아무 인터럽트든 받을 때 까지 아무 명령도 실행하지 않기 때문에 전력소모를 줄일 수 있다.
2) CPU에 따라 다르며, 인텔CPU는 ' hlt ' 라는 이름의 명령이다.
인터럽트 플래그 켜고 끄기
1) 대부분의 cpu는 인터럽트가 발생할 때 처리할지 무시할지 나타내는 비트를 가지고있음. == 인터럽트 플래그.
2) CPU들은 이 플래그를 켜거나 끄는 명령 갖고 있음.
인텔 CPU의 경우 ==> cli, sti
(clear interrupt flag == 인터럽트 플래그 꺼라 == 인터럽트 받지마라) ,
(set interrupt flag == 인터럽트 플래그 다시켜라 == 인터럽트 받아라)
cli 명령을 실행하면 CPU는 인터럽트 플래그를 끄고 sti 명령이 실행될 때 까지 프로그램 실행도중 발생하는 어떠한 인터럽트도 처리하지 않는다. (키보드 쳐도 키 안먹음. 인터럽트 서비스 루틴 실행 안하므로.)
타이머 설정
-> 타이머를 설정하는 명령은 특권명령이다.
컨텍스트 스위칭
-> 현재의 cpu 레지스터를 커널영역(프로세스 제어 블록)에 저장하고, 저장된 컨텍스트 정보 cpu레지스터에 복귀시키는 컨텍스트 스위칭 명령은 커널모드에서 실행되는 특권명령이다!!!!
3-3-5 다양한 이슈들 ((((중 요))))***
1. 사용자 모드와 커널모드는 CPU에 의해 구현되는가 아니면 커널에 의해 구현되는가?
답 = CPU에 의해 구현되는 것이다.
-> CPU가 모드 레지스터 갖고 있어서, 0이면 커널모드, 1이면 사용자모드 이런식으로 모드레지스터의 값에 따라 커널코드는 커널모드에서만 실행한다.
-> CPU는 사용자모드-커널모드로 바꾸는 명령과 반대로 바꾸는 명령또한 제공한다.
-> 운영체제는 응용프로그램이 무단으로 커널 코드를 액세스 하는 것을 막으려고 CPU의 모드기능을 활용하는 것 뿐이다.
2. 운영체제가 사용자 모드와 커널모드로 나누어 동작시키는 이유는?
-> 커널 코드와 데이터에 대한 보안과 보호를 위함이다. 응용프로그램은 기본적으로 못믿는다. 악의적인 개발자나 응용프로그램에 오류가 있는 등 커널코드에 문제를 끼칠 여지가 있기 때문에 응용프로그램은 사용자모드에서만 실행시킨다.
-> 응용프로그램은 사용자모드에서 돌아가고, 특권명령을 실행하지 못하기 때문에 입출력 장치 등 하드웨어를 접근할 수 없는 것이다.
-> 사용자모드, 커널모드를 나눠놓으면 응용프로그램에서 오류가 발생해도 시스템을 중단시키지는 않는다.
3. 응용프로그램이 커널기능을 어떻게 활용할 수 있는가?
-> 하드웨어 자원에 대한 액세스가 필요할 경우 시스템 호출을 통해 커널 코드를 호출하여 사용가능하다.
4. CPU가 커널모드에서 실행되는 시간과 사용자모드에서 실행되는 시간을 알 수 있는가?
->가능하다
-> 커널 모드의 시간 비율이 높은 경우는, 현재 Windows에서 아무 작업도 이뤄지고 있지 않을 때 커널모드에서 실행되는 시스템 유휴 프로세스 때문일 수 있다.
-> 시스템 유휴프로세스는 부팅시부터 생성되어 커널모드에서만 실행되는 특별한 프로세스다.
-> 컴퓨터가 켜진 채로 사용되지 않고 있을 때 시스템 유휴프로세스가 실행된다. 즉, 커널모드로 실행중인 것으로 통계에 잡힌다. 아래는 커널모드 시간비율이 높기 때문에 이런 경우일 가능성이 있다.
-> 또한 계산 중심적인 프로그램이 실행되는 경우보다 키보드에서 읽고 디스플레이에 출력하고 디스크나 네트워크등 장치에 대한 입출력이 많을수록 커널모드의 시간 비율이 높아진다.
3-4 커널의 실체
3-4-1 커널은 부팅 시에 커널 공간에 적재되는 함수들과 데이터들의 집합
커널은 컴파일된 바이너리 형태로 운영체제가 설치되는 하드디스크의 특정영역에 있다. ( 부팅시에 메모리에 적재된다! )
커널모드에서 실행될 함수들과 시스템을 관리하기 위한 여러 종류의 테이블과 구조체 등으로 구성된다!
3-4-2 커널코드는 함수들의 집합이다
위 그림을 보면,
- 커널공간은 수백개의 함수들과 이들이 생성하고 사용하는 많은 자료구조들, 여러 디바이스 드라이버들로 이루어져있다.
- app2가 시스템호출을 통해 커널에 작성된 함수를 호출하고, 이 함수는 다시 디스크 장치 드라이버를 호출하여 디스크 장치 드라이버가 디스크장치를 제어하는 모습이다!
- 프로그램은 app2 -> 커널코드 -> 디바이스드라이버 코드 까지 이어진다.
<<<중요>>> CPU가 app2를 실행하던 중 시스템호출을 통해 커널모드로 바뀌어 커널 코드를 실행하고 있을때, 현재 어떤 프로세스가 실행중인가?
-> 당연히 app2 프로세스이다. 커널 프로세스란 말은 없다. 이제 헷갈리지도 않지...!
3-4-3 커널은 프로세스인가? NO.
커널은 시스템 관리 기능을 하도록 만들어진 함수들과 데이터의 집합이다.
스스로 실행되는 프로세스는 아니다.
운영체제는 부팅 시 운영체제의 기능을 돕기 위해 터음부터 커널모드에서 실행되는 프로세스나 스레드들을 수십개 실행시킨다. 하지만 그렇다고 커널 자체가 프로세스인 것은 아님.
- 응용프로그램의 프로세스가 시스템호출로 커널 함수를 실행하던 중 입출력 장치로부터 입력을 기다리게 되면, 커널함수는 현재 프로세스의 실행을 중단시키고 대기중인 프로세스 중 하나를 선택하는 스케줄링 함수를 호출한다.
- 혹은 타이머로부터 발생한 인터럽트 서비스 루틴은 현재 프로세스에 할당된 타임 슬라이스가 다 된 경우 다른 프로세스를 선택하기 위해 스케줄링 코드를 호출하기도 한다.
3-4-4 커널은 실행중인가? NO.
"커널이 실행중이다" 라는 말은 틀렸다. 커널은 함수의 집합일 뿐 실행은 CPU가 한다.
응용프로그램에 의해 시스템 호출이 발생하거나 인터럽트가 발생하여 커널 코드가 실행되고 있을 뿐이다.
커널은 하드웨어 장치가 아님을 기억하자!! 그냥 메모리에 적힌 코드다!!!!!
3-4-5 커널은 스택이나 힙을 가지는가? NO.
스택이나 힙은 프로세스(스레드)가 실행 중 데이터를 저장하는 공간이며, 프로세스마다 별도로 주어진다.
커널은 프로세스도 아니므로 스택이나 힙을 가지지 않는다.
다만, 프로세스가 생성될 때, 프로세스가 커널 모드에서 사용할 스택이 "커널 안" 에 할당된다.
이게 무슨말이냐면, 프로세스가 시스템 호출을 통해 커널에 진입하면, 자신에게 할당된 커널 스택을 활용하여 커널에 있는 함수를 호출할 때 매개변수나 지역변수를 저장한다.
이 커널 스택은 응용프로그램에 속한 것이다. 프로세스가 시스템호출로부터 복귀하면 프로세스가 커널 내에서 사용하던 스택 내용은 사라진다.
3-5 응용프로그램 빌딩
라이브러리 : 응용프로그램에서 활용하도록 미리 함수들을 작성하여 컴파일하고 바이너리 형태로 만든 파일.
(번외 : 바이너리파일..? ->
라이브러리를 사용하지 않고 응용프로그램을 작성하는 것은 거의 불가능..
표준 라이브러리와 시스템 호출 라이브러리가 있다.
시스템호출 라이브러리의 함수들은 기계명령을 이용하여 시스템호출을 일으켜서 커널함수를 실행시킨다.
그래서 시스템호출 라이브러리에 들어있는 함수들을 시스템 호출 함수 혹은 커널 API라고 부른다.
3-5-1 사용자 코드와 라이브러리 코드의 링킹
3-5-2 함수 호출 (function call)로 라이브러리 활용
3-5-3 시스템 호출(system call)로 커널코드 호출
3-5-4 응용프로그램이 라이브러리와 커널코드를 활용하는 과정
'OS [명품 운영체제]' 카테고리의 다른 글
명품 운영체제 전체 과제 #Chap 01-12 (0) | 2024.03.30 |
---|---|
Chap2. 컴퓨터 시스템과 운영체제 1,2절 (0) | 2024.03.13 |
Chap1. 운영체제의 시작과 발전 (4) | 2024.03.06 |