DevLog ๐Ÿ“จ

[DevLog][PintOS] PRJ1 Threads/PintOS ์Šค๋ ˆ๋“œ๋Š” ์–ด๋–ป๊ฒŒ ๋Œ์•„๊ฐˆ๊นŒ?

cece00 2023. 10. 3. 04:26

Pintos Project 1: Threads

thread_init์„ ํ•˜๋ฉด main thread(initial_thread)๊ฐ€ ๋งŒ๋“ค์–ด์ง€๊ณ  ์‹คํ–‰๋œ๋‹ค. ์Šค์ผ€์ค„๋ง์„ ์œ„ํ•ด thread_start๋ฅผ ์‹คํ–‰ํ•˜๋ฉด, idle_thread๋ฅผ ๋งŒ๋“ค๊ณ  ๋Œ๋ฆฐ๋‹ค. idle_thread๋Š” ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ณ  ์ž๊ธฐ ์ž์‹ ์„ ๋ธ”๋ฝํ•œ ๋‹ค์Œ, sti; hlt; ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ํ™œ์„ฑํ™”ํ•˜๊ณ , ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ๊นŒ์ง€ CPU๋ฅผ ๋Œ€๊ธฐ ์ƒํƒœ๋กœ ์ „ํ™˜ํ•˜๋Š” ์ผ์„ ๋ฐ˜๋ณตํ•œ๋‹ค. create_thread๋Š” ์Šค๋ ˆ๋“œ ์ด๋ฆ„, ์šฐ์„ ์ˆœ์œ„๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„ ์Šค๋ ˆ๋“œ๋ฅผ ์ดˆ๊ธฐํ™”(init_thread)ํ•˜๊ณ , ์Šค๋ ˆ๋“œ ๋‚ด๋ถ€ intr_frame ๊ตฌ์กฐ์ฒด์— ์ธ์ž๋กœ ๋ฐ›์€ ์‹คํ–‰ ํ•จ์ˆ˜ (thread_func type)์™€ ๊ทธ ์ธ์ž๋ฅผ ์ €์žฅํ•œ ํ›„ thread_unblock์„ ํ†ตํ•ด status๋ฅผ THREAD_READY๋กœ ๋ฐ”๊พผ ํ›„ ready_list์— ๋„ฃ๋Š”๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์ธํ„ฐ๋ŸฝํŠธ๋งˆ๋‹ค ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜์ธ thread_tick์˜ if(thread_tick >= TIME_SLICE) intr_yield_on_return(); ๋ผ์ธ์— ์˜ํ•ด thread_yield๊ฐ€ ์ผ์–ด๋‚  ๋•Œ ready_list์—์„œ ๊บผ๋‚ด์–ด์ ธ์„œ, thread_launch์™€ do_iret ํ•จ์ˆ˜์— ์˜ํ•ด ์‹ค์งˆ์ ์ธ context switching์ด ๋ฐœ์ƒํ•˜์—ฌ ์‹คํ–‰๋˜๊ฒŒ ๋œ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ์ธํ„ฐ๋ŸฝํŠธ๋Š” ๋ˆ„๊ฐ€ ๋ณด๋‚ด๋Š” ๊ฑธ๊นŒ? Programmable Interval Timer (PIT)์ธ 8254 ํƒ€์ด๋จธ๊ฐ€ ๋ณด๋‚ธ๋‹ค. ์ด ํƒ€์ด๋จธ๋Š” ์ปดํ“จํ„ฐ์˜ ๋ฉ”์ธ๋ณด๋“œ์— ์œ„์น˜ํ•˜์—ฌ* , init_timer์—์„œ ์„ธํŒ…๋œ ์ธํ„ฐ๋ฒŒ๋งˆ๋‹ค PIC (Programmable Interrupt Controller, ์ „ํ†ต์ ์œผ๋กœ๋Š” 8259A)์— ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ์•ผ ํ•œ๋‹ค๋Š” ์š”์ฒญ์„ ์ „๋‹ฌํ•œ๋‹ค. ๊ตฌ์ฒด์ ์œผ๋กœ๋Š” IRQ0, Interrupt Request 0 ๋ผ์ธ์„ ํ†ตํ•ด master PIC์— ์š”์ฒญํ•œ๋‹ค. x86์•„ํ‚คํ…์ฒ˜์—์„œ IRQ์˜ ๊ฐ’์€ ๋ฒกํ„ฐ๊ฐ’ 0x08๋กœ ๋งคํ•‘๋˜์–ด ์žˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด๊ฒƒ์€ internal interrupt (CPU ์˜ˆ์™ธ)์˜ ๋ฒกํ„ฐ๊ฐ’๊ณผ ์ค‘๋ณต๋˜๊ธฐ ๋•Œ๋ฌธ์—, PIC์—์„œ 0x08 ๋ฒกํ„ฐ๋ฅผ 0x20์œผ๋กœ ์กฐ์ •ํ•˜์—ฌ CPU์— ์ „๋‹ฌํ•œ๋‹ค.

