Pintos 2주차 keyword 정리

1. Process Controll Block

ID : 고유 이름

State : Ready, wating, terminated 등

Program Counter : 특정 프로세스가 실행해야 하는 다음 instruction의 주소를 나타낸다.

CPU Registers : 특정 프로세스가 사용하고 있는 레지스터(index register, stack pointer, general purpose register, …)

Memory limits

List of open files

CPU scheduling information : 프로세스의 우선순위. 스케쥴링 큐를 가리키는 포인터나 다른 스케쥴링 parameter.

memory management information : 특정 프로세스에 의해 사용되는 메모리에 관한 정보

accounting information : 특정 프로세스에 의해 사용되는 자원(CPU,time, memory, …) 에 대한 account

I/O Status information : 특정 프로세스와 연관된 입출력 장치

2. Context Switch

Interrupts는 운영 체제가 CPU의 현재 실행 업무를 바꾸고 kernel routine을 실행하도록 한다.

이런 일은 일반적인 목적의 시스템에서 빈번하게 발생한다.

인터럽트가 발생하면, 시스템은 현재 CPU에서 작동중인 프로세스의 현재 context를 저장해야 한다. 프로세싱이 끝나고 프로세스를 연기하였다가 다시 재개할 때 그 context를 복원할 수 있기 때문이다.

context 는 프로세스의 PCB에 나타난다.

또 다른 프로세스로 CPU를 전환할 때, 현재 프로세스의 state를 저장해야하고 다른 프로세스의 state를 restore해야 한다.

Context switch 시간은 순전히 overhead이다. 시스템이 전환하는 동안 유용한 일을 하지 않기 때문이다.

속도는 기계마다 다양하지만, 메모리 속도, 복사되야 하는 레지스터의 수, 모든 레지스터를 저장하거나 불러오는 한 줄짜리 instruction 같은 특별한 instruction의 존재에 따라 또 달라진다.

일반적인 속도는 몇 밀리초(ms, 천분의 1)

3. virtual Machine

아이디어 구조 : 단일 컴퓨터의 하드웨어(CPU, memory, disk drives, network interface cards, and so forth)를 복수의 다른 실행 환경으로 추상화하여, 각 분리된 실행 환경이 각자 자신만의 컴퓨터에서 실행되고 있다는 착각을 만든다.

Virtualization은 복수의 OS(그리고 그들의 applitcations)가 동일한 실제 기계에서 동시에 실행되도록 해준다.

virtual resources : 각 OS가 ‘소유한다고’ 생각하는 하드웨어 자원

virtual machine(vm) : OS + applitcations + virtual resources

virtualization layer : management of 실제 하드웨어

CPU, Memory, NIC, Disk는 실제론 같이 쓰지만 마치 각자가 자신의 것을 가졌다고 착각함.

Implementation

Virtual Machine Software - Kernel mode에서 실행

Virtual Machine 그 자체 본인 - User mode에서 실행

실제 기계처럼, virtual machine도 유저모드와 가상모드 필요하다.

그 결과 : 가상 유저 모드, 가상 커널 모드

두 개 모두 실제 물리적으로는 User mode에서 실행된다.

4. PEB

PEB(Process Environment Block)는 자료구조이다. 그 자체로 커널 모드의 자료구조는 아니다. 프로세스와 관련된 application 모드 주소 공간에 있다. 운영체제에서 application-mode 코드로 사용되도록 고안되었기 때문이다.

DLLs,environment variables, heaps, command line arguments 등을 가리킨다.

5. Process identifier(Process ID or PID)

Unix-like 운영체제에서, 새로운 프로세스들은 fork() 시스템 콜로 만들어 진다. PID는 부모 process에게서 반환되고, 이후의 함수 호출로 자식에게 연결된다. 예를 들어, 부모는 자식이 waitpid()함수로 종결되거나 , kill로 프로세스를 종결시키기를 기다릴 지도 모른다.

