커널 공간과 사용자 공간의 차이점은 무엇입니까?


답변:


117

정말 간단한 대답은 커널이 커널 공간에서 실행하고, 일반 프로그램은 사용자 공간에서 실행됩니다. 사용자 공간은 기본적으로 샌드 박싱의 한 형태입니다. 사용자 프로그램을 제한하여 다른 프로그램이나 OS 커널이 소유 한 메모리 (및 기타 리소스)를 엉망으로 만들 수 없습니다. 이로 인해 기계 충돌과 같은 나쁜 일을 할 수있는 능력이 제한되지만 (일반적으로 완전히 제거되는 것은 아닙니다).

커널은 운영 체제의 핵심입니다. 일반적으로 모든 메모리 및 시스템 하드웨어 (및 시스템의 다른 모든 항목)에 대한 전체 액세스 권한이 있습니다. 컴퓨터를 가능한 한 안정적으로 유지하려면 일반적으로 가장 신뢰할 수 있고 테스트를 거친 코드 만 커널 모드 / 커널 공간에서 실행하려고합니다.

스택은 메모리의 또 다른 부분이므로 당연히 나머지 메모리와 함께 분리됩니다.


4
내 시스템에 10 개의 프로세스가 있다면 말하십시오. 각 프로세스는 사용자 스택과 커널 스택으로 나뉘어 진 자체 스택을 가지고 있거나 모든 프로세스가 단일 커널 스택을 공유합니까?
kc3

10
@ kc3 : 그것은 적어도 부분적으로 OS에 달려 있지만, 커널이 프로세스 (예를 들어, I / O)를 대신하여 작업을 수행 할 때 사용되는 각 프로세스마다 커널 모드 스택이 있다고 생각합니다. 커널이 독점적으로 사용하는 커널 스택 (예 : 스케줄링).
Jerry Coffin

2
커널 프로세스가 존재하며 문제가되는 사용자 공간 프로세스와의 관계 또는 차이점은 무엇입니까?
Victor Choy

따라서 사용자 공간 프로세스 를 실행하려면 커널 공간에 매핑되어야 합니까?
roottraveller

@roottraveller : 그 아이디어가 무엇인지 확실하지 않지만 전혀 아닙니다. 동시에, 사용자 공간 프로세스 일반적으로 (숨겨진) 커널 공간 메모리를 가지게되므로 (예를 들어) 프로세스는 사용자 공간 스택과 커널 공간 스택을 갖게됩니다. 커널 모드에서 실행해야하는 OS 호출을 만듭니다.
Jerry Coffin

64

랜덤 액세스 메모리 (RAM)을 논리적으로, 즉 두 가지 영역으로 나눌 수 있습니다 -. 커널 공간과 사용자 공간 ( 물리적 주소 램의 실제로 나누어되지 않은 경우에만 가상 주소 , 모든이에 의해 구현 MMU )

커널은 권한이있는 메모리 부분에서 실행됩니다. 커널은 메모리의 모든 부분에 액세스 할 수있는 반면 일반 사용자의 프로세스는이 부분의 메모리에 직접 액세스 할 수 없습니다. 커널의 일부에 액세스하려면 사용자 프로세스가 호출 즉, 미리 정의 된 시스템을 사용할 필요는 open, read, write등 또한, C같은 라이브러리 함수 printf호출 시스템 호출 write차례입니다.

시스템 호출은 사용자 프로세스와 커널 프로세스 사이의 인터페이스 역할을합니다. 사용자가 무심코 커널을 엉망으로 만드는 것을 막기 위해 커널 공간에 액세스 권한이 부여됩니다.

따라서 시스템 호출이 발생하면 소프트웨어 인터럽트가 커널로 전송됩니다. CPU는 제어를 관련 인터럽트 핸들러 루틴으로 일시적으로 넘길 수 있습니다. 인터럽트에 의해 중단 된 커널 프로세스는 인터럽트 핸들러 루틴이 작업을 완료 한 후 재개됩니다.


2
이 답변의 첫 부분이 잘못되었습니다. RAM은 커널과 사용자 공간으로 분할되지 않습니다. 가상 메모리 입니다. 답을 편집하려고했지만 편집 큐가 며칠 동안 가득 찼습니다. 수정하십시오. 자세한 내용은 아래 Varun의 답변을 참조하십시오.
MeLikeyCode

1
@MeLikeyCode 광범위하게 이해할 수있는 답변을 제공하려는 맥락에서 그렇게 간단하지 않습니까?
problemofficer

