System Memory
original source: http://egloos.zum.com/studyfoss/v/5020843
[Linux] x86 시스템 메모리 맵 설정
시스템 부팅 시에 수행하는 가장 중요한 일 중 하나는 시스템에서 사용할 수 있는 메모리의 크기와 위치를 파악하여 이를 적절히 설정하는 것이다. ARM이나 MIPS와 같은 임베디드에서 주로 사용되는 코어들은 하드웨어 구성이 표준적으로 정해질 수 없으므로 이러한 작업은 보통 컴파일 시 특정 하드웨어에 정해진 설정을 그대로 사용하거나 부트로더에서 명령행 옵션으로 설정을 넘겨주어야 한다.
하지만 x86/PC 환경에서는 이러한 작업을 위한 표준적인 BIOS 서비스를 제공한다. 그 중 가장 대표적으로 사용되는 것이 이른바 'e820' 방식이라고 하는 BIOS 인터럽트 15번을 이용하는 방법이다. (실행 시 AX 레지스터에 16진수 e820이 들어있어야 하기 때문에 붙여진 이름이다.) 이에 대한 설명은 Ralf Brown's Interrupt List에 다음과 같이 나와있다.
AX = E820h
EAX = 0000E820h
EDX = 534D4150h ('SMAP')
EBX = continuation value or 00000000h to start at beginning of map
ECX = size of buffer for result, in bytes (should be >= 20 bytes)
ES:DI -> buffer for result (see #00581)
Return: CF clear if successful
EAX = 534D4150h ('SMAP')
ES:DI buffer filled
EBX = next offset from which to copy or 00000000h if all done
ECX = actual length returned in bytes
CF set on error
AH = error code (86h) (see #00496 at INT 15/AH=80h)
Notes: originally introduced with the Phoenix BIOS v4.0, this function is
now supported by most newer BIOSes, since various versions of Windows
call it to find out about the system memory
a maximum of 20 bytes will be transferred at one time, even if ECX is
higher; some BIOSes (e.g. Award Modular BIOS v4.50PG) ignore the
value of ECX on entry, and always copy 20 bytes
some BIOSes expect the high word of EAX to be clear on entry, i.e.
EAX=0000E820h
if this function is not supported, an application should fall back
to AX=E802h, AX=E801h, and then AH=88h
the BIOS is permitted to return a nonzero continuation value in EBX
and indicate that the end of the list has already been reached by
returning with CF set on the next iteration
this function will return base memory and ISA/PCI memory contiguous
with base memory as normal memory ranges; it will indicate
chipset-defined address holes which are not in use and motherboard
memory-mapped devices, and all occurrences of the system BIOS as
reserved; standard PC address ranges will not be reported
SeeAlso: AH=C7h,AX=E801h"Phoenix",AX=E881h,MEM xxxxh:xxx0h"ACPI"
Format of Phoenix BIOS system memory map address range descriptor:
Offset Size Description (Table 00580)
00h QWORD base address
08h QWORD length in bytes
10h DWORD type of address range (see #00581)
(Table 00581)
Values for System Memory Map address type:
01h memory, available to OS
02h reserved, not available (e.g. system ROM, memory-mapped device)
03h ACPI Reclaim Memory (usable by OS after reading ACPI tables)
04h ACPI NVS Memory (OS is required to save this memory between NVS
sessions)
other not defined yet -- treat as Reserved
SeeAlso: #00580
이 방식을 통해 메모리 맵 정보를 구성하는 코드는 (setup 프로그램에 포함되는) arch/x86/boot/memory.c 파일의 detect_memory_e820 함수이다. e820 방식을 통해 얻은 메모리 맵 정보는 부트로더 혹은 setup 프로그램을 통해 boot_params내에 포함되어 커널로 전달된다. 커널은 해당 e820 맵 정보를 모두 검사하여 중복된 정보가 있는지 확인하고 이를 순서대로 정리한다. (sanitize_e820_map) 이 후 이 정보를 통대로 max_pfn, max_low_pfn 등의 변수를 설정하고 init_memory_mapping 함수를 호출하여 커널 영역의 페이지 테이블을 초기화한다. e820 방식으로 얻은 메모리 정보 및 커널이 수정한 메모리 정보는 dmesg 명령을 통해 확인할 수 있으며 /sys/firmware/memmap 디렉토리에서도 확인할 수 있다.
현재 이 글을 작성 중인 머신에서의 dmesg 출력은 다음과 같다.
[ 0.000000] BIOS-e820: 0000000000000000 - 000000000009f800 (usable)
[ 0.000000] BIOS-e820: 000000000009f800 - 00000000000a0000 (reserved)
[ 0.000000] BIOS-e820: 00000000000dc000 - 0000000000100000 (reserved)
[ 0.000000] BIOS-e820: 0000000000100000 - 000000007f6e0000 (usable)
[ 0.000000] BIOS-e820: 000000007f6e0000 - 000000007f700000 (ACPI NVS)
[ 0.000000] BIOS-e820: 000000007f700000 - 0000000080000000 (reserved)
[ 0.000000] BIOS-e820: 00000000e0000000 - 00000000f0000000 (reserved)
sysfs의 정보는 다음과 같다.
0x0
0x9f7ff
System RAM
'Linux Kernel' 카테고리의 다른 글
malloc 소개 (0) | 2016.08.18 |
---|---|
posix_fallocate (0) | 2016.08.16 |
Radix Tree (0) | 2016.08.12 |
Linear VS Physical Address (0) | 2016.08.10 |
Block I/O Operation (0) | 2016.08.06 |