구별된 PID로 특히 2가지 task를 처리할 수 있다. swapper 나 sched는 PID로 0을 가지고 paging을 담당하며 일반적인 유저모드 프로세스보다 커널 쪽이다. PID 1은 보통 시스템을 키고 닫는 초기 프로세스이다. 원래, PID 1은 init을 위해 따로 지정되어 있지 않았다. 커널에 의해 첫 프로세스의 결과가 그렇다보니 이렇게 되었다. 좀더 최근 Unix 시스템들은 일반적으로 ‘프로세스들’처럼 보이는 부가적인 커널 구성요소들을 가지는데, 그 경우 PID 1은 더 오래된 시스템과 동일성을 유지하기 위해 init 프로세스를 위해 PID 1을 지정한다.

6. User Stack

User stack은 보통 특정 유저와 프로세스와 연관된 정보와 데이터를 저장하기 위해 할당된 메모리 지역을 일컫는다. 함수 호출, 지역 변수, 실행중에 프로그램이 사용하는 다른 데이터와 같은 정보들을 포함한다.

User stack은 프로그램의 실행 환경의 중요한 구성요소인데, 프로그램이 함수 호출의 순서 및 과정과 각 호출과 연관된 변수를 유지해주기 때문이다. 프로그램이 함수를 호출할 때, 시스템은 함수의 인자를 입력하고 새로운 stack frame을 만드는 유저 스택 위의 주소를 반환받는다. 함수가 실행될 때, argument와 지역 변수에 접근하기 위해 stack frame을 사용한다. 함수가 반환될때, 시스템은 user stack에서 stack frame을 뽑아내고, stack의 이전 상태를 복구한다.

전반적으로, 프로그램이 실행중에 데이터를 관리하고 조직하는데 도움을 주기 때문에, user stack은 메모리 관리 시스템의 필수적인 파트이다.

7. x86_64 calling convention

x86_64 calling convention은 x86_64 architecture에서 실행중인 프로그램 내에서 어떻게 함수 호출과 반환을 다룰지에 관한 규칙들이다. 호출 convention은 어떻게 함수에게 arguments가 전달되는지, 함수가 어떻게 결과를 반환하는지, 어떻게 함수가 지역 변수와 register를 관리하는지를 구체화한다.

x86_84 calling convention의 주요 기능

  • Register : x86_64 architecture는 16개의 다목적 레지스터를 가지며, 호출 convention은 어떤 레지스터들이 arguments를 전달하는데 쓰이고 어떤 레지스터들이 함수 호출중 보존되는지를 구체화 한다.
  • Argument passing : 첫 6개의 정수 나 포인터 arguments는 레지스터에서 전달된다. %rdi, %rsi, %rdx, %rcs, %r8, %r9 다. 추가적인 arguments는 stack에 전해진다.
  • Return values : 정수와 값을 반환하는 포인터는 %rax register에 전달된다. 값을 반환하는 Floating-point는 %xmmO 레지스터에 전달된다.
  • stack frame : 스택은 지역변수와 반환 주소를 저장하기 위해 사용된다. stack pointer(%rsp)는 16 바이트 boundary를 지켜야 한다.
  • Caller vs callee responsibility : 호출자는 stack frame, 전달 arguments, 그리고 함수를 호출하는 것에 대한 책임이 있다. callee는 사용한 어떤 레지스터든 저장하고 복구하는데 책임이 있고 반환 전에 stack을 청소하는데도 책임이 있다.

전반적으로. x86_64 calling convention은 함수 호출과 반환이다른 프로그램과 운영 체제를 뛰어넘어 동시에 관리되는데 도움이 되는 잘 정의된 규칙들이다.

8. Register vs memory

레지스터와 메모리는 컴퓨팅에서 데이터를 저장하고 컴퓨터가 프로그램을 실행하기 위해 필요한 것들을 저장하기 위해 사용되는 두 타입의 저장소 이다.

Register

레지스터는 CPU 내에 작고 빠른 저장지역이다. 이것은 데이터를 저장하고 현재 처리되는 프로세스의 지시를 저장하거나 곧 CPU가 처리할 것들에 대해 저장한다. 레지스터는 매우 빠른데, CPU 칩 위에 있기도 하고 memory보다 매우 매우 빠르게 접근할 수 있기 때문이다. Register는 또한 8~64 bits 범위로 사이즈가 제한되어 있다.

