· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
Unreliable Guide To Hacking The Linux Kernel

Unreliable Guide To Hacking The Linux Kernel


ÀúÀÚ : Paul Rusty Russell <rusty@rustcorp.com.au>

¹ø¿ª : ±è³²Çü <pastime@ece.uos.ac.kr>


ÀÌ ¹®¼­´Â ÀÚÀ¯ ¼ÒÇÁÆ®¿þ¾îÀÌ´Ù; ´ç½ÅÀº Free Software Foundation ¿¡¼­ ¹ßÇ¥ÇÑ GNU General Public License ÇÏ¿¡ ÀÌ ¹®¼­¸¦ ¼öÁ¤Çϰųª Àç¹èÆ÷ÇÒ ¼ö ÀÖ´Ù; License ¹öÀü 2 ȤÀº (´ç½ÅÀÌ ¿øÇÑ´Ù¸é) ±× ÀÌÈÄÀÇ ¹öÀüÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù.

À¯¿ëÇÏ°Ô ÀÌ¿ëµÇ±â¸¦ ¹Ù¶ó´Â ¸¶À½¿¡¼­ ÀÌ ¹®¼­¸¦ ¹èÆ÷ÇÏÁö¸¸, ¿©±â¿¡¼­ ´ëÇÑ ¾î¶°ÇÑ Ã¥ÀÓµµ ÁöÁö ¾ÊÀ½À» ¹àÇôµÐ´Ù; »ó¾÷ÀûÀ̳ª ƯÁ¤ÇÑ ¸ñÀû¿¡ µû¶ó ÀÌ¿ëÇÏ´Â °æ¿ì¿¡µµ ÀÌ ¹®¼­¿¡ ÀÇÇØ ¹ß»ýÇÏ´Â ¹®Á¦¿¡ ´ëÇØ ¾î¶°ÇÑ Ã¥ÀÓµµ ¹°À»¼ö ¾ø´Ù. ´õ ÀÚ¼¼ÇÑ ³»¿ëÀº GNU General Public License ¹®¼­¸¦ »ìÆ캸±â ¹Ù¶õ´Ù.

GNU General Public License ¹®¼­¸¦ ¹Þ¾Æº¸±â¸¦ ¿øÇÑ´Ù¸é Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 03111-1307 USA ·Î ½ÅûÇϱ⠹ٶõ´Ù.

´õ ÀÚ¼¼ÇÑ »çÇ×Àº Linux ¼Ò½º ¹èÆ÷ÆÇÀÇ COPYING ÆÄÀÏ¿¡ ÀûÇôÀÖ´Ù.




Contents

