본문 바로가기

분류 전체보기

(58)
15장. 콘솔 셸 Ⅰ. 콘솔 입출력 처리 1. 콘솔 자료구조 생성과 printf( ) 함수 구현 콘솔 자료구조와 매크로 // 비디오 메모리의 속성(Attribute) 값 설정 #define CONSOLE_BACKGROUND_BLACK 0x00 #define CONSOLE_BACKGROUND_BLUE 0x10 #define CONSOLE_BACKGROUND_GREEN 0x20 #define CONSOLE_BACKGROUND_CYAN 0x30 #define CONSOLE_BACKGROUND_RED 0x40 #define CONSOLE_BACKGROUND_MAGENTA 0x50 #define CONSOLE_BACKGROUND_BROWN 0x60 #define CONSOLE_BACKGROUND_WHITE 0x70 #define ..
14장. 키보드 디바이스 드라이버 업그레이드 Ⅰ. 인터럽트 핸들러와 큐 1. 범용 큐 구현과 사용 방법 큐에 대한 정보를 관리하는 자료구조 bLastOperationPut : 삽입 위치와 제거 위치가 같아지는 경우를 처리하기 위한 필드 (삽입 시 TRUE, 제거 시 False로 설정된다.) typef struck kQueueManagerStruct { // 큐를 구성하는 데이터 하나의 크기와 최대 개수 int iDataSize; int iMaxDataCount; // 큐 버퍼의 포인트와 삽입/제거 인덱스 void pvQueueArray; int iPutIndex; int iGetIndex; // 큐에 수행된 마지막 명령이 삽입인지를 저장 // 큐의 버퍼가 비어있는지, 가득 찼는지 확인하는 용도 BOOL bLastOperationPut; } QUEU..
13장. PIC 컨트롤러와 인터럽트 핸들러 이용해, 인터럽트 처리 Ⅰ. PIC 컨트롤러 제어 1. PIC 컨트롤러 초기화 마스터 PIC 컨트롤러와 슬레이브 PIC 컨트롤러의 초기화 코드 // I/O 포트 정의 #define PIC_MASTER_PORT1 0X20 #define PIC_MASTER_PORT2 0X21 #define PIC_SLAVE_PORT1 0XA0 #define PIC_SLAVE_PORT2 0XA1 // IDT 테이블에서 인터럽트 벡터가 시작되는 위치, 0x20 #define PIC_IRQSTARTVECTOR 0x20 void kInitializePIC( void ){ // 마스터 PIC 컨트롤러를 초기화 // ICW1(포트 0x20), IC4 비트(비트 0) = 1 kOutPortByte( PIC_MASTER_PORT1, 0x11 ); // ICW2..
12장. GDT, IDT 테이블, TSS 세그먼트를 추가해 인터럽트에 대비하자 Ⅰ. GDT 테이블 교환과 TSS 세그먼트 디스크립터 추가 1. GDT 테이블 생성과 TSS 세그먼트 디스크립터 추가 현재까지 사용한 코드&데이터 세그먼트 디스크립터는 보호 모드 커널 엔트리 포인트영역에서 어셈블리어로 작성한 것이다. 멀티 코어를 활성화하게 되면, 코어 별로 TSS 세그먼트가 필요하므로, 이를 대비하여 1MB 이상의 공간에 GDT 테이블을 생성한다. C코드로 GDT 테이블을 새로 작성한다. 세그먼트 디스크립터 & GDT 테이블 & TSS 세그먼트를 위한 자료구조와 매크로 // 조합에 사용할 기본 매크로 #define GDT_TYPE_CODE 0x0A #define GDT_TYPE_DATA 0x02 #define GDT_TYPE_TSS 0x09 #define GDT_FLAGS_LOWER_S..
11장. 키보드 디바이스 드라이버 추가 Ⅰ. 키보드 컨트롤러 제어 1. 키보드와 키보드 컨트롤러 활성화 키보드 컨트롤러에서 키보드 디바이스를 사용 가능하게 하려면, 커맨드 포트로 키보드 디바이스 활성화 커맨드인 0xAE를 보내면 된다. (But, 해당 과정은 키보드 컨트롤러를 활성화한 것이지, 실제 키보드를 활성화한 것은 아니다.) 키보드 컨트롤러와 키보드는 PS/2 방식의 케이블로 연결되어 있으며 PC외부에 존재하기 때문에, 키보드에도 활성화 커맨드를 보내줄 필요가 있다. 키보드는 커맨드나 데이터에 대한 응답이 전송되며, 정상적으로 처리한 경우 ACK(0xFA)를 전송하며, ACK가 수신되지 않으면 수행 도중 에러가 발생한 것이다. 키보드 컨트롤러와 키보드를 활성화하는 코드 // 출력 버퍼(포트 0x60)에 수신된 데이터가 있는지 여부를 반..
10장. 64비트 모드로 전환 Ⅰ. 프로세서의 제조사와 IA-32e 지원 여부 검사 CPUID 명령어를 이용하여, 프로세서 제조사를 확인하는 방법과 IA-32e 모드를 지원하는지 확인하는 방법에 대해 살펴본다. 1. CPUID를 사용하여, 프로세서 정보 확인 방법 CPUID는 EAX 레지스터에 설정된 값에 따라 해당 정보를 조회하며, 범용 레지스터 EAX, EBX, ECX, EDX를 통해 결과를 넘겨준다. CPUID 명령어 실행했을 때, 반환되는 정보는 프로세서가 생산된 제조자(인텔, AMD 등)에 따르지만, 여러 프로세서 간의 호환을 위해 공통적인 필드를 가지고 있다. EAX 값 0x00000000 일 경우, 기본 CPUID 정보를 조회한다. EAX 값 0x80000001 일 경우, 확장 기능 CPUID 정보를 조회한다. 2. 프로..
9장. 페이징 기능을 활성화하여, 64비트 전환 준비 해당 과정부터는 자세한 설명을 적지 않을 예정이다. 적을 시간에 한 글자라도 더 보는 것이 좋을 것 같아서, 간단히 기록만 해둔다. Ⅰ. 페이지 테이블 생성과 페이징 기능 활성화 1. 페이지 엔트리를 위한 자료구조 정의 매크로 정의 페이지 테이블은 각 엔트리의 집합이므로, 페이지 엔트리를 나타내는 자료구조를 먼저 정의한다. 아래는 8바이트 크기의 페이지 엔트리 자료구조를 정의한 것이다. typedef struct pageTableEntryStruct{ DWORD dwAttributeAndLowerBaseAddress; DWORD dwUpperBaseAddressAndEXB; } PWL4TENTRY, PDPTENTRY, PDENTRY, PTENTRY; 페이지 엔트리 속성 필드를 매크로로 정의한 것이다. /..
8장. A20 게이트를 활성화하여 1MB이상 영역에 접근 Ⅰ. IA-32e 모드 커널과 메모리 맵 IA-32e 모드 커널을 실행하기 위한 준비 작업으로, PC에 설치된 메모리가 64MB이상인지 검사하고, IA-32e 커널이 위치할 영역을 모두 0으로 초기화하는 작업을 수행한다. 부팅 과정을 완료하고 나서, 1MB 이상의 메모리에 정상적으로 접근이 되는지 확인하고 이를 위해 어떤 작업이 필요한지 살펴본다. 1. 1MB 이상의 메모리에 접근해야 하는 이유 부트 로더에 의해 커널 이미지가 메모리에 로딩되는 어드레스는 0x10000이다. 만약, 1MB 이하의 어드레스 중에서 비디오 메모리가 위치한 0xA0000 이하를 커널 공간을 사용한다고 가정하면, 보호 모드 커널과 IA-32e 모드 커널의 최대 크기는 (0xA0000 - 0x10000)로 576KB가 된다. 커널..