2
@problemofficer, 큰 단순화는 잘못된 기본 이해를 제공 할 수 있다고 생각합니다. 각 물리적 메모리는 사용자 공간과 커널 공간으로 나뉘 지 않지만 커널은 가상 메모리의 추상화를 제공하며, 가상 메모리는 커널과 사용자 공간으로 나뉘어져 나중에 물리적 메모리에 매핑됩니다.
dshil

22

커널 공간과 가상 공간은 가상 메모리의 개념입니다. 램 (실제 메모리)이 커널과 사용자 공간으로 나뉘어 진 것은 아닙니다. 각 프로세스에는 가상 메모리가 주어지며 커널과 사용자 공간으로 나뉩니다.

"임의 액세스 메모리 (RAM)는 커널 공간과 사용자 공간의 두 가지 영역으로 나눌 수 있습니다." 잘못되었습니다.

"커널 공간 대 사용자 공간"에 관한 것

프로세스가 생성되고 가상 메모리가 사용자 공간과 커널 공간으로 나뉘어지면 사용자 공간 영역에는 데이터, 코드, 스택, 프로세스 힙 및 커널 공간이 포함되며 프로세스의 페이지 테이블과 같은 것들이 포함됩니다. 커널 공간 코드를 실행하려면 제어는 커널 모드 (시스템 호출에 0x80 소프트웨어 인터럽트 사용)로 전환해야하며 커널 스택은 기본적으로 현재 커널 공간에서 실행중인 모든 프로세스간에 공유됩니다.


1
일반적인 프로세스에는 자체 커널 공간과 사용자 공간이 있습니까?
Victor Choy

@VictorChoy, 프로세스는 사용자와 커널의 두 가지 모드로 실행됩니다. 프로세스가 보는 메모리는 고유합니다. 그러나 커널 모드에서 실행되는 모든 프로세스 (커널 코드 실행)에는 하나의 공간 (커널 공간) 만 있습니다.
dshil

또한 프로세스가 작성 될 때 가상 메모리는 두 부분 (사용자 및 커널)으로 나뉘며, 여기서 가상 주소의 일부는 사용자 모드로 예약되고 다른 부분은 커널 모드로 예약됩니다.
dshil

19

CPU 링은 가장 분명한 차이점입니다

x86 보호 모드에서 CPU는 항상 4 개의 링 중 하나에 있습니다. Linux 커널은 0과 3 만 사용합니다.

  • 커널의 경우 0
  • 사용자를위한 3

이것은 커널과 사용자 영역 중 가장 어렵고 빠른 정의입니다.

Linux가 링 1과 2를 사용하지 않는 이유 : CPU Privilege Rings : 링 1과 2가 사용되지 않는 이유는 무엇입니까?

전류 링은 어떻게 결정됩니까?

현재 링은 다음의 조합으로 선택됩니다.

  • 글로벌 디스크립터 테이블 : GDT 엔트리의 메모리 내 테이블이며, 각 엔트리는 Privl링을 인코딩 하는 필드 를 갖는다 .

    LGDT 명령어는 주소를 현재 설명자 테이블로 설정합니다.

    참조 : http://wiki.osdev.org/Global_Descriptor_Table

  • 세그먼트는 GDT에서 엔트리의 인덱스를 가리키는 CS, DS 등을 등록한다.

    예를 들어, CS = 0GDT의 첫 번째 항목이 현재 실행 코드에 대해 활성화되어 있음을 의미합니다.

각 반지는 무엇을 할 수 있습니까?

CPU 칩은 물리적으로 다음과 같이 구성됩니다.

  • 링 0은 무엇이든 할 수 있습니다

  • 링 3은 여러 명령을 실행할 수 없으며 여러 레지스터에 쓸 수 있습니다.

    • 자신의 반지를 변경할 수 없습니다! 그렇지 않으면 자체가 링 0으로 설정 될 수 있으며 링은 쓸모가 없습니다.

      즉, 현재 링을 결정하는 현재 세그먼트 디스크립터를 수정할 수 없습니다 .

    • 페이지 테이블을 수정할 수 없습니다 : x86 페이징은 어떻게 작동합니까?

      즉, CR3 레지스터를 수정할 수 없으며 페이징 자체가 페이지 테이블 수정을 방지합니다.

      이것은 보안 / 편의 프로그래밍의 이유로 하나의 프로세스가 다른 프로세스의 메모리를 보지 못하게합니다.

    • 인터럽트 핸들러를 등록 할 수 없습니다. 메모리 위치에 쓰면 구성되며 페이징으로도 방지됩니다.

      처리기는 링 0에서 실행되며 보안 모델을 손상시킵니다.

      즉, LGDT 및 LIDT 명령어를 사용할 수 없습니다.

    • 같은 IO 지침을 할 수 없어 in하고 out, 따라서 임의의 하드웨어 액세스가 있습니다.

      그렇지 않으면, 예를 들어, 프로그램이 디스크에서 직접 읽을 수있는 경우 파일 권한이 쓸모가 없습니다.

      Michael Petch 덕분에 더 정확하게 는 OS가 링 3에서 IO 명령을 허용하는 것이 실제로 가능하며, 이는 실제로 작업 상태 세그먼트에 의해 제어됩니다 .

      불가능한 것은 링 3이 처음에 그것을 가지고 있지 않은 경우 링 3에 권한을 부여하는 것입니다.

      리눅스는 항상 그것을 허용하지 않습니다. 참고 : Linux가 TSS를 통해 하드웨어 컨텍스트 스위치를 사용하지 않는 이유는 무엇입니까?