1. ¼Ò°³
2. µ¿ÀÛ ¸ðµå (the Players)
2.1. User Context
2.2. Çϵå¿þ¾î ÀÎÅÍ·´Æ® (Hard IRQs)
2.3. ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ® (Bottom Halves, Tasklets, softirqs)
3. ±âº»ÀûÀÎ °³³äµé
4. ioctls: »õ·Î¿î ½Ã½ºÅÛ ÄÝÀ» Ãß°¡ÇÏÁö ¾Ê´Â ¹æ¹ý
5. Deadlock 󸮹ý
6. °øÅë ·çƾ
6.1. printk() <include/linux/kernel.h>
6.2. copy_to/from_user()/get/put_user() <include/asm/uaccess.h>
6.3. kmalloc()/kfree() <include/linux/slab.h>
6.4. current <include/asm/current.h>
6.5. udelay()/mdelay() <include/asm/delay.h> / <include/linux/delay.h>
6.6. cpu_to_be/le32()/be/le32_to_cpu() <include/linux/byteorder/*.h>
6.7. local_irq_save/restore() <include/asm/system.h>
6.8. local_bh_disable/enable() <include/asm/softirq.h>
6.9. smp_processor_id()/cpu_number/logical_map() <include/asm/smp.h>
6.10. init/exit/__initdata <include/linux/init.h>
6.11. __initcall()/modult_init() <include/linux/init.h>
6.12. module_exit() <include/linux/init.h>
6.13. MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT <include/linux/module.h>
7. ´ë±â Å¥ (Wait Queues) <include/linux/wait.h>
7.1. ¼±¾ðÇϱâ
7.2. Å¥¿¡ ³Ö±â
7.3. Å¥¿¡ µé¾îÀִ ŽºÅ© ±ú¿ì±â
8. ¿øÀÚÀû ¿¬»ê
9. ½Éº¼
9.1. EXPORT_SYMBOL() <include/linux/module.h>
9.2. EXPORT_NO_SYMBOLS <include/linux/module.h>
9.3. EXPORT_SYMBOL_GPL() <include/linux/module.h>
10. Routines and Conventions
10.1. Doubly-Linked Lists <include/linux/list.h>
10.2. ¸®ÅÏ°ª¿¡ ´ëÇÑ ÀüÅë
10.3. Breaking Compilation
10.4. ±¸Á¶Ã¼ º¯¼ö ÃʱâÈ­
10.5. GNU È®Àå
10.6. C++
10.7. #if
11. ´ç½ÅÀÇ Äڵ带 Ä¿³Î³»¿¡ ³Ö´Â ¹æ¹ý
12. Kernel Cantrips
13. °¨»çÀÇ ±Û


1. ¼Ò°³


Rusty ÀÇ Unreliable Guide to Linux Kernel Hacking ¹®¼­¸¦ Àаí ÀÖ´Â ¿©·¯ºÐÀ» ȯ¿µÇÑ´Ù. ÀÌ ¹®¼­´Â Ä¿³Î Äڵ忡¼­ »ç¿ëµÇ´Â °øÅëÀûÀÎ ·çƾµé°ú ÀϹÝÀûÀÎ ¿ä±¸»çÇ×µéÀ» ¼³¸íÇÏ°í ÀÖ´Ù: ÀÌ ¹®¼­ÀÇ ¸ñÀûÀº ¼÷·ÃµÈ C ÇÁ·Î±×·¡¸Óµé¿¡°Ô ¸®´ª½º Ä¿³Î °³¹ß¿¡ ´ëÇÑ ÀÔ¹®¼­·Î¼­ »ç¿ëµÇ°íÀÚ ÇÏ´Â °ÍÀÌ´Ù. ÀÌ ¹®¼­¿¡¼­´Â ±¸Ã¼ÀûÀÎ ±¸Çö¿¡ °üÇÑ ºÎºÐÀº ´Ù·çÁö ¾Ê´Â´Ù

ÀÌ ¹®¼­¸¦ Àбâ Àü¿¡, ÇÑ°¡Áö »ç½ÇÀ» ÀÌÇØÇØ Áֱ⠹ٶõ´Ù. »ç½Ç °³ÀÎÀûÀ¸·Î ³ª´Â ÀüüÀûÀ¸·Î ¸¸Á·½º·´Áö ¸øÇÑ ¼öÁØÀÇ ÀÌ ¹®¼­¸¦ ÀÛ¼ºÇÏ°í ½ÍÁö ¾Ê¾Ò¾ú´Ù. ÇÏÁö¸¸ Ç×»ó ÀÌ·¯ÇÑ ¹®¼­¸¦ Àаí´Â ½Í¾ú±â ¶§¹®¿¡ ¾î¿¼ö ¾øÀÌ? ÀÌ·¸°Ô ÀÛ¼ºÇÏ°Ô µÇ¾ú´Ù. ÀÌ ¹®¼­°¡ ÈǸ¢ÇÑ ¿ä¾à¼­ ȤÀº Ä¿³Î¿¡ ´ëÇÑ ÀϹÝÀûÀÎ ½ÃÀÛÁ¡À̳ª ÀÓÀÇÀÇ Á¤º¸¸¦ Á¦°øÇÒ ¼ö ÀÖ´Â ÁÁÀº ¹®¼­·Î ¹ßÀüÇØ °¡±â¸¦ ¹Ù¶õ´Ù.


2. µ¿ÀÛ ¸ðµå (the Players)


ƯÁ¤ÇÑ ¼ø°£¿¡ ½Ã½ºÅÛ »óÀÇ CPU ´Â ´ÙÀ½°ú °°Àº »óÅ ÁßÀÇ Çϳª°¡ µÈ´Ù:

  • ƯÁ¤ ÇÁ·Î¼¼½º¿¡ ¿¬°üµÇÁö ¾ÊÀº, Çϵå¿þ¾î ÀÎÅÍ·´Æ® ó¸®
  • ƯÁ¤ ÇÁ·Î¼¼½º¿¡ ¿¬°üµÇÁö ¾ÊÀº, ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ® (softirq, tasklet, bh) ó¸®
  • ƯÁ¤ ÇÁ·Î¼¼½º¿¡ ¿¬°üµÇ¾î Ä¿³Î ¸ðµå¿¡¼­ µ¿ÀÛ
  • »ç¿ëÀÚ ¸ðµå¿¡¼­ ƯÁ¤ ÇÁ·Î¼¼½º ¼öÇà

À§ÀÇ ¸®½ºÆ®´Â °¢°¢ÀÌ ¾ö°ÝÇÑ ¿ì¼±¼øÀ§¸¦ °¡Áø´Ù: ¸¶Áö¸·ÀÇ »óÅ (»ç¿ëÀÚ ¸ðµå) ¸¦ Á¦¿ÜÇÑ ´Ù¸¥ »óŵéÀº ¿ÀÁ÷ Àڽź¸´Ù »óÀ§¿¡ ÀÖ´Â »óÅ¿¡ ÀÇÇØ ¼±Á¡µÉ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, softirq °¡ CPU ¿¡¼­ ¼öÇàµÇ°í ÀÖ´Â µ¿¾È ´Ù¸¥ softirq ´Â À̸¦ ¼±Á¡ÇÒ ¼ö ¾øÁö¸¸ Çϵå¿þ¾î ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇÏ¸é ¼±Á¡µÈ´Ù. ÇÏÁö¸¸ ½Ã½ºÅÛ³»ÀÇ ´Ù¸¥ CPU µéÀº µ¶¸³ÀûÀ¸·Î ¼öÇàµÈ´Ù.

¾ÕÀ¸·Î user context [1] ¿¡¼­ ½ÇÁ¦ÀûÀÎ ºñ¼±Á¡¼ºÀ» °¡Áö±â À§ÇØ ÀÎÅÍ·´Æ®¸¦ ¸·¾ÆµÎ´Â ¹æ¹ýµéÀ» »ìÆ캼 °ÍÀÌ´Ù.


2.1. User Context


user context ´Â ½Ã½ºÅÛ ÄÝÀ̳ª ´Ù¸¥ Æ®·¦ µî¿¡ ÀÇÇؼ­ ÁøÀÔÇÑ Äڵ带 ¸»ÇÑ´Ù: ¿©±â¿¡¼­´Â sleep À» ÇÒ ¼ö ÀÖ°í (ÀÎÅÍ·´Æ®¸¦ Á¦¿ÜÇϸé) schedule() ÇÔ¼ö¸¦ È£ÃâÇϱâ Àü±îÁö CPU ¸¦ ¼ÒÀ¯ÇÏ°Ô µÈ´Ù. ´Ù½Ã ¸»Çϸé, user context ´Â (»ç¿ëÀÚ ¸ðµå¿Í ´Þ¸®) ºñ¼±Á¡¼ºÀ» °¡Áø´Ù.

(!) Âü°í: ¸ðµâÀ» ·ÎµùÇϰųª ¾ð·ÎµùÇÒ ¶§, ±×¸®°í ºí·Ï µð¹ÙÀ̽º µå¶óÀ̹ö¿¡ ´ëÇÑ ¿¬»êÀ» ¼öÇàÇÏ´Â °æ¿ì¿¡´Â Ç×»ó user context ¿¡ ÀÖ´Â °ÍÀÌ´Ù.

user context »ó¿¡¼­´Â (ÇöÀç ¼öÇàÁßÀΠŽºÅ©¸¦ °¡¸®Å°´Â) current Æ÷ÀÎÅ͸¦ ÀÌ¿ëÇÒ ¼ö ÀÖ°í, in_interrupt() ¸ÅÅ©·Î (include/asm/hardirq.h) ´Â °ÅÁþÀ» ¸®ÅÏÇÑ´Ù.

/!\ ÁÖÀÇ: ÀÎÅÍ·´Æ® ȤÀº ÇϹݺΠÇڵ鷯°¡ ÀÌ¹Ì ºñÈ°¼ºÈ­ µÇ¾îÀÖ´Â °æ¿ì¿¡µµ, in_interrupt() ¸ÅÅ©·Î°¡ ¹«Á¶°Ç °ÅÁþÀ» ¸®ÅÏÇÑ´Ù´Â °ÍÀ» ¿°µÎ¿¡ µÎÀÚ.


2.2. Çϵå¿þ¾î ÀÎÅÍ·´Æ® (Hard IRQs)


ŸÀÌ¸Ó Æ½, ³×Æ®¿öÅ© Ä«µå, Å°º¸µå¿Í °°Àº °ÍµéÀº ¾î¶² ¼ø°£¿¡µµ ÀÎÅÍ·´Æ®¸¦ ¹ß»ý½Ãų ¼ö ÀÖ´Â ½ÇÁ¦ Çϵå¿þ¾î µéÀÌ´Ù. Ä¿³Î¿¡¼­´Â ÀÎÅÍ·´Æ® Çڵ鷯¸¦ ¼öÇàÇؼ­ ÀÌ·¯ÇÑ Çϵå¿þ¾îµé¿¡ ´ëÇÑ Ã³¸®¸¦ ÇÑ´Ù. Ä¿³Î¿¡¼­´Â ÀÌ·¯ÇÑ ÀÎÅÍ·´Æ® Çڵ鷯°¡ Àý´ë ÀçÁøÀÔµÇÁö ¾Êµµ·Ï ÇØ ÁØ´Ù: ¸¸¾à (ó¸® Áß¿¡) ¶Ç´Ù¸¥ ÀÎÅÍ·´Æ®°¡ ¹ß»ýµÇ¾ú´Ù¸é, ±×°ÍÀº Å¥¿¡ µé¾î°¡°Ô µÈ´Ù (Å¥°¡ °¡µæ Â÷ÀÖ´Â °æ¿ì ¹ö·ÁÁø´Ù). ÀÌ·¸°Ô ÀÎÅÍ·´Æ®¸¦ ºñÈ°¼ºÈ­ ÇØ µÎ±â ¶§¹®¿¡, ÀÎÅÍ·´Æ® Çڵ鷯´Â ¸Å¿ì »¡¸® ¼öÇàµÇ¾î¾ß ÇÑ´Ù: ÁÖ·Î ÀÎÅÍ·´Æ® Çڵ鷯¿¡¼­´Â ÀÎÅÍ·´Æ®¸¦ ¹Þ¾Ò´Ù´Â ÀÀ´äÀ» º¸³»ÁÖ°í, ½ÇÇàÀº ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ® ¸¦ ÀÌ¿ëÇØ Ã³¸®Çϵµ·Ï Ç¥½ÃÇÑ ÈÄ Á¾·áÇÑ´Ù.

Çϵå¿þ¾î ÀÎÅÍ·´Æ® ºÎºÐÀ» ó¸®ÇÏ´Â ºÎºÐ¿¡¼­´Â in_irq() ¸ÅÅ©·Î°¡ ÂüÀ» ¸®ÅÏÇÑ´Ù.

/!\ ÁÖÀÇ: ÀÎÅÍ·´Æ®°¡ ºñÈ°¼ºÈ­ µÇ¾îÀÖ´Â °æ¿ì¿¡´Â in_irq() ¸ÅÅ©·Î°¡ ¹«Á¶°Ç °ÅÁþÀ» ¸®ÅÏÇÑ´Ù´Â °ÍÀ» ¿°µÎ¿¡ µÎÀÚ.


2.3. ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ® (Bottom Halves, Tasklets, softirqs)


½Ã½ºÅÛ ÄÝÀ» È£ÃâÇÑ µÚ »ç¿ëÀÚ ¸ðµå·Î µ¹¾Æ°¡±â ÀüÀ̳ª Çϵå¿þ¾î ÀÎÅÍ·´Æ® Çڵ鷯°¡ Á¾·áÇÑ ÈÄ¿¡´Â (º¸Åë Çϵå¿þ¾î ÀÎÅÍ·´Æ® Çڵ鷯¿¡¼­ ó¸®ÇÑ) Ç¥½ÃµÈ ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ® °¡ ¼öÇàµÈ´Ù.

¸¹Àº ½ÇÁ¦ÀûÀÎ ÀÎÅÍ·´Æ® 󸮰¡ ÀÌ ºÎºÐ¿¡¼­ ÀÌ·ç¾îÁø´Ù. SMP ÃÊâ±â¿¡´Â ¿ÀÁ÷ bottom halves (ÇϹݺÎ, BHs) ¶ó´Â °³³ä¸¸ÀÌ Á¸ÀçÇÏ¿´´Âµ¥, ÀÌ°ÍÀº ´Ù¼öÀÇ CPU ¿¡ ÀÇÇÑ ÀåÁ¡À» »ì¸®Áö ¸øÇß´Ù. ¾ó¸¶ ÈÄ (°í¼º´ÉÀÇ ÄÄÇ»ÅÍ·Î ÀüȯÇÑ ÈÄ¿¡?) ÀÌ·¯ÇÑ Á¦ÇÑ»çÇ×µéÀº »ç¶óÁ³´Ù.

include/linux/interrupt.h ÆÄÀÏ¿¡ ¿©·¯°¡Áö ÇϹݺεéÀÇ ¸®½ºÆ®°¡ ÀÖ´Ù. ¾ó¸¶³ª ¸¹Àº CPU ¸¦ °¡Áö°í Àִ°¡¿¡ »ó°ü¾øÀÌ, ÇϹݺδ µ¿½Ã¿¡ µÎ °³ÀÌ»ó ¼öÇàµÉ ¼ö ¾ø´Ù. ÀÌ·¯ÇÑ ¹æ½ÄÀº SMP ¿¡ Àû¿ëÇϱâ´Â ½±Áö¸¸, ¼º´ÉÀ» °³¼±½ÃÅ°±â´Â ¾î·Æ´Ù. ÇϹݺο¡¼­ Áß¿äÇÑ °ÍÀº ŸÀÌ¸Ó ÇϹݺÎÀÌ´Ù. (include/linux/timer.h): ¿©±â¼­´Â ÁÖ¾îÁø ±æÀ̸¸Å­ÀÇ ½Ã°£ÀÌ Áö³­ ÈÄ¿¡ ƯÁ¤ ÇÔ¼ö¸¦ È£ÃâÇϵµ·Ï µî·ÏÇÒ ¼ö ÀÖ´Ù.

Ä¿³Î ¹öÀü 2.3.43 ¿¡¼­ softirq °¡ ¼Ò°³µÇ¾ú°í, ±× ¾Æ·¡¿¡¼­ ÇϹݺΰ¡ µ¿ÀÛÇϵµ·Ï ¼öÁ¤µÇ¾ú´Ù. (Áö±ÝÀº ÇϹݺÎÀÇ »ç¿ëÀ» ±ÇÇÏÁö ¾Ê°í ÀÖ´Ù... deprecated) softirq ´Â SMP ÀÇ ÀåÁ¡À» ¿ÏÀüÈ÷ »ì¸± ¼ö ÀÖµµ·Ï ÇÑ ÇϹݺζó°í ÇÒ ¼ö ÀÖ´Ù: µ¿½Ã¿¡ ¼öÇàµÉ ¼ö ÀÖ´Â CPU ÀÇ ¼ö¸¸Å­ Çѹø¿¡ ¼öÇàµÈ´Ù. ÀÌ°ÍÀº °æÀï Á¶°Ç¿¡¼­ °¢°¢ÀÇ ¶ôÀ» ÀÌ¿ëÇؼ­ °øÀ¯µÈ µ¥ÀÌŸ¿¡ Á¢±ÙÇϵµ·Ï Çϴ ó¸®°¡ ÇÊ¿äÇÏ´Ù´Â °ÍÀ» ÀǹÌÇÑ´Ù. ¾î¶² softirq °¡ È°¼ºÈ­ µÇ¾ú´ÂÁö¸¦ Ç¥½ÃÇϱâ À§ÇØ bitmask ¸¦ »ç¿ëÇϹǷÎ, 32 °³ ÀÌ»óÀÇ softirq ¸¦ ó¸®ÇÒ ¼ö ¾ø´Ù.

tasklet (include/linux/interrupt.h) Àº µ¿ÀûÀ¸·Î µî·ÏÇÒ ¼ö ÀÖ´Ù´Â Á¡ (Áï, ¿øÇÏ´Â ¸¸Å­ ¸¹ÀÌ µî·ÏÇÒ ¼ö ÀÖ´Ù) À» Á¦¿ÜÇÏ°í softirq ¿Í µ¿ÀÏÇÏ´Ù. ±×¸®°í (ÇÏ¹ÝºÎ¿Í ´Þ¸®) °¢°¢ÀÇ tasklet Àº µ¿½Ã¿¡ ¼öÇàµÉ ¼ö ÀÖÁö¸¸, ƯÁ¤ tasklet Àº ÇÑ ¼ø°£¿¡ ¿ÀÁ÷ ÇϳªÀÇ CPU ¿¡¼­¸¸ ¼öÇàµÇµµ·Ï º¸ÀåÇÑ´Ù. [2]

/!\ ÁÖÀÇ: tasklet À̶ó´Â À̸§Àº À߸øµÈ °ÍÀÌ´Ù: ÀÌ°ÍÀº task ¿Í ¾Æ¹«·± ¿¬°üÀÌ ¾ø´Ù. (¾Æ¸¶ À̶§ Alexey Kuznetsov °¡ º¸µåÄ«¸¦ ¸¹ÀÌ ¸¶½Å °Í °°´Ù..)

ÇöÀç softirq (ȤÀº ÇϹݺγª tasklet) °¡ ½ÇÇà ÁßÀÎÁö¸¦ ¾Ë¾Æº¸±â À§ÇØ in_softirq() ¸ÅÅ©·Î (include/linux/softirq.h)¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

/!\ ÁÖÀÇ: ÇϹݺο¡ ´ëÇÑ ¶ôÀÌ °É·ÁÀÖ´Â °æ¿ì¿¡´Â in_softirq() ¸ÅÅ©·Î°¡ Ç×»ó °ÅÁþÀ» ¸®ÅÏÇÔÀ» ¿°µÎ¿¡ µÎÀÚ


3. ±âº»ÀûÀÎ °³³äµé


* ¸Þ¸ð¸® º¸È£ ±â´ÉÀ» Áö¿øÇÏÁö ¾ÊÀ½
¸¸¾à user context ³ª ÀÎÅÍ·´Æ®°¡ °É¸° »óÅ¿¡¼­ ¸Þ¸ð¸® ¿µ¿ªÀ» À߸ø »ç¿ëÇÏ°Ô µÈ´Ù¸é ½Ã½ºÅÛ Àüü°¡ ¸Á°¡Áú ¼ö ÀÖ´Ù. ´ç½ÅÀÌ Áö±Ý ÇÏ·Á´Â ÀÛ¾÷ÀÌ »ç¿ëÀÚ ¸ðµå¿¡¼­ ÇØ°áÇÒ ¼ö ÀÖ´Â ÀÛ¾÷ÀÎÁö¸¦ ¸ÕÀú È®ÀÎÇØ º¸ÀÚ

* ºÎµ¿¼Ò¼öÁ¡ À̳ª MMX ¿¬»êÀ» Áö¿øÇÏÁö ¾ÊÀ½
FPU »óÅÂÁ¤º¸´Â ÀúÀåµÇÁö ¾Ê´Â´Ù. user context ¿¡¼­µµ FPU ÀÇ »óÅ´ ÇöÀç ÇÁ·Î¼¼½º¿¡ ´ëÀÀµÇÁö ¾ÊÀ» °ÍÀÌ´Ù: »ç¿ëÀÚ ¸ðµåÀÇ ÇÁ·Î¼¼½º°¡ FPU ÀÇ »óÅÂÁ¤º¸¸¦ °¡Áö°í ÀÖ´Ù´Â »ç½ÇÀº Àؾî¹ö¸®´Â °ÍÀÌ ÁÁ´Ù. ¸¸¾à Á¤¸»·Î ÀÌ·± ÀÛ¾÷ÀÌ ÇÊ¿äÇÏ´Ù¸é ¸í½ÃÀûÀ¸·Î ¸ðµç FPU ÀÇ »óÅÂÁ¤º¸¸¦ ÀúÀåÇÏ°í º¹±¸ÇÏ´Â (±×¸®°í ÀÎÅÍ·´Æ®¸¦ ±ÝÁö½ÃÄÑ¾ß ÇÑ´Ù) ÀÛ¾÷À» ÇؾßÇÑ´Ù. ÀÌ·¯ÇÑ ÀÛ¾÷Àº ÀϹÝÀûÀ¸·Î ÁÁÀº ¾ÆÀ̵ð¾î°¡ ¾Æ´Ï´Ù: ¸ÕÀú °íÁ¤¼Ò¼öÁ¡[3] ¿¬»êÀ» ÀÌ¿ëÇؼ­ ÇØ°áÇϵµ·Ï ÇÏÀÚ.

* ¾ö°ÝÇÑ ½ºÅà Á¦ÇÑ
Ä¿³Î ¹öÀü 2.2 ¿¡¼­ Ä¿³Î ½ºÅÃÀÇ Å©±â´Â ´ë·« 6K Á¤µµÀÌ°í (´ëºÎºÐÀÇ ¾ÆÅ°ÅØÃÄ¿¡¼­ ±×·¸´Ù´Â °ÍÀÌ´Ù: Alpha ÀÇ °æ¿ì´Â ¾à 14K ÀÌ´Ù) ÀÎÅÍ·´Æ® ó¸® ·çƾ°ú ½ºÅÃÀ» °øÀ¯Çϱ⠶§¹®¿¡ ÀÌ ¿µ¿ª ¸ðµÎ¸¦ ¾µ ¼ö°¡ ¾ø´Ù. ¸¹Àº Àç±ÍÈ£ÃâÀ̳ª ½ºÅà º¯¼ö·Î Å« ¹è¿­À» Àâ¾ÆµÎ´Â °ÍÀ» ÇÇÇϵµ·Ï ÇÏÀÚ. (´ë½Å µ¿ÀûÀ¸·Î ÇÒ´ç¹Þµµ·Ï ÇÑ´Ù)

* ¸®´ª½º Ä¿³ÎÀº À̽ļºÀÌ ÀÖ´Ù
ÀÌ ¿øÄ¢À» °¡½¿¼Ó¿¡ »õ°ÜµÎÀÚ. ´ç½ÅÀÌ ÀÛ¼ºÇÏ´Â ÄÚµå´Â 64-ºñÆ® ¿¡¼­µµ ȣȯµÇµµ·Ï ÇÏ°í endian ¿¡ Á¾¼ÓÀûÀÌÁö ¾Ê¾Æ¾ß ÇÑ´Ù. ¶ÇÇÑ CPU ¿¡ Á¾¼ÓÀûÀÎ ºÎºÐÀ» ÁÙ¿©¾ß ÇÑ´Ù. Áï Æ÷ÆÃÇϱ⠽±µµ·Ï ÀζóÀÎ ¾î¼Àºí¸®´Â ±ò²ûÇÏ°Ô Ä¸½¶È­µÇ¾î¾ß ÇÏ°í ÃÖ¼ÒÈ­ ÇØ¾ß ÇÑ´Ù. ÀϹÝÀûÀ¸·Î ÀÌ°ÍÀº Ä¿³Î Æ®¸® ³»ÀÇ ¾ÆÅ°ÅØÃÄ Á¾¼ÓÀûÀÎ ºÎºÐ¿¡ ÇØ´çµÇ´Â À̾߱âÀÌ´Ù.


4. ioctls: »õ·Î¿î ½Ã½ºÅÛ ÄÝÀ» Ãß°¡ÇÏÁö ¾Ê´Â ¹æ¹ý


½Ã½ºÅÛ ÄÝÀº ´ÙÀ½°ú °°Àº ÇüÅ°¡ µÈ´Ù.

asmlinkage int sys_mycall(int arg) 
{
        return 0; 
}

¿ì¼± ´ëºÎºÐÀÇ °æ¿ì¿¡ À־ ´ç½ÅÀº »õ·Î¿î ½Ã½ºÅÛ ÄÝÀ» Ãß°¡ÇÏ°í ½ÍÁö´Â ¾ÊÀ» °ÍÀÌ´Ù. ij¸¯ÅÍ µð¹ÙÀ̽º¸¦ ¸¸µé°í °Å±â¿¡ ´ëÇÑ ÀûÀýÇÑ ioctl À» ±¸ÇöÇÏ´Â ¹æ¹ýÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÀÌ°ÍÀÌ ½Ã½ºÅÛ Äݺ¸´Ù ÈξÀ À¯¿¬ÇÑ ¹æ¹ýÀÌ´Ù. ¸ðµç ¾ÆÅ°ÅØÃÄ¿¡ ´ëÇØ include/asm/unistd.h ÆÄÀÏ°ú arch/kernel/entry.S ÆÄÀÏÀ» ¼öÁ¤ÇÒ ÇÊ¿ä°¡ ¾ø°í ¶Ç Linus °¡ Àß ¹Þ¾ÆµéÀÌ´Â ¹æ½ÄÀ̱⵵ ÇÏ´Ù.

¸¸¾à ´ç½ÅÀÌ ÀÛ¼ºÇÑ ¸ðµç ·çƾÀÌ ¸î°¡Áö ÆĶó¹ÌÅ͸¦ ÀÐ°í ¾²´Â ¿¬»êÀ» ¼öÇàÇÑ´Ù¸é ´ë½Å sysctl ÀÎÅÍÆäÀ̽º¸¦ ±¸ÇöÇÏ´Â ¹æ¹ýÀ» °í·ÁÇØ º¼ ¼ö ÀÖ´Ù.

ioctl ³»¿¡¼­´Â process ÀÇ user context ¿¡ ¼ÓÇÑ °ÍÀÌ´Ù. ¿¡·¯°¡ ¹ß»ýÇß´Ù¸é À½¼ö°ªÀÎ errno (include/linux/errno.h Âü°í) ¸¦ ¸®ÅÏÇÏ°í, ±×·¸Áö ¾Ê´Ù¸é 0 À» ¸®ÅÏÇϵµ·Ï ÇÑ´Ù.

sleep ¿¡¼­ ±ú¾î³­ ÈĶó¸é signal À» ¹Þ¾Ò´ÂÁö °Ë»çÇØ¾ß ÇÑ´Ù. Unix/Linux ¿¡¼­ signal À» ó¸®ÇÏ´Â ¹æ¹ýÀº ½Ã½ºÅÛ ÄÝ¿¡¼­ -ERESTARTSYS ¶ó´Â ¿¡·¯Äڵ带 ¸®ÅÏÇÏ´Â °ÍÀÌ´Ù. ½Ã½ºÅÛ ÄÝ ÁøÀÔÄÚµå´Â user context ·Î µ¹¾Æ¿Í¼­ signal handler ¸¦ ½ÇÇàÇÏ°í (»ç¿ëÀÚ°¡ ±ÝÁöÇÏÁö ¾Ê¾Ò´Ù¸é) ½Ã½ºÅÛ ÄÝÀ» ´Ù½Ã ½ÃÀÛÇÒ °ÍÀÌ´Ù..? ±×·¯¹Ç·Î ¾î¶² ÀڷᱸÁ¶¸¦ ´Ù·ç°í ÀÖ´Â °æ¿ì¿¡ À־ ÇÁ·Î¼¼½º°¡ ´Ù½Ã ½ÃÀÛµÉ ¼ö ÀÖµµ·Ï Áغñ¸¦ ÇØ µÎ¾î¾ß ÇÑ´Ù.

if (signal_pending()) 
        return -ERESTARTSYS;

¸¸¾à ¿À·£ ½Ã°£µ¿¾È °è»êÇÏ´Â ÀÏÀÌ ÇÊ¿äÇÏ´Ù¸é: ¸ÕÀú »ç¿ëÀÚ ¸ðµå¿¡¼­ ¼öÇàÇÒ °ÍÀ» °í·ÁÇØ º»´Ù. ¸¸¾à Á¤¸»·Î ÀÌ·¯ÇÑ ¿¬»êÀ» Ä¿³Î ³»¿¡¼­ ¼öÇàÇØ¾ß ÇÑ´Ù¸é CPU ¸¦ ¾çµµÇØ¾ß ÇÏ´ÂÁö¸¦ Á¤±âÀûÀ¸·Î °Ë»çÇØ¾ß ÇÑ´Ù (CPU ¸¶´Ù Çùµ¿ÀûÀ¸·Î ¸ÖƼŽºÅ·À» ¼öÇàÇÑ´Ù´Â °ÍÀ¸·Î ±â¾ïÇ϶ó). ´ÙÀ½°ú °°Àº °ü¿ëÀûÀΠǥÇöÀÌ ¾²ÀδÙ:

if (current->need_resched)
        schedule(); /* Will sleep */ 