ํ•€ํ† ์Šค์—์„œ ์ธํ„ฐ๋ŸฝํŠธ ํ•ธ๋“ค๋ง์˜ ์—”ํŠธ๋ฆฌ๋Š” intr-stubs.S์— ์ •์˜๋˜์–ด ์žˆ๋‹ค. ๋‚ด๋ถ€ ๋˜๋Š” ์™ธ๋ถ€ ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด CPU๋Š” ์ž๋™์œผ๋กœ rip, cs, eflag, rsp, ss๋ฅผ ์Šคํƒ์— ํ‘ธ์‹œํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ธํ„ฐ๋ŸฝํŠธ ๋ฒกํ„ฐ๊ฐ’์„ ์ฐธ์กฐํ•ด idt์—์„œ ์‹คํ–‰ํ•  stub ์ฝ”๋“œ๋ฅผ ์ฐพ๊ณ  (์ด idt ๋งคํ•‘์€ interrupt.c์˜ register_handler() ํ•จ์ˆ˜๊ฐ€ ํ•œ๋‹ค) ์‹คํ–‰ํ•œ๋‹ค. stub์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜๋˜์–ด ์žˆ๋‹ค.

// intr-stubs.S

#define zero pushq $0;  // error code 0์„ ์Šคํƒ์— ํ‘ธ์‹œํ•œ๋‹ค
#define REAL            // cpu๊ฐ€ pushํ•œ๋‹ค

.section .data
.globl intr_stubs
intr_stubs:                     // stub์˜ ๋ฐฐ์—ด

/* STUB ๋งคํฌ๋กœ๋ฅผ ์ •์˜ํ•œ๋‹ค */
#define STUB(NUMBER, TYPE)
.section .text;                 // ๋ฐ์ดํ„ฐ ์„น์…˜์— ๋ช…๋ น์–ด๋ฅผ ์œ„์น˜์‹œ์ผœ๋ผ
.globl intr##NUMBER##_stub;     // intr00_stub๊ณผ ๊ฐ™์€ ์ „์—ญ ํ•จ์ˆ˜ ์„ ์–ธ
.func intr##NUMBER##_stub;      // ํ•จ์ˆ˜ ์ •์˜ ์‹œ์ž‘
intr##NUMBER##_stub:
    TYPE;                       // type (zero์ธ ๊ฒฝ์šฐ pushq $0)  
    push $0x##NUMBER;           // $0x00๊ณผ ๊ฐ™์€ vec_no push
    jmp intr_entry;             // intr_entry ๋กœ jump
.endfunc;
.section .data;                 // ๋ฐ์ดํ„ฐ ์„น์…˜์—
.quad intr##NUMBER##_stub;      // intr00_stub์˜ ์ฃผ์†Œ๋ฅผ 8๋ฐ”์ดํŠธ๋กœ ์ €์žฅ

/* ํ•˜๋‚˜์˜ ์ธํ„ฐ๋ŸฝํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ €์žฅํ•˜๋Š” STUB๋งคํฌ๋กœ */
STUB(00, zero) STUB(01, zero) STUB(02, zero) ... 256