프로그램과 운영 체제는 링간에 어떻게 전환됩니까?

  • CPU가 켜질 때, 링 0에서 초기 프로그램을 실행하기 시작합니다 (좋은 종류이지만 근사치입니다). 이 초기 프로그램을 커널이라고 생각할 수 있습니다 (그러나 일반적으로 링 0으로 커널을 호출하는 부트 로더입니다 ).

  • 유저 랜드 프로세스가 커널이 파일에 쓰는 것과 같은 일을하기를 원할 때, 커널과 같은 인터럽트를 발생 시키 int 0x80거나syscall 신호를 보내는 명령을 사용합니다 . x86-64 Linux syscall hello world 예제 :

    .data
    hello_world:
        .ascii "hello world\n"
        hello_world_len = . - hello_world
    .text
    .global _start
    _start:
        /* write */
        mov $1, %rax
        mov $1, %rdi
        mov $hello_world, %rsi
        mov $hello_world_len, %rdx
        syscall
    
        /* exit */
        mov $60, %rax
        mov $0, %rdi
        syscall
    

    컴파일하고 실행하십시오.

    as -o hello_world.o hello_world.S
    ld -o hello_world.out hello_world.o
    ./hello_world.out
    

    GitHub의 상류 .

    이 경우 CPU는 부팅시 커널이 등록한 인터럽트 콜백 핸들러를 호출합니다. 다음은 핸들러를 등록하고 사용 하는 구체적인 베어 메탈 예제입니다 .

    이 핸들러는 링 0에서 실행되며,이 커널은 커널이이 조치를 허용하는지, 조치를 수행하고, 링 3에서 userland 프로그램을 다시 시작할 것인지 결정합니다. x86_64

  • exec시스템 호출을 사용하는 (또는 경우 커널 시작한다/init ), 커널은 레지스터와 메모리를 준비하고 , 새로운 유저 기반 프로세스를 다음의 엔트리 포인트로 점프 링 (3)에 CPU 스위치

  • 프로그램이 금지 된 레지스터 또는 메모리 주소에 쓰기 (페이징 때문에)와 같은 잘못된 작업을 시도하면 CPU는 링 0에서 일부 커널 콜백 핸들러를 호출합니다.

    그러나 사용자 영역이 좋지 않기 때문에 커널은 이번에 프로세스를 종료하거나 신호와 함께 경고를 줄 수 있습니다.

  • 커널이 부팅 될 때 일정한 고정 주파수로 하드웨어 클록을 설정하여 주기적으로 인터럽트를 생성합니다.

    이 하드웨어 클럭은 링 0을 실행하는 인터럽트를 생성하고 어떤 사용자 프로세스가 깨어날 지 예약 할 수 있습니다.

    이런 식으로 프로세스가 시스템 호출을하지 않더라도 스케줄링이 발생할 수 있습니다.

여러 개의 고리가있는 점은 무엇입니까?

커널과 사용자 영역을 분리하면 두 가지 주요 이점이 있습니다.

  • 하나는 다른 하나를 방해하지 않을 것이기 때문에 프로그램을 만드는 것이 더 쉽습니다. 예를 들어, 한 사용자 프로세스는 페이징으로 인해 다른 프로그램의 메모리를 덮어 쓰거나 다른 프로세스에 대해 하드웨어를 유효하지 않은 상태로 만드는 것에 대해 걱정할 필요가 없습니다.
  • 더 안전합니다. 예를 들어 파일 권한과 메모리 분리는 해킹 앱이 은행 데이터를 읽지 못하게 할 수 있습니다. 이것은 물론 커널을 신뢰한다고 가정합니다.

어떻게 놀아?

링을 직접 조작하는 좋은 방법이어야하는 베어 메탈 셋업을 만들었습니다 : https://github.com/cirosantilli/x86-bare-metal-examples

불행히도 userland 예제를 만들려는 인내심은 없었지만 페이징 설정까지 진행 했으므로 userland가 가능해야합니다. 풀 요청을보고 싶습니다.