ÀÎÅÍÆäÀ̽º µðÀÚÀο¡ ´ëÇؼ­ ÇѸ¶µð ÇÏÀÚ¸é: UNIX ½Ã½ºÅÛ ÄÝÀÇ ¸ðÅä´Â "¸ÞÄ«´ÏÁòÀ» Á¦°øÇÏ°í Á¤Ã¥À» Á¦°øÇÏÁö´Â ¾Ê´Â´Ù" (Provide mechanism not policy) ÀÌ´Ù.


5. Deadlock 󸮹ý


¸¸¾à ´ÙÀ½°ú °°Àº »óȲÀÌ ¾Æ´Ï¶ó¸é, sleep ¿¡ µé¾î°¥ ¼ö ÀÖ´Â ¾î¶² ·çƾÀÌ¶óµµ ½ÇÇàÇؼ­´Â ¾ÈµÈ´Ù:

  • user context ¿¡ ÀÖ´Â °æ¿ì
  • ¾î¶² spinlock µµ ¼ÒÀ¯ÇÏÁö ¾Ê´Â °æ¿ì
  • ÀÎÅÍ·´Æ®¸¦ È°¼ºÈ­ ÇÏ°í ÀÖ´Â °æ¿ì (½ÇÁ¦·Î, Andi Kleen Àº ½ºÄÉÁÙ¸µ °ü·Ã Äڵ忡¼­µµ ÀÎÅÍ·´Æ®¸¦ È°¼ºÈ­ ½Ãų¼ö ÀÖ´Ù°í Çß´Ù. ÇÏÁö¸¸ ±×°ÍÀº ¾Æ¸¶ ´ç½ÅÀÌ ¿øÇÏÁö ¾ÊÀ» °ÍÀÌ´Ù.)

¸î¸î ÇÔ¼öµéÀº ¾Ï½ÃÀûÀ¸·Î sleep ¿¡ µé¾î°¥ ¼ö ÀÖÀ½¿¡ ÁÖÀÇÇÏÀÚ: ÀϹÝÀûÀ¸·Î »ç¿ëÀÚ ¸ðµå Á¢±Ù ÇÔ¼ö (*_user) ³ª GFP_ATOMIC Ç÷¡±× ¾øÀÌ È£ÃâÇÏ´Â ¸Þ¸ð¸® ÇÒ´ç ÇÔ¼ö°¡ ÀÌ·± ·ù¿¡ ¼ÓÇÑ´Ù.

¸¸¾à À§¿¡¼­ À̾߱âÇÑ ¿øÄ¢µéÀ» ¾î±ä´Ù¸é ´ç½ÅÀÇ ¸Ó½ÅÀº °á±¹ ´Ù¿îµÇ°í ¸» °ÍÀÌ´Ù.

Á¤¸»·Î.


6. °øÅë ·çƾ


6.1. printk() <include/linux/kernel.h>


printk() ´Â Ä¿³ÎÀÇ ¸Þ¼¼Áö¸¦ ÄܼÖÀ̳ª dmesg, syslog µ¥¸ó¿¡°Ô ³Ñ°ÜÁÖ´Â ÀÏÀ» ÇÑ´Ù. ÀÌ°ÍÀº µð¹ö±ë½Ã¿¡³ª ¿¡·¯¸¦ ¾Ë·ÁÁÖ´Â µ¥ À¯¿ëÇϸç interrupt context ³»¿¡¼­µµ »ç¿ëÀÌ °¡´ÉÇÏÁö¸¸ ÁÖÀÇ°¡ ÇÊ¿äÇÏ´Ù: printk() ¸Þ¼¼Áö¿¡ ÀÇÇØ ÄܼÖÀÌ °¡µæÂù (flooded) ¸Ó½ÅÀº »ç¿ëÇÒ ¼ö ¾ø´Ù. printk() ¿¡¼­ »ç¿ëµÇ´Â Çü½Ä ¹®ÀÚ¿­Àº ´ëºÎºÐ ANSI C ÀÇ printf() ¿Í ȣȯµÈ´Ù. ±×¸®°í C ¾ð¾îÀÇ ¹®ÀÚ¿­ °áÇÕ ±â´ÉÀ» ÀÌ¿ëÇÏ¿© ¸Ç óÀ½ ÀÎÀÚ·Î Áß¿äµµ(priority) ¸¦ »ç¿ëÇÑ´Ù:

printk(KERN_INFO "i = %u\n", i);

<include/linux/kernel.h> ÆÄÀÏ¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Â Áß¿äµµ¿¡ ´ëÇÑ ¸ÅÅ©·Î°¡ Á¤ÀǵǾî ÀÖ´Ù. ÀÌ Áß¿äµµµéÀº syslog ´ë¸óÀÌ ¸Þ¼¼ÁöÀÇ ´Ü°è(level) ·Î Çؼ®ÇÑ´Ù. Ưº°ÇÑ °æ¿ì·Î IP ÁÖ¼Ò°ªÀ» Ãâ·ÂÇÏ°íÀÚ ÇÏ´Â °æ¿ì¿¡´Â ´ÙÀ½À» ÀÌ¿ëÇÒ ¼ö ÀÖ´Ù.

__u32 ipaddress;
printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));

printk() ´Â ³»ºÎÀûÀ¸·Î 1K ÀÇ ¹öÆÛ¸¦ »ç¿ëÇÏ¸ç ¹öÆÛ°¡ ³ÑÄ¡´Â °ÍÀ» °Ë»çÇÏÁö ¾Ê´Â´Ù. À̸¦ ³Ñ±âÁö ¾Êµµ·Ï ÁÖÀÇÇÑ´Ù.

(!) Âü°í: ´ç½ÅÀÌ »ç¿ëÀÚ ¸ðµåÀÇ ÇÁ·Î±×·¥¿¡¼­ printf() ´ë½Å printk() ¸¦ »ç¿ëÇÏ°í ÀÖÀ½À» ¾Ë°ÔµÉ ¶§, ÁøÁ¤ÇÑ Ä¿³Î ÇØÄ¿°¡ µÇ¾úÀ½À» ´À³¢°Ô µÉ °ÍÀÌ´Ù.

(!) Âü°í: ¶ÇÇÑ, ¿ø·¡ Unix Version 6 ÀÇ ¼Ò½º¿¡´Â printf() ÇÔ¼ö À§Æí¿¡ ´ÙÀ½°ú °°Àº ÁÖ¼®ÀÌ ´Þ·Á ÀÖ´Ù. "printf() ´Â Àâ´ãÀ» À§ÇØ »ç¿ëµÇ¼­´Â ¾ÈµÈ´Ù." À̸¦ ¸í½ÉÇϱ⠹ٶõ´Ù.

6.2. copy_to/from_user()/get/put_user() <include/asm/uaccess.h>


'''SLEEPS'''

put_user() ¿Í get_user() ´Â (int, char, long °ú °°Àº) ÇϳªÀÇ °ªÀ» »ç¿ëÀÚ ¿µ¿ª°ú ÁÖ°í¹Þ±â À§ÇØ »ç¿ëµÈ´Ù. »ç¿ëÀÚ ¿µ¿ªÀÇ Æ÷ÀÎÅÍ´Â (user context ³»¿¡¼­) ´Ü¼øÈ÷ ±× °ªÀ» ÂüÁ¶Çؼ­´Â ¾ÈµÈ´Ù: µ¥ÀÌŸ´Â ¹Ýµå½Ã ÀÌ ÇÔ¼öµéÀ» ÀÌ¿ëÇØ º¹»çµÇ¾î¾ß ÇÑ´Ù. µÎ ÇÔ¼ö ¸ðµÎ -EFAULT ³ª 0 À» ¸®ÅÏÇÑ´Ù.

copy_to_user() ¿Í copy_from_user() ´Â Á»´õ ÀϹÝÀûÀÎ ÇÔ¼öÀÌ´Ù: ÀÌ ÇÔ¼öµéÀº ÀÓÀÇÀÇ ¾çÀÇ µ¥ÀÌŸ¸¦ »ç¿ëÀÚ ¿µ¿ª°ú ÁÖ°í¹Þ´Â´Ù.

