Segmentation.png

개요

Memory segmentation이란 메모리 보호를 수행하는 가장 일반적인 방법 가운데 하나이다. 다른 방법으로는 페이징 이 있다. 메모리를 여러 세그먼트로 나누어서 한 세그먼트에서 다른 세그먼트로의 접근을 막는 것을 말한다. 이러한 이용은 인텔 8086, 인텔 8088과 같은 초기 x86 프로세서에 쓰인 메모리 세그먼트의 이용과 혼동해서는 안 된다. 왜냐하면 이들은 어떠한 보호 기능도 제공하지 않았기 때문이다. (어떠한 프로그램도 제한 없이 세그먼트에 쉽게 접근할 수 있었고 세그먼트는 64 KiB라는 고정 길이와 시작 위치로만 구성되어 있었다.) 인텔 80286 이후의 메모리 세그먼트 방식에는 보호 기능이 제공된다.

80286 이전 리얼 모드의 세그먼트

세그멘테이션은 segment와 offset으로 구현되어 있다. CPU에 있는 segmentation register을 참고하여 적절한 segmentation table을 참고하여 segment table에서 base와 bound그리고 access레벨을 가져온다. base + offset을 통해서 메모리 영역을 구하고, 이 영역이 bound안에 있는지 혹은 Access 규칙을 위반하지 않는지 확인하여 메모리에 접근하게 된다. 각각의 세그멘테이션 테이블은 프로세스마다 하나씩 구현되어 있어서 그에 따라 적절한 가상 메모리 영역에 접근 할 수 있도록 하게 해준다.

모든 메모리는 65535바이트 (64KB)의 일정한 크기를 가진 작은 세그먼트로 나누어지고, 각각의 세그먼트 셀렉터 * 16 + 오프셋 을 통해서 메모리에 접근하였다. 이 이유는 간단히 말하면 그 시대에, 메모리 버스의 크기가 16비트였기 때문이었다. 당연히 레지스터의 길이도 16비트였으며 이는 1M의 공간에 접근은 커녕 오직 64킬로바이트의 메모리 영역에만 접근 할 수 있었다. 따라서 세그먼트 레지스터를 이용하여 1M이상의 메모리 영역에 접근하고자 하였다. 그렇다면 만약 아주큰 CS의 값이 있을 경우는 어떻게 될까? 이 경우는 A20라인이 그 역활을 담당하고 있다. A20라인은, 21번쨰 어드레스 비트를 켜고 끄는 라인을 말한다. 이 라인이 켜져있으면 오버플로우된 메모리 영역이 제대로 동작하기 때문에 메모리 세그멘테이션을 성공적으로 작동 시킬 수 있다.

이러한 시스템하에서

  1. 세그 멘테이션은 프로세스간에 code/data 세그멘트를 분리할 수 있게 해주며
  2. cow과 같은 기법을 사용할 수 있게 해주며,
  3. 투명하게 heap과 stack영역을 사용할 수 있게 해주며
  4. protected code segment가 overwritten되는 것을 막는다.

그러나

  1. fragmentation이 심각하게 발생한다는 단점이 있다.