커널 스택 및 사용자 공간 스택


110

커널 스택과 사용자 스택의 차이점은 무엇입니까? 커널 스택이 사용되는 이유는 무엇입니까? 지역 변수가 ISR에서 선언되면 어디에 저장됩니까? 각 프로세스에 자체 커널 스택이 있습니까? 그러면이 두 스택 사이에서 프로세스가 어떻게 조정됩니까?

답변:


187
  1. 커널 스택과 사용자 스택의 차이점은 무엇입니까?

요컨대, 메모리의 다른 위치 (따라서 스택 포인터 레지스터에 대해 다른 값)를 사용하고 일반적으로 다른 메모리 액세스 보호를 사용하는 것 외에는 아무것도 없습니다. 즉, 사용자 모드에서 실행할 때 커널 메모리 (일부 커널 스택)는 매핑 된 경우에도 액세스 할 수 없습니다. 반대로 커널 코드에 의해 명시 적으로 요청되지 않으면 (Linux에서는, 같은 함수를 통해 copy_from_user()) 사용자 메모리 (사용자 스택 포함)에 일반적으로 직접 액세스 할 수 없습니다.

  1. [별도의] 커널 스택이 사용되는 이유는 무엇입니까?

권한과 보안의 분리. 하나의 경우, 사용자 공간 프로그램은 원하는 모든 스택 (포인터)을 만들 수 있으며 일반적으로 유효한 것을 갖기위한 아키텍처 요구 사항이 없습니다. 따라서 커널 은 사용자 공간 스택 포인터가 유효하거나 사용 가능하다고 믿을 수 없으므로 자체 제어하에 하나의 세트가 필요합니다. 다른 CPU 아키텍처는이를 다른 방식으로 구현합니다. x86 CPU는 권한 모드 전환이 발생할 때 스택 포인터를 자동으로 전환하고 다른 권한 수준에 사용할 값은 권한이있는 코드 (예 : 커널 만)로 구성 할 수 있습니다.

  1. 지역 변수가 ISR에서 선언되면 어디에 저장됩니까?

커널 스택에서. 커널 (Linux 커널, 즉)은 ISR을 x86 아키텍처에 직접 연결 하지 않습니다. 인터럽트 게이트에 대신 등록 된 핸들러를 호출하기 전에 사전 인터럽트 레지스터 상태를 저장하는 공통 커널 인터럽트 진입 / 종료 메커니즘에 인터럽트 디스패치를 ​​위임합니다. . 인터럽트를 디스패치 할 때 CPU 자체는 권한 및 / 또는 스택 스위치를 실행할 수 있으며, 이는 공통 인터럽트 항목 코드가 이미 존재하는 커널 스택에 의존 할 수 있도록 커널에 의해 사용 / 설정됩니다.
즉, 커널 코드를 실행하는 동안 발생하는 인터럽트는 해당 지점에서 커널 스택을 단순히 사용합니다 (계속). 이는 인터럽트 핸들러에 깊게 중첩 된 호출 경로가있는 경우 스택 오버플로로 이어질 수 있습니다 (깊은 커널 호출 경로가 중단되고 핸들러가 다른 깊은 경로를 유발하는 경우, Linux에서 파일 시스템 / 소프트웨어 RAID 코드가 iptables가 활성화 된 네트워크 코드에 의해 중단되는 경우). 조정되지 않은 오래된 커널에서 이러한 문제를 유발하는 것으로 알려진 솔루션은 이러한 작업 부하에 대한 커널 스택 크기를 늘리는 것입니다.

  1. 각 프로세스에 자체 커널 스택이 있습니까?

각 프로세스뿐만 아니라 각 스레드 에는 자체 커널 스택이 있습니다 (실제로 자체 사용자 스택도 있음). 프로세스와 스레드 (Linux)의 유일한 차이점은 여러 스레드가 하나의 주소 공간을 공유 할 수 있다는 것입니다 (프로세스 형성).

  1. 이 두 스택 사이에서 프로세스가 어떻게 조정됩니까?

