3.2. idtr 레지스터의 초기화

일단 앞절에서 살펴본 것과 같이 초기화된 인터럽트 게이트들을 가리키는 레지스터 idtrstartup_32 어셈블리 루틴에서 초기화된다 :

--------------------------------------
/usr/src/linux/arch/i386/kernel/head.S
--------------------------------------
ENTRY(_stext)
startup_32:
	:
	:
#ifdef CONFIG_SMP
	orw  %bx,%bx
	jz  1f				/* Initial CPU cleans BSS */
	pushl $0
	popfl
	jmp checkCPUtype
1:
#endif CONFIG_SMP			/* SMP 가 아니면 그냥 자연스럽게 아래에 있는
	:				   ckeckCPUtype 레이블까지 진행함 */
	:
checkCPUtype:
	:
	:
	lgdt gdt_descr
	lidt idt_descr
	:
	:

이때, idt_descr 이라는 심벌은 head.S 맨 아랫쪽 부분에서 다음과 같이 정의되고 있다 :

#define IDT_ENTRIES	256
#define GDT_ENTRIES	(__TSS(NR_CPUS))

.globl SYMBOL_NAME(idt)
.globl SYMBOL_NAME(gdt)

	ALIGN
	.word 0
idt_descr:
	.word IDT_ENTRIES*8-1		# idt contains 256 entries
SYMBOL_NAME(idt):
	.long SYMBOL_NAME(idt_table)

	.word 0
gdt_descr:
	.word GDT_ENTRIES*8-1
SYMBOL_NAME(gdt):
	.long SYMBOL_NAME(gdt_table)
편의상 gdt_descr 까지 정의하는것까지 보였다(-_-a) 소스를 보면, idt_descr 번지에 16비트 크기(.word)로 256*8-1 의 값이 들어간다. 이부분은, 앞서 다룬 idtr 레지스터의 구조를 생각해 보면 알 수 있는 부분이다. 하위 16비트는 limit 의 의미를 띠었었다. 이것은 idtr 에 256개의 엔트리가 들어간다는 사실을 생각할 때 쉽게 알 수 있다. 그리고, 32비트 크기(.long)로 idt_table 의 주소를 저장하고 있다.

이 부분은, 위에서 이야기한 checkCPUtype 블록에서

	lidt idt_descr
인스트럭션에서 사용된다. lidt 명령을 인텔의 매뉴얼에서 찾아보면, 오퍼랜드가 16비트 어드레스일때와 32비트 어드레스일때의 동작이 약간 차이가 나는데(16비트 어드레스일때는 베이스에 해당하는 필드에 0x00ffffff 를 and 해서 넣음) 뭐, 제대로 만들었다고 생각하고, 어쨌든, 48비트 크기의 idtr 의 idt base address 필드(상위 32비트)에 idt_table 의 주소와, 아랫부분의 idt limit 필드(하위 16비트)에 256*8-1 개를 나타내는 값을 넣는다.

여기까지 일단, 최초의 idt_table 의 세팅과 idtr 의 세팅을 알아보았다. 이제는 다음 섹션에서 실제 인터럽트 벡터 테이블을 세팅하는 부분을 살펴보겠다

참, idt_table 심볼이 정의되는 곳을 말하지 않았다. 그 심벌은 아래와 같이 정의되어 있다 :

--------------------------------------
/usr/src/linux/arck/i38/kernel/traps.c
--------------------------------------
struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };