OS가 CPU와 직접 작동하는 경우 프로그램 기능을 어떻게 제한합니까?
프로그램이 메모리에로드되고 실행을 시작하면 cpu는 코드에서 각 명령어를로드하고 opcode와 인수를 기반으로 명령어를 실행하므로 프로그램은 cpu에 대해 직접적으로 말하기 위해 인터랙트합니다.
그러나 OS (리눅스 / 윈)가 모든 것을 할 수있는 것은 아니기 때문에 시스템 호출을 통해 몇 가지 권한을 요청해야합니다. 하지만 사용자 코드가 OS가 할 수있는 특정 작업을 수행 할 수없는 이유가 궁금합니다. OS 커널 코드가 명령을 실행하는지 또는 사용자가 실행하는지 여부에 관계없이 Cpu에 어떤 차이가 있습니까?
OS가 코드를로드하기 전에 내 코드를 살펴보고 내가 사용할 수없는 특정 명령을 사용하고 있는지 확인하고 실행하지 않는지 확인합니까?
어떻게 관리되고 있습니까?
Btw는 Assembly를 프로그래밍 언어로 간주하므로 프로그래머는 코드에서 사용할 명령을 선택할 수 있습니다.
답변
최신 CPU에는 운영 체제에서 사용하는 권한 모드가 특정 명령을 잠급니다. 예를 들어 user
모드에서 권한 모드를 수정 (상승)하거나 현재 구성된 페이지 테이블과 같은 시스템 리소스에 액세스하는 명령은 예외를 발생시킵니다. 이를 통해 운영 체제는 사용자 프로세스를 중단할지 또는 작업을 에뮬레이션할지 결정할 수 있습니다.
OS가 코드를로드하기 전에 내 코드를 살펴보고 내가 사용할 수없는 특정 명령을 사용하고 있는지 확인하고 실행하지 않는지 확인합니까?
아니요, 그럴 필요는 없습니다. 운영 체제는 사용자 코드를 실행할 때마다 프로세서를 "사용자"모드로 전환합니다. 그러면 권한있는 명령이 발견되면 하드웨어의 예외 메커니즘이 활성화됩니다. 사용자 모드에서는 권한있는 명령을 실행하는 대신 예외가 발생합니다 (예외를 트리거하는 것은 권한있는 작업이 아닌 해당 명령의 실행입니다).
Btw, 사용자 모드 코드가 운영 체제에서 서비스를 요청하는 데 사용하는 시스템 호출 유형의 명령은 하드웨어 예외 메커니즘도 활성화합니다.
어떻게 관리되고 있습니까?
운영 체제는 항상 사용자 모드 (사용자 수준 권한)에서 사용자 코드를 실행하고 일반적으로 더 높은 권한에서 자체 코드를 실행합니다. 이러한 모드는 프로세서에게 권한있는 명령을 처리하는 방법을 알려줍니다. 대부분의 사용자 모드 코드는 쓸모가 없기 때문에 권한있는 명령을 실행하려고 시도조차하지 않을 것입니다.하지만 그렇게한다면 하드웨어 예외 메커니즘이 작동하여 운영 체제에 이러한 일이 발생했음을 효과적으로 알리고 상황을 처리 할 수 있도록합니다.
사용자 모드 코드를 실행하기 위해 운영 체제는 "인터럽트에서 복귀"명령을 사용하여 사용자 코드를 다시 시작할 수 있습니다 (기술적으로 이전에 시작되었는지 여부는 중요하지 않음). 인터럽트에서 복귀는 명령 스트림을 변경하면서 (일명 분기) 권한 수준을 변경하는 한 가지 방법 인 명령 유형입니다. 이러한 명령 자체는 권한이 있으므로 프로세서가 사용자 모드에서이를 허용하지 않습니다.
프로세서가 인터럽트를 받으면 중요한 CPU 상태 중 일부를 기록합니다. 중요한 CPU 상태는 인터럽트를 처리하기 위해 반드시 수정해야하는 상태입니다. 인터럽트를 서비스하는 것은 프로그램 카운터 일명 명령 포인터를 수정함으로써 명령 스트림 피드의 제어를 CPU로 전송합니다. 인터럽트시 프로세서는 인터럽트 서비스 루틴으로 갑작스런 분기를 효과적으로 수행합니다. 또한 더 많은 명령에 대한 ISR 액세스를 허용하는 더 높은 권한으로 모드를 갑작스럽게 변경합니다. ISR을 활성화하려면이 두 가지 갑작스런 변경이 필요하기 때문에 하드웨어는 중단 된 사용자 모드 코드를 다시 시작할 때 소프트웨어가 나중에 사용할 수 있도록 이전 값을 기록합니다. 따라서 하드웨어 및 운영 체제는 높은 권한으로 OS를 실행하고 사용자 코드는 낮은 권한으로 함께 공모합니다.
사용자 모드 프로그램이 syscall 유형의 명령 (I / O와 같은 운영 체제 서비스 요청)을 사용하는 경우 동일한 하드웨어 예외 메커니즘이 제어를 ISR로 전송합니다. 운영 체제가 하드웨어에 따라 사용자 모드 프로세스를 다시 시작하려고 할 때 다시 시작하기 전에 syscall 명령을 통해 사용자 모드 프로세스의 프로그램 카운터를 수동으로 진행해야 할 수 있습니다. 마치 사용자 모드 프로세스로 전환하는 것과 같습니다. 운영 체제는 시스템 호출을 시뮬레이션 / 에뮬레이션했습니다.
또한 프로그램의 모든 CPU 명령은 자체 가상 메모리 공간에서 실행됩니다. 이것은 기본적으로 시스템 데이터, 기타 프로세스 데이터 또는 커널 데이터에 액세스하거나 수정하기 위해 코딩하는 모든 명령을 비활성화합니다.
기본적으로 원하는대로 집을 엉망으로 만들 수 있지만 다른 사람의 집을 들여다 볼 수는 없습니다.
주소 공간 밖에서 무언가를 실행하고 싶다면, 당신을 위해 그것을 수행하는 시스템 루틴 / 서비스를 호출하는 것 외에 선택의 여지가 없습니다.
위의 그림에서 다른 사람의 집에서 원하는 것이 있다면 신뢰할 수있는 서비스 (OS 커널 루틴)를 사용해야합니다.
이 답변은 특정 하드웨어 지원 (ARM, x86, PowerPC 등)이있는 프로세서에서 최신 멀티 태스킹 운영 체제 (Windows, MacOS, Linux 등)를 실행하고 있다고 가정합니다. Erik Eidt와 Aganju의 이전 답변을 기반으로합니다.
이러한 시스템은 수년에 걸쳐 일반 사용자 프로그램에 대해 점점 더 제한적으로 개발되었습니다.
이러한 시스템에서 프로그램은 실제 메모리에 직접 액세스 할 수 없습니다. 모든 메모리 주소는 가상 메모리 관리자를 통과합니다. 특정 주소가 주소 공간에 할당 된 경우 주소는 실제 메모리 주소에 매핑됩니다. 그렇지 않으면 액세스가 실패하고 트랩이 생성됩니다. 운영 체제가 프로그램을 종료 할 수 있습니다. 메모리 관리자는 어떤 프로세스도 다른 프로세스의 메모리를 손상시킬 수 없도록합니다.
하드웨어 장치는 일반적으로 메모리 매핑됩니다. 다시 말하지만, 메모리 관리자는 이들에 대한 모든 직접 액세스를 차단합니다. 당신은 당신을 위해 그것을하기 위해 운전사에게 전화해야합니다.
모든 것을 설정하고 장치 드라이버를 구현하기 위해 운영 체제에서 사용하는 특수 기계 코드 명령이 있습니다. 이러한 지침에는 실행하는 데 필요한 여러 권한 수준이 있습니다. 프로그램이 시작되면 운영 체제에서 가장 낮은 권한을 가진 사용자 프로그램으로 표시됩니다. 따라서 이러한 명령을 사용하여 메모리 관리를 수정하거나 우회하려는 모든 시도는 트랩됩니다. 다시 말하지만, 프로그램이 종료 될 가능성이 있습니다.