또는 Linux 커널 모듈은 링 0으로 실행되므로이를 사용하여 권한있는 작업을 시도 할 수 있습니다 (예 : 제어 레지스터 읽기 : 프로그램에서 제어 레지스터 cr0, cr2, cr3에 액세스하는 방법)? 세그먼테이션 결함 얻기

다음은 편리한 QEMU + Buildroot 설정 으로 호스트를 종료하지 않고 사용해 볼 수 있습니다.

커널 모듈의 단점은 다른 kthread가 실행 중이고 실험을 방해 할 수 있다는 것입니다. 그러나 이론적으로 커널 모듈로 모든 인터럽트 핸들러를 인수하고 시스템을 소유 할 수 있습니다. 실제로는 흥미로운 프로젝트입니다.

네거티브 링

음수 링은 실제로 인텔 설명서에서 참조되지 않지만 실제로 링 0보다 더 많은 기능을 가진 CPU 모드가 있으므로 "음의 링"이름에 적합합니다.

한 가지 예로 가상화에 사용되는 하이퍼 바이저 모드가 있습니다.

자세한 내용은 다음을 참조하십시오.

ARM에서는 링을 예외 수준이라고하지만 주요 아이디어는 동일하게 유지됩니다.

ARMv8에는 다음과 같이 일반적으로 사용되는 4 가지 예외 수준이 있습니다.

  • EL0 : 유저 랜드

  • EL1 : 커널 (ARM 용어에서 "감독자").

    Linux 시스템 호출을 수행하는 데 사용되는 명령 인 이전 통합 어셈블리svc 로 알려진 명령 (SuperVisor Call) 과 함께 입력되었습니다 . Hello world ARMv8 예제 :swi

    안녕하세요 .S

    .text
    .global _start
    _start:
        /* write */
        mov x0, 1
        ldr x1, =msg
        ldr x2, =len
        mov x8, 64
        svc 0
    
        /* exit */
        mov x0, 0
        mov x8, 93
        svc 0
    msg:
        .ascii "hello syscall v8\n"
    len = . - msg
    

    GitHub의 상류 .

    Ubuntu 16.04에서 QEMU를 사용하여 테스트하십시오.

    sudo apt-get install qemu-user gcc-arm-linux-gnueabihf
    arm-linux-gnueabihf-as -o hello.o hello.S
    arm-linux-gnueabihf-ld -o hello hello.o
    qemu-arm hello
    

    다음은 SVC 핸들러등록하고 SVC 호출을 수행하는 구체적인 베어 메탈 예제입니다 .

  • EL2 : 하이퍼 바이저 예를 들어, .

    hvc지침 (HyperVisor Call) 과 함께 입력했습니다 .

    하이퍼 바이저는 OS에 대한 것이며 OS는 사용자 영역에 있습니다.

    예를 들어 Xen을 사용하면 동일한 시스템에서 Linux 또는 Windows와 같은 여러 OS를 동시에 실행할 수 있으며 Linux가 사용자 프로그램에 대해하는 것처럼 보안 및 디버그 용이성을 위해 OS를 서로 분리합니다.

    하이퍼 바이저는 오늘날 클라우드 인프라의 핵심 부분입니다. 단일 서버에서 여러 서버를 실행하여 하드웨어 사용량을 항상 100 %에 가깝게 유지하고 많은 비용을 절약 할 수 있습니다.

    예를 들어, AWS는 KVM으로 이동 했을 때 2017 년까지 Xen을 사용 했습니다 .

  • EL3 : 또 다른 수준. TODO 예.

    smc지침 과 함께 입력 (보안 모드 호출)

ARMv8 아키텍처 참조 모델 DDI 0487C.a는 - 장 D1 일 - AArch64 시스템 레벨 프로그래머 모델 - 그림 D1-1 아름답게이 보여

여기에 이미지 설명을 입력하십시오

ARMv8.1 ARM V8.1 (Virtualization Host Extensions) 의 등장으로 ARM 상황이 약간 바뀌 었습니다 . 이 확장을 통해 커널은 EL2에서 효율적으로 실행될 수 있습니다.

여기에 이미지 설명을 입력하십시오

VHE는 KVM과 같은 Linux 내 커널 가상화 솔루션이 Xen보다 우위를 점했기 때문에 만들어졌습니다 (예 : 위에서 언급 한 AWS의 KVM으로 이동 참조). 대부분의 클라이언트는 Linux VM 만 필요하고 상상할 수 있듯이 모두 단일 KVM은 Xen보다 간단하고 잠재적으로 더 효율적입니다. 따라서 이제는 호스트 Linux 커널이 하이퍼 바이저 역할을합니다.