Memory

반면에, Memory는 CPU에게 방금 막 처리된 instruction과 저장 데이터를 위헤 사용되는 매우 크지만 느린 저장소이다. 메모리는 일반적으로 바이트로 측정이 되고 레지스터보다 훨씬 큰 양의 데이터를 저장할 수 있다. 메모리는 보통 분리된 칩이나 모듈에 위치해 있다. CPU가 레지스터에 접근하는 것보다 더 오래 걸린다.

두 레지스터와 메모리 모두 정보와 지시를 저장하는데 사용되지만, 그들 사이에 주요한 차이점 들이 있다.

  • Speed : 레지스터는 CPU에 위치해 있고, 훨씬 빠르게 접근할 수 있기 때문에 메모리보다 빠르다.
  • Size : 레지스터는 메모리보다 훨씬 작고 제한된 용량이다. 메모리는 레지스터보다 훨씬 더 많은 양을 저장할 수 있다.
  • Access: 레지스터는 CPU가 직접적으로 접근하지만 메모리는 CPU와 메모리 사이에서 데이터 흐름을 관리하는 memory controller를 통해 접근된다.
  • Purpose : 레지스터는 지금 CPU가 처리하는 프로세스의 정보를 저장하기 위해서고, 메모리는 지금 처리되는 정보는 아니다.

전반적으로 레지스터와 메모리는 둘다 컴퓨터 구조에 필수적이고 CPU가 프로그램을 더 효율적으로 실행하기 위해 함께 일한다.

9. argument vector(argv, command line argument)

command line에서나 다른 프로그램으로부터 받은 argument를 프로그램에게 전달하는 메커니즘이다.

프로그램이 command line에서 시작되면, 운영체제는 일반적으로 arguments들을 argument vector를 이용해 프로그램에게 전달한다. argument vector는 문자열의 배열이고 개별 argument를 나타내는데, 첫 요소는 프로그램 자신의 이름이다.

예시.

myprogram arg1 arg2 arg3

이 경우, myprogram에 전달되는 argument vector는 4개의 요소를 가진다.

1
2
3
4
argv[0] = "myprogram"
argv[1] = "arg1"
argv[2] = "arg2"
argv[3] = "arg3"

프로그램은 argument vector를 indexing 함으로써 이 arguments들에 접근할 수 있다.

argument vector는 프로그램에 arguments를 전달하는 유연하고 강력한 메커니즘이고, 매우 다양한 프로그래밍 언어와 환경에서 사용된다. 그러나, command line에서 arguments를 처리할 때 조심하는 것은 매우 중요한데, 그 arguments들이 프로그램이나 시스템 전체적으로 문제를 야기하는 예상 밖의, 악의적인 입력일 수도 있기 때문이다.

10. ELF & loader

ELF

Excutable and Linkable Format은 실행가능 파일, object code, shared libraries, 그리고 Unix와 Unix-like 운영 체제의 core dumps에 사용되는 파일 형식이다. ELF는 더 오래된 a.out 형식을 대체하기 위해 고안되었고 Unix 시스템에서 표준 실행 가능 파일 형식이 되었다.

ELF 파일은 코드, 데이터, symbol tables, relocation information 같은 다양한 종류의 정보들을 가지는 섹션들로 나누어져 있다. 각 섹션은 구체적인 목적이 있고 시스템이나 프로그램들이 다른 operation을 위해 사용한다.

ELF 파일들은 플랫폼-독립적으로 고안되었기에, ELF 형식을 지원하는 다른 종류의 하드웨어 에서도 실행될 수 있다. 다른 Unix 시스템에서 recompile 하거나 코드를 수정하는 일 없이 소프트웨어를 전달하고 실행시키기 더 쉬워졌다.

