6. A20 게이트를 활성화하여 1MB이상 영역에 접근해보자

들어가기

A20 게이트에 대해 공부 해보자.

본론

6.1 IA-32e 모드 커널과 메모리 맵

  • 1MB(0x100000) 이하의 공간은 IA-32e 모드 커널의 공간으로 활용하기에는 부족.
    • IA-32e 모드 커널을 2MB ~ 6MB까지 위치 시킬 예정.

6.2 IA-32e 모드 커널을 위한 메모리 초기화

6.2.1 메모리 초기화 기능 추가

BOOL kIntializeKernel64Area()
 {
    DWORD* pdwCurrentAddress;

    // 초기화을 시작할 어드레스 0x100000(1MB)을 설정
    pdwCurrentAddress = (DWORD*) 0x100000;

    // 마지막 어드레스인 0x600000까지 루프를 돌면서 4바이트씩 0으로 채움
    while( ( DWORD ) pdwCurrentAddress < 0x600000 )
    {
        *pdwCurrentAddress = 0x00;

        // 0으로 저장한 후 다시 읽었을 때 0이 나오지 않으면 해당 어드레스를
        // 사용하는데 문제가 생긴것으로 종료
        if ( *pdwCurrentAddress != 0)
        {
            return FALSE;
        }

        // 다음 주소로 이동
        pdwCurrentAddress++;
    }

    return TRUE;
 }
  • 메모리 영역 1MB ~ 6MB까지 0으로 초기화.

6.2.2 빌드와 실행

  • 0으로 초기화 이후 문자열을 찍어 확인 -> 정상작동.
  • 하지만 PC에 따라 정상작동 안할 가능성도 있음.
    • 하위 호환성을 유지하기 위해 어드레스 라인을 비활성화했기 때문.

6.3 1MB 어드레스와 A20 게이트

6.3.1 A20 게이트의 의미와 용도

  • 초창기 XT PC는 최대 1MB까지 접근 가능했기 때문에 1MB가 넘는 어드레스는 하위 어드레스만 남음.
  • 이후 16MB까지 접근 가능한 AC PC가 탄생하면서 XT PC용 프로그램을 AC PC에서 실행하면서 문제 발생.
    • 이런 호완성의 문제 해결을 위해 A20게이트를 만듬.
  • A20 게이트에서 A20의 의미는 어드레스의 20번째 비트를 의미하며 해당 비트가 비활성되면 어드레스 라인의 20번째(1MB)가 항상 0으로 고정.
    • 0x10FFEF가 되더라도 0xFFEF로 처리

6.3.2 A20 게이트 활성화 방법

  • A20 게이트를 활성화하는 방법은 크게 세 가지.
    • 키보드 컨트롤러
    • 시스템 컨트롤 포트
    • BIOS 서비스
  • 키보드 컨트롤러를 사용하면 속도가 느리고 복잡하지만 PS/2 방식의 키보드/마우스를 지원하는 PC라면 어디서나 사용 가능.
  • 시스템 컨트롤 포트는 키보드 컨트롤러를 통하는 방법보다 속도가 빠르고 간략함.
  • 가장 확실한 방법은 BIOS 서비스를 사용하는 방법.
  • 시스텀 컨트롤 포트와 BIOS 서비스를 사용해 A20 게이트를 활성화 해볼 예정.

시스템 컨트롤 포트로 A20 게이트 활성화하기

 in al, 0x92        ; 시스템 컨트롤 포트(0x92)에서 1 바이트를 읽어 레지스터에 저장
 or al, 0x02        ; 읽은 값에 A20 게이트 비트(활성화는 비트 1이 1)를 1로 설정
 and al, 0xFE       ; 시스템 리셋 방지를 위한 0xFE와 AND 연산하여 비트 0를 0으로 설정
 out 0x92, al
  • 시스템 컨트롤 포트는 I/O 포트 어드레스의 0x92에 위치.

BIOS 서비스로 A20 게이트 활성화 방법

 mov ax, 0x2401     ; A20 게이트 활성화 서비스 설정
 int 0x15           ; BIOS interrupt 호출
  • 시스템 컨트롤 포트를 사용하는 것 보다 훨씬 간편.
    • 인터럽트 벡트 0x15 호출.

6.4 A20 게이트 적용과 메모리 크기 검사

6.4.1 A20 게이트 활성화 코드 적용

  • 한 가지 방법만 사용해도 되지만 여러 가능성을 대비해 두 가지 방법을 모두 사용.
    • 믿을 만한 BIOS를 먼저 실행하고 실패하면 시스템 컨트롤 포트 사용.

A20 게이트 활성화 반영된 코드 보기

6.4.2 메모리 크기 검사 기능 추가

  • 사용 가능한 메모리를 검사하는 가장 확실한 방법은 메모리의 특정 값을 쓰고 다시 읽어 같은 값을 확인.
    • 어드레스가 진짜 물리 메모리라면 쓴 값이 그대로 출력, 진짜 물리 메모리가 아니라면 임의의 값이 출력.
    • 이런 특징을 활용해 메모리 크기 계산 가능.
  • 검사 방법은 1MB 단위로 어드레스를 증가시키면서 각 MB의 첫 번째 4바이트에 0x12345678을 쓰고 읽음.

메모리 크기 검사 코드 반영된 코드 보기

6.4.3 빌드와 실행


  • 메모리 영역을 임의로 작게해서 테스트 결과 정상 작동.

마치며

이번 챕터는 그나마 이해가 갔다…

Share