가늠자의 이점으로 인해 ARM이 음수 수준을 필요로하지 않고 x86보다 권한 수준에 대해 더 나은 명명 규칙을 갖는 방법에 유의하십시오. 0은 낮고 3은 높습니다. 높은 레벨은 낮은 레벨보다 자주 생성되는 경향이 있습니다.

현재 EL은 다음 MRS명령 으로 쿼리 할 수 ​​있습니다 . 현재 실행 모드 / 예외 수준 등은 무엇입니까?

ARM은 칩 영역을 절약하는 기능이 필요하지 않은 구현을 허용하기 위해 모든 예외 수준을 제시 할 필요는 없습니다. ARMv8 "예외 수준"에서는 다음과 같이 말합니다.

구현에 모든 예외 레벨이 포함되지 않을 수 있습니다. 모든 구현에는 EL0 및 EL1이 포함되어야합니다. EL2 및 EL3은 선택 사항입니다.

예를 들어 QEMU의 기본값은 EL1이지만 EL2 및 EL3은 명령 줄 옵션으로 활성화 할 수 있습니다. qemu-system-aarch64는 a53 전원을 에뮬레이션 할 때 el1을 입력합니다.

코드 스 니펫은 Ubuntu 18.10에서 테스트되었습니다.


11

커널 공간과 사용자 공간은 권한있는 운영 체제 기능과 제한된 사용자 응용 프로그램을 분리 한 것입니다. 사용자 응용 프로그램이 컴퓨터를 가로 채지 못하도록하려면 분리해야합니다. 이전 사용자 프로그램이 임의의 데이터를 하드 드라이브에 쓰거나 다른 사용자 프로그램의 메모리 공간에서 메모리를 읽을 수 있으면 좋지 않습니다.

사용자 공간 프로그램은 시스템 자원에 직접 액세스 할 수 없으므로 운영 체제 커널이 프로그램을 대신하여 액세스를 처리합니다. 사용자 공간 프로그램은 일반적으로 시스템 호출을 통해 운영 체제에 요청합니다.

커널 스레드, 프로세스, 스택은 같은 의미가 아닙니다. 그것들은 사용자 공간에서 커널 공간과 비슷한 구조입니다.


8

각 프로세스에는 페이지 테이블을 통해 실제 메모리에 매핑되는 자체 4GB의 가상 메모리가 있습니다. 가상 메모리는 주로 프로세스 사용에 3GB, 커널 사용에 1GB의 두 부분으로 나뉩니다. 생성 한 대부분의 변수는 주소 공간의 첫 부분에 있습니다. 이 부분을 사용자 공간이라고합니다. 마지막 부분은 커널이있는 곳이며 모든 프로세스에 공통입니다. 이를 커널 공간이라고하며이 공간의 대부분은 부팅시 커널 이미지가로드되는 실제 메모리의 시작 위치에 매핑됩니다.


1
귀하의 답변은 Windows에만 해당됩니다. 당신은 그것을 명확히해야합니다.
Matthew

1
당신은 4GB 가상 메모리 중 모든 프로세스에 대해 1GB는 모든 프로세스에 대해 동일한 커널 공간이며 매핑을 보유하고 있다고 말합니다. 왜 시작하는지에 대한 매핑에만 1GB가 필요한 이유는 무엇입니까?
VISHAL DAGA

5

주소 공간의 최대 크기는 CPU의 주소 레지스터 길이에 따라 다릅니다.

32 비트 주소 레지스터가있는 시스템에서 주소 공간의 최대 크기는 2 32 바이트 또는 4GiB입니다. 마찬가지로 64 비트 시스템에서는 2 64 바이트를 처리 할 수 ​​있습니다.

이러한 주소 공간을 가상 메모리 또는 가상 주소 공간 이라고 합니다 . 실제로 실제 RAM 크기와 관련이 없습니다.

Linux 플랫폼에서 가상 주소 공간은 커널 공간과 사용자 공간으로 나뉩니다.

작업 크기 제한 또는 아키텍처라는 특정 상수 TASK_SIZE는 분할이 발생하는 위치를 나타냅니다.

  • 0에서 TASK_SIZE-1 까지의 주소 범위 가 사용자 공간에 할당됩니다.

  • TASK_SIZE최대 2 32 -1 (또는 2 64 -1) 의 나머지는 커널 공간에 할당됩니다.

예를 들어 특정 32 비트 시스템에서 사용자 공간은 3GiB, 커널 공간은 1GiB를 차지할 수 있습니다.

유닉스 계열 운영 체제의 각 응용 프로그램 / 프로그램은 프로세스입니다. 각각에는 Process Identifier (또는 단순히 Process ID , 즉 PID) 라는 고유 식별자가 있습니다. Linux는 프로세스 생성을위한 두 가지 메커니즘을 제공합니다. 1. fork()시스템 호출 또는 2. exec()호출.

