BIOS를 위해 CONFIG_X86_RESERVE_LOW 메모리를 예약하는 커널의 요점은 무엇입니까?

BIOS를 위해 CONFIG_X86_RESERVE_LOW 메모리를 예약하는 커널의 요점은 무엇입니까?

최소한 2.6 커널부터 Kconfig는 "BIOS용으로 예약된 낮은 메모리 양(KB)"으로 설명되는 CONFIG_X86_RESERVE_LOW 옵션을 제공합니다. (제가 알기로는 물리적 주소 0에서 시작해서 4K부터 640K까지의 범위입니다.)

내 시스템에서 부팅할 때 내 로그는 부팅 프로세스가 시작되려고 할 때 알려줍니다.

BIOS-provided physical RAM map:
BIOS-e820: [mem 0x0000000000000000-0x000000000009ebff] usable

이것으로부터 나는 BIOS가 RAM의 첫 번째 0x9ec00(~640K) 바이트를 사용할 수 있음을 커널에 알리고 있다고 추론합니다. (보존되지 않음)

몇 줄을 더 보면 다음과 같은 내용을 읽을 수 있습니다.

e820: update [mem 0x00000000-0x00000fff] usable ==> reserved

내 설정의 결과인 것으로 알고 있습니다. CONFIG_X86_RESERVE_LOW = 4K

그러나 BIOS 자체가 0-0x9ebff 범위를 사용할 수 있다고 주장하는 경우 커널이 BIOS를 위해 <~640K의 적은 양의 메모리를 "예약"하는 요점은 무엇입니까?

답변1

이 구성 옵션에 대한 더 긴 도움말 텍스트가 표시됩니다. 두 가지 이유를 제공합니다.

config X86_RESERVE_LOW
int "BIOS용으로 예약된 낮은 메모리 양(KB)"
기본값 64
범위 4 640
도움말

BIOS용으로 예약된 낮은 메모리 양을 지정합니다.

첫 번째 페이지에는 커널에서 사용해서는 안 되는 BIOS 데이터 구조가 포함되어 있으므로 이 페이지는 항상 예약되어야 합니다.

[자르다]

온라인에도 비슷한 댓글이 있네요암호:

     * A special case is the first 4Kb of memory;
     * This is a BIOS owned area, not kernel ram, but generally
     * not listed as such in the E820 table.

레거시 BIOS는 처음 1280바이트(0x500)를 사용합니다. Linux는 MMU 페이지 크기(4096바이트) 단위로 RAM을 할당합니다. 운영 체제 개발지적 -

모든 BIOS 기능이 호출되고 커널이 메모리 어딘가에 로드된 후 부트로더나 커널이 리얼 모드를 영구적으로 종료할 수 있습니다(보통 32비트 보호 모드). 커널이 더 이상 리얼 모드를 사용하지 않으면 PC 메모리의 처음 0x500바이트를 재사용하고 덮어쓸 수 있습니다.

Linux는 일반적으로 BIOS를 호출할 수 없습니다. 그러나 너무 일찍 시작하고, 종료하고, 절전 모드에서 다시 시작하는 등 무서운 순간에는 그렇게 할 수 있습니다. UEFI를 사용하여 시스템을 부팅하는 경우 Linux가 인식하는 BIOS가 없습니다.

또한 첫 번째 페이지를 유지한다는 것은 성공적인 실제 메모리 할당이 결코 값 0을 반환하지 않음을 의미합니다. C 프로그래밍에서는 전통적으로 "NULL 포인터"를 나타내기 위해 주소 0을 예약합니다. 우리는 이것이 반영된 것을 볼 수 있습니다memblock_phys_alloc_range(). 이 시점에서 변경하는 것은 성공할 것 같지 않습니다(그리고 위험합니다 :-).

 * Return: physical address of the allocated memory block on success,
 * %0 on failure.
 */
phys_addr_t __init memblock_phys_alloc_range(

이것이 두 번째 이유입니다:

기본적으로 물리적 RAM의 처음 64K를 예약합니다. 많은 BIOS가 일시 중지/재개 또는 모니터 케이블 삽입과 같은 이벤트 중에 이 메모리 범위를 손상시키는 것으로 알려져 있으므로 커널은 이를 사용해서는 안 됩니다.

BIOS가 모든 메모리를 예약하고 올바르게 사용할 수 있다고 확신하는 경우 4로 설정할 수 있습니다. BIOS에 기본 64K 영역 외부에 문제가 있다는 것을 알고 있는 경우 이를 640으로 설정하여 전체 낮은 메모리 범위를 사용하지 않도록 할 수 있습니다.

BIOS에 문제가 있는 경우(예: 일시 중지/재개 작동 안 함 또는 특정 하드웨어 핫플러그 이벤트 후 커널 패닉) X86_CHECK_BIOS_CORRUPTION=y를 활성화하여 커널이 일반적인 손상 패턴을 확인할 수 있도록 할 수 있습니다.

확실하지 않은 경우 이 값을 기본값인 64로 그대로 두십시오.

가장 안전한 가정은 이것이 BIOS와 마찬가지로 UEFI 펌웨어에도 적용된다는 것입니다 :-).