/!\ ÁÖÀÇ: put_user() ³ª get_user() ¿Í ´Þ¸® copy_to_user() ¿Í copy_from_user() ¿¡¼­´Â º¹»çµÇÁö ¾ÊÀº µ¥ÀÌŸÀÇ ¾çÀ» ¸®ÅÏÇÑ´Ù. (Áï, (¸¶Âù°¡Áö·Î) 0 Àº ¼º°øÀ» ÀǹÌÇÑ´Ù.)

±×·¸´Ù. ÀÌ ÀÌ»óÇÑ ÀÎÅÍÆäÀ̽º´Â ³ª¸¦ Â¥Áõ³ª°Ô ¸¸µé¾ú´Ù. Á¦¹ß ¿©±â¿¡ ´ëÇÑ ÆÐÄ¡¸¦ º¸³»ÁÖ¾î ³ªÀÇ ¿µ¿õÀÌ µÇ¾î ÁÖ±æ ¹Ù¶õ´Ù. -- RR

ÀÌ ÇÔ¼öµéÀº ¾Ï½ÃÀûÀ¸·Î sleep ¿¡ µé¾î°¥ ¼ö ÀÖ´Ù. ±×·¡¼­ ÀÌ ÇÔ¼öµéÀº user context ¹Û¿¡¼­³ª (user context ¹Û¿¡¼­´Â º° Àǹ̰¡ ¾ø´Ù), ÀÎÅÍ·´Æ®°¡ ºñÈ°¼ºÈ­µÈ »óÅ ȤÀº spinlock ÀÌ °É¸° »óÅ¿¡¼­ Àý´ë »ç¿ëµÇ¼­´Â ¾ÈµÈ´Ù.

6.3. kmalloc()/kfree() <include/linux/slab.h>


ÀÌ ·çƾµéÀº (»ç¿ëÀÚ ¸ðµå¿¡¼­ÀÇ malloc()/free() ó·³) µ¿ÀûÀ¸·Î ¸Þ¸ð¸®¸¦ ¿äûÇÒ ¶§ »ç¿ëµÈ´Ù. ÇÏÁö¸¸ kmalloc() ¿¡¼­´Â º°µµÀÇ Ç÷¡±× Çϳª¸¦ ´õ ÃëÇϴµ¥ ±×Áß¿¡¼­ Áß¿äÇÑ °ªµé·Î´Â ´ÙÀ½°ú °°Àº °ÍµéÀÌ ÀÖ´Ù:

  • GFP_KERNEL - sleep µÇ°Å³ª swap µÉ ¼ö ÀÖ´Ù. user context ³»¿¡¼­¸¸ »ç¿ë°¡´ÉÇÏÁö¸¸, ¸Þ¸ð¸®¸¦ ÇÒ´ç¹Þ´Â °¡Àå ½Å·ÚÇÒ ¼ö ÀÖ´Â ¹æ¹ýÀÌ´Ù.
  • GFP_ATOMIC - sleep µÇÁö ¾Ê´Â´Ù. GFP_KERNEL º¸´Ù´Â ½Å·Ú¼ºÀÌ ¶³¾îÁöÁö¸¸ interrupt context ³»¿¡¼­µµ »ç¿ëÇÒ ¼ö ÀÖ´Â °­Á¡ÀÌ ÀÖ´Ù. ÀÌ °æ¿ì ¿¡·¯¿¡ ´ëÇÑ Ã³¸®°¡ ¹«Ã´ Áß¿äÇÏ´Ù.
  • GFP_DMA - 16MB º¸´Ù ÇÏÀ§ÀÇ ISA DMA ¿µ¿ªÀÇ ¸Þ¸ð¸®¸¦ ¿äûÇÒ ¶§ »ç¿ëµÈ´Ù. ¸¸¾à ÀÌ°ÍÀÌ ¹«½¼ ¸»ÀÎÁö ¸ð¸£°Ú´Ù¸é »ç¿ëÇÒ ÇÊ¿ä°¡ ¾øÀ» °ÍÀÌ´Ù. ¸Å¿ì ½Å·Ú¼ºÀÌ ¶³¾îÁø´Ù.

¸¸¾à 'kmem_grow: Called nonatomically from int' ¶ó´Â °æ°í ¸Þ¼¼Áö¸¦ º¸¾Ò´Ù¸é, ´ç½ÅÀÌ Â§ ÇÁ·Î±×·¥¿¡¼­ interrupt context »ó¿¡¼­ GFP_ATOMIC Ç÷¡±×¸¦ ¼³Á¤ÇÏÁö ¾ÊÀº »óÅ·Π¸Þ¸ð¸® ÇÒ´çÀ» ¿äûÇÑ °ÍÀÌ´Ù. ÀÌ ¿¡·¯´Â Áï½Ã °íÃÄÁ®¾ß ÇÑ´Ù.

¸¸¾à PAGE_SIZE (include/linux/page.h) ¹ÙÀÌÆ® ÀÌ»óÀÇ ¸Þ¸ð¸®¸¦ ÇÒ´ç¹Þ°íÀÚ ÇÏ´Â °æ¿ì¿¡´Â __get_free_pages() (include/linux/mm.h) ÇÔ¼öÀÇ »ç¿ëÀ» °í·ÁÇØ º¸ÀÚ. ÀÌ ÇÔ¼ö´Â order (2ÀÇ ½Â¼ö, 0 À̸é 1 ÆäÀÌÁö, 1 À̸é 2 ÆäÀÌÁö, 2 À̸é 4 ÆäÀÌÁö, ...) ÀÎÀÚ¿Í À§¿¡¼­ ¸»ÇÑ ¸Þ¸ð¸® ¿ì¼±¼øÀ§ Ç÷¡±× ÀÎÀÚ (GFP_*) ¸¦ ÃëÇÑ´Ù.

ÇÑ ÆäÀÌÁö ´ÜÀ§? ÀÌ»óÀÇ (more than a page worth of bytes) ¸Þ¸ð¸®¸¦ ÇÒ´ç¹Þ°íÀÚ ÇÏ´Â °æ¿ì¿¡´Â vmalloc() ÇÔ¼ö¸¦ ÀÌ¿ëÇÒ ¼ö ÀÖ´Ù. ÀÌ ÇÔ¼ö´Â kernel map »óÀÇ °¡»ó ¸Þ¸ð¸®¸¦ ÇÒ´çÇÑ´Ù. ÀÌ ºí·°µéÀº ¹°¸®ÀûÀ¸·Î ¿¬¼ÓµÈ ¸Þ¸ð¸® ¿µ¿ªÀÌ ¾Æ´ÏÁö¸¸, MMU [4] °¡ ¸¶Ä¡ ¿¬¼ÓµÈ ¸Þ¸ð¸®ÀÎ °Í ó·³ ó¸®ÇØ ÁØ´Ù. (Áï, ¿ÀÁ÷ CPU ¿¡°Ô¸¸ ¿¬¼ÓÀûÀ¸·Î º¸ÀÌ´Â °ÍÀÌÁö ´Ù¸¥ ¿ÜºÎÀÇ µð¹ÙÀ̽º µå¶óÀ̹ö¿¡¼­´Â ¿¬¼ÓÀûÀ¸·Î º¸ÀÌÁö ¾Ê´Â´Ù.) ¸¸¾à ¾î¶² (ÀÌ»óÇÑ) ÀåÄ¡¿¡¼­ ¹°¸®ÀûÀ¸·Î ¿¬¼ÓµÈ Å« ¸Þ¸ð¸® ¿µ¿ªÀ» ÇÊ¿ä·Î ÇÑ´Ù¸é ¹®Á¦°¡ µÉ ¼ö ÀÖ´Ù. ÀÌ°ÍÀº Linux ¿¡¼­´Â Àß Áö¿øÀÌ µÇÁö ¾Ê´Â ºÎºÐÀε¥ Ä¿³ÎÀÌ ½ÇÇàµÇ°í ³ª¸é ¹ß»ýÇÏ´Â ¸Þ¸ð¸® ´ÜÆíÈ­ Çö»óÀÌ ÀÌ°ÍÀ» ¾î·Æ°Ô Çϱ⠶§¹®ÀÌ´Ù. ÀÌ·¯ÇÑ ¸Þ¸ð¸®¸¦ ÇÒ´ç¹Þ´Â °¡Àå ÁÁÀº ¹æ¹ýÀº ºÎÆ® ÇÁ·Î¼¼½º¿¡¼­ alloc_bootmem() ÇÔ¼ö¸¦ ÀÌ¿ëÇؼ­ ¹Ì¸® ÇÒ´ç¹Þ¾Æ µÎ´Â °ÍÀÌ´Ù.

ÀÚÁÖ »ç¿ëµÇ´Â °´Ã¼¸¦ À§ÇØ »õ·Î¿î ij½Ã¸¦ ¸¸µé±â Àü¿¡ include/linux/slab.h ¿¡ ÀÖ´Â ½½·¦ ij½ÃÀÇ »ç¿ëÀ» °í·ÁÇØ º¸ÀÚ.

6.4. current <include/asm/current.h>


ÀÌ Àü¿ª º¯¼ö (½ÇÁ¦·Î´Â ¸ÅÅ©·ÎÀÌ´Ù) ´Â ÇöÀç ½ÇÇàÁßÀÎ task_struct ±¸Á¶Ã¼¿¡ ´ëÇÑ Æ÷ÀÎÅÍÀÌ´Ù. ±×·¡¼­ ¿ÀÁ÷ user context ¿¡¼­¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î ÇÁ·Î¼¼½º°¡ ½Ã½ºÅÛ ÄÝÀ» È£ÃâÇß´Ù¸é current º¯¼ö´Â È£ÃâÇÑ ÇÁ·Î¼¼½ºÀÇ task_struct ¸¦ °¡¸®Å³ °ÍÀÌ´Ù. ÀÌ °ªÀº interrupt context ³»¿¡¼­µµ NULL ÀÌ ¾Æ´Ï´Ù.

6.5. udelay()/mdelay() <include/asm/delay.h> / <include/linux/delay.h>


ÇÁ·Î¼¼½º¸¦ Àá½Ã ÁߴܽÃÅ°±â À§ÇØ udelay() ÇÔ¼ö¸¦ ÀÌ¿ëÇÒ ¼ö ÀÖ´Ù. udelay() ÇÔ¼ö¿¡ Å« °ªÀ» »ç¿ëÇÏ´Â °ÍÀº ¿À¹ö ÇÃ·Î¿ì ¹®Á¦¸¦ ÀÏÀ¸Å³ ¼ö ÀÖ´Ù - À̸¦ º¸Á¶Çϱâ À§ÇÑ ÇÔ¼öÀÎ mdelay() ÇÔ¼ö¸¦ ÀÌ¿ëÇϰųª schedule_timeout() ÇÔ¼ö¸¦ ÀÌ¿ëÇϵµ·Ï ÇÑ´Ù.