커널 스레드는 간단한 프로세스이며 실행중인 프로그램입니다. 단일 프로세스는 동일한 데이터와 리소스를 공유하지만 프로그램 코드를 통해 다른 경로를 취하는 여러 스레드로 구성 될 수 있습니다. Linux는 clone()스레드를 생성하기 위한 시스템 호출을 제공 합니다.

커널 스레드의 사용 예는 다음과 같습니다. RAM의 데이터 동기화, 스케줄러가 CPU간에 프로세스를 분배하는 데 도움이됩니다.


4

간단히 : 커널은 커널 공간에서 실행되며 커널 공간은 모든 메모리와 리소스에 대한 모든 액세스 권한을 가지고 있습니다. 메모리는 커널 부분과 사용자 자신 프로세스 부분 (사용자 공간)이 두 부분으로 나뉘어 있다고 말할 수 있습니다. space는 커널 공간에 직접 액세스 할 수 없으므로 커널에서 리소스 사용을 요청합니다. syscall (glibc에서 사전 정의 된 시스템 호출)

다른 " 사용자 공간은 단지 커널에 대한 테스트로드입니다 "라는 간단한 설명이 있습니다 ...

프로세서 아키텍처는 CPU가 커널 모드와 사용자 모드의 두 가지 모드로 작동 할 수 있도록하며 하드웨어 명령어를 사용하면 한 모드에서 다른 모드로 전환 할 수 있습니다.

메모리는 사용자 공간 또는 커널 공간의 일부로 표시 될 수 있습니다.

CPU가 사용자 모드에서 실행중인 경우 CPU가 사용자 공간에있는 메모리에만 액세스 할 수있는 반면, CPU가 커널 공간의 메모리에 액세스하려고하면 "하드웨어 예외"가 발생합니다. 커널 모드에서 실행중인 CPU는 CPU가 직접 액세스 할 수 있습니다 커널 공간과 사용자 공간 모두에 ...


2

커널 공간은 메모리 공간이 커널에 의해서만 만질 수 있음을 의미합니다. 32 비트 리눅스에서는 1G (가상 메모리 주소로 0xC0000000에서 0xffffffff까지)입니다. 커널에 의해 생성 된 모든 프로세스는 커널 스레드이기도합니다. 따라서 하나의 프로세스에는 두 개의 스택이 있습니다. 하나는이 프로세스의 사용자 공간에 스택과 다른 하나는 커널에 커널 스레드를위한 공간입니다.

커널 스택은 2 페이지 (32 비트 리눅스에서 8k)를 차지했으며 task_struct (약 1k)와 실제 스택 (약 7k)을 포함합니다. 후자는 일부 자동 변수 또는 함수 호출 매개 변수 또는 함수 주소를 커널 함수에 저장하는 데 사용됩니다. 코드는 다음과 같습니다 (Processor.h (linux \ include \ asm-i386)).

#define THREAD_SIZE (2*PAGE_SIZE)
#define alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
#define free_task_struct(p) free_pages((unsigned long) (p), 1)

__get_free_pages (GFP_KERNEL, 1))은 할당량 메모리를 2 ^ 1 = 2 페이지로 의미합니다.

그러나 프로세스 스택은 또 다른 것입니다. 주소는 0xC0000000 (32bit linux)입니다. 사용자 공간 함수 호출에 사용되는 크기는 상당히 클 수 있습니다.

시스템 호출에 대한 질문이 있습니다. 커널 공간에서 실행 중이지만 사용자 공간의 프로세스에 의해 호출되었습니다. 어떻게 작동합니까? 리눅스는 매개 변수와 함수 주소를 커널 스택이나 프로세스 스택에 넣을 것인가? Linux 솔루션 : 모든 시스템 호출은 소프트웨어 중단 INT 0x80에 의해 트리거됩니다. entry.S (linux \ arch \ i386 \ kernel)에 정의 된 예는 다음과 같습니다.

ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_ni_syscall)   /* 0  -  old "setup()" system call*/
.long SYMBOL_NAME(sys_exit)
.long SYMBOL_NAME(sys_fork)
.long SYMBOL_NAME(sys_read)
.long SYMBOL_NAME(sys_write)
.long SYMBOL_NAME(sys_open)     /* 5 */
.long SYMBOL_NAME(sys_close)

마지막 질문은 당신이 제시 한 매우 좋습니다. 그러나 소프트웨어 중단 INT 0x80이라면? 나에게 좋은 설명이 아닙니다. 스스로 제기 한 질문에 솔루션이 어떻게 작동하는지 자세히 설명해 주시겠습니까?
Victor Choy

