커널 모드 비트

커널 모드 비트

Galvin 책에서 운영 체제 및 개념에 대해 아래 내용을 읽었습니다.

"모드 비트라고 불리는 비트가 컴퓨터의 하드웨어에 추가되어 현재 모드(커널(0) 또는 사용자(1))를 나타냅니다. 모드 비트를 사용하면 다음에서 실행되는 작업을 구별할 수 있습니다. 운영 체제를 대신하여 사용을 대신하여 실행되는 것"

이제 다중 프로세서 시스템이라면 프로세스가 시스템 호출을 실행하고 모드 비트를 1에서 0으로 변경한다고 가정합니다.

이제 다중 프로세서 시스템이므로 사용자 모드에서 병렬로 실행되는 다른 프로세스가 있을 수 있지만 모드 비트는 불일치를 유발하는 커널 모드를 나타내는 0으로 설정됩니다.

그렇다면 레지스터 수(모드 비트를 저장하는 데 필요함)는 프로세서 수에 따라 달라지나요?

답변1

당신의 책은 사물을 지나치게 단순화하고 있습니다. 실제로 모드가 설정되는 방식은 CPU에 따라 달라지며 반드시 "비트"일 필요도 없고 반드시 두 가지 모드만 있을 필요도 없습니다.

질문의 목적에 따라 Linux, Intel x86 및 멀티코어를 가정하겠습니다.

멀티태스킹은 Linux에서 소프트웨어 기반인 컨텍스트 전환을 통해 구현됩니다. 컨텍스트 스위치는 프로세서가 수행 중인 작업(코어 또는 CPU)을 중지하고 해당 상태를 RAM에 저장한 다음 이를 다른 컨텍스트로 대체합니다.

x86은 프로세스 수준 실행이 발생하기 전에 각 프로세서에 설정할 수 있는 보호 링을 구현합니다. Linux 커널은 메모리 공간에서 실행을 시작하기 전에 프로세스를 링 3(권한 없음)으로 설정하여 이를 처리합니다. 앞서 언급한 컨텍스트 전환 구현을 통해 커널은 특정 스레드(종종 인텔의 경우 코어당 2개의 스레드)에서 실행되는 프로세스의 개념을 유지합니다. 왜냐하면 해당 프로그램 코드가 실행될 때마다 커널은 항상 링을 3으로 다시 설정하기 때문입니다. 프로세서는 초당 여러 번 컨텍스트 전환이 발생하여 많은 프로세스가 동일한 코어에서 실행되는 것을 확인합니다. 하나 이상의 코어를 사용하여 본질적으로 동일한 방식으로 이 작업을 수행할 수 있습니다.

x86을 사용하는 Linux에서 스레드가 링 3에서 링 0(감독자)으로 전환하려는 경우 소프트웨어 인터럽트를 통해서만 이를 수행할 수 있습니다. 링 1과 2에서는 특수 지침으로도 가능하지만 Linux에서는 이를 구현하지 않습니다. Linux는 소프트웨어 인터럽트 핸들러를 제어하기 때문에 스레드가 이제 링 0에 있더라도 "커널 공간"(사용자 공간 코드를 실행하는 동일한 스레드임에도 불구하고 커널의 일부인 코드)에서만 코드를 실행하도록 보장할 수 있습니다. 운영 체제 용어로 이것은 실제로 수행되는 작업이므로 시스템 호출이라고 합니다. 이것을 "프로세스"가 커널 모드로 전환했다가 다시 돌아가는 것으로 간주할지 아니면 사용자 공간으로 다시 돌아갈 때까지 커널 공간 코드만 실행되기 때문에 프로세스가 효과적으로 보류 상태로 간주할지 여부는 사용자에게 달려 있습니다.

x86에서는 높은 링에 있는 링이 낮은 링으로 전환되도록 허용하므로 인터럽트 처리기가 완료된 후 다시 3으로 전환할 수 있습니다. 이는 모든 시스템 호출에서 발생하는 일입니다. 하드웨어 관점의 모든 시스템 호출은 시스템에서 무엇이든 할 수 있습니다. 프로그램의 모든 명령을 역순으로 실행한 다음 원하는 경우 메모리에서 모든 코드를 삭제할 수 있습니다. 또는 링 0으로 전환하여 프로그램 시작 시 실행을 시작할 수도 있습니다. 보시다시피 이러한 예는 하드웨어에 그러한 개념이 존재하지 않기 때문에 "커널/사용자" 모드의 개념을 깨뜨립니다. 그러나 Linux에서는 항상 커널 공간에 대한 호출과 사용자 공간으로의 복귀로 구현됩니다(효과적으로 x86의 링 0에서 메모리가 보호되지 않음).

따라서 커널/사용자 모드 전환은 스레드 보호 링에서 벗어날 수 있는 소프트웨어 인터럽트 핸들러를 사용하여 구현되지만 실행은 커널 공간에서만 발생하고 사용자 공간, 특히 해당 작업을 실행한 사용자 공간 프로세스로 다시 반환되도록 구현됩니다. syscall이지만 링 3으로 돌아온 후에만 가능합니다.

관련 정보