x86 Linux ã®ã¡ã¢ãªã¢ãã«ãããã»ã¹ç©ºéåãæ¿ããã«ã¼ãã«ã¹ã¿ãã¯
ã²ã¨ã¤åã®ã¨ã³ã㪠id:naoya:20070924:1190653790 ã§ã¯ Linux ã®ã³ã³ããã¹ãã¹ã¤ããã«ãããã主ã«ãã¼ãã¦ã§ã¢ã³ã³ããã¹ãã®éé¿/復帰ã®å¦çã追ã£ã¦ã¿ã¾ããããã®ä¸ã§
ã«ã¼ãã«ã¹ã¿ã㯠(switch_to() å 㧠pushl %ebp ã¨ããã¦å¤ãç©ã¾ããã¹ã¿ãã¯)ã¨ã¯ãã®ã¨ãã®å®è¡ã³ã³ããã¹ãã«ç´ã¥ãã«ã¼ãã«ããã»ã¹ã¹ã¿ãã¯ã¨ããç解ã§ãããã
ã¨ããçåããããã湧ãã¦åºã¦ãã¾ãããããæ°æ¥ ã¯ããã¦èªã486â32ãããã³ã³ãã¥ã¼ã¿ãããããèªã ãèªãã§ããã®ã§ããããã®ä¸ã«ãã®çåã¸ã®çãã¸ã®å ¥ãå£ãè¼ã£ã¦ãã¾ãã¦ãããã糸å£ã«èª¿ã¹ã¦ã¿ã¾ãããã§ãçµæã¨ãã¦ã¯
- çã: è¯ã
ã§ããã
x86 ã¯ç¹æ¨©ã¬ãã«ã®ç§»è¡ã¨é£åãã¦ã¹ã¿ãã¯ãã¤ã³ã¿ãåãæ¿ããä»çµã¿ãæã£ã¦ãã¾ããLinux ã®å ´åã¢ã¼ãã¯ã«ã¼ãã«ã¢ã¼ã(ç¹æ¨©ã¬ãã«0) ã¨ã¦ã¼ã¶ã¼ã¢ã¼ã(ç¹æ¨©ã¬ãã«3) ã®äºã¤ã®ã¢ã¼ããè¡ãæ¥ãã¾ãããã®ã¢ã¼ããåãæ¿ããã¨ãã«ãã¹ã¿ãã¯ãã¤ã³ã¿ãåãæ¿ãã = å©ç¨ããã¹ã¿ãã¯é åãåãæ¿ããã¾ããããããã¼ãã¦ã§ã¢ãèªåçã«è¡ã£ã¦ããã¦ããã®ã§ããã
ãã® x86 ã®ã¹ã¿ãã¯åãæ¿ãã®æ©è½ã«ä¼´ããå ·ä½çã«ããããã®ã¢ã¼ãã§ä½¿ãã¹ã¿ãã¯é åã®ã¢ãã¬ã¹ããã¼ãã«ç¥ãããå¿ è¦ãããã¾ãããã®ããã«ã¯ TSS (ã¿ã¹ã¯ç¶æ ã»ã°ã¡ã³ã) ã使ããã¨ã«ãªãã¾ãã
ã¨ãã㧠TSS ã¯ã¿ã¹ã¯ç¶æ ã»ã°ã¡ã³ãã®ååãããåããã¨ãããã¿ã¹ã¯ã®ç¶æ ãéé¿ãã¦ããããã®ã»ã°ã¡ã³ãã§ãããããååè¦ãã¨ãã Linux ã¯ãã¼ãã¦ã§ã¢ã³ã³ããã¹ãã®éé¿ã«ã¯ TSS ã使ç¨ãããèªå㧠task_struct ã® thread ã¡ã³ãã«ãããæ ¼ç´ãã¦ãã¾ãããã¨ã¾ããã®è¾ºããæ´ã«è¿½ã£ã¦ãã£ãçµæãçµå± Linux ã®ã¡ã¢ãªã¢ãã«ã®æ¦è¦ãææ¡ãããã¨ãã§ããã®ã§ãããã以ä¸ã«ã¾ã¨ãã¾ãã
ãªãã486 æ¬ã«å ãã¦
- 詳解 Linuxã«ã¼ã㫠第3ç
- Linuxã«ã¼ãã«2.6解èªå®¤
- Linuxã®ãã¼ãããã»ã¹ãã¿ã (UNIXMAGAZINE COLLECTION)
ã® 3 åãèªãã§èª¿ã¹ãå 容ã«ãªã£ã¦ãã¾ããã¨ããã©ããä¸è¨æ¸ç±ããã®å¼ç¨ã¨ãªãã¾ããã¾ãã主㫠i386 (not x86_64) ãåæã«æ¸ãã¾ããå¨è¾ºæ å ±ããèªåã®æ¨æ¸¬ã§æ¸ããã¨ããã«ã¯å é ã« (*) ãä»ãã¦ããã¾ãã
Linux ã®ã¡ã¢ãªã¢ãã«
x86 Linux ã¯ã»ã°ã¡ã³ãæ©æ§ã¯ã»ã¨ãã©ä½¿ãããè«çã¢ãã¬ã¹ã¨ãªãã¢ã¢ãã¬ã¹ãä¸è´ãããåºæ¬ãã©ããã¢ãã«ããæ¡ç¨ãã¦ãã¾ãã
- Linux ã§ã¯ x86 ã®ã»ã°ã¡ã³ãæ©æ§ã¯ããä¸é¨ãã使ã£ã¦ããªãã
- ãã¹ã¦ã®ã»ã°ã¡ã³ããã£ã¹ã¯ãªãã¿ã¯ãã¼ã¹ã¢ãã¬ã¹ã 0ããªãããå¤ã 0xfffffh (G ãããæå¹)
- è«çã¢ãã¬ã¹ã¨ãªãã¢ã¢ãã¬ã¹ãä¸è´ãã¦ãã â 常ã«è«çã¢ãã¬ã¹ã®ãªãã»ãããã£ã¼ã«ãããªãã¢ã¢ãã¬ã¹ã¨ä¸è´ãã
- ããããåºæ¬ãã©ããã¢ãã«ãã¨å¼ã¶
- ã¢ã¼ãã¨ã»ã°ã¡ã³ããç°ãªãçµã¨ã㦠__USER_CSã__USER_DSã__KERNEL_CSã__KERNEL_DS ã® 4 ã¤ã®ã»ã°ã¡ã³ãã®ã¿ãç¨æããã¦ãã
- (*) C è¨èªã§ã®é¢æ°å¼ã³åºãã¯åºæ¬çã«åä¸ã»ã°ã¡ã³ãéã§ã®ã¸ã£ã³ãã«å¤æããããã»ã°ã¡ã³ãéã¸ã£ã³ãã¯ããªããã¨ãããã¨
- ããã»ã¹ç©ºéã®åé¢ãã¡ã¢ãªã®ä¿è·ã¯ãã¼ã¸ã³ã°æ©æ§ãå©ç¨ãã¦å®ç¾ããã
- å ·ä½çã«ã¯? â å¾è¿°
ãªããã©ããã¢ãã«ãã
- ã¡ã¢ãªç®¡çãç°¡ç¥åãããã¨ãã§ãã (ãã¹ã¦ã®ããã»ã¹ã§åãå¤ã®ã»ã°ã¡ã³ãã¬ã¸ã¹ã¿ã使ç¨ãã¦ãåããªãã¢ã¢ãã¬ã¹ç©ºéãå ±æãããã¨ãã§ãã)
- åºç¯å²ã¢ã¼ããã¯ãã£ã¸ã®ç§»æ¤æ§ãèæ ®ã㦠(ã¢ã¼ããã¯ãã£ã«ãã£ã¦ã¯ã»ã°ã¡ã³ãæ©æ§ãéå®ããã¦ãã)
Linux 㮠GDT 㨠LDT
- åCPUãã¨ã«ã²ã¨ã¤ã® GDT ãæã¤
- åºæ¬çã«åCPUã® GDT ã®ä¸ã®ãã£ã¹ã¯ãªãã¿ã®æ§æã¯å ¨é¨ä¸ç·ã
- ç°ãªãã®ã¯ä»¥ä¸ã®ãã®
- TSS â Linux 㯠TSS ãéå®çã«ãã使ç¨ããªãã1CPU ã«ã¤ãä¸ã¤ã® TSS ã»ã°ã¡ã³ãã®ãã£ã¹ã¯ãªãã¿ã®ã¿ã GDT ã«ç»é²ãã
- CPU ãå®è¡ãã¦ããããã»ã¹ã«ä¾åãã¦ãã GDT â LDTãTLS ã®ãã£ã¹ã¯ãªãã¿
- Linux ã®ã¦ã¼ã¶ã¼ã¢ã¼ãã¢ããªã±ã¼ã·ã§ã³ã®ã»ã¨ãã©ã¯ LDT ãå©ç¨ããªã
Pentium 以éã®ãã¼ã¸ã³ã°æ©æ§ã«é¢ãã¦éè¦ãªè©±ã®ã¡ã¢
- Page Size Extension (PSE)
- Pentium ã¢ãã«ä»¥éã®æ¡å¼µãã¼ã¸ã³ã°æ©æ§ã«ã¯ãã¼ã¸ãã¬ã¼ã ã®å¤§ããã 4KB ã®ä»£ããã« 4MB ã«ããæ©è½ããã
- cr4 ã® PSE ãã©ã°ãã»ããããã¨æå¹ã«ãªã
- PDE ã®ç¬¬ 7 ãããã«ãã£ã¦ãPDE ã®æãå ããã¼ã¸ãã¼ãã«ãªã®ã 4MB ãã¼ã¸ãã¬ã¼ã ãªã®ããèå¥ã§ãããããã«ãã£ã¦ 4KB or 4MB ã®ãã¼ã¸ãã¬ã¼ã ãæ··å¨ããããã¨ãã§ããã
- 4MB ãã¼ã¸ãã¬ã¼ã ã® Pros: TLB ã®ãããçãä¸ãããã£ãã·ã¥ãã¹ãæ¸ãã/ Cons: ã¡ã¢ãªé åã®å©ç¨çãä¸ãã
- Linux ã«ã¼ãã«ã¯ 4MB ãã¼ã¸ãã¬ã¼ã ã«ç½®ããã
- Pentium ã¢ãã«ä»¥éã®æ¡å¼µãã¼ã¸ã³ã°æ©æ§ã«ã¯ãã¼ã¸ãã¬ã¼ã ã®å¤§ããã 4KB ã®ä»£ããã« 4MB ã«ããæ©è½ããã
- TLB ãã£ãã·ã¥ã®è²¼ãä»ã
- Pentium Pro 以éã® PTE ã«ã¯ Global ãã©ã°ã¨ãããã£ã¼ã«ããããããã®ãã©ã°ãå©ç¨ããã¨ãã®ãã¼ã¸ãã¼ãã«ã TLB ãã追ãåºãããã®ãé²ããã¨ãã§ããã
- å©ç¨ã®ããã«ã¯ cr4 ã® PGE ãã©ã°ã« 1 ãç«ã¦ããã¨
- (*) invlpg å½ä»¤ã®ãã¨ããª?
- PAE (Physical Address Extension)
- Pentium Pro 以éã¯ã¢ãã¬ã¹ãã¹ã 36æ¬ ã«å¢ãã¦ããã â 2^36 = 64GB ã®ã¡ã¢ãªãã¢ãã¬ã¹ä»ãã§ãã
- 32 ããã CPU 㧠36 ãããã¢ãã¬ã¹ãã¹ãå©ç¨ããã«ã¯ã32 ããããªãã¢ã¢ãã¬ã¹ã 36 ãããç©çã¢ãã¬ã¹ã«å¤æããæ°ãããã¼ã¸ã³ã°æ©æ§ãå¿ è¦ã ã£ããããã PAEã
- å¾æ¥ã®ãã¼ã¸ã³ã°æ©æ§ã®ãã¼ã¸ãã£ã¬ã¯ããªããã¼ã¸ãã¼ãã«ã«å ãã¦ãã¼ã¸ãã£ã¬ã¯ããªãã¤ã³ã¿ãã¼ãã« (PDPT) ã¨ããé層ã追å ã
- PAE ã§ã¯ 64 ãããã®ç©çã¡ã¢ãªã¸ã®ãããã³ã°ãå¯è½ã«ãªããããªãã¢ã¢ãã¬ã¹ã¯ç¸å¤ããã 32 ãããã®ã¾ã¾ããã£ã¦ç©çã¢ãã¬ã¹ã®ã¿ãæ¡å¼µãããããã»ã¹ã®ãªãã¢ã¢ãã¬ã¹ç©ºéã¯æ¡å¼µãããªããã¤ã¾ã OS 㯠64GB ã®ã¡ã¢ãªãæ±ãããããã»ã¹ãããã®æ大ã¡ã¢ãªç©ºé㯠4GBã
- (*) ãã¾ã©ã㯠x86_64 ã使ãã®ã§ããå¤ã話é¡ã§ããããã¾ã§ 32 ãããæ代ã§ã®ã
Linux ã®ãã¼ã¸ã³ã°ã¢ãã«
- 32ããã PAE ç¡å¹/æå¹ã64 ããããªã©ã«é¢ããããã¹ã¦å ±éã®ãã¼ã¸ã³ã°æ©æ§ãå©ç¨ãæ±ç¨çãªãã¼ã¸ã³ã°ã¢ãã«ã
- 4é層5åå²ã§ãªãã¢ã¢ãã¬ã¹ãæ±ã
- ãã¼ã¸ã°ãã¼ãã«ãã£ã¬ã¯ããªããã¼ã¸ã¢ããã¼ãã£ã¬ã¯ããªããã¼ã¸ããã«ãã£ã¬ã¯ããªããã¼ã¸ãã¼ãã«
- PAE ãªã 32 ãããã®å ´åã¢ããã¼ãããã«ãå®è³ªã¢ãã¬ã¹å¤æããåãé¤ãããã¼ãã¦ã§ã¢ã®ãã¼ã¸ã³ã°æ©æ§ã®ããã¨ã»ã¼åä¸ã®å¯¾å¿ãè¡ã
Linux ã®ããã»ã¹ç©ºéåãæ¿ã (ï¼ ãã¼ã¸ã°ãã¼ãã«ãã£ã¹ã¯ãªãã¿ã®åãæ¿ã)
ãããã»ã°ã¡ã³ãæ©æ§ã使ããã«ãã©ããã¡ã¢ãªã¢ãã«ã§ããã»ã¹ç©ºéã®åãæ¿ããè¡ã£ã¦ããããããã©ã©ããã£ã¦ããã®ãããã®åçã«ãªãã¾ãã
- Linux ã¯ãã©ããã¡ã¢ãªã¢ãã«ã§ãããã»ã¹ç©ºéã®åãæ¿ãã¯ããã»ã¹æ¯ã«ãã¼ã¸ãã£ã¬ã¯ããªãåãæ¿ãããã¨ã«ããå®ç¾ãããã
- ãã®ãã¼ã¸ãã£ã¬ã¯ããªã®ãã¨ããã¼ã¸ã°ãã¼ãã«ãã£ã¬ã¯ããªã¨å¼ã¶ã(*) PAE ã¨ããããã¨ãã¼ã¸ã³ã°ã¢ãã«ã®ãããé層ãå¿ ããããã¼ã¸ãã£ã¬ã¯ããªã§ã¯ãªãã£ããããã®ã§ããã®ããã«ã°ãã¼ãã«ã¨æ¢ãã¦å¼ãã§ããã®ããªã
- å©ç¨ä¸ã®ãã¼ã¸ãã£ã¬ã¯ããªã¯ cr3 ã®å¶å¾¡ã¬ã¸ã¹ã¿ã«ãã£ã¦ãã®å é ã¢ãã¬ã¹ãæå®ããã¦ãã
- cr3 ãå¥ã®ãã¼ã¸ãã£ã¬ã¯ããªã«åãæ¿ãã = ããã»ã¹ç©ºéã®åãæ¿ãã«ç¸å½
- cr3 ã®å¶å¾¡ã¬ã¸ã¹ã¿ãæ´æ°ããå ´åããã¼ãã¦ã§ã¢ã TLB ãèªåçã«ãã©ãã·ã¥ãã (ãã®å¦çãé«ã³ã¹ã)
- ãã ããTLB ç¡å¹åãçç¥ããå ´åããã
- åããã¼ã¸ãã¼ãã«ã®çµã使ç¨ãã¦ãã2ã¤ã®é常ããã»ã¹éã§ãããã»ã¹åãæ¿ããè¡ãå ´å â ã¹ã¬ããã®åãæ¿ã
- ã¤ã¾ãããã«ãã¹ã¬ããã®å®è¡ã³ã³ããã¹ãåãæ¿ãã®é㯠TLB ããã©ãã·ã¥ãããªãã®ã§ããã»ã¹ã«ããè¤æ°å®è¡ã³ã³ããã¹ããããã³ã¹ããä½ãæ¸ãã
- é常ããã»ã¹ã¨ã«ã¼ãã«ã¹ã¬ããéã§ã®ããã»ã¹åãæ¿ã
- ã«ã¼ãã«ããã»ã¹ã¯åºæã®ãã¼ã¸ãã¼ãã«ãæãããç´åã«ãã® CPU ä¸ã§åä½ãã¦ããé常ããã»ã¹ã®ãã¼ã¸ãã¼ãã«ããã®ã¾ã¾ä½¿ç¨ãã
- åããã¼ã¸ãã¼ãã«ã®çµã使ç¨ãã¦ãã2ã¤ã®é常ããã»ã¹éã§ãããã»ã¹åãæ¿ããè¡ãå ´å â ã¹ã¬ããã®åãæ¿ã
- ãã ããTLB ç¡å¹åãçç¥ããå ´åããã
- ããã»ã¹ç©ºéã管çããã«ã¼ãã«å
é¨ã§ã®å¶å¾¡è¡¨ã mm_struct æ§é ä½ãtask_struct æ§é ä½ãããªã³ã¯ãããã
- mm_struct æ§é ä½ã«ã¯ pgd ã¡ã³ãããããããããã®ããã»ã¹ã®ãã¼ã¸ã°ãã¼ãã«ãã£ã¬ã¯ããªã®å ´æãä¿æãã¦ãã
- ãã® pgd ã¡ã³ãã®å¤ã cr3 ã«èªã¿è¾¼ããã¨ã§ããã»ã¹ç©ºéã®åãæ¿ããè¡ãããã
context_switch() ããå¼ã°ãã switch_mm ãä¸è¨ã®å¦çããã£ã¦ããç®æã«ãªãã¾ãã
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) { int cpu = smp_processor_id(); if (likely(prev != next)) { /* stop flush ipis for the previous mm */ cpu_clear(cpu, prev->cpu_vm_mask); #ifdef CONFIG_SMP per_cpu(cpu_tlbstate, cpu).state = TLBSTATE_OK; per_cpu(cpu_tlbstate, cpu).active_mm = next; #endif cpu_set(cpu, next->cpu_vm_mask); /* Re-load page tables */ load_cr3(next->pgd); /* * load the LDT, if the LDT is different: */ if (unlikely(prev->context.ldt != next->context.ldt)) load_LDT_nolock(&next->context); } #ifdef CONFIG_SMP else { per_cpu(cpu_tlbstate, cpu).state = TLBSTATE_OK; BUG_ON(per_cpu(cpu_tlbstate, cpu).active_mm != next); if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) { /* We were in lazy tlb mode and leave_mm disabled * tlb flush IPI delivery. We must reload %cr3. */ load_cr3(next->pgd); load_LDT_nolock(&next->context); } } #endif }
prev != nextãã¤ã¾ãç°ãªãã¡ã¢ãªç©ºéã ã£ãå ´å㯠load_cr3(next->pgd) 㧠cr3 ã®å¤ã次ã®ããã»ã¹ã®ãã¼ã¸ãã£ã¬ã¯ã㪠next->pgd ã«å¤æ´ãã¦ããã»ã¹ç©ºéåãæ¿ããè¡ã£ã¦ããã®ãåããã¾ããããã
ã«ã¼ãã«ã¹ã¿ãã¯ã¨ã¯
ãããããããã®çåã®ã«ã¼ãã«ã¹ã¿ãã¯ã£ã¦ä½ããã¨ãããããããã¾ã TSS ãéå®çã«ä½¿ã£ã¦ãã®ã¯ä½ã§ãã®åçãããã«ããã¾ãã
- Linux ã«ã¼ãã«ã¯å²ãè¾¼ã¿ã¹ã¿ãã¯ãç¨æãã¦ããªãã¨ããå®è£ ä¸ã®ç¹å¾´ãããã
- Linux ã«ã¼ãã«ã§ã¯ãå²ãè¾¼ã¿ãçºçããã¨ããã®æç¹ã§å®è¡ä¸ã®ã«ã¬ã³ãããã»ã¹ã®ã«ã¼ãã«ã¹ã¿ãã¯ãå©ç¨ãã¦åä½ããã
- åããã»ã¹ã«ã¯1ã¤ã®ã¡ã¢ãªé åãå²ãå½ã¦ããããã®ã¡ã¢ãªé å 8,192 ãã¤ãã« thread_info æ§é ä½ã¨ã«ã¼ãã«ã¢ã¼ãããã»ã¹ã¹ã¿ãã¯ãå²ãä»ããã
union thread_union { struct thread_info thread_info; unsigned long stack[THREAD_SIZE/sizeof(long)]; };
- x86 ã«ã¯ç¹æ¨©ã¬ãã«ç§»è¡ã¨é£åãã¦ã¹ã¿ãã¯ãã¤ã³ã¿ãèªåçã«åãæ¿ããä»çµã¿ãããã
- ç¹æ¨©ã¬ãã«ã®ç§»è¡ â å²ãè¾¼ã¿ãä¾å¤çºçãã³ã¼ã«ã²ã¼ãå¼ã³ã ãæãªã©ã«ã
- GDT ã«ç»é²ãã TSS ã«ãåç¹æ¨©ã¬ãã« (0ã3) ã«å¯¾å¿ãã ss 㨠esp ã®å¤ãæå®ããç®æããããx86 ã¯ç¹æ¨©ã¢ã¼ãåæ¿æã«ããã®æç¹ã§æå¹ãª TSS (Linux ã®å ´åã¯å CPU ã« TSS 㯠1 ã¤ã®ã¿ããªã®ã§ãã) ã®è©²å½ç¹æ¨©ã¢ã¼ãã«å¯¾å¿ãã ss:esp ãèªã¿è¾¼ãã§ã¹ã¿ãã¯ãåãæ¿ããã
- Linux ã¯ç¹æ¨©ã¢ã¼ã 0 ã¾ã㯠3 (Xen 使ç¨æ㯠1 ã使ãããã) ãã¦ã¼ã¶ã¼ã¢ã¼ãããã»ã¹ â ã«ã¼ãã«ã¢ã¼ãã¸ã®ã¢ã¼ã移è¡æã«ã¯ ss0:esp0 ãã¬ã¸ã¹ã¿ã«èªã¿è¾¼ã¾ããã
- ãã® ss0ãesp0 ã«å ã®ã«ã¼ãã«ããã»ã¹ã¹ã¿ãã¯ã®ã¢ãã¬ã¹ãæå®ãããã¨ã§ãå²ãè¾¼ã¿çºçæã«ã¹ã¿ãã¯ãã¦ã¼ã¶ã¼ããã»ã¹ã¹ã¿ãã¯ããã«ã¼ãã«ã¹ã¿ãã¯ã¸åãæ¿ãã
Linux ã§ã¯ TSS 㯠tss_struct æ§é ä½ã«ãã£ã¦è¡¨ç¾ããã¾ããinclude/asm-i386/processor.h ã« tss_struct ã®å®ç¾©ãããã¾ãã
struct tss_struct { unsigned short back_link,__blh; unsigned long esp0; unsigned short ss0,__ss0h; ... } __attribute__((packed));
ãããã« esp0 ã ss0 ã¡ã³ããããã¾ãããããã«å ã®ã«ã¼ãã«ã¹ã¿ãã¯ã®ã¢ãã¬ã¹ãå ¥ãã¦ããã°ãç¹æ¨©ã¢ã¼ãåæ¿æã«èªåã§ãã®ã¹ã¿ãã¯ã«åãæ¿ããã¨ããä»çµã¿ããã£ãã®ã§ããã
ã¨ããã§ããããã TSS ã¯ã¿ã¹ã¯åãæ¿ãæã«ãã¼ãã¦ã§ã¢ã³ã³ããã¹ããéé¿ããããã®ã»ã°ã¡ã³ãã§ãããåã®ã¨ã³ããªã§è¦ãããã« Linux ã¯ã³ã³ããã¹ãã¹ã¤ããã¯èªåã§è¡ã£ã¦ãã¦ãTSS ã«ããã¿ã¹ã¯ã²ã¼ããªã©ã¯å©ç¨ãã¾ããããã
- x86 ã®ã¹ã¿ãã¯åãæ¿ãã®æ©è½
- I/O ãã¼ããã·ã§ã³ããããããã®åç §
ã® 2 ã¤ã®ç®çã«ã®ã¿ TSS ãå©ç¨ããã¾ããåè ãããã§è§£èª¬ããã¹ã¿ãã¯åãæ¿ãã®è©±ãè¦ã¯ã»ã¼èªåã§ãã£ã¦ã¦ TSS ã®ã³ã¢ã¯è¦ããªããã ãã©ãä¸é¨å¿ è¦ãªãã¼ãã¦ã§ã¢ã®æ©è½ãå©ç¨ããããã®ã¤ã³ã¿ãã§ã¼ã¹ã¨ã㦠TSS ãä»ããã®ã§ããã®ããã«ç¨æãã¦ãããã¨ãããã¨ãªãã§ãããã
Linux ã®ã·ã¹ãã ã³ã¼ã«
確ãã«ç¹æ¨©ã¢ã¼ã移è¡æã«ã¹ã¿ãã¯ãåãæ¿ããã¾ãããããã§ä¸ã¤çæç¹ãã·ã¹ãã ã³ã¼ã«å¼ã³åºã(ã½ããã¦ã§ã¢å²ãè¾¼ã¿çºç â ç¹æ¨©ã¢ã¼ãåãæ¿ããä¼´ã)ã®å¼æ°ãã©ã渡ãããããã¨ããã¨ããã
- ç¹æ¨©ã¢ã¼ããåãæ¿ããéã«ã¹ã¿ãã¯ãã«ã¼ãã«ã¹ã¿ãã¯ã«åãæ¿ããã¨ãã·ã¹ãã ã³ã¼ã«å¼ã³ã ãæã«ãã¹ã¿ãã¯ãåãæ¿ãããã¨ã«ãªã
- å¾ã£ã¦ã¦ã¼ã¶ã¼ã¢ã¼ãã®ã¹ã¿ãã¯ã«ã·ã¹ãã ã³ã¼ã«ã®å¼æ°ãç©ãã§ããã«ã¼ãã«ããã¯ç´æ¥ãããåãåºããã¨ãã§ããªãã
- ãã®ãããã·ã¹ãã ã³ã¼ã«ã¸ã®å¼æ°ã¯ã¬ã¸ã¹ã¿çµç±ã§æ¸¡ããã
- eflags, cs, eip, ss, esp ã¯ãã¼ãã¦ã§ã¢ã«ãã£ã¦ä¾å¤(å²ãè¾¼ã¿) çºçæã«ã«ã¼ãã«ã¹ã¿ãã¯ä¸ã«éé¿ããã
- system_call() ããã³ sysenter_entry() é¢æ°ã¯ SAVE_ALL ãã¯ãã«ããæ±ç¨ã¬ã¸ã¹ã¿ããã³ gs, es, ds, ebp çãã«ã¼ãã«ã¹ã¿ãã¯ã«ç©ã
- ã·ã¹ãã ã³ã¼ã«ã¸ã®å¼æ°ã¯ ebxãecxãedxãesiãediãebp ã® 6 ã¤ã®ã¬ã¸ã¹ã¿ã«ãã£ã¦æ¸¡ããããã®ã§ãããããããã®å¼æ°ãåãåºãã¦å¦çãã
- ãªããLinux ã®ã·ã¹ãã ã³ã¼ã«ã¯ int 0x80 ã®ã½ããã¦ã§ã¢å²ãè¾¼ã¿ã¾ã㯠sysenter å½ä»¤ã«ãã£ã¦å®ç¾ããã¦ãããã³ã¼ã«ã²ã¼ãã¯ä½¿ããã¦ããªã
- ã¾ãã¬ã¸ã¹ã¿çµç±ã§å¼æ°ã渡ãã®ã§ãã²ã¼ããã£ã¹ã¯ãªãã¿ã®ã³ãã¼ã«ã¦ã³ããå©ç¨ããªã
- ãã®æ¹æ³ã§ã¦ã¼ã¶ã¼ã¢ã¼ãããã®å¼æ°æ¸¡ããå®ç¾ãããã¨ã§ãã·ã¹ãã ã³ã¼ã«ãã³ãã©ãã»ãã®ä¾å¤ãã³ãã©ã¨åããããªæ§é ã«ã§ããã¨ããå©ç¹ãå¾ãããã
SAVE_ALL ãã¯ãã¯ä»¥ä¸ã§ããarch/i386/kernel/entry.S ããã
#define SAVE_ALL \ cld; \ pushl %gs; \ CFI_ADJUST_CFA_OFFSET 4;\ /*CFI_REL_OFFSET gs, 0;*/\ pushl %es; \ CFI_ADJUST_CFA_OFFSET 4;\ /*CFI_REL_OFFSET es, 0;*/\ pushl %ds; \ CFI_ADJUST_CFA_OFFSET 4;\ /*CFI_REL_OFFSET ds, 0;*/\ pushl %eax; \ CFI_ADJUST_CFA_OFFSET 4;\ CFI_REL_OFFSET eax, 0;\ pushl %ebp; \ CFI_ADJUST_CFA_OFFSET 4;\ CFI_REL_OFFSET ebp, 0;\ pushl %edi; \ CFI_ADJUST_CFA_OFFSET 4;\ CFI_REL_OFFSET edi, 0;\ pushl %esi; \ CFI_ADJUST_CFA_OFFSET 4;\ CFI_REL_OFFSET esi, 0;\ pushl %edx; \ CFI_ADJUST_CFA_OFFSET 4;\ CFI_REL_OFFSET edx, 0;\ pushl %ecx; \ CFI_ADJUST_CFA_OFFSET 4;\ CFI_REL_OFFSET ecx, 0;\ pushl %ebx; \ CFI_ADJUST_CFA_OFFSET 4;\ CFI_REL_OFFSET ebx, 0;\ movl $(__USER_DS), %edx; \ movl %edx, %ds; \ movl %edx, %es; \ movl $(__KERNEL_PDA), %edx; \ movl %edx, %gs
ã¾ã¨ããã¨ãã¹ã¿ãã¯ãåãæ¿ããã®ã¯ãããã©å ´åã«ãã£ã¦ã¯ã¦ã¼ã¶ã¢ã¼ãããã«ã¼ãã«ã¢ã¼ãã«å¤ã渡ããªãããããªããã§ãããã¯é常ã®é¢æ°å¼ã³åºãã®ããã«åã«ã¹ã¿ãã¯ã«ç©ãã§æ¸¡ããã¨ããã®ã¯ã§ããªãããã¬ã¸ã¹ã¿ãçµç±ããã¾ãããã¨ãã話ã§ããã
ã¾ã¨ã
- ã«ã¼ãã«ããã»ã¹ã¹ã¿ãã¯ã¨ã¯ä½ãããã¨ããã¨ãããã追ã£ã¦ãã£ã¦ Linux ã®ã¡ã¢ãªã¢ãã«ãããã¼ã¸ã³ã°æ©æ§ãå©ç¨ããããã»ã¹ç©ºéã®åãæ¿ããªã©ãè¦ã¦ã¿ã¾ããã
- Linux ã¯ãã©ããã¢ãã«ã§ãããã»ã¹ç©ºéã®åãæ¿ãã¯ãã¼ã¸ã°ãã¼ãã«ãã£ã¬ã¯ããªã®åãæ¿ã (cr3 å¶å¾¡ã¬ã¸ã¹ã¿ã®æ´æ°) ã«ãã£ã¦å®ç¾ããã¦ãã¾ãã
- ç¹æ¨©ã¢ã¼ã移è¡æã«ã¹ã¿ãã¯ãã«ã¼ãã«ã¹ã¿ãã¯ã«åãæ¿ããã¾ããx86 㯠TSS ãã¤ã³ã¿ãã§ã¼ã¹ã«ãã®åãæ¿ããèªåã§è¡ãã¾ãããã¼ãã¦ã§ã¢ã³ã³ããã¹ãã§ã¬ã¸ã¹ã¿ã®å¤ãéé¿ãã¦ããå ã®æ£ä½ã¯ãã®åãæ¿ãã£ãå¾ã®ã¹ã¿ãã¯ã§ããã㯠task_struct æ§é ä½ãããªã³ã¯ãããç®æãã¤ã¾ãå®è¡ã³ã³ããã¹ãã®ä¸ã«ããã¾ããã
- ååã®ãã¼ãã¦ã§ã¢ã³ã³ããã¹ãã®éé¿/復帰ã¨ä½µããã¨ã³ã³ããã¹ãã¹ã¤ããä¸ã®ä¸»è¦å¦ç (1) ããã»ã¹ç©ºéã®åãæ¿ã (2) ãã¼ãã¦ã§ã¢ã³ã³ããã¹ãã®åãæ¿ãã®ä¸¡æ¹ãè¦ããã¨ã«ãªãã¾ãã
- ã»ã°ã¡ã³ãæ©æ§ã使ã£ã¦ããªããTSS ã LDT ãéå®çã«ãã使ã£ã¦ããªããªã©ããã¼ãã¦ã§ã¢ã®æ©è½ã使ããã«èªåã§å®è£ ãã¦ããç®æãè²ã ããã¾ãããUNIX OS ã®è¨è¨ã®åºæ¬æ¹éã移æ¤æ§ããã¼ãã¦ã§ã¢ã®æ©æ§ãä½ãããæ代èæ¯ãªã©ã絡ã¿åã£ãçµæãã¨æããã¾ãã
- éä¸ããªããã«ãã¹ã¬ããããã«ãããã»ã¹ãããã³ã³ããã¹ãã¹ã¤ããã®è² è·ãä½ãããã®çç±ãå£éè¦ãããããã¾ããã
åèæç®
- ã¯ããã¦èªã486â32ãããã³ã³ãã¥ã¼ã¿ãããããèªã
- 詳解 Linuxã«ã¼ã㫠第3ç
- Linuxã«ã¼ãã«2.6解èªå®¤
- Linuxã®ãã¼ãããã»ã¹ãã¿ã (UNIXMAGAZINE COLLECTION)
ã¯ããã¦èªã486â32ãããã³ã³ãã¥ã¼ã¿ãããããèªã ã¯æ¹ã ã§èãã¦ããã¨ããã¨ã¦ãè¯ãæ¸ç±ã§ããããå®ã¯æåã«èªãã ã¨ãã¯ã¡ãã£ã¨é£ããã¦æ«æãã¾ããã
- ã¯ããã¦èªã8086â16ãããã»ã³ã³ãã¥ã¼ã¿ãããããèªã (ã¢ã¹ãã¼ããã¯ã¹)
- ã¯ããã¦èªãMASMâã½ããã¦ã§ã¢ç°å¢ã®ãããããå¦ã¶
ã¨äºåãèªãã§ããæ¹ã㦠486 æ¬ãèªãã§ã¿ãããæå¾ã¾ã§æ«æããã«èªããã¨ãã§ãã¾ãããã¾ã 486 æ¬ã¯å°ã㪠OS ã®ã³ã¢ãåç¾ãããããªã³ã¼ããä¼´ã£ãå ·ä½çãªæ¬ã§ã¯ãããã®ã®ãã§ã¯ãããå®ç¨ç㪠OS ã§ã¯ã©ããªã£ã¦ããã®ãã¾ã§ãã¤ããã®ã«ãLinux ã«ã¼ãã«ã®æ¬ãä½µãã¦èªãã¨ããã®ã¯ã¨ã¦ãããæ¹æ³ã§ã¯ãªããã¨æãã¾ãããOS ã®æç§æ¸ãããã¾ã§è±å¯ãè¯ãæ代ã§ããã