e820 및 커널 물리적 메모리 매핑

우리 모두는 운영 체제가 메모리를 관리하는 방법에 대해 어느 정도 이해하고 있지만 운영 체제가 메모리 관리를 시작하기 전에 먼저 사용 가능한 물리적 주소 수, ACPI(Advanced Configuration and Power Interface) 데이터에서 사용하는 물리적 주소 및 이 정보의 출처와 같은 물리적 메모리에 대한 정보를 얻어야 합니다.

e820은 물리적 메모리 정보를 제공하기 위해 x86 아키텍처(x86_64 포함)의 운영 체제 부트로더에서 BIOS 기능입니다. BIOS 인터럽트 번호 15H가 요청되고 연산 코드 AX=E820H가 설정되면 BIOS는 사용 가능한 물리적 주소 범위와 같은 정보를 호출자에게 보고하므로 e820이라는 이름이 붙습니다.

Linux 커널은 또한 이 메커니즘을 사용하여 물리적 주소 정보를 얻으며 dmesg를 사용하여 관련 정보를 볼 수 있습니다.

위는 내 컴퓨터에서 얻은 데이터로, 사용 가능한 간격은 실제 메모리에 실제로 매핑 된 주소 공간이고 위에 표시된 4 개의 간격은 사용 가능한 4 개의 주요 실제 주소 간격 (약 4GB)입니다.

  • 사용 가능: 실제 메모리에 매핑된 실제 주소입니다.
  • 예약됨: 이 구획은 어디에도 매핑되지 않으며 RAM으로 사용할 수 없지만 커널은 이러한 구획을 PCI 장치와 같은 다른 위치에 매핑하기로 결정할 수 있습니다. /proc/iomem 파일을 검사하면 예약된 공간이 다른 장치에 어떻게 추가로 할당되는지 확인할 수 있습니다.
  • ACPI 데이터: ACPI 데이터를 저장하는 데 사용되는 RAM 공간이며 운영 체제는 ACPI 테이블을 이 구획으로 읽어야 합니다.
  • ACPI NVS: 운영 체제에서 사용할 수 없는 ACPI 데이터를 저장하는 데 사용되는 비휘발성 스토리지 공간에 매핑됩니다.
  • 사용할 수 없음: 오류가 발생한 실제 메모리가 감지되었음을 나타냅니다. 이것은 상대적으로 드물기 때문에 위의 예에는 없습니다.

커널은 이 정보를 읽어서 e820map 구조체에 저장하는데, 이 구조체에는 두 개의 복사본이 있는데, 하나는 E820 기호이고 다른 하나는 e820_saved 기호이다. 데이터 구조에 대한 자세한 내용은 arch/x86/include/asm/e820.h를 참조하십시오. 커널이 부팅되면 커널은 e820의 정보도 수정합니다.

예를 들어, 필자의 시스템에서 e820에 세 가지 변경 사항이 있었는데 이러한 변경 사항은 BIOS와 관련이 없지만 커널 자체는 자체 메모리 데이터 구조를 수정하여 메모리 간격 사용을 변경합니다.

또 다른 전형적인 예로, 커널 부팅 파라미터에 memmap과 같은 파라미터 항목이 있을 때, 커널은 지정된 사용 가능한 간격을 reserved로 수정하여 커널이 가상 주소를 이러한 물리적 주소 공간에 매핑할 수 없도록, 즉 이 물리적 메모리를 사용할 수 없게 하는 것입니다(사실, ioremap을 통해 커널의 가상 주소 공간에 여전히 매핑할 수 있지만, 이러한 동작은 다른 프로그램의 간섭 없이 자체적으로 제어됩니다). 이것은 물리적 메모리를 기반으로 하는 파일 시스템과 같이 커널이 개입하는 것을 원하지 않고 물리적 메모리의 특정 부분을 직접 관리해야 할 때 유용할 수 있습니다.

커널은 또한 e820 데이터 구조를 조작하기 위한 일련의 함수를 제공하며, 함수 선언은 모두 arch/x86/include/asm/e820.h에 있고 해당 정의는 arch/x86/kernel/e820.c에 있습니다. 기사의 시작 부분에 표시되는 메시지는 void __init e820_print_map (char *who)에 의해 인쇄됩니다.

이 과정에서 BIOS에서 제공하는 실제 매핑 정보를 쿼리하기 위해 원래 상태를 변경하지 e820_saved 있지만 커널은 현재 이 데이터 구조를 사용하지 않는 것 같습니다. 물리적 주소가 실제로 물리적 메모리인지 확인하는 데 사용했습니다.