리눅스 커널 스택에 대해서 궁금합니다.
1.커널 스택은 프로세스마다 하나씩 생성되는 건가요 ?
2.커널 스택에는 어떤 정보가 들어가게 되나요 ? (얼핏 알기로는 해당 프로세스에 인터럽트가 걸리면 이에 필요한 정보들을 커널 스택에 저장해 놓고 사용한다고 하던데요...)
3.프로세스 하나는 4기가의 가상 공간을 사용한다고 들었습니다. 이 중에서 0~3기가 까지는 응용프로그램에서 사용하는 공간이고 3~4기가는 커널이 사용하는 공간이라고 알고 있는데요...
여기서 3~4기가 공간과 커널 스택이 어떠한 연관 관계가 있나요?
고수님들의 답변 부탁드립니다.
----------------------------------------------------------------------------------------------------------------------------------------
1. 커널 스택은 프로세스마다 하나씩 생성됩니다.
일반적인 프로세스는 User Mode 스택과 Kernel Mode 스택을 각각 하나씩 가지고 있습니다.
User Mode에서 Kernel Mode로의 전환은 시스템호출이나 인터럽트가 발생하면 일어납니다.
즉, esp 레지스터는 프로세스가 User Mode이면 User Mode 스택의 top을 가르키다가
Kernel Mode로 전환이 되면 Kernel Mode 스택의 top을 가르킵니다.
2. Kernel Mode 스택은 적어도 다음 두가지 목적으로 사용됩니다. 다른 사용처는 딱히 생각나지 않네요.
가. Kernel Mode로 전환된 프로세스는 언젠간 다시 User Mode로 되돌아가야 합니다.
따라서 User Mode로 전환하기위해 필요한 정보 중 일부를 저장합니다. (일부는 다른 곳에 저장합니다.)
나. Kernel Mode에서 함수를 호출하게 되면 그 함수의 지역변수는 Kernel Mode 스택에서 할당됩니다. (User Mode에서 함수를 호출하면 지역변수가 User Mode 스택에 할당되는 것과 같습니다.)
참고로 80x86 아키텍처에서 커널 스택으로 할당된 공간의 크기는 8KB로 고정되어있습니다. 프로세스 생성때 한번 할당되어 작아지지도 커지지도 않습니다. 따라서 커널에 있는 함수에서는 지역변수를 많이 할당하거나 재귀 함수 호출을 하면 좋지 않습니다.
3. 어떻게 설명드려야할 지 상당히 난해한 질문이군요.
커널은 주소 공간 3~4GB를 사용합니다. Kernel Mode 스택은 Kernel Mode에서만 사용되므로 커널 주소 공간에서 할당됩니다.
즉, User Mode 스택을 가르키는 esp 값을 읽어보면 0GB~3GB 사이의 값을 가지고 Kernel Mode 스택을 가르키는 esp 값을 읽어보면 3~4GB 사이의 값을 가지게 됩니다.
4. 기타
가. 프로세스의 User Address Space는 프로세스마다 각각 다르지만, Kernel Address Space는 모든 프로세스가 동일하게 봅니다. 즉, 프로세스 A와 프로세스 B의 특정 가상주소 (예를 들면 0xa0001000) 은 서로 다른 물리주소로 맵핑될 수 있습니다. 하지만 특정 커널 공간 주소 (예를 들면 0xc0001000) 는 모든 프로세스에서 동일한 물리주소로 맵핑됩니다.
이를 위해서 커널은 kernel master page table (swapper_pg_dir 변수가 가르킴)을 관리하고, 필요할 때마다 특정 엔트리를 kernel master page table에서 해당 프로세스의 page table에 복사를 합니다 -- 이런 작업은 Kernel Mode에서 페이지 폴트가 발생했을 때 페이지 폴트 핸들러가 수행합니다.
나. 시스템호출, 인터럽트 핸들러, 커널 모듈 등은 임의의 프로세스의 context를 이용합니다. 예를 들어, 프로세스 A가 User Mode에서 수행되고 있을 때 timer interrupt가 발생하는 경우 Kernel Mode로 전환하여 timer interrupt service routine을 수행하게 되는데 이때 프로세스 A의 page table과 Kernel Mode 스택을 빌어 쓰게됩니다.
Timer interrupt와 프로세스 A와는 별다른 연관이 없지만 interrupt 발생시점에 프로세스 A가 CPU를 점유하고 있었기 때문에 부하가 큰 context switch 등을 따로 하지 않고 프로세스 A의 context를 그대로 이용하는 것입니다. 다만 커널 모듈 등이 기능의 일부를 따로 커널 쓰레드를 생성하여 구현한 경우라면 그 커널 쓰레드의 context를 사용하겠죠.
출 처 : http://kldp.org/node/73308