stub ์ฝ”๋“œ๋Š” ์ˆœ์„œ๋Œ€๋กœ error_code, vector number๋ฅผ ์Šคํƒ์— pushํ•˜๊ณ  intr_entry๋กœ ์ ํ”„ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด intr_entry๋Š” ๋ญ˜ ํ• ๊นŒ?

.section .text
.func intr_entry
intr_entry:
    /* Save caller's registers. */
    subq $16,%rsp
    movw %ds,8(%rsp)
    movw %es,0(%rsp)
    subq $120,%rsp
    movq %rax,112(%rsp)
    movq %rbx,104(%rsp)
    movq %rcx,96(%rsp)
    movq %rdx,88(%rsp)
    movq %rbp,80(%rsp)
    movq %rdi,72(%rsp)
    movq %rsi,64(%rsp)
    movq %r8,56(%rsp)
    movq %r9,48(%rsp)
    movq %r10,40(%rsp)
    movq %r11,32(%rsp)
    movq %r12,24(%rsp)
    movq %r13,16(%rsp)
    movq %r14,8(%rsp)
    movq %r15,0(%rsp)
    cld                      /* String instructions go upward. */

    /* kernel data segement์˜ selector๋ฅผ %rax์— ์ €์žฅ */
    movq $SEL_KDSEG, %rax

    /* ๋ฐ์ดํ„ฐ ์„ธ๊ทธ๋จผํŠธ ๋ ˆ์ง€์Šคํ„ฐ์— %ax ์ €์žฅ */
    movw %ax, %ds         
    movw %ax, %es
    movw %ax, %ss
    movw %ax, %fs
    movw %ax, %gs

    /* %rdi๊ฐ€ intr_handler์˜ ์ธ์ž์ด๋‹ค */
    movq %rsp,%rdi        

    /* interrupt handler call */
    call intr_handler     
    movq 0(%rsp), %r15
    movq 8(%rsp), %r14
    movq 16(%rsp), %r13
    movq 24(%rsp), %r12
    movq 32(%rsp), %r11
    movq 40(%rsp), %r10
    movq 48(%rsp), %r9
    movq 56(%rsp), %r8
    movq 64(%rsp), %rsi
    movq 72(%rsp), %rdi
    movq 80(%rsp), %rbp
    movq 88(%rsp), %rdx
    movq 96(%rsp), %rcx
    movq 104(%rsp), %rbx
    movq 112(%rsp), %rax
    addq $120, %rsp
    movw 8(%rsp), %ds
    movw (%rsp), %es
    addq $32, %rsp
    iretq
.endfunc

ํ˜„์žฌ์˜ ๋ ˆ์ง€์Šคํ„ฐ๊ฐ’์„ ์Šคํƒ์— pushํ•˜๊ณ , ์„ธ๊ทธ๋จผํŠธ ๋ ˆ์ง€์Šคํ„ฐ์— $SEL_KDSEG, ์ฆ‰ ์ปค๋„ ๋ฐ์ดํ„ฐ ์„ธ๊ทธ๋จผํŠธ ์„ ํƒ์ž (gdt์˜ ์ธ๋ฑ์Šค)๋ฅผ ์ €์žฅํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  movq %rsp, %rdi๋กœ ์Šคํƒ ํฌ์ธํ„ฐ๋ฅผ %rdi ๋ ˆ์ง€์Šคํ„ฐ์— ์ €์žฅํ•˜๋Š”๋ฐ, ์ด๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ํ•จ์ˆ˜์˜ ์ธ์ž๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ ˆ์ง€์Šคํ„ฐ๋‹ค. ๋”ฐ๋ผ์„œ, ์Šคํƒ ํฌ์ธํ„ฐ๋ฅผ ์ธ์ž๋กœ ํ•˜์—ฌ call intr_handler๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

void intr_handler(struct intr_frame *frame);

