운영체제란
운영체제: 사용자가 컴퓨터를 편리하고 효율적으로 사용할 수 있도록 환경을 제공하는 시스템 소프트웨어입니다.
하드웨어를 제어하고 응용 프로그램이 하드웨어 자원을 효율적으로 사용할 수 있도록 중간에서 조율하는 역할을 합니다.
대표적인 운영체제로는 Windows, Linux, Mac 등이 있습니다.
운영체제의 주요 역할
- 프로세스 관리: 여러 프로그램이 동시에 실행될 수 있도록 CPU의 사용 순서를 조절하고, 프로세스 간 통신 및 자원 공유를 관리합니다.
- 저장장치 관리: 메인 메모리와 하드디스크 등의 자원을 효율적으로 관리하고, 가상 메모리와 파일 시스템을 통해 안정적인 데이터 저장을 지원합니다.
- 네트워킹: 인터넷 연결 및 다양한 네트워크 프로토콜(TCP/IP 등)을 지원하여, 시스템 간 통신을 가능하게 합니다.
- 사용자 관리: 여러 사용자가 하나의 시스템을 사용할 수 있도록 계정을 분리하고 접근 권한을 제어합니다.
- 디바이스 드라이버 관리: 다양한 하드웨어 장치와의 연결을 가능하게 해주는 드라이버들을 운영체제 내부에서 관리합니다.
커널(Kernel)과 Dual Mode
커널: 운영체제의 핵심이 되는 부분으로, 하드웨어와 사용자 프로그램 간의 중재자 역할을 합니다.
메모리 관리, 프로세스 스케줄링, 파일 시스템, 장치 드라이버, 네트워크 통신 등 핵심 기능을 담당하며, 커널 모드에서 실행되어 하드웨어 자원에 직접 접근할 수 있습니다.
→ 시스템 전체의 안정성과 효율성을 보장하기 위해 반드시 신뢰할 수 있는 코드로 구성되어야 하며, 외부 프로그램이 커널의 기능을 사용할 수 있는 유일한 통로가 시스템 콜입니다.
Dual Mode
- User Mode: 일반 애플리케이션이 실행되는 환경으로, 직접적인 하드웨어의 접근이 불가능하며 제한된 명령만 수행할 수 있습니다.
- Kernel Mode: 운영체제 핵심 기능이 실행되는 환경으로, 메모리, 디스크, 네트워크 등 모든 시스템 자원에 접근할 수 있습니다.
■ User Mode와 Kernel Mode를 구분하는 이유
→ 시스템 보호와 안정성 확보
사용자 프로그램이 커널 모드나 다른 프로세스의 메모리에 임의로 접근하면 시스템 오류나 보안 사고가 발생할 수 있기 때문에 모드를 구분하여 시스템 자원이 무분별하게 사용되는 것을 방지할 수 있습니다. 또한, 커널이 시스템 전반을 통제함으로써, 메모리 충돌이나 자원 경쟁 등으로 부터각 프로세스를 격리하고 보호할 수 있습니다.
시스템 콜의 개념과 종류
시스템 콜(System Call): 응용 프로그램이 운영체제의 기능을 사용하고자 할 때, 커널에 요청을 전달하는 메커니즘
운영체제는 메모리, 파일, 네트워크, 프로세스 등의 중요한 자원을 제어하고 보호하는 역할을 하며, 일반 사용자 프로그램이 이러한 자원에 직접 접근하지 못하도록 제한합니다. 따라서, 사용자는 시스템 콜이라는 인터페이스를 통해 간접적으로 운영체제의 기능을 사용하게 됩니다.
예를 들어, 파일을 열거나 데이터를 저장할 때, 내부적으로는 open()이나 write() 같은 시스템 콜이 호출되어 커널이 요청을 처리합니다.
시스템 콜의 종류
- 프로세스 제어: fork(), exec(), exit() 등, 프로세스 생성 및 종료에 관련된 호출
- 파일 관리: open(), read(), write(), close() 등, 파일 생성, 읽기/쓰기, 삭제 관련 호출
- 장치 관리: ioctl(), read(), write() 등, I/O 장치 제어 및 데이터 송수신
- 정보 유지 및 보안: getuid(), setuid(), chmod() 등, 사용자 정보 및 권한 제어
- 메모리 관리: mmap(), brk() 등, 동적 메모리 할당 및 해제
- 통신 및 네트워킹: socket(), connect(), recv() 등, 프로세스 간 혹은 네트워크 간 통신 기능 제공
■ 서로 다른 시스템 콜을 구분하는 방법
→ 각 시스템 콜은 운영체제 내부에 고유한 번호(System Call Number)를 가지고 있습니다.
운영체제는 시스템 콜이 호출되면 전달받은 번호를 기준으로 시스템 콜 테이블(System Call Table)을 조회하고, 해당 작업을 수행하는 함수를 찾아 실행합니다.
예를 들어, 리눅스에서는 read()는 0번, write()는 1번, open()은 2번 등으로 번호가 매겨져 있습니다. 사용자 프로그램은 이러한 번호를 통해 어떤 기능을 요청했는지 커널에 전달할 수 있습니다.
■ 시스템 콜이 많아지면 성능에 영향을 주나요?
→ 네! 시스템 콜은 User Mode에서 Kernel Mode로 전환이 필요하기 때문에 일반 함수 호출보다 오버헤드가 큽니다. 따라서 반복적으로 많은 시스템 콜을 호출하면 성능 저하가 발생할 수 있습니다.
인터럽트(Interrupt)와 폴링(Polling)
인터럽트: CPU가 특정 프로그램을 실행하고 있을 때, 예기치 않거나 우선적으로 처리해야 하는 사건이 발생했음을 CPU에 알리는 신호
이 신호는 하드웨어 또는 소프트웨어에 의해 발생할 수 있으며, CPU가 이를 감지하면 현재 수행 중인 작업을 일시 중단하고, 우선순위가 높은 작업을 먼저 처리하게 됩니다. 인터럽트는 자원을 효율적으로 관리하고 시스템 반응 속도를 높이는 데 중요한 역할을 합니다.
인터럽트는 하드웨어 인터럽트와 소프트웨어 인터럽트로 구분됩니다.
- 하드웨어 인터럽트(Hardware Interrupt): 외부 장치(예: 키보드, 디스크, 네트워크 등)에서 발생하는 인터럽트로, 장치가 CPU에 직접 신호를 보내 작업을 요청합니다. 주로 실시간 반응이 필요한 장체 제어에 사용됩니다.
- 소프트웨어 인터럽트(Software Interrupt): 프로그램 내부에서 명시적으로 발생시키는 인터럽트로, 보통 시스템 콜이나 예외 상황 처리(예: 0으로 나누기, 접근 권한 위반 등)에 사용됩니다. 트랩(Trap)이라고도 부릅니다.
인터럽트 처리 과정
CPU는 매 명령 사이클 동안 인터럽트 발생 여부를 점검합니다. 만약 인터럽트가 감지되면 CPU는 현재의 작업 상태(프로그램 카운터, 레지스터 등)를 저장하고, 인터럽트 벡터 테이블에 정의된 해당 인터럽트 서비스 루틴(ISR)의 주소로 점프하여 그 작업을 처리합니다. 처리 후에는 저장해두었던 상태로 복귀하여 중단된 작업을 이어서 수행하거나 상황에 따라 다른 작업을 수행합니다. 이 과정을 통해 시스템은 다양한 이벤트에 빠르게 반응할 수 있습니다.
인터럽트 발생 → 현재 작업 상태 저장 → ISR 실행 → ISR 종료 → 저장된 작업 상태 복원 → 원래 작업 재개
■ 인터럽트 벡터 테이블(Interrupt Vector Table)
인터럽트 벡터 테이블은 인터럽트가 발생했을 때, 어떤 처리 루틴을 호출할지를 정의한 주소 테이블입니다. CPU는 특정 인터럽트가 발생하면, 해당 인터럽트 번호(또는 타입)를 기반으로 벡터 테이블에서 처리 루틴의 주소를조회하여 해당 위치로 점프합니다.
운영체제는 이 테이블을 통해 다양한 인터럽트 상황에 따라 적절한 처리를 수행할 수 있게 하며, 시스템 초기화 시 인터럽트 핸들러들을 이 테이블에 등록합니다.
■ 인터럽트 처리 루틴(ISR: Interrupt Service Routine)
ISR은 인터럽트가 발생했을 때, CPU가 실행하는 특정 처리 루틴(함수)를 말합니다.
인터럽트 벡터 테이블을 통해 연결된 주소로 점프하여 실행되며, 해당 이벤트에 대한 적절한 처리를 수행합니다.
예를 들어, 키보드 인터럽트가 발생하면 ISR은 키 입력 데이터를 읽어오고, 이후 다시 원래 작업으로 복귀하게 됩니다. ISR은 가능한 한 빠르고 간단하게 처리되어야 하며, 시스템 전체 응답성에 영향을 주기 때문에 설계가 중요합니다.
폴링(Polling): CPU가 장치에 직접 접근하여 주기적으로 상태를 확인하는 방법 (예: 키보드 입력 여부를 일정 간격마다 주기적으로 확인)
이 방식은 구조가 단순하고 구현이 쉽다는 장점이 있지만, 장치에 변화가 없을 때에도 계속해서 체크를 수행해야 하므로 CPU 자원을 불필요하게 낭비하는 단점이 있습니다.
■ 폴링 방식돠 인터럽트 방식의 차이
폴링 방식은 장치에 변화가 없을 때에도 계속해서 체크를 수행해야 하므로 CPU 자원을 불필요하게 낭비하는 단점이 있습니다. 반면, 인터럽트 방식은 이벤트가 발생할 때만 CPU가 반응하므로 자원 효율성이 높습니다.
인터럽트 방식은 MCU 자체가 하드웨어적으로 변화를 체크하여 변화 시에만 일정한 동작을 하는 방식으로 하드웨어로 지원을 받아야 하는 제약이 있지만, 폴링에 비해 신속하게 대응하는 것이 가능하기 때문에 실시간 대응이 필요할 때는 필수적인 기능입니다.
■ 시스템 콜과 인터럽트의 연계 구조
사용자 프로그램
↓ (시스템 콜 요청)
소프트웨어 인터럽트 발생
↓
커널 모드로 전환 (privilege level 상승)
↓
인터럽트 벡터 테이블 참조
↓
해당 시스템 콜에 해당하는 커널 코드(ISR 유사 루틴) 실행
↓
작업 완료 후 사용자 모드로 복귀