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. ¼Ò°³ ¶Rusty ÀÇ Unreliable Guide to Linux Kernel Hacking ¹®¼¸¦ Àаí ÀÖ´Â ¿©·¯ºÐÀ» ȯ¿µÇÑ´Ù.
ÀÌ ¹®¼´Â Ä¿³Î Äڵ忡¼ »ç¿ëµÇ´Â °øÅëÀûÀÎ ·çƾµé°ú ÀϹÝÀûÀÎ ¿ä±¸»çÇ×µéÀ» ¼³¸íÇÏ°í ÀÖ´Ù:
ÀÌ ¹®¼ÀÇ ¸ñÀûÀº ¼÷·ÃµÈ C ÇÁ·Î±×·¡¸Óµé¿¡°Ô ¸®´ª½º Ä¿³Î °³¹ß¿¡ ´ëÇÑ ÀÔ¹®¼·Î¼ »ç¿ëµÇ°íÀÚ ÇÏ´Â °ÍÀÌ´Ù.
ÀÌ ¹®¼¿¡¼´Â ±¸Ã¼ÀûÀÎ ±¸Çö¿¡ °üÇÑ ºÎºÐÀº ´Ù·çÁö ¾Ê´Â´Ù
ÀÌ ¹®¼¸¦ Àбâ Àü¿¡, ÇÑ°¡Áö »ç½ÇÀ» ÀÌÇØÇØ Áֱ⠹ٶõ´Ù.
»ç½Ç °³ÀÎÀûÀ¸·Î ³ª´Â ÀüüÀûÀ¸·Î ¸¸Á·½º·´Áö ¸øÇÑ ¼öÁØÀÇ ÀÌ ¹®¼¸¦ ÀÛ¼ºÇÏ°í ½ÍÁö ¾Ê¾Ò¾ú´Ù.
ÇÏÁö¸¸ Ç×»ó ÀÌ·¯ÇÑ ¹®¼¸¦ Àаí´Â ½Í¾ú±â ¶§¹®¿¡ ¾î¿¼ö ¾øÀÌ? ÀÌ·¸°Ô ÀÛ¼ºÇÏ°Ô µÇ¾ú´Ù.
ÀÌ ¹®¼°¡ ÈǸ¢ÇÑ ¿ä¾à¼ ȤÀº Ä¿³Î¿¡ ´ëÇÑ ÀϹÝÀûÀÎ ½ÃÀÛÁ¡À̳ª ÀÓÀÇÀÇ Á¤º¸¸¦ Á¦°øÇÒ ¼ö ÀÖ´Â ÁÁÀº ¹®¼·Î ¹ßÀüÇØ °¡±â¸¦ ¹Ù¶õ´Ù.
2. µ¿ÀÛ ¸ðµå (the Players) ¶Æ¯Á¤ÇÑ ¼ø°£¿¡ ½Ã½ºÅÛ »óÀÇ 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 ) ³ª GFP_ATOMIC Ç÷¡±× ¾øÀÌ È£ÃâÇÏ´Â ¸Þ¸ð¸® ÇÒ´ç ÇÔ¼ö°¡ ÀÌ·± ·ù¿¡ ¼ÓÇÑ´Ù.
¸¸¾à À§¿¡¼ À̾߱âÇÑ ¿øÄ¢µéÀ» ¾î±ä´Ù¸é ´ç½ÅÀÇ ¸Ó½ÅÀº °á±¹ ´Ù¿îµÇ°í ¸» °ÍÀÌ´Ù.
Á¤¸»·Î.
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() ´Â Á»´õ ÀϹÝÀûÀÎ ÇÔ¼öÀÌ´Ù:
ÀÌ ÇÔ¼öµéÀº ÀÓÀÇÀÇ ¾çÀÇ µ¥ÀÌŸ¸¦ »ç¿ëÀÚ ¿µ¿ª°ú ÁÖ°í¹Þ´Â´Ù.
ÁÖÀÇ:
±×·¸´Ù. ÀÌ ÀÌ»óÇÑ ÀÎÅÍÆäÀ̽º´Â ³ª¸¦ Â¥Áõ³ª°Ô ¸¸µé¾ú´Ù. Á¦¹ß ¿©±â¿¡ ´ëÇÑ ÆÐÄ¡¸¦ º¸³»ÁÖ¾î ³ªÀÇ ¿µ¿õÀÌ µÇ¾î ÁÖ±æ ¹Ù¶õ´Ù. -- RR
put_user() ³ª get_user() ¿Í ´Þ¸® copy_to_user() ¿Í copy_from_user() ¿¡¼´Â º¹»çµÇÁö ¾ÊÀº µ¥ÀÌŸÀÇ ¾çÀ» ¸®ÅÏÇÑ´Ù. (Áï, (¸¶Âù°¡Áö·Î) 0 Àº ¼º°øÀ» ÀǹÌÇÑ´Ù.)
ÀÌ ÇÔ¼öµéÀº ¾Ï½ÃÀûÀ¸·Î sleep ¿¡ µé¾î°¥ ¼ö ÀÖ´Ù.
±×·¡¼ ÀÌ ÇÔ¼öµéÀº user context ¹Û¿¡¼³ª (user context ¹Û¿¡¼´Â º° Àǹ̰¡ ¾ø´Ù), ÀÎÅÍ·´Æ®°¡ ºñÈ°¼ºÈµÈ »óÅ ȤÀº spinlock ÀÌ °É¸° »óÅ¿¡¼ Àý´ë »ç¿ëµÇ¼´Â ¾ÈµÈ´Ù.
6.3. kmalloc()/kfree() <include/linux/slab.h> ¶ÀÌ ·çƾµéÀº (»ç¿ëÀÚ ¸ðµå¿¡¼ÀÇ
malloc() /free() ó·³) µ¿ÀûÀ¸·Î ¸Þ¸ð¸®¸¦ ¿äûÇÒ ¶§ »ç¿ëµÈ´Ù.
ÇÏÁö¸¸ kmalloc() ¿¡¼´Â º°µµÀÇ Ç÷¡±× Çϳª¸¦ ´õ ÃëÇϴµ¥ ±×Áß¿¡¼ Áß¿äÇÑ °ªµé·Î´Â ´ÙÀ½°ú °°Àº °ÍµéÀÌ ÀÖ´Ù:
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.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 ÆäÀÌÁöÀÇ ÂªÀº ¿ä¾àº»¿¡ ºÒ°úÇÏ´Ù):
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. |