intr_handler๋Š” interrupt.c์— ์ •์˜๋˜์–ด ์žˆ๋‹ค. ์ฆ‰, stack์— intr_frame ๊ตฌ์กฐ์ฒด์— ํ•ด๋‹นํ•˜๋Š” ๋‹ค์Œ ๊ฐ’์„ ์ˆœ์ฐจ์ ์œผ๋กœ pushํ•˜๊ณ , ์Šคํƒ ํฌ์ธํ„ฐ๋ฅผ ์ธ์ž๋กœ ๋„˜๊ธด๋‹ค. intr_handler๋Š” ์ธ์ž๋กœ ๋„˜๊ฒจ์ง„ frame์—์„œ vec_no๋ฅผ ์ฐพ์•„ ํ˜„์žฌ ์–ด๋–ค ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ์ธ์‹ํ•˜๊ณ , register_handler()์— ์˜ํ•ด ๋งคํ•‘๋œ ์ธํ„ฐ๋ŸฝํŠธ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜๋ฅผ intr_handlers์—์„œ ๋ฒกํ„ฐ๊ฐ’์œผ๋กœ ์ธ๋ฑ์‹ฑํ•ด ์ฐพ์•„ ์‹คํ–‰ํ•œ๋‹ค. pintos์˜ ํƒ€์ด๋จธ ์ธํ„ฐ๋ŸฝํŠธ์˜ ๊ฒฝ์šฐ, ์ด ๋•Œ ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜๊ฐ€ timer.c์˜ timer_interrupt() ์ด๋‹ค.

/* Interrupt stack frame. */
struct gp_registers { /* 8byte * 16 */
  uint64_t r15;
  uint64_t r14;
  uint64_t r13;
  uint64_t r12;
  uint64_t r11;
  uint64_t r10;
  uint64_t r9;
  uint64_t r8;
  uint64_t rsi;
  uint64_t rdi;
  uint64_t rbp;
  uint64_t rdx;
  uint64_t rcx;
  uint64_t rbx;
  uint64_t rax;
} __attribute__((packed));

struct intr_frame {
  /* Pushed by intr_entry in intr-stubs.S.
     These are the interrupted task's saved registers. */
  struct gp_registers R; /* rax to r15 (64bit registers) */
  uint16_t es;           /* segment register */
  uint16_t __pad1;       /* padding */
  uint32_t __pad2;       /* padding */
  uint16_t ds;           /* data segment */
  uint16_t __pad3;
  uint32_t __pad4;

  /* Pushed by intrNN_stub in intr-stubs.S. */
  uint64_t vec_no; /* Interrupt vector number.
                      ์ธํ„ฐ๋ŸฝํŠธ ๋ฒกํ„ฐ๊ฐ’, ์ด๊ฑธ๋กœ ์ธํ„ฐ๋ŸฝํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ฐพ์Œ */

  uint64_t error_code;  /* Sometimes pushed by the CPU,
                      otherwise for consistency pushed as 0 by intrNN_stub.*/

  uintptr_t rip;   /* Instruction Pointer */
  uint16_t cs;     /* Code Segment */
  uint16_t __pad5; /* padding */
  uint32_t __pad6; /* padding */
  uint64_t eflags; /* EFLAG: CF, PF, AF, ZF, SF, TF, IF, DF, OF */
  uintptr_t rsp;   /* Stack Pointer */
  uint16_t ss;     /* Segment Register */
  uint16_t __pad7;
  uint32_t __pad8;
} __attribute__((packed));

intr_handler๋Š” ํ•ญ์ƒ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ณ  ์‹œ์ž‘ํ•˜๋Š”๋ฐ, ์ด๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ํ•˜๋‚˜์˜ ์ธํ„ฐ๋ŸฝํŠธ ํ•ธ๋“ค๋ง์€ ๋‹ค๋ฅธ ์ธํ„ฐ๋ŸฝํŠธ์— ์˜ํ•ด ์ค‘๋‹จ๋  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ์ข…๋ฃŒ๋œ ํ›„์—๋Š”, call intr_handlerํ•˜๊ธฐ ์ „ stack์— pushํ•ด๋‘์—ˆ๋˜ ๋‹ค์Œ ์ธ์ŠคํŠธ๋Ÿญ์…˜ ์ฃผ์†Œ๋ฅผ popํ•ด์™€์„œ %rip๋ฅผ ํ•ด๋‹น ์ธ์ŠคํŠธ๋Ÿญ์…˜์˜ ์ฃผ์†Œ๋กœ ๋ฐ”๊พผ๋‹ค.