6.6. cpu_to_be/le32()/be/le32_to_cpu() <include/linux/byteorder/*.h>


cpu_to_be32() °èÅëÀÇ ¸ÅÅ©·Î µéÀº Ä¿³Î³»ÀÇ ¿£µð¾È¿¡ °üÇÑ º¯È¯À» À§ÇÑ ÀϹÝÀûÀÎ ¹æ¹ýÀ» Á¦°øÇÑ´Ù (32 ´ë½Å 64 ³ª 16 ÀÌ ¾²Àϼö ÀÖ°í, be ´ë½Å le °¡ ¾²ÀÏ ¼ö ÀÖ´Ù): À̵éÀº º¯È¯µÈ °ªÀ» ¸®ÅÏÇÑ´Ù. ÀÌ¿Í ¹Ý´ëµÇ´Â ÀÏÀ» ÇÏ´Â °Íµéµµ ¿ª½Ã Á¸ÀçÇÑ´Ù: be32_to_cpu µî..

ÀÌ ÇÔ¼öµéÀº Å©°Ô µÎ°¡Áö ÇüÅ·Πº¯È­µÇ¾î »ç¿ëµÈ´Ù: ±× ù¹ø°´Â cpu_to_be32p() ó·³ Æ÷ÀÎÅÍ·Î º¯È­µÈ ÇüÅÂÀÌ´Ù. ÀÌ ÇÔ¼ö´Â ¸í½ÃµÈ ŸÀÔÀÇ Æ÷ÀÎÅ͸¦ ¹Þ¾Æ¼­ º¯È¯µÈ °ªÀ» ¸®ÅÏÇÑ´Ù. ¶Ç´Ù¸¥ ÇüÅ´ cpu_to_be32s() ¿Í °°Àº in-situ °è¿­Àε¥, ÀÌ°ÍÀº Æ÷ÀÎÅÍ·Î ÁÖ¾îÁø °ªÀ» º¯È­½ÃŲ ÈÄ¿¡ void ¸¦ ¸®ÅÏÇÑ´Ù.

6.7. local_irq_save/restore() <include/asm/system.h>


ÀÌ ·çƾµéÀº ÇöÀç CPU ÀÇ Çϵå¿þ¾î ÀÎÅÍ·´Æ®¸¦ È°¼ºÈ­/ºñÈ°¼ºÈ­ ½ÃŲ´Ù. ÀÌ ÇÔ¼öµéÀº ÀçÁøÀÔÀÌ °¡´ÉÇÏ´Ù; ÀÌÀüÀÇ »óÅ°ªÀ» unsigned long flags ÀÎÀÚ¿¡ ÀúÀå½ÃŲ´Ù. ¸¸¾à ÀÎÅÍ·´Æ®°¡ È°¼ºÈ­µÇ¾î ÀÖ´ÂÁö ¾Æ´ÑÁö ¾Ë°í ÀÖ´Ù¸é ´Ü¼øÈ÷ local_irq_disable() °ú local_irq_enable() ÇÔ¼ö¸¦ ÀÌ¿ëÇÒ ¼ö ÀÖ´Ù.

6.8. local_bh_disable/enable() <include/asm/softirq.h>


ÀÌ ·çƾµéÀº ÇöÀç CPU ÀÇ ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ®¸¦ È°¼ºÈ­/ºñÈ°¼ºÈ­ ½ÃŲ´Ù. ÀÌ ÇÔ¼öµéµµ ÀçÁøÀÔÀÌ °¡´ÉÇÏ´Ù; ¸¸¾à ÀÌÀü¿¡ ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ®°¡ ºñÈ°¼ºÈ­µÇ¾î ÀÖ¾ú´Ù¸é, ÀÌ ÇÔ¼öµéÀÌ ½ÖÀ¸·Î È£ÃâµÈ ÈÄ¿¡µµ ¿©ÀüÈ÷ ºñÈ°¼ºÈ­ µÈ ä·Î ³²¾ÆÀÖÀ» °ÍÀÌ´Ù. [5] ÀÌ ÇÔ¼öµéÀº ÇöÀç CPU ¿¡¼­ softirq, tasklet, bottom halves °¡ ½ÇÇàµÇ´Â °ÍÀ» ±ÝÁöÇÑ´Ù.

6.9. smp_processor_id()/cpu_number/logical_map() <include/asm/smp.h>


smp_processor_id() ÇÔ¼ö´Â 0°ú NR_CPUS (Linux ¿¡¼­ Áö¿øÇÏ´Â ÃÖ´ë CPU ÀÇ °¹¼ö·Î ÇöÀç´Â 32 ÀÌ´Ù) »çÀÌÀÇ °ªÀÎ ÇöÀç ÇÁ·Î¼¼¼­ ¹øÈ£¸¦ ¾Ë·ÁÁØ´Ù. ÀÌ °ªÀº ¹Ýµå½Ã ¿¬¼ÓÀûÀÏ ÇÊ¿ä´Â ¾ø´Ù: 0 °ú smp_num_cpus() (ÀÌ ¸Ó½ÅÀÌ °¡Áö°í ÀÖ´Â ½ÇÁ¦ ÇÁ·Î¼¼¼­ÀÇ °¹¼ö) »çÀÌÀÇ °ªÀ» ¾Ë±â À§Çؼ­´Â cpu_number_map() ÇÔ¼ö¸¦ »ç¿ëÇؼ­ ÇÁ·Î¼¼¼­ ¹øÈ£¸¦ ³í¸®ÀûÀÎ ¹øÈ£·Î ¹Ù²Ü ¼ö ÀÖ´Ù. [6] cpu_logical_map() ÇÔ¼ö´Â ÀÌ¿Í ¹Ý´ëµÇ´Â ÀÏÀ» ¼öÇàÇÑ´Ù.

6.10. init/exit/__initdata <include/linux/init.h>


ºÎÆÃÀÌ µÇ°í ³­ ÈÄ¿¡, Ä¿³ÎÀº ƯÁ¤ ¿µ¿ªÀÇ ¸Þ¸ð¸®¸¦ ÇØÁ¦ÇÑ´Ù; init ·Î ¼±¾ðµÈ ÇÔ¼öµé°ú, initdata ¶ó°í ¼±¾ðµÈ µ¥ÀÌŸ´Â ºÎÆÃÀÌ ¿Ï·áµÈ ÈÄ¿¡ ÇØÁ¦µÈ´Ù. (¸ðµâ³»¿¡¼­´Â ÀÌ·¯ÇÑ Áö½ÃÀÚµéÀÌ ¹«½ÃµÈ´Ù) __exit ´Â Á¾·áµÉ ¶§¿¡¸¸ ÇÊ¿äÇÑ ÇÔ¼öµéÀ» ¼±¾ðÇϴµ¥ »ç¿ëµÈ´Ù: ÀÌ ÇÔ¼öµéÀº ÆÄÀÏÀÌ ¸ðµâ·Î ÄÄÆÄÀϵÇÁö ¾ÊÀ¸¸é ÇØÁ¦µÈ´Ù. ÀÌ Áö½ÃÀÚµéÀ» »ç¿ëÇÑ Çì´õ ÆÄÀϵéÀ» »ìÆ캸±â ¹Ù¶õ´Ù. __init Áö½ÃÀÚ¿Í ÇÔ²² ¼±¾ðµÈ ÇÔ¼ö¿¡¼­ EXPORT_SYMBOL() ¸ÅÅ©·Î¸¦ ÀÌ¿ëÇØ ½Éº¼À» ¸ðµâ·Î °ø°³ÇÏ´Â °ÍÀº Àǹ̰¡ ¾ø´Ù´Â °Í¿¡ ÁÖÀÇÇÏÀÚ.

__initdata ·Î ¼±¾ðµÈ Á¤Àû ÀÚ·á ±¸Á¶´Â (0 À¸·Î ÃʱâÈ­ µÇ´Â BSS ¿µ¿ªÀÇ ÀϹÝÀûÀÎ Á¤Àû µ¥ÀÌŸ¿Í´Â ´Þ¸®) ¹Ýµå½Ã ÃʱâÈ­ µÇ¾î¾ß ÇÏ°í »ó¼ö°¡ µÇ¾î¼­´Â ¾ÈµÈ´Ù.

6.11. __initcall()/modult_init() <include/linux/init.h>


Ä¿³ÎÀÇ ¸¹Àº ºÎºÐÀº (µ¿ÀûÀ¸·Î ·ÎµåÇÒ ¼ö ÀÖ´Â ºÎºÐÀÎ) ¸ðµâ·Î¼­µµ Àß µ¿ÀÛÇÑ´Ù. module_init() ¿Í module_exit() ¸ÅÅ©·Î´Â #ifdef ¿Í °°Àº Àü󸮱â Áö½ÃÀÚ ¾øÀ̵µ ¸ðµâÀ̳ª Ä¿³Î¿¡ Á¤ÀûÀ¸·Î Æ÷ÇԵǴ °ÍÀ» µÑ ´Ù Áö¿øÇÏ´Â Äڵ带 ½±°Ô ÀÛ¼ºÇÒ ¼ö ÀÖµµ·Ï ÇØ ÁØ´Ù.

module_init() ¸ÅÅ©·Î´Â (ÆÄÀÏÀÌ ¸ðµâ·Î ÄÄÆÄÀϵǴ °æ¿ì) ¸ðµâÀÌ Ãß°¡µÉ ¶§, ȤÀº ºÎÆýÿ¡ ¾î¶² ÇÔ¼ö°¡ ºÒ·Á¾ß ÇÒÁö¸¦ °áÁ¤ÇÑ´Ù: ÆÄÀÏÀÌ ¸ðµâ·Î ÄÄÆÄÀϵÇÁö ¾Ê´Â´Ù¸é module_init() ¸ÅÅ©·Î´Â __initcall() ¸ÅÅ©·Î¿Í µ¿ÀÏÇÑ ¿ªÇÒÀ» Çϴµ¥ ÀÌ°ÍÀº ¸µÄ¿¿¡ ÀÇÇØ ºÎÆýÿ¡ ÇÔ¼ö°¡ ºÒ·ÁÁöµµ·Ï ¼³Á¤ÇØ ÁØ´Ù.

ÀÌ ÇÔ¼ö´Â ¸ðµâÀ» ·ÎµùÇÏ´Â µ¥ ½ÇÆÐÇÏ´Â °æ¿ì À½¼ö°ªÀÎ ¿¡·¯ ¹øÈ£¸¦ ¸®ÅÏÇÒ ¼ö ÀÖ´Ù (ºÒÇàÈ÷µµ Ä¿³Î¿¡ Á¤ÀûÀ¸·Î Æ÷ÇԵǴ °æ¿ì¿¡´Â ¾Æ¹«·± ¿µÇâÀ» ¹ÌÄ¡Áö ¸øÇÑ´Ù). ¸ðµâÀÇ °æ¿ì¿¡´Â, ÀÌ ÇÔ¼ö´Â ÀÎÅÍ·´Æ®°¡ È°¼ºÈ­ µÇ¾î ÀÖ°í, Ä¿³Î lock ÀÌ °É·ÁÀÖ´Â??? »óÅÂÀÇ user context ¿¡¼­ È£ÃâµÇ¹Ç·Î sleep µÉ ¼ö ÀÖ´Ù.

6.12. module_exit() <include/linux/init.h>


ÀÌ ¸ÅÅ©·Î´Â ¸ðµâÀÌ Á¦°ÅµÉ ¶§ È£ÃâµÉ ÇÔ¼ö¸¦ Á¤ÀÇÇÑ´Ù (Ä¿³Î³»¿¡ Á¤ÀûÀ¸·Î Æ÷ÇԵǴ °æ¿ì¿¡´Â È£ÃâÁöÁö ¾Ê´Â´Ù). ±× ÇÔ¼ö´Â ¿ÀÁ÷ ¸ðµâÀÇ »ç¿ë Ƚ¼ö (usage count) °¡ 0 ÀÌ µÇ´Â °æ¿ì¿¡¸¸ È£ÃâµÉ °ÍÀÌ´Ù. ÀÌ ÇÔ¼öµµ ¿ª½Ã sleep µÉ ¼ö ÀÖÁö¸¸, ½ÇÆÐÇÏÁö´Â ¾Ê´Â´Ù: ¸ðµç ÀÚ·áµéÀº ¸®Å쵃 ¶§ ÇØÁ¦µÇ¾î¾ß ÇÑ´Ù.

6.13. MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT <include/linux/module.h>


ÀÌ ¸ÅÅ©·ÎµéÀº ¸ðµâÀÇ »ç¿ë Ƚ¼ö¸¦ °ü¸®Çؼ­ ¸ðµâÀÌ À߸ø Á¦°ÅµÇ´Â °ÍÀ» ¹æÁöÇϱâ À§ÇØ »ç¿ëµÈ´Ù. (´Ù¸¥ ¸ðµâ¿¡¼­ ÇöÀç ¸ðµâ¿¡¼­ °ø°³ÇÏ°í ÀÖ´Â ½Éº¼À» »ç¿ëÇÏ°í ÀÖ´Â °æ¿ì¿¡ ¸ðµâÀº Á¦°ÅµÉ ¼ö ¾ø´Ù: ¾Æ·¡¸¦ Âü°íÇϱ⠹ٶõ´Ù). (¼ÒÄÏÀ̳ª ¸ðµç ÀڷᱸÁ¶¿Í °°Àº) »ç¿ëÀÚ °ø°£¿¡¼­ÀÇ ¸ðµâ¿¡ ´ëÇÑ ÂüÁ¶´Â Ç×»ó ÇÔ¼ö°¡ sleep ¿¡ µé¾î°¡±â Àü¿¡ ÀÌ »ç¿ë Ƚ¼ö¿¡ ¹Ý¿µµÇ¾î¾ß ÇÑ´Ù. Tim Waugh ÀÇ Äڵ带 ÀοëÇϸé:

/* THIS IS BAD */
foo_open (...)
{
        stuff..
        if (fail)
                return -EBUSY;
        sleep.. (might get unloaded here)
        stuff..
        MOD_INC_USE_COUNT;
        return 0;
}

