· 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
Your mode of life will be changed for the better because of good news soon.


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.0018 sec