*ํ˜„๋Œ€ ์ปดํ“จํ„ฐ์—์„œ ํƒ€์ด๋จธ๋Š” cpu์— ์žˆ๋‹ค. 1988 ์ž๋ฃŒ์ž„์„ ์žŠ์ž๋ง์ž.

๐Ÿ‘€ PIC์—์„œ ์™œ ๋ฒกํ„ฐ๊ฐ’์„ ์žฌ๋งคํ•‘ํ•ด์•ผ ํ• ๊นŒ?

์• ์ดˆ์— ์„ค๊ณ„ ๋‹จ๊ณ„์—์„œ ์ž˜ ๋ถ„๋ฆฌํ•ด๋’€์œผ๋ฉด ์•ˆ๋˜๋Š” ๊ฑธ๊นŒ? ํ•˜์ง€๋งŒ ์ปดํ“จํ„ฐ ์•„ํ‚คํ…์ฒ˜๋Š” ์—ญ์‚ฌ์ ์œผ๋กœ ๋ฐœ์ „๋˜์–ด ์™”์œผ๋ฉฐ, ์‹œ์Šคํ…œ์˜ ๋ณต์žก์„ฑ์ด ์ฆ๊ฐ€ํ•จ์— ๋”ฐ๋ผ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ์ธํ„ฐ๋ŸฝํŠธ์˜ ์ˆ˜๊ฐ€ ์ ์ฐจ ์ฆ๊ฐ€ํ•˜๊ธฐ๋„ ํ–ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ ๋ฒกํ„ฐ๊ฐ’์„ ์ƒˆ๋กœ ๋‹ค ํ• ๋‹นํ•˜๊ธฐ๋ณด๋‹ค๋Š” ์†Œํ”„ํŠธ์›จ์–ด์ ์œผ๋กœ ์žฌ๋งคํ•‘ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•  ํ•„์š”์„ฑ์ด ์ƒ๊ฒจ๋‚ฌ๋‹ค. ์•„ํ‚คํ…์ฒ˜๋ž€ ์—ญ์‚ฌ์  ์‚ฐ์ถœ๋ฌผ์ด๋ฏ€๋กœ.. ์–ด๋Š ํ•œ ์ˆœ๊ฐ„์— ์™„๋ฒฝํ•œ ์„ค๊ณ„์— ์˜ํ•ด ํƒ„์ƒํ•œ ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

