컴퓨터 시스템 구조
"memory" = CPU의 작업 공간
"local buffer" = device controller의 작업 공간
CPU는 memory로부터 기계어를 읽어와 하나씩 처리하는데,(memory에 "program counter"라는 register를 두어 현재 처리해야 할 것 가리킴 !!!)
OS의 기계어를 처리할 때는 믿고 맡길 수 있지만, 사용자의 프로세스를 처리할 때는 그럴 수 없다.
(CPU 독점 코드, 무한루프 코드 -> CPU 자원 분배가 제대로 안 이루어짐)
OS의 기계어는 CPU를 사용 중일 때만 의미 있기 때문에 사용자 프로그램에게 CPU가 넘어가면 제어 못 함
=> "mode bit" -> 사용자 모드 / 커널 모드 구분
mode bit(중요)
: 사용자 프로그램의 잘못된 수행으로 다른 프로그램 및 운영체제에 피해가 가지 않도록 하기 위해 0/1로 모드 나눔
* 사용자 모드 = 1 -> 사용자 프로그램 수행 -> 특권 명령 사용 불가(보안 해칠 우려) -> 사용하면 mode bit=0 자동 변경
* 모니터 모드(=커널모드=시스템모드) = 0 -> OS 코드 수행 -> 특권 명령 사용 가능 & I/O controller에게 맡기기 가능
<모니터모드(0) -> 사용자모드(1)>
: 사용자의 프로세스 수행하기 위해 다음과 같이 설정하고 넘겨줌
1. timer 설정 -> 지나면 interrupt 주어 뺏음
2. mode bit = 1로 설정하고 넘겨줌
<사용자모드(1) -> 모니터모드(0)>
: 사용자 모드 -> interrupt(I/O에게 맡긴 일 끝) OR 특권명령 실행 -> 모니터모드로 강제 변경
* 특권명령(위험한 코드)할 때 OS에게 자동으로 넘어감(mode bit=0)
* OS가 처리해야 하는 일이 있으면 -> 모니터 모드로 변경(1->0) -> OS가 메모리에 저장 -> 다시 사용자 모드로(0->1)
* timer = 사용자의 프로세스의 악의적 행동/독점을 막기 위해 두어 지나면 뺏음
* I/O controller도 특권 명령어이기 때문에
사용자 프로세스가 I/O controller에게 맡기고 싶다면 부탁하기 위해 system call(자진하여 interrupt)
-> CPU의 interrupt line
-> memory 내 OS 위치의 기계어로 점프하여 실행(OS에게 CPU 제어권 넘어감)
이때 기계어를 'device driver'라고 함.
** device controller(하드웨어)
: I/O device를 control해줌
** device driver(소프트웨어)
: I/O controller를 호출하는 CPU 내부의 코드
timer
: 정해진 시간이 흐른 뒤 운영체제에게 제어권 넘어가도록 interrupt
타이머값 = 0 -> interrupt -> 독점 보호
Interrupt
1. 타이머가
2. device controller가 일 끝나면
3. system call
4. exception(특권명령 실행 시도)
=> 1,2는 하드웨어 인터럽트이고
3,4는 소프트웨어 인터럽트이다.(trap이라고 부른다)
이렇게 interrupt가 일어나면
각각의 경우에 맞는 인터럽트 벡터로 가서
인터럽트 처리 루틴이 실행되어 interrupt에 대응한다.
=> 이렇게 OS(운영체제)는 interrupt에 의해 호출되면서 작동한다.
synchronous I/O & asynchronous I/O
사용자가 I/O device에서 파일을 읽어오고 싶다면,
CPU가 모니터모드로 전환되어 OS가 대신 I/O device에게 일을 요청한다고 했었다.
하지만 I/O device는 일하는 데 오래 걸림
사용자 프로세스는 결과를 받을 때까지 어떻게 하느냐에 따라 synchronous/asynchronous로 나뉜다.
- synchronous I/O(동기식)
: I/O 완료될 때까지 해당 사용자에게서 빼앗고 다른 사용자에게 제어권 넘김 -> I/O 처리를 기다리는 줄에 줄세움
: 결과가 나올 때까지 주지 않다가 I/O controller의 일 처리 결과가 나오면 주면서 다시 제어권 부여
- asynchronous I/O(비동기식)
: I/O 작업 요청해도 빼앗지 않고 해당 사용자가 계속 쓸 수 있도록.
: 결과에 무관하게 사용자에게 곧바로 응답해서 해당 결과와 무관한 다른 일 하고 있도록.
DMA(Direct Memory Access)
: CPU의 interrupt 부담을 줄여줌
Interrupt가 걸리면 CPU에게는 어쨌든 비효율적이다.
"DMA": CPU 대신 controller에서 데이터를 읽어올 수 있는 보조 장치
-> interrupt를 일단 얘가 받고, 좀 쌓이면 CPU의 memory에 저장해두고 interrupt걸어 알려줌
-> CPU에 interrupt가 너무 자주 걸리는 것 막음
메모리와 I/O에 접근하는 두 가지 방법
- 메모리 접근와 I/O접근을 따로 하는 방법
- 메모리 접근 방식을 통해 I/O에 접근하는 방법
저장 장치 계층 구조
위로 갈수록 (+)용량 작고 빠르지만 (-)휘발성이고 비쌈
아래로 갈수록 (-)용량은 크고 느리지만, (+)비휘발성이고 쌈
위쪽 부분에서 가지고 있다면 밑에까지 가지 않고(I/O device에게 요청도 불필요) 빨리 읽어 쓸 수 있어 효율적
하지만 용량은 제한돼있기 때문에 다 저장하지는 못함 (자주 쓰이는 것만)
프로그램의 실행(메모리 load)
다음과 같이 CPU의 physical memory에 올라가기 전에
사실 virtual memory, 즉 가상 메모리를 거친다.
- virtual memory: 각 프로세스들만의 주소
- physical memory: 사용되는 모든 프로세스들을 하나의 주소 체계로
=> 동일한 프로세스라도 두 memory에 각각 다른 주소로 저장되기 때문에 address translation 필요
<virtual memory>
: 다음 세 가지 구성요소 있음
- code: 실제로 CPU가 실행할 기계어가 존재
- data: 전역변수 등 프로그램이 실행될 때까지 남아있는 data들
* memory data(변수, 배열 등)를 쓸 때가 있음
- stack: 함수 안의 지역변수
위와 같이 각 프로세스마다, 그리고 커널도 code,data,stack를 각각 가지고 있다.
<kernel address space>
1. code
다음은 모두 운영체제의 역할이고,
운영체제의 역할이 모두 kernel space의 code에 들어가있다.
- 사용자에게 편리한 서비스 제공하기 위한 코드
- interrupt가 들어왔을 때 무엇을 처리해야 하는지
- 사용자가 I/O 에게서 읽어와달라고 부탁했을 때 system call 처리
- 하드웨어 자원 관리
2. data
- 모든 하드웨어들 관리 위한 자료구조: CPU/mem/disk 관리
- 모든 프로세스 관리 위한 자료구조: PCB(우선순위, 메모리 등에 대한 정보)
3. stack
각 프로세스마다 별도로 둠("누구에 의해 호출되어 code가 실행되었는가")
ex. A를 실행하다가 OS로 넘어왔으면 -> A의 kernel stack에 저장
<각 프로세스의 Address space>
1. code => 각 프로세스드이 사용하는 함수 정의돼 있음
- 사용자 정의 함수(사용자 모드)
: 내가 직접 만듦
- 라이브러리 함수(사용자 모드)
: 내가 만든 함수는 아니지만 쓰고 싶어서 가져옴
- 커널 함수(커널 모드)
: 커널의 code에 들어 있는 함수
=> 사용자 정의 함수와 라이브러리 함수는 내 프로세스의 code 영역에 들어있지만,
커널함수는 비록 가져다 쓰긴 했지만 내 프로세스의 code에 들어 있는 것이 아니라 kernel code 영역에 들어 있다. -> system call해서 CPU 제어권이 OS(kernel)에게 넘어간다.
2. data
3. stack
'학교 강의 > 운영체제' 카테고리의 다른 글
[Chapter 4] Process Management (0) | 2025.04.19 |
---|---|
[Chapter 3] Process (0) | 2025.04.19 |
[Chapter 1] Introduction to Operating Systems (0) | 2025.04.10 |
[Chapter 5] CPU scheduling (0) | 2025.04.07 |