2

으로 선일 야다 브, Quora의에 :

Linux 커널은 커널 모드에서 실행되는 모든 것을 말하며 몇 가지 다른 계층으로 구성됩니다. 가장 낮은 계층에서 커널은 HAL을 통해 하드웨어와 상호 작용합니다. 중간 수준에서 UNIX 커널은 4 개의 개별 영역으로 나뉩니다. 네 가지 영역 중 첫 번째 영역은 문자 장치, 가공되지 않은 TTY 및 터미널 처리를 처리합니다. 두 번째 영역은 네트워크 장치 드라이버, 라우팅 프로토콜 및 소켓을 처리합니다. 세 번째 영역은 디스크 장치 드라이버, 페이지 및 버퍼 캐시, 파일 시스템, 가상 메모리, 파일 이름 지정 및 매핑을 처리합니다. 네 번째와 마지막 영역은 신호 처리뿐만 아니라 프로세스 디스패치, 스케줄링, 생성 및 종료를 처리합니다. 무엇보다도 시스템 호출, 인터럽트 및 트랩을 포함하는 커널의 최상위 계층이 있습니다. 이 레벨은 각 하위 레벨 기능에 대한 인터페이스 역할을합니다. 프로그래머는 다양한 시스템 호출 및 인터럽트를 사용하여 운영 체제의 기능과 상호 작용합니다.



1

매우 간단한 설명을 시도

가상 메모리는 커널 공간과 사용자 공간으로 나뉩니다. 커널 공간은 커널 프로세스가 실행될 가상 메모리 영역이고 사용자 공간은 사용자 프로세스가 실행될 가상 메모리 영역입니다.

이 부서는 메모리 액세스 보호에 필요합니다.

부트 로더가 커널을 RAM의 위치 (일반적으로 ARM 기반 컨트롤러)로로드 한 후 커널을 시작할 때마다 컨트롤러가 FIQ 및 IRQ를 비활성화 한 상태에서 관리자 모드인지 확인해야합니다.


1

커널 공간과 사용자 공간은 논리 공간입니다.

최신 프로세서의 대부분은 다른 권한 모드에서 실행되도록 설계되었습니다. x86 컴퓨터는 4 가지 다른 권한 모드에서 실행될 수 있습니다. 여기에 이미지 설명을 입력하십시오

또한 특정 권한 모드에있을 때 특정 머신 명령어를 실행할 수 있습니다.

이 디자인으로 인해 시스템을 보호하거나 실행 환경을 샌드 박싱 할 수 있습니다.

커널은 하드웨어를 관리하고 시스템 추상화를 제공하는 코드입니다. 따라서 모든 기계 명령어에 액세스 할 수 있어야합니다. 그리고 가장 신뢰할 수있는 소프트웨어입니다. 그래서 나는 가장 높은 특권으로 처형되어야한다. 그리고 링 레벨 0 이 가장 특권 모드입니다. 따라서 링 레벨 0커널 모드 라고도 합니다.

사용자 응용 프로그램은 타사 공급 업체에서 제공하는 소프트웨어이므로 완전히 신뢰할 수는 없습니다. 악의적 인 의도를 가진 사람이 모든 컴퓨터 명령에 완전히 액세스 할 수 있으면 시스템을 중단시키는 코드를 작성할 수 있습니다. 따라서 응용 프로그램에는 제한된 지침 세트에 대한 액세스 권한이 제공되어야합니다. 그리고 링 레벨 3 은 가장 낮은 권한 모드입니다. 따라서 모든 응용 프로그램은 해당 모드에서 실행됩니다. 따라서 링 레벨 3사용자 모드 라고도 합니다.

참고 : 링 레벨 1과 2를 얻지 못했습니다. 기본적으로 중간 권한이있는 모드입니다. 따라서이 권한으로 장치 드라이버 코드가 실행될 수 있습니다. AFAIK, Linux는 커널 코드 실행 및 사용자 응용 프로그램에 각각 링 레벨 0 및 3 만 사용합니다.

따라서 커널 모드에서 발생하는 모든 작업은 커널 공간으로 간주 될 수 있습니다. 그리고 사용자 모드에서 발생하는 모든 작업은 사용자 공간으로 간주 될 수 있습니다.


0

정답은 다음과 같습니다. 커널 공간과 사용자 공간은 없습니다. 프로세서 명령어 세트에는 페이지 테이블 맵의 루트 또는 하드웨어 장치 메모리에 액세스하는 등의 파괴적인 사항을 설정할 수있는 특수 권한이 ​​있습니다.

커널 코드는 가장 높은 수준의 권한을 가지며 사용자 코드는 가장 낮은 권한을 갖습니다. 이렇게하면 사용자 코드가 시스템 충돌, 다른 프로그램 수정 등을 방지 할 수 있습니다.