/* THIS IS GOOD /
foo_open (...)
{
        MOD_INC_USE_COUNT;
        stuff..
        if (fail) {
                MOD_DEC_USE_COUNT;
                return -EBUSY;
        }
        sleep.. (safe now)
        stuff..
        return 0;
}

ȤÀº ÀÌ·¯ÇÑ ¹®Á¦¸¦ ÇØ°áÇϱâ À§ÇØ ¸ðµâÀÇ file_operations ±¸Á¶Ã¼ÀÇ owner Çʵ带 »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÀÌ °ªÀº THIS_MODULE À̶ó´Â ¸ÅÅ©·Î¸¦ ÀÌ¿ëÇØ ¼³Á¤ÇÑ´Ù.

Á»´õ º¹ÀâÇÑ ¸ðµâÀ» ¾ð·ÎµåÇϱâ À§ÇØ lock ÀÌ ÇÊ¿äÇÒ ¼öµµ ÀÖ´Ù. ÀÌ °æ¿ì ¸ðµâ³»¿¡ can_unload ¶ó´Â ÇÔ¼ö¸¦ Á¤ÀÇÇؼ­ À̸¦ ¾Ë¾Æº¼ ¼ö ÀÖ´Ù. ÀÌ ÇÔ¼ö´Â ¸ðµâÀ» ¾ð·ÎµåÇÒ ¼ö ÀÖ´Â °æ¿ì 0 À» ¸®ÅÏÇÏ°í, ±×·¸Áö ¾ÊÀ¸¸é -EBUSY ¸¦ ¸®ÅÏÇØ¾ß ÇÑ´Ù.


7. ´ë±â Å¥ (Wait Queues) <include/linux/wait.h>


''SLEEPS''

´ë±â Å¥´Â ƯÁ¤ Á¶°ÇÀÌ ¸¸Á·µÉ ¶§ ±ú¾î³ª¼­ ½ÇÇàµÇ±â¸¦ ¿øÇÒ ¶§ »ç¿ëµÈ´Ù. ´ë±â Å¥¸¦ »ç¿ëÇÒ ¶§´Â °æÀï Á¶°ÇÀÌ ¹ß»ýÇÏÁö ¾Êµµ·Ï Á¶½ÉÇؼ­ »ç¿ëÇØ¾ß ÇÑ´Ù. ¸ÕÀú wait_queue_head_t ¸¦ ¼±¾ðÇÏ°í, ƯÁ¤ Á¶°ÇÀ» ±â´Ù¸®´Â ÇÁ·Î¼¼½º µéÀ» ÀÚ½ÅÀ» ÂüÁ¶ÇÏ´Â wait_queue_t ·Î ¼±¾ðÇÏ¿© Å¥¿¡ ³Ö´Â´Ù.

7.1. ¼±¾ðÇϱâ


ÃʱâÈ­ ÄÚµå ºÎºÐ¿¡¼­ DECLARE_WAIT_QUEUE_HEAD() ¸ÅÅ©·Î³ª init_waitqueue_head() ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© wait_queue_head_t ¸¦ ¼±¾ðÇÒ ¼ö ÀÖ´Ù.

7.2. Å¥¿¡ ³Ö±â


ÀÚ½ÅÀ» ´ë±â Å¥ ¾È¿¡ ³Ö´Â °ÍÀº ²Ï º¹ÀâÇÑ ÀÏÀÌ´Ù. ¿Ö³ÄÇϸé Á¶°ÇÀ» °Ë»çÇϱâ Àü¿¡ Å¥¿¡ ³Ö¾î¾ß Çϱ⠶§¹®ÀÌ´Ù..? ÀÌ·¯ÇÑ ÀÏÀ» ÇØÁÖ´Â ¸ÅÅ©·Î°¡ ÀÖ´Ù: wait_queue_interruptible() <include/linux/sched.h>. ÀÌ ¸ÅÅ©·ÎÀÇ Ã¹¹ø° ÀÎÀÚ´Â wait queue head °¡ µÇ°í, µÎ¹ø° ÀÎÀÚ´Â Æò°¡µÉ °è»ê½Ä (expression) ÀÌ µÈ´Ù. ÀÌ ¸ÅÅ©·Î´Â °è»ê½ÄÀÌ ÂüÀÏ ¶§ 0 À» ¸®ÅÏÇÏ°í, ½Ã±×³ÎÀ» ¹ÞÀ¸¸é -ERESTARTSYS ¸¦ ¸®ÅÏÇÑ´Ù. (interruptible ÀÌ ¾ø´Â) wait_queue() ¹öÀüÀº °°Àº ÀÏÀ» ÇÏÁö¸¸ ½Ã±×³ÎÀ» ¹«½ÃÇÑ´Ù.

sleep_on() °è¿­ÀÇ ÇÔ¼öµéÀ» »ç¿ëÇÏÁö ¾Êµµ·Ï ÇÑ´Ù - ÀÌ ÇÔ¼öµéÀº °æÀï Á¶°ÇÀ» ºÒ·¯ÀÏÀ¸Å°°ï ÇÑ´Ù. °ÅÀÇ ¸ðµç °æ¿ì¿¡ À־ wait_event() °è¿­ÀÇ ÇÔ¼öµéÀÌ °°Àº ÀÏÀ» ÇØ ÁÙ °ÍÀÌ´Ù. ȤÀº schedule_timeout() ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© ·çÇÁ¸¦ µ¹¸®´Â ¹æ¹ýµµ °¡´ÉÇÏ´Ù. ¸¸¾à schedule_timeout() °ú ·çÇÁ¸¦ »ç¿ëÇϱâ·Î Çß´Ù¸é ¸Å ¹Ýº¹ Áֱ⸶´Ù (set_current_state() ¸¦ ÀÌ¿ëÇÏ¿©) ŽºÅ© »óŸ¦ ¼³Á¤ÇØ¾ß busy-looping À» ÇÇÇÒ ¼ö ÀÖ´Ù.

7.3. Å¥¿¡ µé¾îÀִ ŽºÅ© ±ú¿ì±â


wake_up() <include/linux/sched.h> ¸¦ È£ÃâÇÑ´Ù; ÀÌ ÇÔ¼ö´Â Å¥¿¡ µé¾îÀÖ´Â ¸ðµç ÇÁ·Î¼¼½º¸¦ ±ú¿ì°Ô µÉ °ÍÀÌ´Ù. ¸¸¾à ¾î¶² ŽºÅ©°¡ TASK_EXCLUSIVE ·Î ¼³Á¤µÇ¾î ÀÖ´Ù¸é Å¥¿¡ µé¾îÀÖ´Â ³ª¸ÓÁö ÇÁ·Î¼¼½ºµéÀº ±ú¾î³ªÁö ¾ÊÀ» °ÍÀÌ´Ù.


8. ¿øÀÚÀû ¿¬»ê


ƯÁ¤ ¿¬»êµéÀº ¸ðµç Ç÷§Æû¿¡¼­ ¿øÀÚÀûÀ¸·Î µ¿ÀÛÇÑ´Ù. ÀÌ·¯ÇÑ ¿¬»êµéÀÇ Ã¹¹ø° ºÎ·ù´Â <include/asm/atomic.h> ¿¡ Á¤ÀÇµÈ atomic_t ¶ó´Â ŸÀÔ°ú ÇÔ²² ¼öÇàµÇ´Â ¿¬»êµéÀÌ´Ù; atomic_t ´Â ºÎȣȭµÈ Á¤¼öÇü (ÃÖ¼Ò 24 ºñÆ®) À̸ç atomic_t ·Î ¼±¾ðµÈ º¯¼ö¿¡ Á¢±ÙÇÒ ¶§´Â ¹Ýµå½Ã ÀÌ·¯ÇÑ ÇÔ¼öµéÀ» ÀÌ¿ëÇØ¾ß ÇÑ´Ù. atomic_read() ¿Í atomic_set() ÇÔ¼ö´Â º¯¼ö°ªÀ» Àоî¿À°í ¼³Á¤ÇÏ´Â µ¥ »ç¿ëµÇ¸ç atomic_add(), atomic_sub(), atomic_inc(), atomic_dec(), atomic_dec_and_test() (0 À¸·Î °¨¼ÒµÇ¸é true ¸¦ ¸®ÅÏÇÑ´Ù) µîÀÇ ÇÔ¼ö°¡ ÀÖ´Ù.

ÀÌ·¯ÇÑ ÇÔ¼öµéÀº ÀϹÝÀûÀÎ »ê¼ú ¿¬»êµé¿¡ ºñÇØ ´À¸®°Ô µ¿ÀÛÇϹǷÎ, ºÒÇÊ¿äÇÏ°Ô »ç¿ëµÇ¾î¼­´Â ¾ÈµÈ´Ù. ¶ÇÇÑ spinlock À» »ç¿ëÇÏ´Â 32-bit Sparc ¸Ó½Å°ú °°Àº ƯÁ¤ÇÑ Ç÷§Æû¿¡¼­´Â ´õ¿í ´À¸®°Ô µ¿ÀÛÇÑ´Ù.

¿øÀÚÀûÀ¸·Î ¼öÇàµÇ´Â ¿¬»êÀÇ µÎ¹ø° ºÎ·ù´Â <include/asm/bitops.h> ¿¡ Á¤ÀÇµÈ long ŸÀÔ¿¡ Àû¿ëµÇ´Â ¿øÀÚÀûÀÎ ºñÆ® ¿¬»êÀÌ´Ù. ÀÌ·¯ÇÑ ¿¬»êµéÀº ÀϹÝÀûÀ¸·Î ºñÆ® ÆÐÅÏÀÇ Æ÷ÀÎÅÍ¿Í ºñÆ® ¹øÈ£¸¦ ÀÎÀÚ·Î ¹Þ´Â´Ù: ºñÆ® ¹øÈ£ 0 Àº LSB (Least Significant Bit) ÀÌ´Ù. set_bit(), clear_bit(), change_bit() ¿Í °°Àº ÇÔ¼öµéÀº °¢°¢ ƯÁ¤ ºñÆ®°ªÀ» 1·Î ¼³Á¤Çϰųª, 0À¸·Î ¼³Á¤Çϰųª, ÇöÀç°ªÀ» ¹Ù²Ù´Â (flip) ¿¬»êÀ» ¼öÇàÇÑ´Ù. test_and_set_bit(), test_and_clear_bit(), test_and_change_bit() µµ °°Àº ÀÏÀ» ¼öÇàÇÏÁö¸¸, ÇØ´ç ºñÆ®°¡ ÀÌ¹Ì 1·Î ¼³Á¤µÇ¾î ÀÖ´Â °æ¿ì¿¡´Â true ¸¦ ¸®ÅÏÇÑ´Ù. ÀÌ ÇÔ¼öµéÀº ¾ÆÁÖ °£´ÜÇÑ locking À» ±¸ÇöÇϴµ¥ À¯¿ëÇÏ°Ô »ç¿ëµÈ´Ù.

ÀÌ·¯ÇÑ ÇÔ¼öµéÀ» BITS_PER_LONG º¸´Ù Å« ºñÆ® ¹øÈ£¿Í ÇÔ²² È£ÃâÇÏ´Â °Íµµ °¡´ÉÇÏ´Ù. ÇÏÁö¸¸ big-endian Ç÷§Æû¿¡¼­ ÀÌ»óÇÑ µ¿ÀÛÀ» ÀÏÀ¸Å°°Ô µÇ¹Ç·Î ÀÌ·¸°Ô Çϴ°ÍÀº ±×¸® ÁÁÀº ¾ÆÀ̵ð¾î°¡ ¾Æ´Ï´Ù.

ºñÆ®ÀÇ ¼ø¼­´Â Ç÷§Æû¿¡ µû¶ó ´Þ¶óÁú ¼ö ÀÖ´Ù´Â °Í°ú, ƯÈ÷ ÀÌ ÇÔ¼öµéÀÇ ÀÎÀÚ·Î ³Ñ°ÜÁö´Â ºñÆ® ÆÐÅÏÀÇ ±æÀÌ´Â ÃÖ¼ÒÇÑ long ŸÀÔº¸´Ù Ä¿¾ß ÇÑ´Ù´Â »ç½Ç¿¡ ÁÖÀÇÇ϶ó.


9. ½Éº¼


Ä¿³Î ³»¿¡¼­´Â ÀϹÝÀûÀÎ ¸µÅ· ¹ýÄ¢ÀÌ Àû¿ëµÈ´Ù. (Áï, static À̶ó´Â Å°¿öµå¸¦ ÅëÇØ file scope ·Î ¼±¾ðµÈ ½Éº¼ÀÌ ¾Æ´Ï¶ó¸é, Ä¿³Î ³»ÀÇ ¾î´À °÷¿¡¼­³ª »ç¿ëµÉ ¼ö ÀÖ´Ù.) ÇÏÁö¸¸, ¸ðµâ¿¡ ´ëÇؼ­´Â Ä¿³Î¿¡ ´ëÇÑ Á¢±ÙÁ¡À» Á¦ÇÑÇϱâ À§ÇØ Æ¯º°È÷ ¿ÜºÎ·Î °ø°³ (export) µÈ ½Éº¼ Å×À̺íÀ» À¯ÁöÇÑ´Ù. ¹°·Ð ¸ðµâµµ ½Éº¼À» °ø°³ÇÒ ¼ö ÀÖ´Ù.

9.1. EXPORT_SYMBOL() <include/linux/module.h>


ÀÌ ¹æ¹ýÀº ½Éº¼À» °ø°³ÇÏ´Â ÀϹÝÀûÀÎ ¹æ¹ýÀ̸ç, ¸ðµâÀÌ°Ç ¾Æ´Ï°Ç ´Ù »ç¿ëÇÒ ¼ö ÀÖ´Â ¹æ¹ýÀÌ´Ù. Ä¿³Î ³»¿¡¼­´Â ÀÌ·¯ÇÑ ¸ðµç ¼±¾ðµéÀº genksyms (Ä¿³Î ½Éº¼À» »ý¼ºÇÏ´Â ÇÁ·Î±×·¥ - ÀÌ·¯ÇÑ ¼±¾ðµéÀ» ã±â À§ÇØ ¸ðµç ÆÄÀÏÀ» °Ë»öÇÑ´Ù.) ¸¦ À§Çؼ­ ÇϳªÀÇ ÆÄÀÏ·Î ¸ð¾Æ³õ±âµµ ÇÑ´Ù. genksyms ³ª Makefile ÀÇ ÁÖ¼®À» »ìÆ캸±â ¹Ù¶õ´Ù.

9.2. EXPORT_NO_SYMBOLS <include/linux/module.h>


¸¸¾à ¸ðµâÀÌ ¾Æ¹«·± ½Éº¼µµ °ø°³ÇÏÁö ¾Ê´Â´Ù¸é ¸ðµâ ³»ÀÇ ¾î´À°÷¿¡¼­°Ç ´ÙÀ½°ú °°ÀÌ Àû¾îÁÖ¸é µÈ´Ù.

EXPORT_NO_SYMBOLS;

Ä¿³Î 2.4 ¹öÀüÀ̳ª ±× ÀÌÀü ¹öÀü¿¡¼­´Â, ¸ðµâÀÌ EXPORT_SYMBOL() À̳ª EXPORT_NO_SYMBOLS ¸¦ Æ÷ÇÔÇÏÁö ¾ÊÀ¸¸é ±âº»ÀûÀ¸·Î static ÀÌ ¾Æ´Ñ ¸ðµç Àü¿ª ½Éº¼µéÀ» °ø°³ÇÑ´Ù. Ä¿³Î 2.5 ¹öÀü ÀÌÈÄ¿¡´Â ½Éº¼À» °ø°³ÇÒÁö ¸»Áö¸¦ ¸í½ÃÀûÀ¸·Î Ç¥½ÃÇØ¾ß ÇÑ´Ù.

9.3. EXPORT_SYMBOL_GPL() <include/linux/module.h>


EXPORT_SYMBOL() °ú µ¿ÀÏÇÏÁö¸¸ EXPORT_SYMBOL_GPL() ·Î °ø°³µÈ ½Éº¼µéÀº GPL °ú ȣȯµÇ´Â ¶óÀ̼¾½º·Î MODULE_LICENSE() ¸¦ µî·ÏÇÑ ¸ðµâ¿¡¼­¸¸ º¸¿©Áø´Ù.


10. Routines and Conventions


10.1. Doubly-Linked Lists <include/linux/list.h>


Ä¿³ÎÀÇ Çì´õ¿¡´Â ¼¼°¡Áö Á¾·ùÀÇ ¸µÅ©µå ¸®½ºÆ® ·çƾÀÌ Á¸ÀçÇÑ´Ù. ±×Áß¿¡¼­µµ °¡Àå ¸¹ÀÌ »ç¿ëµÇ´Â °ÍÀÌ ¹Ù·Î À§ÀÇ °ÍÀÌ´Ù. (Linus µµ ÀÌ°ÍÀ» »ç¿ëÇÑ´Ù) ¸¸¾à ´ç½ÅÀÌ ¹Ýµå½Ã ´Ü¼ø ¸µÅ©µå ¸®½ºÆ®¸¦ »ç¿ëÇØ¾ß ÇÏ´Â »óȲÀÌ ¾Æ´Ï¶ó¸é ÀÌ°ÍÀ» »ç¿ëÇÏ´Â °ÍÀÌ ÁÁÀº ¼±ÅÃÀÏ °ÍÀÌ´Ù. »ç½Ç, ³ª´Â ÀÌ°ÍÀÌ ÁÁÀ¸³Ä ÁÁÁö ¾ÊÀ¸³Ä¸¦ ¶°³ª¼­, ´ÜÁö ´Ù¸¥ ¸µÅ©µå ¸®½ºÆ® ±¸ÇöµéÀ» ¾ø¾Ö¹ö¸± ¸ñÀûÀ¸·Î »ç¿ëÇÏ°í ÀÖ´Ù.

10.2. ¸®ÅÏ°ª¿¡ ´ëÇÑ ÀüÅë


user context ³»¿¡¼­ È£ÃâµÇ´Â ÇÔ¼öµéÀº ´ëºÎºÐ C ¾ð¾îÀÇ ÀüÅë (Convention) À» ¹«½ÃÇÑ´Ù - ¼º°ø½Ã¿¡´Â 0 À», ½ÇÆнÿ¡´Â (-EFAULT °°Àº) À½¼ö°ªÀÎ ¿¡·¯ Äڵ带 ¸®ÅÏÇÑ´Ù. óÀ½¿¡´Â ÀÌ°ÍÀÌ Á÷°üÀûÀÌÁö ¾ÊÀ» ¼öµµ ÀÖ°ÚÁö¸¸, ³×Æ®¿öÅ© ÇÁ·Î±×·¡¹Ö °°Àº °÷¿¡¼­´Â ²Ï ³Î¸® »ç¿ëµÇ°í ÀÖ´Ù.

ÆÄÀÏ ½Ã½ºÅÛ Äڵ忡¼­´Â ERR_PTR() <include/linux/fs.h> ¸ÅÅ©·Î¸¦ ÀÌ¿ëÇÑ´Ù; À½¼ö°ªÀÎ ¿¡·¯ Äڵ带 Æ÷ÀÎÅÍ·Î ÀÎÄÚµùÇÑ ÈÄ, IS_ERR() ³ª PTR_ERR() ¿Í °°Àº ¸ÅÅ©·Î¸¦ ÀÌ¿ëÇÏ¿© ´Ù½Ã ¾ò¾î¿Â´Ù; À̸¦ ÀÌ¿ëÇÏ¸é ¿¡·¯ Äڵ带 ¾ò±âÀ§ÇÑ Æ÷ÀÎÅ͸¦ µû·Î ÀÎÀÚ·Î ³Ñ±âÁö ¾Ê¾Æµµ µÈ´Ù. Á» ÀÌ»óÇØ º¸ÀÌÁö¸¸, ÁÁÀº ¹æ¹ýÀÌ´Ù.

10.3. Breaking Compilation


Linus ³ª ´Ù¸¥ Ä¿³Î °³¹ßÀÚµéÀº °¡²û °³¹ßÁßÀÎ Ä¿³Î³»ÀÇ ÇÔ¼ö³ª ±¸Á¶Ã¼ À̸§À» ¹Ù²Ù±âµµ ÇÑ´Ù. ÀÌ°ÍÀº ºÎºÐÀûÀÎ º¯È­¸¸ÀÌ ¾Æ´Ñ ±âº»ÀûÀÎ º¯È­¸¦ ¸»ÇÏ´Â °ÍÀÌ´Ù. (Áï, ´õÀÌ»ó ÀÎÅÍ·´Æ®°¡ È°¼ºÈ­ µÈ »óÅ¿¡¼­ È£ÃâµÇ°Å³ª, º°µµÀÇ Ã¼Å©°¡ ÀÌ·ç¾îÁö´Â ºÎºÐ, ÀÌÀü¿¡ üũÇß´ø ºÎºÐ µîÀÌ °Ë»çµÇÁö ¾ÊÀ» ¼öµµ ÀÖ´Ù´Â °ÍÀ» ¸»ÇÑ´Ù) º¸Åë ÀÌ·¯ÇÑ º¯È­°¡ ÀϾ´Â °æ¿ì¿¡´Â ¸®´ª½º Ä¿³Î ¸ÞÀϸµ¸®½ºÆ®¿¡ ±×¿¡ ÇØ´çÇÏ´Â ¼³¸íÀÌ ÀÖÀ» °ÍÀÌ´Ù; ¾ÆÄ«À̺긦 °Ë»öÇØ º¸ÀÚ. ´Ü¼øÈ÷ ÆÄÀÏ ³»¿¡¼­ Àü¿ªÀûÀÎ ¹®ÀÚ¿­ ġȯÀ» ÇÏ´Â °ÍÀº ¹®Á¦¸¦ ´õ¿í Ä¿Áö°Ô ÇÒ °ÍÀÌ´Ù.

10.4. ±¸Á¶Ã¼ º¯¼ö ÃʱâÈ­


±¸Á¶Ã¼ÀÇ ¸â¹ö¸¦ ÃʱâÈ­ÇÏ´Â ÁÁÀº ¹æ¹ýÀ¸·Î´Â ISO C99 ¿¡ Á¤ÀÇµÈ designated initializer ¸¦ »ç¿ëÇÏ´Â °ÍÀÌ ÀÖ´Ù.

static struct block_device_operations opt_fops = {
        .open               = opt_open,
        .release            = opt_release,
        .ioctl              = opt_ioctl,
        .check_media_change = opt_media_change,
};

ÀÌ ¹æ¹ýÀº grep À¸·Î °Ë»öÇÏ´Â °ÍÀ» ´õ¿í ¿ëÀÌÇÏ°Ô ÇØÁÖ¸ç, ¾î¶°ÇÑ ¸â¹öµéÀÌ ÁöÁ¤µÇ´ÂÁö¸¦ ¸íÈ®ÇÏ°Ô º¸¿©ÁØ´Ù. ´ç½Åµµ ÀÌ ¹æ¹ýÀ» »ç¿ëÇÏ´Â °ÍÀÌ ÁÁÀ» °ÍÀÌ´Ù.

10.5. GNU È®Àå


GNU È®Àå (Extension) Àº ¸®´ª½º Ä¿³Î ³»¿¡¼­ ¸í½ÃÀûÀ¸·Î Çã¿ëµÈ´Ù. ´Ù¸¥ º¹ÀâÇÑ °ÍµéÀº ÀϹÝÀûÀ¸·Î »ç¿ëµÇÁö ¾ÊÀ¸¹Ç·Î ±×´ÙÁö Àß Áö¿øµÇÁö ¾ÊÁö¸¸, ´ÙÀ½°ú °°Àº °ÍµéÀº °ÅÀÇ Ç¥ÁØ°ú °°ÀÌ »ý°¢µÇ°í ÀÖ´Ù (´õ¿í ÀÚ¼¼ÇÑ »çÇ×Àº GCC info ÆäÀÌÁöÀÇ "C Extension" ÀýÀ» º¸±â ¹Ù¶õ´Ù - man ÆäÀÌÁö´Â info ÆäÀÌÁöÀÇ ÂªÀº ¿ä¾àº»¿¡ ºÒ°úÇÏ´Ù):

  • inline ÇÔ¼ö
  • statement expression (Áï ({ °ú }) °°Àº °Í)
  • ÇÔ¼ö/º¯¼ö/ŸÀÔÀÇ ¼Ó¼º ¼±¾ð (attribute)
  • labeled elements
  • typeof
  • ±æÀÌ°¡ 0 ÀÎ ¹è¿­
  • °¡º¯±æÀÌ ÀÎÀÚ¸¦ °¡Áö´Â ¸ÅÅ©·Î (Macro varargs)
  • void Æ÷ÀÎÅÍÀÇ »ê¼ú¿¬»ê
  • »ó¼ö°¡ ¾Æ´Ñ ÃʱⰪ
  • ¾î¼Àºí·¯ ¸í·É (arch/ ¿Í include/asm/ ³»ºÎ)
  • ¹®ÀÚ¿­ ÇÔ¼ö¸í (FUNCTION)
  • __builtin_constant_p()

Ä¿³Î ³»¿¡¼­ long long ŸÀÔÀ» »ç¿ëÇÒ ¶§¿¡´Â ÁÖÀǸ¦ ±âÇ϶ó. gcc °¡ »ý¼ºÇÏ´Â ÄÚµå´Â ²ûÂïÇÏ´Ù: GCC ÀÇ runtime ÇÔ¼ö´Â Ä¿³Î ȯ°æ¿¡¼­ Á¦¿ÜµÇ±â ¶§¹®¿¡ °ö¼À°ú ³ª´°¼ÀÀº i386 ¿¡¼­ µ¿ÀÛÇÏÁö ¾ÊÀ» °ÍÀÌ´Ù...? (division and multiplication does not work on i386 because the GCC runtime functions for it are missing from the kernel environment.)

10.6. C++


Ä¿³Î ³»¿¡¼­ C++ ¸¦ »ç¿ëÇÏ´Â °ÍÀº º¸Åë ÁÁÁö ¾ÊÀº »ý°¢ÀÌ´Ù. Ä¿³Î ³»¿¡¼­´Â ÇÊ¿äÇÑ runtime environment ¸¦ Á¦°øÇÏÁö ¾ÊÀ¸¸ç Å×½ºÆ®µÇÁö ¾ÊÀº ÆÄÀϵéÀ» Æ÷ÇÔÇØ¾ß Çϱ⠶§¹®ÀÌ´Ù. C++ ¸¦ »ç¿ëÇÏ´Â °ÍÀº °¡´ÉÇÏÁö¸¸, ±ÇÇÏ°í ½ÍÁö ¾Ê´Ù. ¸¸¾à ´ç½ÅÀÌ ÁøÁ¤ C++ ¸¦ »ç¿ëÇÏ°í ½Í´Ù¸é, ÃÖ¼ÒÇÑ ¿¹¿Ü (exception) ¿¡ °üÇÑ °ÍµéÀº Àر⸦ ¹Ù¶õ´Ù.

10.7. #if


ÀϹÝÀûÀ¸·Î ¼Ò½º ÄÚµå ³»¿¡¼­ #if Àü󸮱â Áö½Ã¹®À» »ç¿ëÇÏ´Â °Íº¸´Ù Çì´õ ÆÄÀÏ ³»¿¡¼­ (ȤÀº ¼Ò½º ÆÄÀÏÀÇ ÃÖ»óÀ§ ºÎºÐ¿¡¼­) ¸ÅÅ©·Î¸¦ »ç¿ëÇÏ¿© ÇÔ¼öÀÇ ±âº»ÇüÀ» »Ì¾ÆµÎ´Â °ÍÀÌ ´õ ±ò²ûÇÏ´Ù.


11. ´ç½ÅÀÇ Äڵ带 Ä¿³Î³»¿¡ ³Ö´Â ¹æ¹ý


´ç½ÅÀÌ ÀÛ¼ºÇÑ Äڵ带 Ä¿³Î ³»¿¡ Á¤½ÄÀ¸·Î Æ÷ÇԵǴ ÇüÅ·Π¸¸µé°í ½Í°Å³ª, ´ÜÁö ÆÐÄ¡ÀÇ ÇüÅÂÀÇ ¸¸µé°í ½ÍÀ»¶§¶óµµ ´ÙÀ½°ú °°Àº °ü¸®ÀûÀÎ Â÷¿øÀÇ ÀÛ¾÷ÀÌ ÇÊ¿äÇØ Áø´Ù:

  • ´ç½ÅÀÌ ÀÛ¾÷ÇÑ ºÎºÐ¿¡ ´ëÇÑ °ü¸®¸¦ ¸Ã°íÀÖ´Â »ç¶÷ÀÌ ´©±¸ÀÎÁö È®ÀÎÇ϶ó. ¼Ò½º ÆÄÀÏÀÇ ¸Ç À­ºÎºÐ°ú, MAINTAINERS ÆÄÀÏ°ú, CREDITS ÆÄÀÏÀ» »ìÆ캸±â ¹Ù¶õ´Ù. Áߺ¹µÈ ³ë·ÂÀ» ÇÇÇϰųª ȤÀº ÀÌ¹Ì ÇÏÁö ¾Ê±â·Î °áÁ¤µÈ ÀÛ¾÷¿¡ ¶Ù¾îµéÁö ¾Ê±â À§Çؼ­ ´ç½ÅÀº ÀÌ »ç¶÷µé°ú ÀÇ°ßÀ» Á¶Á¤ÇØ¾ß ÇÑ´Ù.

    ´ç½ÅÀÌ »õ·Î ¸¸µé°Å³ª Å©°Ô ¼öÁ¤ÇÑ ÆÄÀÏÀÇ ¸Ç À­ºÎºÐ¿¡ ´ç½ÅÀÇ À̸§°ú e-mail ÁÖ¼Ò¸¦ Àû¾îµÎ´Â °ÍÀ» ÀØÁö¸¶¶ó. »ç¶÷µéÀÌ ¹ö±×¸¦ ã°Å³ª ¼öÁ¤À» ¿ä±¸ÇÒ ¶§ °¡Àå ¸ÕÀú º¸°ÔµÇ´Â ºÎºÐÀÌ ¹Ù·Î ±× ºÎºÐÀÌ´Ù.

  • º¸Åë ´ç½ÅÀÌ ÀÛ¾÷ÇÑ ºÎºÐ¿¡ ´ëÇÑ Ä¿³Î ¼³Á¤ ¿É¼ÇÀ» ³Ö±â¸¦ ¿øÇÒ °ÍÀÌ´Ù. ÀûÀýÇÑ µð·ºÅ丮ÀÇ Config.in ÆÄÀÏÀ» ÆíÁýÇ϶ó (ÇÏÁö¸¸ arch/ µð·ºÅ丮¿¡¼­´Â (¼Ò¹®ÀÚ) config.in ÆÄÀÏÀÌ´Ù). ¼³Á¤ ÆÄÀÏ¿¡ »ç¿ëµÇ´Â ¾ð¾î´Â bash °¡ ¾Æ´ÏÁö¸¸, bash ¿Í ºñ½ÁÇÏ°Ô º¸ÀδÙ; ¾ÈÀüÇÑ ¹æ¹ýÀº ÀÌ¹Ì Config.in ÆÄÀÏµé ¾È¿¡¼­ »ç¿ëµÈ ÇüŸ¸À» »ç¿ëÇÏ´Â °ÍÀÌ´Ù. (ÀÚ¼¼ÇÑ »çÇ×Àº Documentation/kbuild/config-language.txt ÆÄÀÏÀ» º¸±â ¹Ù¶õ´Ù) ¼³Á¤ ÆÄÀÏÀ» ÀÛ¼ºÇÑ ÈÄ¿¡ Å×½ºÆ®¸¦ À§ÇØ (Á¤Àû parser ¸¦ ÀÌ¿ëÇÏ´Â) make xconfig ¸¦ ÃÖ¼ÒÇÑ Çѹø ÀÌ»ó ½ÇÇà½ÃÄÑ º¸´Â °ÍÀÌ ÁÁ´Ù.

    (CONFIG_ ·Î ½ÃÀÛÇÏ´Â) ¼³Á¤ º¯¼ö´Â Y ³ª N ÀÇ µÑ ÁßÀÇ ÇϳªÀÇ °ªÀ» °¡Áø´Ù. »ï»ó ÇÔ¼ö (tristate function) µµ ÀÌ¿Í µ¿ÀÏÇÏÁö¸¸ CONFIG_MODULE ÀÌ È°¼ºÈ­ µÈ °æ¿ì, M À» ÅÃÇÒ ¼ö ÀÖ´Ù. (ÀÌ °æ¿ì ¼³Á¤ º¯¼ö À̸§Àº CONFIG_FOO °¡ ¾Æ´Ñ CONFIG_FOO_MODULE ÀÌ µÉ °ÍÀÌ´Ù)

    ¶Ç´Â ´ç½ÅÀÇ ¿É¼ÇÀ» CONFIG_EXPERIMENTAL ÀÌ È°¼ºÈ­ µÈ °æ¿ì¿¡¸¸ º¸¿©ÁÖ°Ô ÇÏ°í ½ÍÀ» ¼öµµ ÀÖ´Ù; ÀÌ°ÍÀº »ç¿ëÀÚ¿¡°Ô °æ°í¸¦ ÇØ ÁÖ´Â °ÍÀÌ´Ù. ÀÌ ¹Û¿¡µµ ¿©·¯°¡Áö ÀϵéÀÌ °¡´ÉÇÏ´Ù; ¾ÆÀ̵ð¾î¸¦ ¾ò±â À§ÇØ ¿©·¯ Config.in ÆÄÀÏÀ» »ìÆ캸¶ó.

  • Makefile À» ¼öÁ¤Ç϶ó: ¼³Á¤ º¯¼öµéÀº ¿©±â¼­ Àоî¿Ã ¼ö ÀÖÀ¸¹Ç·Î ifeq ¸¦ ÀÌ¿ëÇÏ¿© ¼±ÅÃÀûÀ¸·Î ÄÄÆÄÀÏ Çϵµ·Ï Á¶Á¤ÇÒ ¼ö ÀÖ´Ù. ´ç½ÅÀÇ ÆÄÀÏÀÌ ½Éº¼À» °ø°³ÇÑ´Ù¸é export-objs ºÎºÐ¿¡ ÆÄÀÏ À̸§À» Ãß°¡Çؼ­ genksyms °¡ ½Éº¼À» ãÀ» ¼ö ÀÖ°Ô ÇÑ´Ù.

    /!\ ½Ã½ºÅÛÀ» ±¸¼ºÇÒ Ä¿³Î¿¡¼­´Â ½Éº¼À» °ø°³ÇÏ´Â °´Ã¼´Â ¹Ýµå½Ã À¯ÀÏÇÑ À̸§À» °¡Á®¾ß ÇÑ´Ù´Â Á¦ÇÑ»çÇ×ÀÌ ÀÖ´Ù. ¸¸¾à ´ç½ÅÀÇ °´Ã¼°¡ À¯ÀÏÇÑ À̸§À» °¡ÁöÁö ¾Ê´Â´Ù¸é, À¯ÀÏÇÑ À̸§À» °¡Áö´Â °´Ã¼¸¦ »ý¼ºÇÏ¿© EXPORT_SYMBOL() ¹®À» ±×°÷À¸·Î ¿Å±â´Â ¹æ¹ýÀÌ ÀϹÝÀûÀÌ´Ù. ÀÌ°ÍÀº ¸î¸î ½Ã½ºÅÛ¿¡¼­ ksyms ·Î ³¡³ª´Â °ø°³µÈ °´Ã¼µéÀÌ Á¸ÀçÇÏ´Â ÀÌÀ¯ÀÌ´Ù.

  • ´ç½ÅÀÇ ÀÇ°ßÀ» Document/Configure.help ÆÄÀÏ¿¡ ÀÛ¼ºÇ϶ó. ºñȣȯ¼º°ú ¹®Á¦Á¡ µîÀ» ¿©±â¿¡ ±â·ÏÇÑ´Ù. ±×¸®°í ¸¶Áö¸·¿¡ Àß ¸ð¸£´Â »ç¶÷µéÀ» À§ÇØ "if in doubt, say N" (ȤÀº "Y" °¡ µÉ¼öµµ ÀÖ´Ù) °ú °°Àº ¾È³»¹®±¸¸¦ ³²°Ü³õÀº °ÍÀÌ Áß¿äÇÏ´Ù.

  • ¸¸¾à ´ç½ÅÀÌ Áß¿äÇÑ °øÇåÀ» Çß´Ù¸é (º¸Åë Çϳª ÀÌ»óÀÇ ÆÄÀÏ¿¡ ´ëÇØ ÀÛ¾÷ÇßÀ» °ÍÀÌ´Ù) CREDITS ÆÄÀÏ¿¡ ÀÚ½ÅÀ» Ãß°¡ÇÑ´Ù. (¹°·Ð ¼Ò½º ÆÄÀÏÀÇ °¡Àå À§¿¡ ´ç½ÅÀÇ À̸§ÀÌ ÀûÇôÀÖ¾î¾ß ÇÑ´Ù) MAINTAINERS ´Â ´ç½ÅÀÌ ¼öÁ¤µÈ ³»¿ë¿¡ ÀÇÇØ ¸¸µé¾îÁø ÇϺΠ±¸Á¶¿¡ ´ëÇØ »ó´ãÇØ Áְųª ¹ö±×¿¡ °üÇÑ ³»¿ëÀ» µè±â¸¦ ¿øÇÑ´Ù´Â °ÍÀ» ÀǹÌÇÑ´Ù; ÀÌ°ÍÀº ÄÚµåÀÇ Æ¯Á¤ ºÎºÐ¿¡ ´ëÇØ Ã¥ÀÓÀ» Áö´Â °Í ÀÌ»óÀÇ ÀÏÀÌ µÉ °ÍÀÌ´Ù.

  • ¸¶Áö¸·À¸·Î, Documentation/SubmittingPatches °ú °¡´ÉÇÑÇÑ Documentation/SubmittingDrivers ÆÄÀÏÀ» Àд °ÍÀ» ÀØÁö ¸»ÀÚ.


12. Kernel Cantrips


´ÙÀ½Àº ¼Ò½º Äڵ带 »ìÆ캸´Ù°¡ ¹ß°ßÇÑ Èï¹Ì·Î¿î °ÍµéÀÌ´Ù. ÀÚÀ¯·Ó°Ô Ãß°¡ÇØ ÁÖ±æ ¹Ù¶õ´Ù.

include/linux/brlock.h:

extern inline void br_read_lock (enum brlock_indices idx)
{
        /*
         * This causes a link-time bug message if an
         * invalid index is used:
         */
        if (idx >= __BR_END)
                __br_lock_usage_bug();

        read_lock(&__brlock_array[smp_processor_id()][idx]);
}

