[Jungle] Week9. 공부 키워드

somi·2024년 5월 22일
0

[Krafton Jungle]

목록 보기
57/68

week9. 공부 키워드

운영체제?

  • 컴퓨터 하드웨어와 사용자간의 인터페이스를 제공하는 소프트웨어
  • 커널, 사용자 인터페이스(GUI, CLI), 시스템 유틸리티 및 라이브러리 등

커널

: 운영체제의 핵심 부분 -> 하드웨어와 직접 상호작용하며 시스템 자원을 관리함
=> 커널 모드: 커널이 동작하는 특권 모드: 모든 시스템 리소스에 대한 접근 권한을 가짐

정리: 운영체제의 핵심 기능을 담당하는게 커널이다!

  • 커널: 하드웨어와 직접 상호작용하고 시스템 자원 관리
  • 운영체제는 사용자와 어플리케이션에게 이러한 기능을 제공하는 전체 시스템


User mode(사용자 모드) vs. Kernel mode(커널 모드)

Kernel Mode
커널 모드 -> CPU가 운영체제의 커널을 실행할 때 사용하는 모드
: 시스템의 모든 메모리와 하드웨어 리소스에 대한 완전한 접근 권한을 가짐, 특권 명령을 실행 가능.
-> 하드웨어 제어, 시스템 자원 관리, 프로세스 스케줄링 등 커널 기능이 실행되는 모드

  • 커널 모드는 CPU의 특권 레벨 중 가장 낮은 레벨인 Ring 0에서 실행 -> 모든 명령어 실행 가능한 권한
  • 커널 모드에서 실행되는 프로그램은 하나의 가상 메모리 영역 공유하여 서로 접근이 가능하다.

User Mode
: 사용자 모드에서는 사용자 애플리케이션이 실행된다. 시스템의 나머지 부분을 보호하기 위해서 제한된 접근 권한을 가짐, 특권 명령을 실행할 수 없음.
각 응용 프로그램은 독립적인 프로세스로 실행됨

  • User mode는 CPU의 특권 레벨 중 가장 높은 레벨인 Ring 3에서 실행 -> 제한된 권한, 특권 명령을 실행할 수 없음.
  • user mode에서 실행되는 프로세스는 각자의 가상 메모리 영역을 가지고 다른 프로세스와 격리되어 있다. -> 한 프로세스에서 오류가 발생해도 다른 프로세스나 운영체제에 영향을 미치지 않는다.

예를 들어, 사용자 프로그램은 파일을 읽거나 쓰려면, OS의 파일 시스템 서비스를 요청해야 한다.

  • 왜?
    만약 직접 접근을 허락했다면 악성 프로그램이 시스템 파일을 수정하고 삭제하는 행위를 마음대로 할 수 있을 것이다. 또한 프로그램 오류나 버그로 인해 시스템 전체가 불안정해지는 것도 커널이 파일 시스템을 관리하면 막을 수 있을 것이다.
    + 시스템의 무결성 유지!

이렇게 user mode와 kernel mode를 분리함으로써 시스템의 보안과 안정성을 크게 향상시킬 수 있다.

User mode에서 Kernel mode로 전환할 때 일반적으로 시스템 콜을 통해 이루어진다!

시스템 콜

: 사용자 모드에서 커널 모드로 전환하기 위해 필요한 인터페이스

파일 조작 (예: open, read, write)
프로세스 관리 (예: fork, exec, exit)
메모리 관리 (예: mmap, munmap)
기타 다양한 운영체제 기능

  1. 시스템 콜 요청
    : 사용자 프로그램은 파일 열기, 읽기 쓰기 등을 수행하기 위해 시스템 콜을 호출
    -> 시스템 콜 번호와 인자들을 레지스터에 설정해준다.
  2. 커널 모드 전환
    : 시스템 콜이 호출되면 CPU는 usermode에서 kernel mode로 전환.
    커널 모드에서 실행되면 운영체제가 하드웨어에 직접 접근할 수 있는 권한을 갖게 된다.
  3. 시스템 콜 처리
    : 커널은 시스템 콜의 번호를 기반으로 시스템 콜 테이블에서 해당하는 처리 루틴을 찾아서 실행한다.
  4. 결과 return, user mode로 전환
    결과를 사용자 프로그램에게 반환하고 cpu는 다시 user mode로 전환된다.

인터럽트와 시스템 콜의 차이가 무엇인가?
Interrupt: 하드웨어나 소프트웨어 이벤트에 의해 발생. 주로 비동기적으로 cpu 흐름을 변경하여 특정 이벤트 처리

  • 주로 시스템이 즉각적으로 처리해야 하는 상황 => 입출력 장치 관리, 타이머 이벤트 처리, 하드웨어 오류 처리, 전원 관리, 프로세스 간 통신 등등

System call: 사용자 프로그램이 운영체제의 기능을 요청할 때 사용됨. 커널 모드로 안전하게 전환하여 시스템 자원을 사용할 수 있게끔


Register vs Memory


Register

  • CPU 내부에 위치
  • 매우 빠름, CPU가 가장 빠르게 접근할 수 있는 저장 공간
  • but 용량이 매우 작음
  • CPU의 연산을 직접 지원하기 위해 사용
  • 주로 명령어 실행 중 중간 결과를 저장
  • 주소 계산, 데이터 이동 등 다양한 단기 작업에 사용
    예시) PC, SP(Stack Pointer), 범용 레지스터 등

context switch가 발생하면 운영체제는 각 프로세스의 PCB를 이용해서 현재 실행중인 프로세스의 레지스터 상태를 저장하고, 다음 실행할 프로세스의 레지스터 상태를 복원한다.

