it-swarm-ko.tech

리눅스는 분할을 사용하지 않고 페이징 만 사용합니까?

Linux Programming Interface 프로세스의 가상 주소 공간 레이아웃을 보여줍니다. 다이어그램의 각 영역이 세그먼트입니까?

enter image description here

리눅스 커널 이해,

다음은 MMU의 세그먼트 단위가 가상 메모리 주소에 세그먼트 및 오프셋을 맵핑하고, 페이징 유닛이 가상 메모리 주소를 실제 메모리 주소에 맵핑 함을 의미한다는 것이 맞습니까? ?

MMU (Memory Management Unit)는 세그먼트 화 단위라는 하드웨어 회로를 통해 논리 주소를 선형 주소로 변환합니다. 이후 페이징 장치라고하는 두 번째 하드웨어 회로는 선형 주소를 물리적 주소로 변환합니다 (그림 2-1 참조).

enter image description here

그렇다면 왜 리눅스가 분할을 사용하지 않고 페이징만을 사용한다고 말하는가?

80x86 마이크로 프로세서에는 세그먼테이션이 포함되어있어 프로그래머가 응용 프로그램을 서브 루틴 또는 글로벌 및 로컬 데이터 영역과 같은 논리적으로 관련된 엔티티로 분할 할 수 있습니다. 그러나 Linux는 매우 제한된 방식으로 분할을 사용합니다. 실제로 분할과 페이징은 물리적 주소 공간을 분리하는 데 사용될 수 있기 때문에 다소 중복됩니다. 프로세스 : 세그먼트 화는 각 프로세스에 서로 다른 선형 주소 공간을 할당 할 수있는 반면, 페이징은 동일한 선형 주소 공간을 서로 다른 물리적 주소 공간에 매핑 할 수 있습니다. Linux는 다음과 같은 이유로 분할보다 페이징을 선호합니다.

• 모든 프로세스가 동일한 세그먼트 레지스터 값을 사용하는 경우, 즉 동일한 선형 주소 세트를 공유하는 경우 메모리 관리가 더 간단합니다.

Linux의 설계 목표 중 하나는 광범위한 아키텍처로의 이식성입니다. 특히 RISC 아키텍처는 세분화에 대한 지원이 제한적입니다.

Linux 2.6 버전은 80x86 아키텍처에 필요한 경우에만 분할을 사용합니다.

27
Tim

x86-64 아키텍처는 긴 모드 (64 비트 모드)에서 분할을 사용하지 않습니다.

세그먼트 레지스터 : CS, SS, DS 및 ES의 4 개는 0으로, 제한은 2 ^ 64로 제한됩니다

https://en.wikipedia.org/wiki/X86_memory_segmentation#Later_developments

더 이상 OS가 사용 가능한 "선형 주소"의 범위를 제한 할 수 없습니다. 따라서 메모리 보호를 위해 분할을 사용할 수 없습니다. 페이징에만 전적으로 의존해야합니다.

레거시 32 비트 모드에서 실행될 때만 적용되는 x86 CPU의 세부 사항에 대해 걱정하지 마십시오. 32 비트 모드의 Linux는 많이 사용되지 않습니다. 심지어 "수년간 양성 방치 상태"로 간주 될 수도 있습니다. Fedora에서 32 비트 x86 지원 [LWN.net, 2017]을 참조하십시오.

(32 비트 리눅스도 세그먼테이션을 사용하지 않습니다. 그러나 당신은 저를 믿지 않아도됩니다. 무시할 수 있습니다 :-).

21
sourcejedi

다이어그램의 각 영역이 세그먼트입니까?

아니.

세그먼테이션 시스템 (x86의 32 비트 보호 모드)은 별도의 코드, 데이터 및 스택 세그먼트를 지원하도록 설계되었지만 실제로 모든 세그먼트는 동일한 메모리 영역으로 설정됩니다. 즉, 0에서 시작하여 메모리 끝에서 끝납니다.(*). 따라서 논리 주소와 선형 주소가 동일합니다.

이것을 "플랫 (flat)"메모리 모델이라고하며, 고유 한 세그먼트가 있고 그 안에 포인터가있는 모델보다 다소 단순합니다. 특히, 세그먼트 선택기는 오프셋 포인터와 함께 포함되어야하므로 세그먼트 화 된 모델에는 더 긴 포인터가 필요합니다. (16 비트 세그먼트 선택기 + 32 비트 플랫 포인터와 비교하여 총 48 비트 포인터의 경우 32 비트 오프셋)

64 비트 롱 모드는 플랫 메모리 모델 이외의 세그먼테이션도 지원하지 않습니다.

286에서 16 비트 보호 모드로 프로그래밍하려는 경우 주소 공간이 24 비트이지만 포인터는 16 비트이므로 세그먼트가 더 필요합니다.

(* 32 비트 Linux가 커널/사용자 공간 분리를 처리하는 방법을 기억할 수 없다는 점에 유의하십시오. 분할은 사용자 공간 세그먼트를 설정하여 커널 공간을 포함하지 않도록 제한합니다. 페이징은 페이지 당 보호 수준.)

그렇다면 왜 리눅스가 분할을 사용하지 않고 페이징만을 사용한다고 말하는가?

X86에는 여전히 세그먼트가 있으며 비활성화 할 수 없습니다. 그들은 가능한 한 적게 사용됩니다. 32 비트 보호 모드에서는 플랫 모델에 대해 세그먼트를 설정해야하며 64 비트 모드에서도 여전히 존재합니다.

9
ilkkachu

X86에는 세그먼트가 있으므로 사용할 수 없습니다. 그러나 cs (코드 세그먼트) 및 ds (데이터 세그먼트) 기본 주소는 모두 0으로 설정되므로 세그먼트 화는 실제로 사용되지 않습니다. 예외적으로 스레드 로컬 데이터는 일반적으로 사용되지 않는 세그먼트 레지스터 중 하나가 스레드 로컬 데이터를 가리 킵니다. 그러나 이는 주로이 작업에 대한 범용 레지스터 중 하나를 예약하지 않도록하기위한 것입니다.

리눅스가 x86에서 분할을 사용하지 않는다고 말하지는 않습니다. 리눅스는 매우 제한된 방식으로 세그먼테이션을 사용합니다. 두 번째 부분은 Linux는 80x86 아키텍처에서 필요할 때만 세그먼테이션을 사용함

페이징이 더 쉽고 휴대하기 쉬운 이유를 이미 인용했습니다.

8
RalfFriedl

Linux x86/32는 모든 세그먼트를 동일한 선형 주소 및 한계로 초기화한다는 의미에서 세그먼트 화를 사용하지 않습니다. x86 아키텍처에는 프로그램에 세그먼트가 있어야합니다. 코드는 코드 세그먼트에서만 실행할 수 있고 스택은 스택 세그먼트에만있을 수 있으며 데이터는 데이터 세그먼트 중 하나에서만 조작 할 수 있습니다. Linux는 모든 세그먼트를 동일한 방식으로 설정하여 (책에서 언급하지 않은 경우를 제외하고)이 메커니즘을 무시하므로 세그먼트에서 동일한 논리 주소가 유효합니다. 이것은 실제로 세그먼트가없는 것과 같습니다.

3
Dmitry Grigoryev