include/linux/fs.h:

/*
 * Kernel pointers have redundant information, so we can use a
 * scheme where we can return either an error code or a dentry
 * pointer with the same return value.
 *
 * This should be a per-architecture thing, to allow different
 * error and pointer decisions.
 */
 #define ERR_PTR(err)    ((void *)((long)(err)))
 #define PTR_ERR(ptr)    ((long)(ptr))
 #define IS_ERR(ptr)     ((unsigned long)(ptr) > (unsigned long)(-1000))

include/asm-i386/uaccess.h:

#define copy_to_user(to,from,n)                         \
        (__builtin_constant_p(n) ?                      \
         __constant_copy_to_user((to),(from),(n)) :     \
         __generic_copy_to_user((to),(from),(n)))

arch/sparc/kernel/head.S:

/*
 * Sun people can't spell worth damn. "compatability" indeed.
 * At least we *know* we can't spell, and use a spell-checker.
 */

/* Uh, actually Linus it is I who cannot spell. Too much murky
 * Sparc assembly will do this to ya.
 */
C_LABEL(cputypvar):
        .asciz "compatability"

/* Tested on SS-5, SS-10. Probably someone at Sun applied a spell-checker. */
        .align 4
C_LABEL(cputypvar_sun4m):
        .asciz "compatible"