v3.9부터 커널 로그 메시지에 매우 낮은 보존 기간이 표시되지 않습니다. 그것도 나타나지 않습니다 /proc/iomem. 커널은 예약된 처음 4k만 표시하지만 나머지 메모리는 여전히 예약되어 있어야 합니다. e820 지도에는 추가되지 않았을 뿐입니다. 다른 목록에 추가됩니다. 이 변경 사항에 대한 패치는 다음과 같습니다.x86, mm: 낮은 메모리를 보존하기 위해 초기화를 나중에 진행합니다..

추가 보류와 이를 요구하는 슬픈 이야기에 대해 더 알고 싶다면 다음 패치 소식을 확인하세요.

x86: 복구 중에 주소 0xc000을 손상시키는 DMI 문제를 AMI BIOS에 추가했습니다.

Alan Jenkins와 Andy Wettstein이 일시 중지/재개 메모리 손상 버그를 보고했습니다. 이에 대한 자세한 내용은 여기에 설명되어 있습니다.

http://bugzilla.kernel.org/show_bug.cgi?id=11237

버그는 BIOS가 e820에 예약된 것으로 등록하지 않거나 커널에 이에 대해 알리지 않고 물리적 주소 0xc000의 메모리 1K를 덮어썼다는 것입니다.

AMI BIOSen을 감지하고 해당 1K를 유지합니다.

이 버그는 찾기가 매우 어렵고 몇 주와 많은 디버깅 및 패치 작업이 필요하기 때문에 매우 광범위한 브러시(모든 AMI BIOS 시스템에서 1K 예약)를 적용합니다.

이 버그는 CONFIG_X86_CHECK_BIOS_CORRUPTION=y 디버그 기능을 통해 발견되었습니다. 이 기능은 유사한 버그가 의심되는 경우 다른 시스템에서도 활성화하여 메모리 부족으로 손상된 메모리를 검색할 수 있습니다.

x86: X86_RESERVE_LOW_64K 추가

이 버그질라:

http://bugzilla.kernel.org/show_bug.cgi?id=11237

일시 중지/재개 및 기타 하드웨어 이벤트 중에 BIOS가 물리적 메모리의 처음 64K를 사용하는 다양한 시스템을 문서화했습니다.

현재 우리는 모든 AMI 및 Phoenix BIOS 시스템에 이 메모리를 예약하고 있습니다. 이와 같은 미묘한 메모리 손상 문제를 추구하기에는 인생이 너무 짧기 때문에 우리는 기본적으로 견고하려고 노력합니다.

그러나 이 설정을 재정의할 수 있습니다. 처음 64K의 메모리를 커널에 사용하려는 사용자는 CONFIG_X86_RESERVE_LOW_64K=n을 통해 이 기능을 비활성화할 수 있습니다.

x86, BIOS: 기본적으로 모든 BIOS에는 하위 64K가 예약되어 있습니다.

낮은 64K를 유지해야 하는 BIOS 목록이 점점 길어지고 있으므로 이를 모든 BIOS의 기본값으로 설정하세요. 또한 이를 통해 코드를 단순화하고 최초의 4K 예약 코드와 통합할 수 있습니다.

이는 커널 버그질라 16661을 수정하며 그 밖의 사항은 누가 알겠습니까?

버그 16661 - 낮은 메모리 손상

[...] 이는 우리가 그의 BIOS(dmidecode 정보 제공)를 arch/x86/kernel/setup.c의 블랙리스트 bad_bios_dmi_table에 추가해야 함을 의미합니다. 그러나 결론은 64K는 적은 양의 메모리이고 이제 목록에는 수많은 기존 BIOS가 포함되므로 무조건 남겨 두어야 한다는 것입니다.

내가 아는 한, Windows 7은 실제로 BIOS 오류를 방지하기 위해 1MiB 미만의 모든 메모리를 예약합니다.

관련 정보