startup_32() ÇÔ¼ö¿¡¼´Â ´ÙÀ½°ú °°ÀÌ
setup_idt() ÇÔ¼ö¸¦
È£ÃâÇÑ´Ù :
--------------------------------------
/usr/src/linux/arch/i386/kernel/head.S
--------------------------------------
startup_32:
:
:
/*
* start system 32-bit setup. We need to re-do some of the things done
* in 16-bit mode for the "real" operations.
*/
call setup_idt
:
: |
±×·³ ÀÌÁ¦ setup_idt() ÇÔ¼ö¸¦ º¸µµ·Ï ÇÏÀÚ.
ÀÌ ÇÔ¼ö¿¡¼´Â ¸ðµç IDT ÀÇ ¿£Æ®¸®°¡ ignore_int()
À¸·Î Á¡ÇÁÇϵµ·Ï ¼¼ÆÃÇÑ´Ù. ½ÇÁ¦ ¾²ÀÌ´Â ÀÎÅÍ·´Æ® µð½ºÅ©¸³ÅÍ Å×À̺íÀÇ
¼¼ÆÃÀº µÚ¿¡ paging_init() ÇÔ¼ö°¡ È£Ã⠵ǰí¼
ÆäÀÌ¡ÀÌ È°¼ºÈ µÈ ÈÄ¿¡ ¼öÇàÇÑ´Ù. setup_idt() ÀÇ
ÄÚµå´Â /usr/src/linux/arch/i386/kernel/head.S
¿¡¼ ã¾Æº¼ ¼ö ÀÖ´Ù :
--------------------------------------
/usr/src/linux/arch/i386/kernel/head.S
--------------------------------------
setup_idt:
lea ignore_int,%edx
movl $(__KERNEL_CS << 16),%eax
movw %dx,%ax /* selector = 0x0010 = cs */
movw $0x8E00,%dx /* interrupt gate - dpl=0, present */
lea SYMBOL_NAME(idt_table),%edi
mov $256,%ecx
rp_sidt:
movl %eax,(%edi)
movl %edx,4(%edi)
addl $8,%edi
dec %ecx
jne rp_sidt
ret |
À§ÀÇ °Í°ú ¶È°°Àº ¾î¼Àºí¸® Äڵ尡 µÚÀÇ ¼½¼Ç¿¡¼ ¼³¸íÇÒ _set_gate()
ÇÔ¼ö¿¡ ³ª¿Â´Ù. ÄÚµåÀÇ ¼³¸íÀº ±×¶§ Çϵµ·Ï ÇÏ°í, ±×¶§ ¼³¸íÇÏÁö ¾ÊÀ»
·çÇÁ¸¦ µµ´Â ºÎºÐÀ» Àá½Ã ¼³¸íÇÏ°Ú´Ù.
Äڵ忡¼,
lea SYMBOL_NAME(idt_table),%edi |
ºÎºÐ¿¡¼, idt_table À̶ó´Â º¯¼ö°¡ ÀúÀåµÈ ½ÇÁÖ¼Ò(effective address)¸¦
edi ·¹Áö½ºÅÍ¿¡ load Çß´Ù. ÀÎÅÚ¿¡¼ edi ·¹Áö½ºÅÍ´Â Åë»óÀûÀ¸·Î
ºí·Ï move µîÀ» ÇÒ ¶§ destination index ·Î ¾²ÀÌ´Â ·¹Áö½ºÅÍÀÌ´Ù. ±×¸®°í,
Åë»óÀûÀ¸·Î Ä«¿îÅÍ·Î ¾²ÀÌ´Â ecx ·¹Áö½ºÅÍ¿¡ idt_table ÀÇ ¿£Æ®¸®ÀÇ °¹¼öÀÎ
256 À» ³Ö°í´Â
rp_sidt: ·çÇÁ·Î ³Ñ¾î°¡¼
ÀÌ ·çÇÁ¸¦ 256¹ø ¹Ýº¹Çϸé¼, ÀÎÅÚÀÇ ÀÎÅÍ·´Æ® °ÔÀÌÆ®ÀÇ »çÀÌÁî(8¹ÙÀÌÆ®)¸¸Å
edi ·¹Áö½ºÅ͸¦ Áõ°¡½ÃÅ°¸é¼ edi °¡ °¡¸®Å°´Â °÷¿¡ ÀÌ¹Ì ¸¸µé¾îÁø ÀÎÅÍ·´Æ®
°ÔÀÌÆ®¸¦ ¼¼ÆÃÇØ ÁØ´Ù. ÀÌ ÀÎÅÍ·´Æ® °ÔÀÌÆ®´Â ¸ðµÎ´Ù µ¿ÀÏÇÏ°Ô ignore_int
ÇÔ¼ö¸¦ °¡¸®Å°´Â °ÍÀ¸·Î½á, ignore_int ÇÔ¼ö´Â ±×³É "Unknown interrupt" ¸¦
ȸ鿡 Ãâ·ÂÇÏ°í ¸®ÅÏÇÏ´Â ÇÔ¼öÀÌ´Ù. ´ÙÀ½°ú °°ÀÌ Á¤ÀǵǾî ÀÖ´Ù :
--------------------------------------
/usr/src/linux/arch/i386/kernel/head.S
--------------------------------------
int_msg:
.asciz "Unknown interrupt\n"
ALIGN
ignore_int:
cld
pushl %eax
pushl %ecx
pushl %edx
pushl %es
pushl %ds
movl $(__KERNEL_DS),%eax
movl %eax,%ds
movl %eax,%es
pushl $int_msg
call SYMBOL_NAME(printk)
popl %eax
popl %ds
popl %es
popl %edx
popl %ecx
popl %eax
iret |