일반적으로 커널 코드는 사용자 공간이 서로 다른 메모리 맵에 유지되는 것처럼 사용자 코드와 다른 메모리 맵에 유지됩니다. "커널 공간"과 "사용자 공간"이라는 용어가 나오는 곳입니다. 그러나 이것은 어렵고 빠른 규칙이 아닙니다. 예를 들어, x86은 인터럽트 / 트랩 핸들러를 항상 간접적으로 매핑해야하므로 커널의 일부 (또는 일부 OS 모두)를 사용자 공간에 매핑해야합니다. 다시 말하지만, 이러한 코드에 사용자 권한이 있다는 의미는 아닙니다.

커널 / 사용자 분할이 필요한 이유는 무엇입니까? 일부 디자이너는 실제로 필요하다고 동의하지 않습니다. 마이크로 커널 아키텍처는 모든 권한있는 작업이 사용자 권한있는 코드에서 수행되는 가장 높은 권한의 코드 섹션이 가능한 작아야한다는 아이디어를 기반으로합니다. 이것이 왜 좋은 생각인지 연구해야 할 것입니다. 단순한 개념이 아니며 (장점과 단점이있는 것으로 유명합니다).


0

메모리 가져 오기는 두 가지 영역으로 나뉩니다.

  • 사용자 공간은 일반적인 사용자 프로세스가 실행되는 위치의 집합입니다 (예 : 커널 이외의 모든 것). 커널의 역할은이 공간에서 실행되는 응용 프로그램이 서로 엉망이되지 않도록 관리하는 것입니다.
  • 커널 코드는 커널 코드가 저장되고 실행되는 위치입니다.

사용자 공간에서 실행되는 프로세스는 제한된 메모리 부분에만 액세스 할 수있는 반면 커널은 모든 메모리에 액세스 할 수 있습니다. 사용자 공간에서 실행중인 프로세스도 커널 공간에 액세스 할 수 없습니다. 사용자 공간 프로세스는 커널에 의해 노출 된 인터페이스 (시스템 호출)를 통해서만 커널의 작은 부분에만 액세스 할 수 있습니다. 프로세스가 시스템 호출을 수행하면 소프트웨어 인터럽트가 커널로 전송되어 적절한 인터럽트 핸들러를 디스패치하고 계속합니다 핸들러가 완료된 후의 작업.


-7

Linux에는 두 개의 공간이 있으며 첫 번째 공간은 사용자 공간이고 다른 공간은 커널 공간입니다. 사용자 공간은 실행하려는 사용자 응용 프로그램으로 만 구성됩니다. 커널 서비스로서 프로세스 관리, 파일 관리, 신호 처리, 메모리 관리, 스레드 관리 등 많은 서비스가 있습니다. 사용자 공간에서 응용 프로그램을 실행하면 해당 응용 프로그램은 커널 서비스와 만 상호 작용합니다. 이 서비스는 하드웨어와 커널 사이에있는 장치 드라이버와 상호 작용합니다. 커널 공간 및 사용자 공간 분리의 주요 이점은 사용자 공간에있는 모든 사용자 응용 프로그램의 virus.bcaz에 의해 보안을 확보 할 수 있으며 서비스는 커널 공간에 있다는 것입니다. 그래서 리눅스가 바이러스에 영향을 미치지 않는 이유는 무엇입니까?


5
"커널"이 아니라 "커널"이라는 사실 외에도 귀하의 답변이 완전히 정확하지는 않습니다. 최신 바이러스 (및 현대에서는 Windows 98 이후의 모든 것을 의미 함)는 "커널 서비스"와 전혀 상호 작용하지 않으며 모든 것이 사용자 공간 내에서 이루어집니다. 리눅스가 바이러스를 많이 가지고 있지 않다는 것은 (물론 리눅스를위한 바이러스가 있다는 것) 그것은 꽤 좋은 권한 관리를 가지고 있다는 것입니다. 가장 중요한 사실은 대부분의 리눅스 사용자는 그렇지 않습니다 : "omaigosh JustinBieber.NewSong.exe! NAO !!! 1111 "사용자의 말을 들어야 단서없이 모든 것을 클릭하여 설치할 수 있습니다.
alexclooze

3
또한 Linux는 Windows만큼 많이 사용되지 않습니다. 바이러스를 작성하기 때문에 바이러스 작성자가 원하는만큼의 손상을 일으키지 않습니다. 사용자 공간 응용 프로그램은 커널 서비스와 통신하지 않으며 syscalls라는 커널에서 제공하는 특수 기능을 호출합니다.
alexclooze
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.