시스템 메모리 크기 구하기(BIOS)
현재까지의 OS 모습이다. 32비트 보호모드에서 IA-32e(64비트)모드로 넘어갈 준비를 하고 있다.
메모리의 크기를 구하는 코드가 책에서는 직접 접근하여 값을 기록하는 식으로 설명이 되있었는데, 이 방법이 마음에 안들었다. cpu-z 같은 프로그램에서는 메모리가 몇번째 슬롯에 꽃혔는지도 알 수 있는데 이런 방법은 너무 별로라고 생각했다.
바이오스 인터럽트로 구하기
가장 간편한 방법이다. eax = 0xE820 일 때 0x15번 인터럽트로 현재 시스템의 메모리 맵을 구할 수 있다. 아래 그림과 같이 Base-Length-Type으로 저장된다.
사용방법은 EAX 에 0xE820 세팅, ECX에 24(10진수) 세팅, EDX 에 0x534D4150 세팅,
ES:DI 에 메모리 맵이 저장될 주소 세팅 후 0x15 인터럽트를 호출한다. 종료 기준은 EBX==0 이다.
메모리 맵은 Base-Length-Type 으로 저장되며 총 24바이트다. 따라서 한번 호출이후 DI도 24씩 늘려준다.
물론 바이오스 인터럽트인 만큼 16비트 리얼모드에서 호출해야 한다. 아래 코드는 0x7E00 에는 맵 개수, 0x7E08 부터 메모리 맵을 저장한다.
DETECT_INIT:
mov ebx, 0 ; ebx 초기화
mov edx, 0x534D4150 ; 매직 넘버
mov ax , 0x7E0
mov es, ax
mov di, 0
mov byte [es:0], 0 ; 0x7E00 = 맵 개수
add di, 0x8 ; 0x7E08 = 맵 시작
DETECT_ENTRY:
mov eax, 0xE820
mov ecx, 24
int 0x15
add byte [es:0], 1
cmp ebx, 0
je DETECT_END
add di, 24
jmp DETECT_ENTRY
DETECT_END:
이후 보호모드로 진입해서 해당 주소의 값을 읽으면 된다. 간단한 C언어 코드로는 아래와 같은 코드를 작성할 수 있겠다.
DWORD kGetTotalMemorySize32()
{
int mapCount = *(int*)(0x7E00); //메모리 맵 개수
int* mapAddr = (int*)(0x7E08);
int totalSize = 0;
for(int i = 0; i< mapCount; i++)
{
totalSize += *(mapAddr+2);
mapAddr += 6;
}
return totalSize;
}
Serial Presense Detection
CPU-Z, HWMoitor 같은 프로그램들이 사용하는 방식이다. 컴퓨터를 커면 메인보드의 장치들이
'나 동작합니다~' 하고 정보를 보내는데, 이때 보낸 정보를 활용하는 것이다.
인데... 아직 잘 모르겠다. PCI Configuration Space 를 통해서 접근을 하는 것 같은데. 나중에 64비트 OS의 기반이 다져지면 정리해서 올려보려고 한다.
흠.. PCI 는 저번에 virtual box 원데이 익스플로잇 할 때 좀 공부해둬서 다행이다 ㅋㅋ
Author And Source
이 문제에 관하여(시스템 메모리 크기 구하기(BIOS)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@kunshim/시스템-메모리-크기-구하기BIOS저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)