ELF의 주요 기능중 하나는 컴파일할 때 정적으로 연결되는 것이 아니라, 실행중에 shared libraries가 로드되고 연결되도록 하는 동적 linking을 지원하는 것이다. 이것은 shared libraries가 업데이트 되고 main excutable로부터 분리되어 유지되도록 해주었기 때문에 소프트웨어를 개발하고 퍼뜨리는데 장점으로 작용했다.

ELF는 Unix 시스템에서 실행가능 파일, 객체 코드 파일의 표준이 되었고 프로그래밍 언어와 개발 툴에게 넓게 호환된다. ELF 형식의 휴대성과 유연성은 Unix와 Unix-like 시스템들을 소프트웨어 개발과 유통을 위한 강력한 도구로 만들어 주었다.

Loader

loader는 실행가능 코드를 메모리에 있는 파일에서 불러오고 실행을 준비하는 프로그램이다. Unix와 Unix-like 시스템에서, loader는 ELF 형식에 있는 실행 가능 파일을 불러오는 역할이다.

ELF 실행가능 파일이 로드되었을 때, loader는 파일 헤더와 프로그램 헤더를 읽고 어떻게 프로그램을 메모리에서 load할지 결정한다. 그 후, 프로그램을 위해 메모리를 할당하고, 메모리의 파일에서 프로그램 섹션을 복사하고, 실제 메모리 위치에 대한 데이터와 프로그램 코드를 조절하기 위해 필요한 relocation을 수행한다.

loader는 또한 프로그램의 스택을 초기화하고 environment variables(환경 변수)와 command-line arguments를 두는 것과 같은 프로그램을 위한 실행 환경을 설치한다. 한번 프로그램이 로드되고 초기화되면, loader는 프로그램 코드 실행을 시작하는 프로그램의 entry point에 전송한다.

loader는 Unix 실행 환경의 중요한 구성요소이고 프로그램이 로드되고 올바르게 실행되는데 중요한 역할을 한다. shared libraries와 실행중에 로드되고 복수의 프로그램들에게 공유되는 동적 linked된 코드를 관리하는데도 중요하다.

전반적으로, ELF 파일과 loader는 Unix 시스템에서 실행가능 코드를 위해 유연하고 강력한 플랫폼을 제공하는데 함께 작용된다. loader는 시스템의 필수적인 구성요소이고, 프로그램이 로드되고 올바르게 실행되는데 중요하며, 공유된 자원을 관리하고 프로그램을 위한 실행 환경을 제공하는데도 마찬가지이다.

12. file descriptor

Unix와 Unix-like 운영 체제에서, file descriptor는 프로세스 내에서 열린 파일을 구별해주는 정수 값이다. file descriptor는 파일이나 pipe나 네트워크 소켓같이 프로세스가 open한 다른 입출력 자원에 대한 참조이다.

프로세스가 파일을 열면 file descriptor에 연결되는데, file descriptor는 open file을 나타내는 정수 값이다. file descriptor는 프로세스가 파일을 읽고, 쓰고, 닫는것과 같이 이후의(subsequent) operation들에서 열린 파일을 참조하는데 사용된다.

Unix에서, 첫 3 file descriptors(0,1,2)는 표준 입력, 표준 출력, 표준 에러에게 배당된다. 추가적인 file descriptor는 open() 시스템 콜을 사용하는 프로세가 열 수 있고, 그것들은 3보다 크거나 같은 다음 가용 정수값이 연결된다.

File descriptor는 종종 Unix 프로그래밍에서 파일과 다른 자원에 대한 입출력 operation을 수행하기 위해 사용된다. File descriptor들은 프로세스들간에 전달될 수 있다. 그 프로세스들은 pipes 나 sockets 같은 상호 의사소통 메커니즘(interprocess communication mechanism)을 사용하는 것이 방법이다.

전반적으로, file descriptors는 Unix와 Unix-like 운영체제에서 입출력 자원과 파일들로 작업하는, 간단하고 강력한 메커니즘을 제공한다. 각 오픈 파일에 고유의 정수 값을 부여함으로서, 프로세스들이 파일과 자원에서 입출력 operation을 동시에, 효율적인 방식으로 수행하게 해주었다.

file descriptor의 배열(array)를 file descriptor table이라 한다.