전혀 그렇지 않습니다. 그럴 필요가 없습니다. 스케줄링 (다른 스레드가 실행되는 방법 /시기, 상태가 저장 및 복원되는 방법)은 운영 체제의 작업이며 프로세스는 이에 대해 걱정할 필요가 없습니다. 스레드가 생성되면 (각 프로세스에는 적어도 하나의 스레드가 있어야 함) 커널은이를위한 커널 스택을 생성하는 반면 사용자 공간 스택은 스레드를 생성하는 데 사용되는 메커니즘 ( 호출자가 다음 과 같은 기능을 수행 makecontext()하거나 pthread_create()허용하는 메커니즘에 의해 명시 적으로 생성 / 제공됩니다. "자식"스레드의 스택에 사용할 메모리 영역을 지정하거나 (새 프로세스를 만들 때 일반적으로 "쓰기시 복사"/ COW라고하는 온 액세스 메모리 복제에 의해) 상속됩니다.
즉,(상태, 그중 스레드의 스택 포인터입니다). 이 이것에 대한 여러 가지 방법 : UNIX 신호는 setcontext(), pthread_yield()/ pthread_cancel(), ... - 그러나 이것은 원래의 질문에서 조금 disgressing된다.


FrankH의 탁월한 답변입니다. 감사.
kumar

1
@FrankH 훌륭한 대답 .. 그러나 그것에 관련된 작은 질문이 있지만 ARM 아키텍처에서 ..이 커널 스택이 다른 프로세서 모드와 어떻게 관련되어 있습니까?
라훌

2
@Rahul : "SO 코멘트의 여백이 너무 작아서 그러한 답변을 포함 할 수 없습니다." 스택 / 스택 포인터 레지스터가 서로 다른 ARM CPU 모드 (뱅킹 SP를 구현하는 모드)에서 작동하는 방법은 좋은 질문이지만 답변 할 수있는 공간이 주석으로 제공 할 수있는 것보다 더 많이 필요합니다. x86 작업 게이트 또는 IST와 같은 것들에도 동일하게 적용됩니다. "단일"커널 스택 포인터와 같은 것은 없습니다 ( "단일"사용자 스택 포인터가없는 것처럼), 그리고 어떤 하드웨어 지원 / 권한이 있는지 다른 작동 모드에서 별도의 스택 포인터는 ... 매우 하드웨어에 따라 다릅니다.
FrankH.

@FrankH. 저도 같은 ... 새로운 질문을 만들어 stackoverflow.com/q/22601165/769260 난 당신이 :) 공간 걱정없이 나를 도울 수 해주기를 바랍니다
라훌

1
@FrankH. 프로세스의 메모리 레이아웃에서 커널 스택이 속한 위치를 보여주는 다이어그램을 제공 할 수 있습니까?
Jithin Pavithran 2018

19

내 대답은 내 물건에 대한 다른 SO 질문에서 수집됩니다.

What's the difference between kernel stack and user stack?

커널 프로그래머는 잘못된 사용자 프로그램으로부터 커널을 제한해야한다는 것을 알고 있습니다. 커널 및 사용자 공간 모두에 대해 동일한 스택을 유지하고 사용자 응용 프로그램의 간단한 segfault가 커널을 충돌시키고 다시 시작해야한다고 가정합니다.

ISR 스택과 같이 CPU 당 하나의 "커널 스택"과 프로세스 당 하나의 "커널 스택"이 있습니다. 각 스레드에는 사용자 및 커널 스레드를 포함하여 자체 스택이 있지만 각 프로세스에는 하나의 "사용자 스택"이 있습니다.

http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-10/3194.html

Why kernel stack is used?

따라서 커널 모드에있을 때 사용자 공간과 유사한 지역 변수 인 함수 호출을 처리하기 위해 스택 종류의 메커니즘이 필요합니다.

http://www.kernel.org/doc/Documentation/x86/kernel-stacks

If a local variable is declared in an ISR, where it will be stored?

ISR 스택 (IRQSTACKSIZE)에 저장됩니다. ISR은 하드웨어가 지원하는 경우에만 별도의 인터럽트 스택에서 실행됩니다. 그렇지 않으면 ISR 스택 프레임이 인터럽트 된 스레드의 스택으로 푸시됩니다.

사용자 공간은 인터럽트가 현재 프로세스의 커널 스택 또는 별도의 ISR 스택에서 제공되는지 여부를 알지 못하며 솔직히 신경 쓰지 않습니다. 인터럽트는 CPU 당 발생하므로 ISR 스택은 CPU 당 발생해야합니다.

 Does each process has its own kernel stack ?

예. 각 프로세스에는 자체 커널 스택이 있습니다.

 Then how the process coordinates between both these stacks?

@FrankH의 대답은 나에게 훌륭해 보입니다.


4
  1. 커널 스택과 사용자 스택의 차이점은 무엇입니까

Robert Love의 Linux 커널 개발을 참조하면 주요 차이점은 크기입니다.

사용자 공간은 거대한 구조와 천 요소 배열을 포함하여 스택에 많은 변수를 정적으로 할당하는 것으로 벗어날 수 있습니다.
사용자 공간에는 동적으로 증가 할 수있는 큰 스택이 있기 때문에이 동작은 합법적입니다.
커널 스택은 크지도 동적도 아닙니다. 작고 크기가 고정되어 있습니다.
커널 스택의 정확한 크기는 아키텍처에 따라 다릅니다.
x86에서 스택 크기는 컴파일 타임에 구성 할 수 있으며 4KB 또는 8KB가 될 수 있습니다.
역사적으로 커널 스택은 2 페이지로, 일반적으로 32 비트 아키텍처에서 8KB이고 64 비트 아키텍처에서 16KB임을 의미합니다.이 크기는 고정적이고 절대적입니다.
각 프로세스는 자체 스택을받습니다.

또한 커널 스택에는 스레드에 대한 정보를 보유하는 thread_info 구조체에 대한 포인터가 포함되어 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.