이를 통해 여러 프로세스가 CPU를 공유하면서도 각 프로세스가 자신의 작업을 이어나갈 수 있게 된다.

Memory

  • CPU 외부에 위치(일반적으로 메인 보드에 장착)
  • 레지스터에 비해 느리다.
  • 용량이 큼
  • 실행 중인 프로그램과 그 데이터를 저장
  • 운영체제, 사용자 프로그램이 사용하는 작업 공간 제공
  • 프로세스 간의 데이터 공유 및 저장
    예시) RAM(Random Access Memory), ROM(Read-Only Memory)

프로그램을 실행하려면 먼저 실행 파일을 디스크에서 읽어서 메모리로 로드한다.
실행 파일의 각 세그먼트(코드, 데이터, 스택 등)를 메모리의 적절한 위치에 배치한다.

Cache

: CPU와 RAM 사이에 위치한 고속 메모리
캐시는 cpu내부에 위치하며 메모리 접근 시간을 줄이고 성능 향상을 위해 사용된다.

레지스터와 캐시의 비교
: 레지스터는 CPU의 가장 빠른 기억장치로, 명령어 실행 시 직접 접근하므로 지연 시간이 거의 없다.
캐시는 레지스터보다는 느리지만 RAM 보다는 훨씬 빠르다. -> 데이터 접근 시간을 줄이기 위해 사용된다.

레지스터는 CPU의 연산 및 명령어 수행 시에 사용된다. 연산 중간 결과를 저장하거나 특정 명령어 실행에 필요한 데이터를 일시적으로 저장한다.
캐시는 자주 사용되는 데이터나 명령어를 저장하여 메모리 접근 시간을 줄인다. -> CPU와 메인 메모리 사이의 중간 저장소 역할


User Stack


: 사용자 프로그램의 함수 호출, 지역 변수 저장, 함수 매개 변수 전달을 위해 사용됨

LIFO(Last In First Out) 방식으로 작동한다. -> 가장 마지막 스택에 추가된 데이터가 가장 먼저 나가게 된다.


스택은 높은 메모리 주소에서 낮은 메모리 주소 방향으로 성장한다. 새로운 데이터가 추가될 때마다 스택 포인터(Stack Pointer: 가장 최근에 추가된 데이터의 주소)가 낮은 주소로 이동한다.

push: 새로운 데이터가 User stack에 추가되면 스택 포인터는 낮은 메모리 주소로 이동하고 데이터는 그 위치에 저장된다.
pop: 가장 최근에 저장된 데이터, 가장 낮은 주소의 데이터가 먼저 제거. 스택에 데이터가 제거되면 스택 포인터는 높은 주소로 이동

궁금증_ 힙과 스택은 왜 서로 다른 방향으로 성장하는가?
서로 반대 방향으로 성장하면 두 메모리 영역이 충돌할 가능성이 줄어든다. 힙은 위로, 스택은 아래로 성장하기 때문에 만나기 전까지는 독립적으로 확장할 수 있다.

그리고 stack-heap collision 을 막기 위한 여러 매커니즘이 사용된다고 한다! 예시 - 가상 메모리 사용하여 물리적 메모리 한계 극복하기
-> but
주소 공간에 여러 쓰레드가 공존할 때는 이런 식으로 주소 공간을 나누게 되면 동작하지 않는다고 한다.

커널 스택(Kernel Stack)

: 운영체제의 커널 모드에서 사용되는 스택
-> 시스템 콜이나 인터럽트 처리와 같은 커널 모드 작업을 처리하는 동안 사용


Atomic operation: 원자적인 연산

-> 중간에 끼어들거나 분리될 수 없는, 즉 한번에 완전히 수행되거나 전혀 수행되지 않는 연산
=> 주로 멀티 쓰레딩 환경에서 데이터 일관성을 유지하고 동기화를 위해 사용된다.

=> 핀토스에서 예를 들면 sema_down, sema_up 과 같이 세마포어의 값을 증가 감소시키는 연산은 원자적으로 수행되어야 한다.


32bit OS vs. 64bit OS

각 메모리 주소 32bit로 표현 가능 vs. 64 bit로 표현 가능

cpu는 메모리에서 값을 읽어올 때 한번에 4byte(32 bit), 8byte(64bit)를 읽어온다.

32 bit OS: 32 bit register -> (예: EAX, EBX, ECX 등).
64 bit OS: 64 bit register -> (예: RAX, RBX, RCX 등). 32 bit 레지스터도 사용할 수 있지만, 상위 32비트는 무시됨


Segmentation Fault?

  • 컴퓨터 프로그램이 허용되지 않은 메모리 영역에 접근하려고 할 때 발생하는 오류
    운영체제는 각 프로그램이 자신의 메모리 공간만 접근하도록 제한 - 다른 프로그램의 메모리나 운영체제 자체의 메모리를 침범하지 못하게.

예시)

 int* ptr = (int*) 0x00000000;
 *ptr = 1;

여기서 ptr은 int형 포인터로 선언되고, 0x00000000 주소로 초기화 -> NULL 포인터 - 유효하지 않은 메모리 주소
운영체제에 의해 보호됨. 일반적인 사용자 프로그램이 이 주소에 접근하려고 하면 오류 발생

포인터를 사용할 때는 항상 유효한 메모리 주소로 초기화해야 한다. -> 동적 메모리 할당을 통해서 가능하다.
그리고 항상 NULL 여부를 확인해서 유효성을 검증해주자.

int* ptr = (int*) malloc(sizeof(int));
if (ptr != NULL) {
    *ptr = 1;
}
profile
📝 It's been waiting for you

0개의 댓글