arch/sparc/lib/checksum.S:

/* Sun, you just can't beat me, you just can't.  Stop trying,
         * give up.  I'm serious, I am going to kick the living shit
         * out of you, game over, lights out.
         */


13. °¨»çÀÇ ±Û


¾ÆÀ̵ð¾î¸¦ ÁÖ°í, ³» Áú¹®¿¡ ´äÇØ ÁÖ¾úÀ¸¸ç, ½Ç¼ö¸¦ °íÃÄÁÖ°í, ³»¿ëÀ» dzºÎÇÏ°Ô ÇØ ÁÖ´Â µî ¸¹Àº ÀÏÀ» µµ¿ÍÁØ Andi Kleen ¿¡°Ô °¨»çÇÑ´Ù. öÀÚ¸¦ È®ÀÎÇØ ÁÖ°í, ºÒ¸í·áÇÑ ºÎºÐ¿¡ ´ëÇØ ÁöÀûÇØ ÁØ Philipp Rumpf ¿¡°Ôµµ °¨»çÇÑ´Ù. disable_irq() ºÎºÐÀ» Àß Á¤¸®ÇØ ÁØ Werner Almesberger ¿Í, ƯÇã±Ç º¸È£ ½Åû? (caveat) À» Ãß°¡ÇØÁØ Jes Sorensen ¿Í Andrea Arcangeli ¿¡°Ôµµ °¨»çÇÑ´Ù. Michael Elizabeth Chastain Àº ¼³Á¤ ºÎºÐ¿¡ ´ëÇØ °Ë»çÇØÁÖ°í ³»¿ëÀ» Ãß°¡ÇØ ÁÖ¾ú´Ù. DocBook À» °¡¸£ÃÄÁØ Telsa Gwynne ¿¡°Ôµµ °¨»çÇÑ´Ù.
----
  • [1] ¿ªÀÚÁÖ: ÇÁ·Î¼¼½º°¡ Ä¿³Î ¸ðµå¿¡¼­ µ¿ÀÛÇÏ°í ÀÖ´Â »óŸ¦ ¸»ÇÏ´Â °ÍÀÌ´Ù. ÀÌ ±ÛÀ» Àд µ¶ÀÚµéÀÌ Ä¿³Î¿µ¿ª¿¡¼­ ÇÁ·Î±×·¡¹ÖÀ» Çϱ⠶§¹®¿¡ ÀÌ·¸°Ô ºÎ¸£´Â °Í °°´Ù.
  • [2] ¿ªÀÚÁÖ: ÇϳªÀÇ tasklet ÀÌ ¿©·¯ CPU ¿¡¼­ Áߺ¹µÇ¾î ½ÇÇàµÇÁö ¾Ê´Â °ÍÀ» º¸ÀåÇÑ´Ù.
  • [3] ¿ªÀÚÁÖ: Á¤¼ö ¿¬»êÀ» ¸»ÇÏ´Â °ÍÀÌ´Ù.
  • [4] Memory Management Unit
  • [5] ¿ªÀÚÁÖ: °¢ CPU ¸¶´Ù local_bh_count ¶ó´Â °ªÀ» À¯ÁöÇÑ´Ù
  • [6] ¿ªÀÚÁÖ: i386 ¿¡¼­´Â µ¿ÀÏÇÑ °ªÀÌ´Ù

ID
Password
Join
Expect a letter from a friend who will ask a favor of you.


sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2005-06-17 09:48:21
Processing time 0.0209 sec