User mode vs Kernel mode
User mode
- 유저(사용자)가 접근할 수 있는 영역을 제한적으로 두고, 프로그램의 자원에 함부로 접근하지 못하는 모드이다.
- 이 모드에서 코드를 작성하고, 프로세스를 실행하는 등의 행동이 가능하다.
- 유저 어플리케이션 코드가 유저 모드에서 실행된다고 이해하면 된다.
Kernel mode
- 하드웨어를 포함한 모든 자원(드라이버, 메모리, CPU 포함)에 접근, 명령할 수 있다.
User mode와 Kernel mode의 전환
- User mode ─> Kernel mode : 프로세스가 유저 모드에서 실행되다가 Kernel mode에서 실행해야하는 특별한 요청이 필요할 때 system call을 이용해 커널에 요청한다.
- Kernel mode ─> User mode : system call의 요청을 받은 커널이 그 요청에 대한 작업을 하고 그 결과 값을 return 값으로 전해준다.
System Call
- 사용자 모드에서 커널 모드로 전환하여, 사용자 모드에서는 할 수 없는 하드웨어를 제어하는 명령어를 실행하는 OS가 제공하는 일종의 인터페이스이다.
- 메모리에 프로그램을 적재하고, I/O처리, 파일 시스템 처리 등 여러 기능을 담당하고 있다.
- read(프로그램을 읽는 것), fork(새로운 프로세스를 만드는 것), execve(새 프로그램을 로드하는 것), 프로세스를 종료하는 등의 서비스를 커널에 요청할 때 system call을 활용한다.
Interrupt
- 인터럽트란 프로세스 실행 도중 예기치 않은 상황이 발생할 때 발생한 상황을 처리한 후 실행중인 작업으로 복귀하는 것을 말한다.
- 인터럽트의 종류는 외부 인터럽트, 내부 인터럽트, 소프트웨어 인터럽트로 나뉜다.
- 비동기적 인터럽트 / 하드웨어 인터럽트 : 전원 이상, 기계 착오, 외부 신호, 입출력 등 프로세스 외부에서 발생하는 인터럽트
- 동기적 인터럽트 / 소프트웨어 인터럽트 : 프로세스 내부에서 잘못된 명령어, 데이터로 exception이 발생하는 것이며 trap이라고도 불린다.
- 인터럽트가 발생하면 그 것을 처리하기 위한 루틴인 ISR(Interrupt Service Routine)이 실행된다.
- 자세한 정리 : https://jeokyong-development.tistory.com/30
File Descriptor
- 파일 디스크립터는 리눅스 혹은 유닉스 계열의 시스템에서 프로세스가 파일을 다룰 때 사용하는 개념으로, 프로세스에서 서 특정 파일에 접근할 때 사용하는 추상적인 값이다.
일반적으로 운영체제가 특정 파일에 0이 아닌 정수값으로 할당해준다.
- 유닉스 시스템에서는 일반적인 정규 파일부터 디렉토리, 소켓, 파이프, 블록 디바이스, 캐릭터 디바이스 등 모든 객체들을 파일로 관리하는데, 유닉스 시스템에서 프로세스가 이 파일들을 접근할 때 파일 디스크립터를 사용한다.
- 프로세스가 실행 중에 파일을 Open하면 커널은 해당 프로세스의 파일 디스크립터 숫자 중 사용하지 않는 가장 작은 값을 할당해준다.
그 다음 프로세스가 열려있는 파일에 시스템 콜을 이용하여 접근할 때, 파일 디스크립터(FD) 값을 이용해서 파일을 지칭할 수 있다.
- 디스크립터는 네트워크 프로그래밍을 할 때 클라이언트와 서버의 데이터 교환도 용이하게 해준다.(관련해서 CS:APP 10장, 11장 정리한 것을 보면 됨)
Atomic Operation
- Atomic Operation(원자적 연산, 작업)이란 시작되면 중간에 중단되지 않고 완전히 수행되는 작업을 말한다. 즉, 이 작업이 실행되는 동안 중단되거나 다른 작업에 의해 간섭받지 않음을 보장한다.
원자적 작업은 일반적으로 멀티쓰레딩 및 동시성 제어에서 중요한 역할을 한다.
특징
1. 불가분성(indivisibility) : 작업이 시작되면 완료될 때까지 중단되지 않는다. 작업이 부분적으로 수행되는 상태가 존재하지 않음을 의미한다.
2. 일관성(consistency) : 작업이 완료된 후 시스템 상태가 일관성을 유지한다. 작업이 성공적으로 완료됐을 때만 시스템 상태가 변하고, 실패한 경우에는 시스템 상태가 작업 전과 동일함을 의미한다.
3. 동시성 제어(concurrency control) : 여러 쓰레드나 프로세스가 동시에 동일한 자원에 접근할 때, 원자적 작업은 race condition을 막는다.
장점
· 데이터 일관성 유지 : 여러 쓰레드가 동시에 데이터에 접근할 때(read or write) 데이터가 손상되거나 불일치가 발생하는 것을 방지한다.
· 동기화 간편화 : 개발자들이 동시성 문제를 쉽게 해결할 수 있게 도와준다.
단점
· 성능 오버헤드 : 원자적 작업을 보장하기 위한 추가 작업 때문에 성능이 저하될 수 있다.
· 복잡성 증가 : 위와 같은 추가 작업 때문에 프로그램이 더 복잡해지고, 잘못 사용하면 deadlock(교착 상태)이나 livelock(라이브 락) 등의 문제가 발생할 수 있다.
OS에서의 Atomic Operation
1. Lock & Mutex : OS는 멀티쓰레드 환경에서 race condition과 critical-section 등의 문제를 방지하기 위해 락과 뮤텍스를 사용한다. 이 때, 스레드가 critical section에 들어가고 나올 때 lock을 얻고 해제하는 작업이 원자적으로 작동한다.
2. Interrupt Handling : 원자적 작업은 인터럽트 핸들러가 실행되는 동안 데이터 구조(카운터 변수, 상태 플래그 등)의 변경 작업을 안전하게 수행하는데 사용된다. 이는 인터럽트가 중단됐을 때, 시스템의 일관성을 유지하게 만든다.
DB에서의 Atomic Operation
1. Transactions : 데이터베이스는 ACID(Atomic(원자성), Consistency(일관성), Isolation(고립성), Durability(지속성)) 속성을 유지하기 위해 트랜잭션을 사용한다.
이 중 원자성은 트랜잭션 내의 모든 작업이 완료되거나 전혀 수행되지 않음을 보장한다.(complete or nothing)
2. Lock Mechanism : 데이터베이스는 레코드나 테이블에 대한 동시 접근을 제어하기 위해 다양한 락을 사용한다.
이 과정에서 원자적 작업은 락을 설정하고 해제하는 작업을 안전하게 수행한다.
Register vs Memory
- 레지스터와 메모리는 컴퓨터 시스템에서 데이터를 저장하고 처리하는 데 필수적인 두 가지 리소스이다.
- 이 두 요소는 속도, 용량, 용도등 여러 면에서 다르다.
Register
- 레지스터는 CPU 내부에 위치한매우 빠른 데이터 저장소이다.
- 소량의 데이터(일반적으로 바이트 단위)를 저장할 수 있고, CPU가 직접 접근하여 사용한다.
- 레지스터는 매우 빠른 데이터 처리 속도를 가진다.(메모리 계층 구조에서 가장 빠른 속도와 가장 작은 크기를 가짐)
역할
· 명령어 실행 : CPU는 현재 실행 중인 명령어와 관련된 데이터를 레지스터에 저장한다.
· 임시 데이터 저장 : 계산 중간 결과나 임시 값들을 레지스터에 저장한다.
· 특수 용도 : 프로그램 카운터, 스택 포인터와 같은 특수한 목적을 위한 레지스터도 존재한다.
- 운영체제는 context switching 시 레지스터의 상태를 저장하고 복원하는 작업을 수행한다.
이는 각 프로세스가 독립적인 실행 환경을 유지하도록 한다.
Memory
- 메모리(주로 RAM을 지칭)는 컴퓨터 시스템에서 데이터를 저장하는 주요 장치이다.
- 레지스터보다 용량이 크지만, 속도는 레지스터보다 느리다.
- 메모리는 프로그램의 코드와 데이터를 저장하는 데 사용된다.
역할
· 프로그램 저장 : 실행 중인 프로그램의 코드와 데이터를 저장한다.
· 임시 데이터 저장소 : 프로그램 실행 중 생성되는 데이터를 임시로 저장한다.(User stack에 저장)
· 가상 메모리 : 실제 물리적 메모리를 초과하는 데이터를 디스크에 저장하고 필요할 때 불러오는 역할을 한다.
- 운영체제는 메모리 관리를 통해 각 프로세스에 메모리 공간을 할당하고 해제하는 등 관리를 한다.
- 메모리 보호, 가상 메모리 관리, 페이징 등의 기법을 통해 시스템의 효율성과 안정성을 유지한다.
레지스터 vs 메모리
· 속도 : 레지스터는 CPU 내부에 있기 때문에 메모리 계층 구조 중 가장 빠른 속도로 데이터에 접근할 수 있는 반면, 메모리는 레지스터보다 접근 속도가 느리다.
· 용량 : 메모리는 레지스터에 비해 훨씬 많은 양의 데이터를 저장할 수 있다.
· 용도 : 레지스터는 현재 CPU가 처리 중인 작업에 필요한 데이터를 빠르게 처리하기 위해 사용된다.
메모리는 프로그램의 코드와 데이터를 저장하는데 사용된다.
· 가격(?) : 레지스터가 훨씬 만들기도 어렵고 비싸다.
rax register
- rax 레지스터는 x86-64 아키텍처에서 사용되는 범용 레지스터 중 하나이다.(관련 정리 글 : https://jeokyong-development.tistory.com/22)
- 64비트 시스템에서는 rax, 32비트에서는 eax, 16비트에서는 ax라는 이름을 갖는다.(이전 16비트 32비트에서도 호환되도록 사용 가능)
- 함수 호출의 결과값을 담는데 사용된다.
- 산술 연산 및 다른 명령어의 결과값을 담는데 사용된다.
OS에서의 역할
1. 시스템 호출 : 시스템 호출을 수행할 때, rax는 호출되는 시스템 호출의 번호를 저장하는데 사용된다.
시스템 호출이 완료된 후, rax는 반환값(return value)를 담는데 사용된다.
2. 프로그램 예외 처리 : 프로그램이 예외 상황을 만났을 때, rax는 예외 처리 루틴에서 중요한 정보를 담는데 사용될 수 있다.
3. 최적화 : 컴파일러는 rax를 자주 사용되는 값의 저장 및 연산에 사용하여 성능을 최적화한다.
- rax 레지스터는 프로그램의 실행과 운영 체제의 시스템 호출에서 핵심적인 역할을 한다.
- 하드웨어 아키텍처와 운영 체제 사이의 인터페이스를 이해하는데 중요한 역할을 하고, 효율적인 프로그램 설계와 최적화에 기여한다.
User Stack
- 사용자 스택은 프로그램의 실행 중에 함수 호출과 반환, 지역 변수, 함수 매개 변수 등을 저장하는데 사용되는 메모리 영역이다.(https://jeokyong-development.tistory.com/17)
- LIFO 구조를 가지며, 마지막에 들어간 요소가 가장 먼저 나온다.
- 스택 포인터는 스택의 최상단을 가리키며, 함수 호출 시에 스택 포인터가 이동하며 새로운 프레임을 생성한다.
용도
· 함수 호출 관리 : 함수 호출 시, 호출 정보(리턴 주소, 매개 변수, 지역 변수 등)가 스택에 저장된다.
· 지역 변수 저장 : 각 함수의 지역 변수는 해당 함수의 스택 프레임에 저장된다.
· 재귀 및 중첩 함수 호출 : 재귀적 함수 호출이나 중첩된 함수 호출을 관리하는데 사용된다.
OS에서의 User Stack
1. 프로세스 관리 : 각 프로세스는 독립적인 사용자 스택을 가진다. 이는 프로세스의 독립성과 데이터 보호에 기여한다.
운영 체제는 프로세스 생성 시 사용자 스택을 할당하고, 프로세스 종료 시 해제한다.
2. 컨텍스트 스위칭 : 프로세스가 전활될 때(context switching), 운영 체제는 현재 프로세스의 스택 상태를 저장하고, 다음 프로세스의 스택 상태를 복원한다. 이는 프로세스가 이전 상태를 유지할 수 있도록 한다.
3. 스택 오버플로우 : 프로그램이 할당된 스택 영역을 초과하여 데이터를 저장하면, 운영 체제가 이를 감지하고 프로그램을 종료시키거나 예외 처리를 수행한다.
4. 보안 : 사용자 스택은 버퍼 오버플로우 공격의 대상이 될 수 있다. 이를 방지하기 위해 운영체제는 스택 카나리(stack canary) 같은 기술을 사용하여 스택의 무결성을 보호한다.
Kernel Stack
- 일반적으로 커널 스택이란 프로세스에서 system call을 이용하여 커널 모드로 들어간 뒤, system call을 처리하는 동안에 사용되는 스택이라고 생각하면 된다.
- 커널 스택은 따로 존재하는 것이 아닌 virtual memory 상의 최상단에 kernel에 관한 데이터를 저장하는 곳에 존재한다.
Cache
- 프로세서에 가까이 존재하는 저장 장치로, 프로세스가 데이터를 사용하는 데에 오버헤드를 줄이기 위한 저장 장치의 일종
- 지역성(locality)을 기반으로 만들어진 장치이다.
- 시간적 지역성(time locality) : 한 번 사용한 데이터를 가까운 시일 내에 다시 사용할 가능성이 높다는 원리
- 공간적 지역성(space locality) : 한 번 사용한 데이터의 주위 데이터에 접근할 가능성이 높다는 원리
https://jeokyong-development.tistory.com/10
32 bit OS vs 64 bit OS
- 32비트와 64비트 운영체제의 차이는 주로 처리할 수 있는 데이터의 양과 메모리 관리 방식에서 크게 나타난다.
32 bit OS | 64 bit OS | |
메모리 주소 지정 | 최대 2^32 바이트(약 4GB)의 메모리 주소 지정 가능 | 이론적으로 최대 2^64(수 페타바이트)의 메모리 주소 지정 가능 |
실제 사용 가능한 메모리 | 4GB 미만으로 제한됨 | 실제 하드웨어나 운영 체제 설계에 따라 훨씬 적을 수 있음 |
성능 및 호환성 | 오래된 하드웨어 및 소프트웨어와의 호환성이 좋음 데이터 처리량이 상대적으로 적기 때문에 낮은 성능의 하드웨어에서도 잘 작동함 |
더 많은 데이터와 메모리 주소를 처리할 수 있어, 높은 성능의 애플리케이션 및 데이터 집약적 작업에 유리 더 큰 메모리 주소 공간을 활용하여 대규모 메모리를 요구하는 응용 프로그램을 효율적으로 실행 가능 |
응용 프로그램 개발 |
32비트 레지스터와 명령어 세트를 사용하여 개발됨 메모리 사용에 있어 제한이 있음 |
64비트 레지스터와 확장된 명령어 세트를 활용하여 개발 향상된 성능과 더 큰 메모리 할당이 가능 |
요약 : 64비트 운영체제는 훨씬 더 큰 메모리 주소 공간을 제공하고, 이는 메모리 집약적 작업과 애플리케이션에 유리하다.
64비트 운영체제의 데이터 처리량이 더 크고, 고성능 컴퓨팅 환경에 효율적임
일부 32비트 응용 프로그램은 64비트 운영체제에서 호완성 모드로 실행될 수 있지만, 반대는 불가능하다.
Segmentation Fault
- 프로그램이 허용되지 않은 메모리 영역에 접근을 시도하거나, 허용되지 않은 방법으로 메모리 영역에 접근을 시도할 경우 발생한다.
ex) 읽기 전용 영역에 어떤 내용을 쓰려고 시도하거나, 운영 체제에서 사용하는 영역에 다른 내용을 덮어쓰려 하는 경우
'TIL & WIL' 카테고리의 다른 글
[WIL] 크래프톤 정글 11~12주차 - PintOS 키워드 정리 (0) | 2024.05.31 |
---|---|
[WIL] 크래프톤 정글 8~9주차 - PintOS 키워드 정리 (0) | 2024.05.21 |
[TIL] 크래프톤 정글 7주차 - 프록시(Proxy) (0) | 2024.05.07 |
[TIL] 크래프톤 정글 7주차 - CS:app 11장(네트워크 프로그래밍) (0) | 2024.05.06 |
[TIL] 크래프톤 정글 7주차 - OSI 7 layer(TCP / IP layer) (0) | 2024.05.06 |