OS가 제공하는 서비스
OS가 유저에게 제공하는 서비스
- 유저 인터페이스를 제공한다.
- 프로그램 수행을 제어한다.
- 하드웨어 자원을 관리한다. (CPU, 메모리, 저장공간, I/O 장치)
- 파일 시스템을 관리한다. (생성, 삭제, 탐색)
- 프로세스들 간의 communication이 일어나도록 해준다. (shared memory, message passing)
- 에러를 탐지한다.
OS는 효율성을 위해서
- 프로세스들에게 적절하게 자원을 할당한다.
- 하드웨어 사용 통계 자료를 제공한다. (Accounting)
- 하드웨어 보호 기능이 있다. (커널 모드와 유저 모드)
- 보안 기능이 있다. (로그인 시, password 입력)
시스템 콜
커널 모드(Privileged Instruction)로 진입하는 방법은 두 가지가 있다.
- 하드웨어 인터럽트 : 외부 device I/O interrupt(DMA가 끝났음을 알리는 것), 비동기
- 트랩 : 소프트웨어에 의해 발생, 동기 -> 예외와, 시스템 콜이 있다.
시스템 콜은 트랩의 일종이다 !
시스템 콜이란?
프로그램이 OS에게 서비스를 받는 것. 일반적으로 라이브러리(API)를 통해 호출되고 이 때 커널모드로 진입된다. |
OS에는 중요한 두 가지 디자인 원리가 있다.
- Policy : 목적, 무엇을 할 것인가?
- Mechanism : 방법, 어떻게 할 것인가?
-> OS에게 서비스를 요청하도록 하는 것이 Policy이고, 시스템 콜은 Mechanism이다.
API(Application Program Interface)를 통해 간접적으로 시스템 콜을 호출한다. POSIX(Portable Operating System Interface)를 통해서 각 OS들 간의 API를 맞춘다.
API를 사용해서 시스템 콜을 간접 호출하게 되면
- 모든 OS에서 호환이 가능해진다.
- 시스템 콜의 세부사항을 몰라도 되므로 프로그래밍이 쉬워진다.
시스템 콜 인터페이스 : 시스템 콜 테이블이다.
- 각 시스템 콜마다 번호가 정해진다. 이 번호를 알면 System Call을 호출할 수 있다.
- 이 번호들에 따라서 시스템 콜이 인덱싱이 된다.
- OS 커널에서 시스템 콜을 호출하면 시스템 콜의 상태와 리턴값을 리턴한다.
시스템 콜의 매개변수는 register를 활용한다. 혹은 block에도 매개변수가 저장되기도 하는데, 매개변수에는 block의 주소가 저장된다.
매개변수가 6개보다 적은 경우, 위처럼 register를 활용하고 매개변수가 6개보다 많은 경우, 주소값을 넘겨준다.
리눅스에서 시스템 콜 호출의 예시는
- API(Library)를 호출한다. 이 때, 매개변수로 시스템 콜 번호를 넘겨주는데, 레지스터를 이용해서 넘겨준다.
- IDT(Interrupt Description Table)에서 시스템 콜을 호출한다.
- System Call Table에서 시스템 콜 번호에 맞는 작업을 수행한다.
OS에서의 디자인과 구현
OS의 목표는
- 유저 관점 : 사용하기 편리하고, 배우기 쉽고, 안정적이고, 빨라야 한다.
- 시스템 관점 : 디자인, 구현, 유지하기 쉬워야하고 유연해야 하며 안정적이고, 에러가 없어야 한다.
Micro Kernel의 예시가 있다. Micro Kernel은 policy 변화가 쉽고 OS의 기능이 User Mode에 존재한다. 피쳐폰 등에 사용된다.
이와 반대로 Monolithic Kernel(리눅스, 윈도우)은 모든 OS의 기능이 Kernel Mode에 있다.
본격적으로 OS 구조를 보자면 구조는 다음들과 같다.
- Simple Structure : 예전 OS에서 사용하던 구조이다. dual-mode와 H/W 보호 기능이 없어서 보안에 취약하다. MS-DOS가 그 예시이다. 요즘에는 잘 쓰이지 않는다.
- Layered approach : 보편적인 구조이다. 계층화를 사용하고 리눅스나 윈도우에서 사용하는 구조이다. 최상위 계층이 user Interface이고 각 Layer는 바로 아래 Layer에서 제공하는 operation을 사용한다. 즉, 각 Layer가 상위 Layer를 고려할 필요없이 독립적이므로 Kernel이 안정적이다. 유저 인터페이스가 최상위에 있고, application에서 kernel에 접근할 대 시스템 콜을 호출한다. 커널에서 하드웨어로 접근할 때는 kernel Interface를 사용한다.
- Microkernel : Monolithic Kernel의 반대되는 개념이다. 많은 기능이 user의 공간에 있다. 장점으로는 기능을 확장하는 것이 쉽고 새 architecture에 OS를 포팅하는게 쉬우며 코드가 적기 때문에 안정적이다. 단점으로는 user와 task 간 communication(Message Passing)이 많이 일어나므로 퍼포먼스 오버헤드가 일어난다.
- Module : 기능 별로 구분한다. 각각의 module이 별도로 loading이 가능하다. 리눅스는 Layered approach와 module 두 구조를 합친 구조를 사용한다. 커널에서 모듈을 기능별로 구분하고 필요없으면 제거하고 필요하다면 사용하는 별도의 loading이 가능하다.커맨드로 insmod로 커널에 module을 넣을 수 있고, 커맨드로 rmmod로 커널에 있는 module을 제거할 수 있다. 리눅스는 Device Driver가 효과적이다.
- Virtual machine : 한 개의 하드웨어에 OS가 여러 개 있는 것이다. 각각의 OS가 같은 하드웨어를 공유하는데, 이는 각 OS가 하나의 컴퓨터인 것처럼 보이게 한다. 이렇게 하면 각기 다른 OS에서 동시에 Test가 가능하므로 유용하다는 장점이 있지만, 구현이 어렵다는 단점이 있다. 같은 하드웨어로 여러 OS가 동작하므로 유지비용이 감소하고, 동시에 서로 다른 OS를 테스트하므로 개발시간도 단축된다. Virtual Machine은 결국 하나의 user program이므로 user mode이고, virtual machine에서는 virtual user space와 virtual kernel이 존재한다. Virtualization Layer에서 여러개 가상머신들이 동시 수행되고, System Call을 통해서 OS에 접근한다.
시스템 부팅
OS는 하드웨어가 작동할 수 있도록 하드웨어를 사용가능하게 만들어야 한다.
- 부팅 : 커널을 load함으로써 컴퓨터를 시작하는 절차를 말한다.
- 부트스트랩 로더 : 커널에 있는 적은 양의 코드로 이 코드를 메모리로 로드하고 코드를 실행한다. 몇몇 시스템들은 두 단계의 프로세스를 사용하는데 이는 단순한 부트 스트랩이 디스크에 존재하는 부트 프로그램을 불러오는 것이다. 컴퓨터가 커지면 ROM이라고 불리는 고정된 메모리 공간에 작업이 수행된다. ROM은 첫 부트 코드를 가지고 있고 RAM보다는 느린 속도를 가지고 있다.
Single Step approach
Single Step approach는 다음과 같은 순서로 이루어져 있다.
- 부팅(ROM에 부트스트랩 로더가 있다.) - 커널이 로드된다.
- 부트스트랩 로더가 제어권을 얻는다.
- 하드웨어를 초기화한다.
- OS를 램으로 로드한다.
- OS의 첫번째 라인으로 제어권을 준다. -> OS가 필요한 프로세스나 하드웨어에서 작업을 수행한다.
Two Step approach는 최근 부팅 시에 많은 코드를 필요로 해서 도입이 됐다.
Two Step approach는 롬에 부트스트랩을 저장하고, 부팅에 필요한 요소, 코드는 디스크 부트블록에 저장한다. 부트스트랩이 부트블록을 램으로 로드하고 부트블록을 진행시킨다. 후에 부트블록이 OS를 램에 로드하고 OS의 첫번째 라인을 실행한다.
Two Step approach는 다음과 같은 순서이다.
- 부팅(ROM에 부트스트랩 로더가 있다.) - 커널 로드
- 부트스트랩 로더가 제어권을 얻는다.
- 부트블럭을 램으로 로드하고 부트블럭이 제어권을 받는다.
- 부트 블럭 진행 후, OS를 RAM으로 로드한 후 OS의 첫번째 라인으로 제어권을 준다.
- OS가 실행 되므로 OS가 필요한 프로세스나 하드웨어에서 작업을 수행한다.
'CS > Operating System' 카테고리의 다른 글
[OS]Operating System의 전반적인 개념 (0) | 2021.07.15 |
---|