๐Ÿค” ์งˆ๋ฌธ์— ๋‹ตํ•ด๋ณด์ž

  1. %rip, %rsp register์˜ ์˜๋ฏธ์™€ CPU ๋™์ž‘์—์„œ์˜ ์—ญํ• 
    %rip๋Š” ํ˜„์žฌ ์ธ์ŠคํŠธ๋Ÿญ์…˜์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค. %rsp๋Š” ์Šคํƒ์˜ top์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
  2. assembly ๋ช…๋ น์–ด JMP์™€ CALL์˜ ์ฐจ์ด์  JMP๋Š” ํŠน์ • ์ฃผ์†Œ์˜ ์ธ์ŠคํŠธ๋Ÿญ์…˜์œผ๋กœ ์ด๋™ํ•œ๋‹ค. CALL์€ ๋‹ค์Œ์— ์‹คํ–‰๋˜์–ด์•ผ ํ•  ์ธ์ŠคํŠธ๋Ÿญ์…˜ ์ฃผ์†Œ๋ฅผ stack์— ์ €์žฅํ•ด๋‘๊ณ  ์ด๋™ํ•œ๋‹ค. stack์— ์–ด๋–ป๊ฒŒ ์ €์žฅํ•˜๋Š”๊ฐ€? %rsp๋ฅผ 8 ๊ฐ์†Œ์‹œ์ผœ์„œ ์Šคํƒ ์˜์—ญ์„ 8byte ๋„“ํžˆ๊ณ , ํ˜„์žฌ %rip๋ฅผ %rsp์— ํ‘ธ์‹œํ•œ๋‹ค.
  3. JMP, CALL, RET, PUSH, POP, IRET ๋ช…๋ น์—์„œ %rip, %rsp๋Š” ์–ด๋–ป๊ฒŒ ๊ฐ’์ด ๋ณ€ํ•˜๋Š”๊ฐ€?
  • JMP 0xa๋ฅผ ํ•˜๋ฉด %rip๋Š” 0xa๊ฐ€ ๋œ๋‹ค. %rsp๋Š” ๋ณ€ํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • CALL 0xa์„ ํ•˜๋ฉด %rip๋Š” 0xa๊ฐ€ ๋œ๋‹ค. %rsp๋Š” 8 ๊ฐ์†Œํ•œ๋‹ค. (๋‹ค์Œ์— ์‹คํ–‰๋  ์ธ์ŠคํŠธ๋Ÿญ์…˜ ์ฃผ์†Œ ํฌ๊ธฐ๋งŒํผ)
  • RET์„ ํ•˜๋ฉด %rip๋Š” (%rsp) ๊ฐ€ ๋œ๋‹ค. %rsp๋Š” 8 ์ฆ๊ฐ€ํ•œ๋‹ค.
  • PUSH a๋ฅผ ํ•˜๋ฉด %rsp๋Š” a์˜ ํฌ๊ธฐ(8)๋งŒํผ ๊ฐ์†Œํ•œ๋‹ค. %rip๋Š” ๋ณ€ํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • POP์„ ํ•˜๋ฉด %rsp๋Š” 8๋งŒํผ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค. %rip๋Š” ๋ณ€ํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • IRET์„ ํ•˜๋ฉด %rsp๋Š” 8๋งŒํผ ์ฆ๊ฐ€ํ•œ๋‹ค. %rip๋Š” ์Šคํƒ์—์„œ pop๋œ ๊ฐ’์ด๋‹ค.
  1. interrupt ๋ฐœ์ƒ ์‹œ CPU๋Š” ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”๊ฐ€? register ๊ฐ’ ๋ฐ ์—ฐ๊ด€๋œ memory๋Š”? interrupt ๋ฐœ์ƒํ•˜๋ฉด CPU๋Š” ํ•ด๋‹น ์ธํ„ฐ๋ŸฝํŠธ ๋ฒกํ„ฐ๊ฐ’์— ๋งคํ•‘๋œ interrupt handler๋ฅผ idt์—์„œ ์ฐพ์•„ callํ•œ๋‹ค. call์„ ํ•˜๋ฉด interrupt handler๊ฐ€ iret์œผ๋กœ ๋ฐ˜ํ™˜๋œ ์ดํ›„ ์‹คํ–‰๋˜์–ด์•ผ ํ•  ์ธ์ŠคํŠธ๋Ÿญ์…˜์˜ ์ฃผ์†Œ๋ฅผ ์Šคํƒ์— ์ €์žฅํ•˜๊ณ , interrupt handler์˜ ์ฃผ์†Œ๋กœ %rip๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค.
  2. interrupt๋ฅผ ์ฒ˜๋ฆฌํ•œ ํ›„์—๋Š” ์–ด๋–ป๊ฒŒ ๋˜๋Š”๊ฐ€? inpterrupt์ฒ˜๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋œ ํ›„์—๋Š”, call์ „์— stack์— pushํ•ด๋‘์—ˆ๋˜ ์ฃผ์†Œ๋ฅผ ์ฐพ์•„ ์‹คํ–‰ํ•œ๋‹ค.
  3. interrupt๋Š” ์–ด๋–ป๊ฒŒ enable/disable ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š”๊ฐ€? enable/disable ๋˜๋ฉด ๋ญ๊ฐ€ ๋‹ฌ๋ผ์ง€๋Š”๊ฐ€? interrupt flag๋ฅผ ๋„๋ฉด disable, ์ผœ๋ฉด enable์ด๋‹ค. interrupt flag๋Š” EFLAG ๋ ˆ์ง€์Šคํ„ฐ์˜ 9๋ฒˆ์งธ ๋น„ํŠธ์— ์œ„์น˜ํ•˜๊ณ  ์žˆ์–ด, 1์ธ ๊ฒฝ์šฐ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ํ—ˆ์šฉ, 0์ธ ๊ฒฝ์šฐ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋น„ํ—ˆ์šฉํ•œ๋‹ค. ์–ด์…ˆ๋ธ”๋ฆฌ ๋ช…๋ น์–ด๋กœ๋Š” sti (set interrupt flag)๊ฐ€ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ํ—ˆ์šฉํ•˜๊ณ , cli (clear interrupt flag)๊ฐ€ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋น„ํ—ˆ์šฉํ•œ๋‹ค. sti๋Š” ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ํ—ˆ์šฉํ•˜์ง€๋งŒ, ๋ฐ”๋กœ ๋‹ค์Œ์— ๋‚˜์˜ค๋Š” ๋ช…๋ น์–ด๊นŒ์ง€๋Š” ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋น„ํ—ˆ์šฉํ•œ๋‹ค. ์ฆ‰, sti; hlt;๋ฅผ ํ•˜๋ฉด ์ด๋“ค ๋ช…๋ น์–ด๊ฐ€ ๋‹ค ์‹คํ–‰๋  ๋•Œ๊นŒ์ง€๋Š” ์ธํ„ฐ๋ŸฝํŠธ์— ์˜ํ•ด ๋ฐฉํ•ด๋ฐ›์ง€ ์•Š๊ณ  ์•„ํ† ๋ฏนํ•˜๊ฒŒ ์‹คํ–‰๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
  4. NMI (Non-Maskable Interrupt)๋Š” ๋ฌด์—‡์ธ๊ฐ€? ์ธํ„ฐ๋ŸฝํŠธ ๋งˆ์Šคํ‚น์ด๋ž€, ํ•ธ๋“ค๋ง ์ค‘์ธ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์ค‘๋‹จํ•˜๊ณ  ๋ฐœ์ƒํ•œ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋จผ์ € ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค. Non Maskable Interrupt๋ž€ ์ด๋ ‡๊ฒŒ ์ค‘๋‹จ๋  ์ˆ˜ ์—†๋Š” ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋งํ•œ๋‹ค.
  5. timer interrupt๋Š” ๋ˆ„๊ฐ€ ๋ฐœ์ƒ์‹œํ‚ค๋Š”๊ฐ€? Pintos์—์„œ๋Š” 8254 Timer (Programmable Timer)๊ฐ€ ์žˆ๋‹ค. ์ด ํƒ€์ด๋จธ๋ฅผ timer_init๋“ฑ์œผ๋กœ ์ผ์ • ๊ฐ„๊ฒฉ๋งˆ๋‹ค ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋„๋ก ์„ค์ •ํ•˜๋ฉด, ๋ฒกํ„ฐ๊ฐ’ 0x20์„ ๊ฐ„๊ฒฉ๋งˆ๋‹ค CPU๋‚ด IPC ์นฉ์œผ๋กœ ๋ณด๋‚ด์„œ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.
  6. EFLAGS register๋Š” ๋ฌด์—‡์ธ๊ฐ€? ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ๋ ˆ์ง€์Šคํ„ฐ์ด๋‹ค. Interrupt ํ—ˆ์šฉ/๋น„ํ—ˆ์šฉ์„ ์„ค์ •ํ•˜๋Š” Interrupt Flag (IF)๊ฐ€ ์ด ๋ ˆ์ง€์Šคํ„ฐ์— ์žˆ๋‹ค.