'''''Unreliable Guide To Hacking The Linux Kernel''''' ÀúÀÚ : Paul Rusty Russell ¹ø¿ª : ±è³²Çü ----- ÀÌ ¹®¼­´Â ÀÚÀ¯ ¼ÒÇÁÆ®¿þ¾îÀÌ´Ù; ´ç½ÅÀº 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` ÆÄÀÏ¿¡ ÀûÇôÀÖ´Ù. ----- [[TableOfContents]] == ¼Ò°³ == Rusty ÀÇ Unreliable Guide to Linux Kernel Hacking ¹®¼­¸¦ Àаí ÀÖ´Â ¿©·¯ºÐÀ» ȯ¿µÇÑ´Ù. ÀÌ ¹®¼­´Â Ä¿³Î Äڵ忡¼­ »ç¿ëµÇ´Â °øÅëÀûÀÎ ·çƾµé°ú ÀϹÝÀûÀÎ ¿ä±¸»çÇ×µéÀ» ¼³¸íÇÏ°í ÀÖ´Ù: ÀÌ ¹®¼­ÀÇ ¸ñÀûÀº ¼÷·ÃµÈ C ÇÁ·Î±×·¡¸Óµé¿¡°Ô ¸®´ª½º Ä¿³Î °³¹ß¿¡ ´ëÇÑ ÀÔ¹®¼­·Î¼­ »ç¿ëµÇ°íÀÚ ÇÏ´Â °ÍÀÌ´Ù. ÀÌ ¹®¼­¿¡¼­´Â ±¸Ã¼ÀûÀÎ ±¸Çö¿¡ °üÇÑ ºÎºÐÀº ´Ù·çÁö ¾Ê´Â´Ù ÀÌ ¹®¼­¸¦ Àбâ Àü¿¡, ÇÑ°¡Áö »ç½ÇÀ» ÀÌÇØÇØ Áֱ⠹ٶõ´Ù. »ç½Ç °³ÀÎÀûÀ¸·Î ³ª´Â ÀüüÀûÀ¸·Î ¸¸Á·½º·´Áö ¸øÇÑ ¼öÁØÀÇ ÀÌ ¹®¼­¸¦ ÀÛ¼ºÇÏ°í ½ÍÁö ¾Ê¾Ò¾ú´Ù. ÇÏÁö¸¸ Ç×»ó ÀÌ·¯ÇÑ ¹®¼­¸¦ Àаí´Â ½Í¾ú±â ¶§¹®¿¡ ¾î¿¼ö ¾øÀÌ? ÀÌ·¸°Ô ÀÛ¼ºÇÏ°Ô µÇ¾ú´Ù. ÀÌ ¹®¼­°¡ ÈǸ¢ÇÑ ¿ä¾à¼­ ȤÀº Ä¿³Î¿¡ ´ëÇÑ ÀϹÝÀûÀÎ ½ÃÀÛÁ¡À̳ª ÀÓÀÇÀÇ Á¤º¸¸¦ Á¦°øÇÒ ¼ö ÀÖ´Â ÁÁÀº ¹®¼­·Î ¹ßÀüÇØ °¡±â¸¦ ¹Ù¶õ´Ù. == µ¿ÀÛ ¸ðµå (the Players) == ƯÁ¤ÇÑ ¼ø°£¿¡ ½Ã½ºÅÛ »óÀÇ CPU ´Â ´ÙÀ½°ú °°Àº »óÅ ÁßÀÇ Çϳª°¡ µÈ´Ù: * ƯÁ¤ ÇÁ·Î¼¼½º¿¡ ¿¬°üµÇÁö ¾ÊÀº, Çϵå¿þ¾î ÀÎÅÍ·´Æ® ó¸® * ƯÁ¤ ÇÁ·Î¼¼½º¿¡ ¿¬°üµÇÁö ¾ÊÀº, ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ® (softirq, tasklet, bh) ó¸® * ƯÁ¤ ÇÁ·Î¼¼½º¿¡ ¿¬°üµÇ¾î Ä¿³Î ¸ðµå¿¡¼­ µ¿ÀÛ * »ç¿ëÀÚ ¸ðµå¿¡¼­ ƯÁ¤ ÇÁ·Î¼¼½º ¼öÇà À§ÀÇ ¸®½ºÆ®´Â °¢°¢ÀÌ ¾ö°ÝÇÑ ¿ì¼±¼øÀ§¸¦ °¡Áø´Ù: ¸¶Áö¸·ÀÇ »óÅ (»ç¿ëÀÚ ¸ðµå) ¸¦ Á¦¿ÜÇÑ ´Ù¸¥ »óŵéÀº ¿ÀÁ÷ Àڽź¸´Ù »óÀ§¿¡ ÀÖ´Â »óÅ¿¡ ÀÇÇØ ¼±Á¡µÉ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, softirq °¡ CPU ¿¡¼­ ¼öÇàµÇ°í ÀÖ´Â µ¿¾È ´Ù¸¥ softirq ´Â À̸¦ ¼±Á¡ÇÒ ¼ö ¾øÁö¸¸ Çϵå¿þ¾î ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇÏ¸é ¼±Á¡µÈ´Ù. ÇÏÁö¸¸ ½Ã½ºÅÛ³»ÀÇ ´Ù¸¥ CPU µéÀº µ¶¸³ÀûÀ¸·Î ¼öÇàµÈ´Ù. ¾ÕÀ¸·Î user context [[FootNote(¿ªÀÚÁÖ: ÇÁ·Î¼¼½º°¡ Ä¿³Î ¸ðµå¿¡¼­ µ¿ÀÛÇÏ°í ÀÖ´Â »óŸ¦ ¸»ÇÏ´Â °ÍÀÌ´Ù. ÀÌ ±ÛÀ» Àд µ¶ÀÚµéÀÌ Ä¿³Î¿µ¿ª¿¡¼­ ÇÁ·Î±×·¡¹ÖÀ» Çϱ⠶§¹®¿¡ ÀÌ·¸°Ô ºÎ¸£´Â °Í °°´Ù.)]] ¿¡¼­ ½ÇÁ¦ÀûÀÎ ºñ¼±Á¡¼ºÀ» °¡Áö±â À§ÇØ ÀÎÅÍ·´Æ®¸¦ ¸·¾ÆµÎ´Â ¹æ¹ýµéÀ» »ìÆ캼 °ÍÀÌ´Ù. === User Context === user context ´Â ½Ã½ºÅÛ ÄÝÀ̳ª ´Ù¸¥ Æ®·¦ µî¿¡ ÀÇÇؼ­ ÁøÀÔÇÑ Äڵ带 ¸»ÇÑ´Ù: ¿©±â¿¡¼­´Â sleep À» ÇÒ ¼ö ÀÖ°í (ÀÎÅÍ·´Æ®¸¦ Á¦¿ÜÇϸé) `schedule()` ÇÔ¼ö¸¦ È£ÃâÇϱâ Àü±îÁö CPU ¸¦ ¼ÒÀ¯ÇÏ°Ô µÈ´Ù. ´Ù½Ã ¸»Çϸé, user context ´Â (»ç¿ëÀÚ ¸ðµå¿Í ´Þ¸®) ºñ¼±Á¡¼ºÀ» °¡Áø´Ù. (!) Âü°í: ¸ðµâÀ» ·ÎµùÇϰųª ¾ð·ÎµùÇÒ ¶§, ±×¸®°í ºí·Ï µð¹ÙÀ̽º µå¶óÀ̹ö¿¡ ´ëÇÑ ¿¬»êÀ» ¼öÇàÇÏ´Â °æ¿ì¿¡´Â Ç×»ó user context ¿¡ ÀÖ´Â °ÍÀÌ´Ù. user context »ó¿¡¼­´Â (ÇöÀç ¼öÇàÁßÀΠŽºÅ©¸¦ °¡¸®Å°´Â) `current` Æ÷ÀÎÅ͸¦ ÀÌ¿ëÇÒ ¼ö ÀÖ°í, `in_interrupt()` ¸ÅÅ©·Î (`include/asm/hardirq.h`) ´Â °ÅÁþÀ» ¸®ÅÏÇÑ´Ù. /!\ ÁÖÀÇ: ÀÎÅÍ·´Æ® ȤÀº ÇϹݺΠÇڵ鷯°¡ ÀÌ¹Ì ºñÈ°¼ºÈ­ µÇ¾îÀÖ´Â °æ¿ì¿¡µµ, `in_interrupt()` ¸ÅÅ©·Î°¡ ¹«Á¶°Ç °ÅÁþÀ» ¸®ÅÏÇÑ´Ù´Â °ÍÀ» ¿°µÎ¿¡ µÎÀÚ. === Çϵå¿þ¾î ÀÎÅÍ·´Æ® (Hard IRQs) === ŸÀÌ¸Ó Æ½, ³×Æ®¿öÅ© Ä«µå, Å°º¸µå¿Í °°Àº °ÍµéÀº ¾î¶² ¼ø°£¿¡µµ ÀÎÅÍ·´Æ®¸¦ ¹ß»ý½Ãų ¼ö ÀÖ´Â ½ÇÁ¦ Çϵå¿þ¾î µéÀÌ´Ù. Ä¿³Î¿¡¼­´Â ÀÎÅÍ·´Æ® Çڵ鷯¸¦ ¼öÇàÇؼ­ ÀÌ·¯ÇÑ Çϵå¿þ¾îµé¿¡ ´ëÇÑ Ã³¸®¸¦ ÇÑ´Ù. Ä¿³Î¿¡¼­´Â ÀÌ·¯ÇÑ ÀÎÅÍ·´Æ® Çڵ鷯°¡ Àý´ë ÀçÁøÀÔµÇÁö ¾Êµµ·Ï ÇØ ÁØ´Ù: ¸¸¾à (ó¸® Áß¿¡) ¶Ç´Ù¸¥ ÀÎÅÍ·´Æ®°¡ ¹ß»ýµÇ¾ú´Ù¸é, ±×°ÍÀº Å¥¿¡ µé¾î°¡°Ô µÈ´Ù (Å¥°¡ °¡µæ Â÷ÀÖ´Â °æ¿ì ¹ö·ÁÁø´Ù). ÀÌ·¸°Ô ÀÎÅÍ·´Æ®¸¦ ºñÈ°¼ºÈ­ ÇØ µÎ±â ¶§¹®¿¡, ÀÎÅÍ·´Æ® Çڵ鷯´Â ¸Å¿ì »¡¸® ¼öÇàµÇ¾î¾ß ÇÑ´Ù: ÁÖ·Î ÀÎÅÍ·´Æ® Çڵ鷯¿¡¼­´Â ÀÎÅÍ·´Æ®¸¦ ¹Þ¾Ò´Ù´Â ÀÀ´äÀ» º¸³»ÁÖ°í, ½ÇÇàÀº ''¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ®'' ¸¦ ÀÌ¿ëÇØ Ã³¸®Çϵµ·Ï Ç¥½ÃÇÑ ÈÄ Á¾·áÇÑ´Ù. Çϵå¿þ¾î ÀÎÅÍ·´Æ® ºÎºÐÀ» ó¸®ÇÏ´Â ºÎºÐ¿¡¼­´Â `in_irq()` ¸ÅÅ©·Î°¡ ÂüÀ» ¸®ÅÏÇÑ´Ù. /!\ ÁÖÀÇ: ÀÎÅÍ·´Æ®°¡ ºñÈ°¼ºÈ­ µÇ¾îÀÖ´Â °æ¿ì¿¡´Â `in_irq()` ¸ÅÅ©·Î°¡ ¹«Á¶°Ç °ÅÁþÀ» ¸®ÅÏÇÑ´Ù´Â °ÍÀ» ¿°µÎ¿¡ µÎÀÚ. === ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ® (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 ¿¡¼­¸¸ ¼öÇàµÇµµ·Ï º¸ÀåÇÑ´Ù. [[FootNote(¿ªÀÚÁÖ: ÇϳªÀÇ tasklet ÀÌ ¿©·¯ CPU ¿¡¼­ Áߺ¹µÇ¾î ½ÇÇàµÇÁö ¾Ê´Â °ÍÀ» º¸ÀåÇÑ´Ù.)]] /!\ ÁÖÀÇ: '''tasklet''' À̶ó´Â À̸§Àº À߸øµÈ °ÍÀÌ´Ù: ÀÌ°ÍÀº ''task'' ¿Í ¾Æ¹«·± ¿¬°üÀÌ ¾ø´Ù. (¾Æ¸¶ À̶§ Alexey Kuznetsov °¡ º¸µåÄ«¸¦ ¸¹ÀÌ ¸¶½Å °Í °°´Ù..) ÇöÀç softirq (ȤÀº ÇϹݺγª tasklet) °¡ ½ÇÇà ÁßÀÎÁö¸¦ ¾Ë¾Æº¸±â À§ÇØ `in_softirq()` ¸ÅÅ©·Î (`include/linux/softirq.h`)¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. /!\ ÁÖÀÇ: ÇϹݺο¡ ´ëÇÑ ¶ôÀÌ °É·ÁÀÖ´Â °æ¿ì¿¡´Â `in_softirq()` ¸ÅÅ©·Î°¡ Ç×»ó °ÅÁþÀ» ¸®ÅÏÇÔÀ» ¿°µÎ¿¡ µÎÀÚ == ±âº»ÀûÀÎ °³³äµé == * ¸Þ¸ð¸® º¸È£ ±â´ÉÀ» Áö¿øÇÏÁö ¾ÊÀ½ ¸¸¾à user context ³ª ÀÎÅÍ·´Æ®°¡ °É¸° »óÅ¿¡¼­ ¸Þ¸ð¸® ¿µ¿ªÀ» À߸ø »ç¿ëÇÏ°Ô µÈ´Ù¸é ½Ã½ºÅÛ Àüü°¡ ¸Á°¡Áú ¼ö ÀÖ´Ù. ´ç½ÅÀÌ Áö±Ý ÇÏ·Á´Â ÀÛ¾÷ÀÌ »ç¿ëÀÚ ¸ðµå¿¡¼­ ÇØ°áÇÒ ¼ö ÀÖ´Â ÀÛ¾÷ÀÎÁö¸¦ ¸ÕÀú È®ÀÎÇØ º¸ÀÚ * ºÎµ¿¼Ò¼öÁ¡ À̳ª MMX ¿¬»êÀ» Áö¿øÇÏÁö ¾ÊÀ½ FPU »óÅÂÁ¤º¸´Â ÀúÀåµÇÁö ¾Ê´Â´Ù. user context ¿¡¼­µµ FPU ÀÇ »óÅ´ ÇöÀç ÇÁ·Î¼¼½º¿¡ ´ëÀÀµÇÁö ¾ÊÀ» °ÍÀÌ´Ù: »ç¿ëÀÚ ¸ðµåÀÇ ÇÁ·Î¼¼½º°¡ FPU ÀÇ »óÅÂÁ¤º¸¸¦ °¡Áö°í ÀÖ´Ù´Â »ç½ÇÀº Àؾî¹ö¸®´Â °ÍÀÌ ÁÁ´Ù. ¸¸¾à Á¤¸»·Î ÀÌ·± ÀÛ¾÷ÀÌ ÇÊ¿äÇÏ´Ù¸é ¸í½ÃÀûÀ¸·Î ¸ðµç FPU ÀÇ »óÅÂÁ¤º¸¸¦ ÀúÀåÇÏ°í º¹±¸ÇÏ´Â (±×¸®°í ÀÎÅÍ·´Æ®¸¦ ±ÝÁö½ÃÄÑ¾ß ÇÑ´Ù) ÀÛ¾÷À» ÇؾßÇÑ´Ù. ÀÌ·¯ÇÑ ÀÛ¾÷Àº ÀϹÝÀûÀ¸·Î ÁÁÀº ¾ÆÀ̵ð¾î°¡ ¾Æ´Ï´Ù: ¸ÕÀú °íÁ¤¼Ò¼öÁ¡[[FootNote(¿ªÀÚÁÖ: Á¤¼ö ¿¬»êÀ» ¸»ÇÏ´Â °ÍÀÌ´Ù.)]] ¿¬»êÀ» ÀÌ¿ëÇؼ­ ÇØ°áÇϵµ·Ï ÇÏÀÚ. * ¾ö°ÝÇÑ ½ºÅà Á¦ÇÑ Ä¿³Î ¹öÀü 2.2 ¿¡¼­ Ä¿³Î ½ºÅÃÀÇ Å©±â´Â ´ë·« 6K Á¤µµÀÌ°í (´ëºÎºÐÀÇ ¾ÆÅ°ÅØÃÄ¿¡¼­ ±×·¸´Ù´Â °ÍÀÌ´Ù: Alpha ÀÇ °æ¿ì´Â ¾à 14K ÀÌ´Ù) ÀÎÅÍ·´Æ® ó¸® ·çƾ°ú ½ºÅÃÀ» °øÀ¯Çϱ⠶§¹®¿¡ ÀÌ ¿µ¿ª ¸ðµÎ¸¦ ¾µ ¼ö°¡ ¾ø´Ù. ¸¹Àº Àç±ÍÈ£ÃâÀ̳ª ½ºÅà º¯¼ö·Î Å« ¹è¿­À» Àâ¾ÆµÎ´Â °ÍÀ» ÇÇÇϵµ·Ï ÇÏÀÚ. (´ë½Å µ¿ÀûÀ¸·Î ÇÒ´ç¹Þµµ·Ï ÇÑ´Ù) * ¸®´ª½º Ä¿³ÎÀº À̽ļºÀÌ ÀÖ´Ù ÀÌ ¿øÄ¢À» °¡½¿¼Ó¿¡ »õ°ÜµÎÀÚ. ´ç½ÅÀÌ ÀÛ¼ºÇÏ´Â ÄÚµå´Â 64-ºñÆ® ¿¡¼­µµ ȣȯµÇµµ·Ï ÇÏ°í endian ¿¡ Á¾¼ÓÀûÀÌÁö ¾Ê¾Æ¾ß ÇÑ´Ù. ¶ÇÇÑ CPU ¿¡ Á¾¼ÓÀûÀÎ ºÎºÐÀ» ÁÙ¿©¾ß ÇÑ´Ù. Áï Æ÷ÆÃÇϱ⠽±µµ·Ï ÀζóÀÎ ¾î¼Àºí¸®´Â ±ò²ûÇÏ°Ô Ä¸½¶È­µÇ¾î¾ß ÇÏ°í ÃÖ¼ÒÈ­ ÇØ¾ß ÇÑ´Ù. ÀϹÝÀûÀ¸·Î ÀÌ°ÍÀº Ä¿³Î Æ®¸® ³»ÀÇ ¾ÆÅ°ÅØÃÄ Á¾¼ÓÀûÀÎ ºÎºÐ¿¡ ÇØ´çµÇ´Â À̾߱âÀÌ´Ù. == 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) ÀÌ´Ù. == Deadlock 󸮹ý == ¸¸¾à ´ÙÀ½°ú °°Àº »óȲÀÌ ¾Æ´Ï¶ó¸é, sleep ¿¡ µé¾î°¥ ¼ö ÀÖ´Â ¾î¶² ·çƾÀÌ¶óµµ ½ÇÇàÇؼ­´Â ¾ÈµÈ´Ù: * user context ¿¡ ÀÖ´Â °æ¿ì * ¾î¶² spinlock µµ ¼ÒÀ¯ÇÏÁö ¾Ê´Â °æ¿ì * ÀÎÅÍ·´Æ®¸¦ È°¼ºÈ­ ÇÏ°í ÀÖ´Â °æ¿ì (½ÇÁ¦·Î, Andi Kleen Àº ½ºÄÉÁÙ¸µ °ü·Ã Äڵ忡¼­µµ ÀÎÅÍ·´Æ®¸¦ È°¼ºÈ­ ½Ãų¼ö ÀÖ´Ù°í Çß´Ù. ÇÏÁö¸¸ ±×°ÍÀº ¾Æ¸¶ ´ç½ÅÀÌ ¿øÇÏÁö ¾ÊÀ» °ÍÀÌ´Ù.) ¸î¸î ÇÔ¼öµéÀº ¾Ï½ÃÀûÀ¸·Î sleep ¿¡ µé¾î°¥ ¼ö ÀÖÀ½¿¡ ÁÖÀÇÇÏÀÚ: ÀϹÝÀûÀ¸·Î »ç¿ëÀÚ ¸ðµå Á¢±Ù ÇÔ¼ö (`*_user`) ³ª `GFP_ATOMIC` Ç÷¡±× ¾øÀÌ È£ÃâÇÏ´Â ¸Þ¸ð¸® ÇÒ´ç ÇÔ¼ö°¡ ÀÌ·± ·ù¿¡ ¼ÓÇÑ´Ù. ¸¸¾à À§¿¡¼­ À̾߱âÇÑ ¿øÄ¢µéÀ» ¾î±ä´Ù¸é ´ç½ÅÀÇ ¸Ó½ÅÀº °á±¹ ´Ù¿îµÇ°í ¸» °ÍÀÌ´Ù. Á¤¸»·Î. == °øÅë ·çƾ == === printk() === `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()` ´Â Àâ´ãÀ» À§ÇØ »ç¿ëµÇ¼­´Â ¾ÈµÈ´Ù." À̸¦ ¸í½ÉÇϱ⠹ٶõ´Ù. === copy_[to/from]_user()/[get/put]_user() === ['''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 ÀÌ °É¸° »óÅ¿¡¼­ Àý´ë »ç¿ëµÇ¼­´Â ¾ÈµÈ´Ù. === kmalloc()/kfree() === ÀÌ ·çƾµéÀº (»ç¿ëÀÚ ¸ðµå¿¡¼­ÀÇ `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 [[FootNote(Memory Management Unit)]] °¡ ¸¶Ä¡ ¿¬¼ÓµÈ ¸Þ¸ð¸®ÀÎ °Í ó·³ ó¸®ÇØ ÁØ´Ù. (Áï, ¿ÀÁ÷ CPU ¿¡°Ô¸¸ ¿¬¼ÓÀûÀ¸·Î º¸ÀÌ´Â °ÍÀÌÁö ´Ù¸¥ ¿ÜºÎÀÇ µð¹ÙÀ̽º µå¶óÀ̹ö¿¡¼­´Â ¿¬¼ÓÀûÀ¸·Î º¸ÀÌÁö ¾Ê´Â´Ù.) ¸¸¾à ¾î¶² (ÀÌ»óÇÑ) ÀåÄ¡¿¡¼­ ¹°¸®ÀûÀ¸·Î ¿¬¼ÓµÈ Å« ¸Þ¸ð¸® ¿µ¿ªÀ» ÇÊ¿ä·Î ÇÑ´Ù¸é ¹®Á¦°¡ µÉ ¼ö ÀÖ´Ù. ÀÌ°ÍÀº Linux ¿¡¼­´Â Àß Áö¿øÀÌ µÇÁö ¾Ê´Â ºÎºÐÀε¥ Ä¿³ÎÀÌ ½ÇÇàµÇ°í ³ª¸é ¹ß»ýÇÏ´Â ¸Þ¸ð¸® ´ÜÆíÈ­ Çö»óÀÌ ÀÌ°ÍÀ» ¾î·Æ°Ô Çϱ⠶§¹®ÀÌ´Ù. ÀÌ·¯ÇÑ ¸Þ¸ð¸®¸¦ ÇÒ´ç¹Þ´Â °¡Àå ÁÁÀº ¹æ¹ýÀº ºÎÆ® ÇÁ·Î¼¼½º¿¡¼­ `alloc_bootmem()` ÇÔ¼ö¸¦ ÀÌ¿ëÇؼ­ ¹Ì¸® ÇÒ´ç¹Þ¾Æ µÎ´Â °ÍÀÌ´Ù. ÀÚÁÖ »ç¿ëµÇ´Â °´Ã¼¸¦ À§ÇØ »õ·Î¿î ij½Ã¸¦ ¸¸µé±â Àü¿¡ `include/linux/slab.h` ¿¡ ÀÖ´Â ½½·¦ ij½ÃÀÇ »ç¿ëÀ» °í·ÁÇØ º¸ÀÚ. === current === ÀÌ Àü¿ª º¯¼ö (½ÇÁ¦·Î´Â ¸ÅÅ©·ÎÀÌ´Ù) ´Â ÇöÀç ½ÇÇàÁßÀÎ `task_struct` ±¸Á¶Ã¼¿¡ ´ëÇÑ Æ÷ÀÎÅÍÀÌ´Ù. ±×·¡¼­ ¿ÀÁ÷ user context ¿¡¼­¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î ÇÁ·Î¼¼½º°¡ ½Ã½ºÅÛ ÄÝÀ» È£ÃâÇß´Ù¸é `current` º¯¼ö´Â È£ÃâÇÑ ÇÁ·Î¼¼½ºÀÇ `task_struct` ¸¦ °¡¸®Å³ °ÍÀÌ´Ù. ÀÌ °ªÀº interrupt context ³»¿¡¼­µµ '''`NULL` ÀÌ ¾Æ´Ï´Ù'''. === udelay()/mdelay() / === ÇÁ·Î¼¼½º¸¦ Àá½Ã ÁߴܽÃÅ°±â À§ÇØ `udelay()` ÇÔ¼ö¸¦ ÀÌ¿ëÇÒ ¼ö ÀÖ´Ù. `udelay()` ÇÔ¼ö¿¡ Å« °ªÀ» »ç¿ëÇÏ´Â °ÍÀº ¿À¹ö ÇÃ·Î¿ì ¹®Á¦¸¦ ÀÏÀ¸Å³ ¼ö ÀÖ´Ù - À̸¦ º¸Á¶Çϱâ À§ÇÑ ÇÔ¼öÀÎ `mdelay()` ÇÔ¼ö¸¦ ÀÌ¿ëÇϰųª `schedule_timeout()` ÇÔ¼ö¸¦ ÀÌ¿ëÇϵµ·Ï ÇÑ´Ù. === cpu_to_[be/le]32()/[be/le]32_to_cpu() === `cpu_to_be32()` °èÅëÀÇ ¸ÅÅ©·Î µéÀº Ä¿³Î³»ÀÇ ¿£µð¾È¿¡ °üÇÑ º¯È¯À» À§ÇÑ ÀϹÝÀûÀÎ ¹æ¹ýÀ» Á¦°øÇÑ´Ù ('''32''' ´ë½Å 64 ³ª 16 ÀÌ ¾²Àϼö ÀÖ°í, '''be''' ´ë½Å '''le''' °¡ ¾²ÀÏ ¼ö ÀÖ´Ù): À̵éÀº º¯È¯µÈ °ªÀ» ¸®ÅÏÇÑ´Ù. ÀÌ¿Í ¹Ý´ëµÇ´Â ÀÏÀ» ÇÏ´Â °Íµéµµ ¿ª½Ã Á¸ÀçÇÑ´Ù: `be32_to_cpu` µî.. ÀÌ ÇÔ¼öµéÀº Å©°Ô µÎ°¡Áö ÇüÅ·Πº¯È­µÇ¾î »ç¿ëµÈ´Ù: ±× ù¹ø°´Â `cpu_to_be32p()` ó·³ Æ÷ÀÎÅÍ·Î º¯È­µÈ ÇüÅÂÀÌ´Ù. ÀÌ ÇÔ¼ö´Â ¸í½ÃµÈ ŸÀÔÀÇ Æ÷ÀÎÅ͸¦ ¹Þ¾Æ¼­ º¯È¯µÈ °ªÀ» ¸®ÅÏÇÑ´Ù. ¶Ç´Ù¸¥ ÇüÅ´ `cpu_to_be32s()` ¿Í °°Àº '''in-situ''' °è¿­Àε¥, ÀÌ°ÍÀº Æ÷ÀÎÅÍ·Î ÁÖ¾îÁø °ªÀ» º¯È­½ÃŲ ÈÄ¿¡ `void` ¸¦ ¸®ÅÏÇÑ´Ù. === local_irq_[save/restore]() === ÀÌ ·çƾµéÀº ÇöÀç CPU ÀÇ Çϵå¿þ¾î ÀÎÅÍ·´Æ®¸¦ È°¼ºÈ­/ºñÈ°¼ºÈ­ ½ÃŲ´Ù. ÀÌ ÇÔ¼öµéÀº ÀçÁøÀÔÀÌ °¡´ÉÇÏ´Ù; ÀÌÀüÀÇ »óÅ°ªÀ» `unsigned long flags` ÀÎÀÚ¿¡ ÀúÀå½ÃŲ´Ù. ¸¸¾à ÀÎÅÍ·´Æ®°¡ È°¼ºÈ­µÇ¾î ÀÖ´ÂÁö ¾Æ´ÑÁö ¾Ë°í ÀÖ´Ù¸é ´Ü¼øÈ÷ `local_irq_disable()` °ú `local_irq_enable()` ÇÔ¼ö¸¦ ÀÌ¿ëÇÒ ¼ö ÀÖ´Ù. === local_bh_[disable/enable]() === ÀÌ ·çƾµéÀº ÇöÀç CPU ÀÇ ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ®¸¦ È°¼ºÈ­/ºñÈ°¼ºÈ­ ½ÃŲ´Ù. ÀÌ ÇÔ¼öµéµµ ÀçÁøÀÔÀÌ °¡´ÉÇÏ´Ù; ¸¸¾à ÀÌÀü¿¡ ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ®°¡ ºñÈ°¼ºÈ­µÇ¾î ÀÖ¾ú´Ù¸é, ÀÌ ÇÔ¼öµéÀÌ ½ÖÀ¸·Î È£ÃâµÈ ÈÄ¿¡µµ ¿©ÀüÈ÷ ºñÈ°¼ºÈ­ µÈ ä·Î ³²¾ÆÀÖÀ» °ÍÀÌ´Ù. [[FootNote(¿ªÀÚÁÖ: °¢ CPU ¸¶´Ù local_bh_count ¶ó´Â °ªÀ» À¯ÁöÇÑ´Ù)]] ÀÌ ÇÔ¼öµéÀº ÇöÀç CPU ¿¡¼­ softirq, tasklet, bottom halves °¡ ½ÇÇàµÇ´Â °ÍÀ» ±ÝÁöÇÑ´Ù. === smp_processor_id()/cpu_[number/logical]_map() === `smp_processor_id()` ÇÔ¼ö´Â 0°ú `NR_CPUS` (Linux ¿¡¼­ Áö¿øÇÏ´Â ÃÖ´ë CPU ÀÇ °¹¼ö·Î ÇöÀç´Â 32 ÀÌ´Ù) »çÀÌÀÇ °ªÀÎ ÇöÀç ÇÁ·Î¼¼¼­ ¹øÈ£¸¦ ¾Ë·ÁÁØ´Ù. ÀÌ °ªÀº ¹Ýµå½Ã ¿¬¼ÓÀûÀÏ ÇÊ¿ä´Â ¾ø´Ù: 0 °ú `smp_num_cpus()` (ÀÌ ¸Ó½ÅÀÌ °¡Áö°í ÀÖ´Â ½ÇÁ¦ ÇÁ·Î¼¼¼­ÀÇ °¹¼ö) »çÀÌÀÇ °ªÀ» ¾Ë±â À§Çؼ­´Â `cpu_number_map()` ÇÔ¼ö¸¦ »ç¿ëÇؼ­ ÇÁ·Î¼¼¼­ ¹øÈ£¸¦ ³í¸®ÀûÀÎ ¹øÈ£·Î ¹Ù²Ü ¼ö ÀÖ´Ù. [[FootNote(¿ªÀÚÁÖ: i386 ¿¡¼­´Â µ¿ÀÏÇÑ °ªÀÌ´Ù)]] `cpu_logical_map()` ÇÔ¼ö´Â ÀÌ¿Í ¹Ý´ëµÇ´Â ÀÏÀ» ¼öÇàÇÑ´Ù. === __init/__exit/__initdata === ºÎÆÃÀÌ µÇ°í ³­ ÈÄ¿¡, Ä¿³ÎÀº ƯÁ¤ ¿µ¿ªÀÇ ¸Þ¸ð¸®¸¦ ÇØÁ¦ÇÑ´Ù; `__init` ·Î ¼±¾ðµÈ ÇÔ¼öµé°ú, `__initdata` ¶ó°í ¼±¾ðµÈ µ¥ÀÌŸ´Â ºÎÆÃÀÌ ¿Ï·áµÈ ÈÄ¿¡ ÇØÁ¦µÈ´Ù. (¸ðµâ³»¿¡¼­´Â ÀÌ·¯ÇÑ Áö½ÃÀÚµéÀÌ ¹«½ÃµÈ´Ù) `__exit` ´Â Á¾·áµÉ ¶§¿¡¸¸ ÇÊ¿äÇÑ ÇÔ¼öµéÀ» ¼±¾ðÇϴµ¥ »ç¿ëµÈ´Ù: ÀÌ ÇÔ¼öµéÀº ÆÄÀÏÀÌ ¸ðµâ·Î ÄÄÆÄÀϵÇÁö ¾ÊÀ¸¸é ÇØÁ¦µÈ´Ù. ÀÌ Áö½ÃÀÚµéÀ» »ç¿ëÇÑ Çì´õ ÆÄÀϵéÀ» »ìÆ캸±â ¹Ù¶õ´Ù. `__init` Áö½ÃÀÚ¿Í ÇÔ²² ¼±¾ðµÈ ÇÔ¼ö¿¡¼­ `EXPORT_SYMBOL()` ¸ÅÅ©·Î¸¦ ÀÌ¿ëÇØ ½Éº¼À» ¸ðµâ·Î °ø°³ÇÏ´Â °ÍÀº Àǹ̰¡ ¾ø´Ù´Â °Í¿¡ ÁÖÀÇÇÏÀÚ. `__initdata` ·Î ¼±¾ðµÈ Á¤Àû ÀÚ·á ±¸Á¶´Â (0 À¸·Î ÃʱâÈ­ µÇ´Â BSS ¿µ¿ªÀÇ ÀϹÝÀûÀÎ Á¤Àû µ¥ÀÌŸ¿Í´Â ´Þ¸®) ¹Ýµå½Ã ÃʱâÈ­ µÇ¾î¾ß ÇÏ°í »ó¼ö°¡ µÇ¾î¼­´Â ¾ÈµÈ´Ù. === __initcall()/modult_init() === Ä¿³ÎÀÇ ¸¹Àº ºÎºÐÀº (µ¿ÀûÀ¸·Î ·ÎµåÇÒ ¼ö ÀÖ´Â ºÎºÐÀÎ) ¸ðµâ·Î¼­µµ Àß µ¿ÀÛÇÑ´Ù. `module_init()` ¿Í `module_exit()` ¸ÅÅ©·Î´Â `#ifdef` ¿Í °°Àº Àü󸮱â Áö½ÃÀÚ ¾øÀ̵µ ¸ðµâÀ̳ª Ä¿³Î¿¡ Á¤ÀûÀ¸·Î Æ÷ÇԵǴ °ÍÀ» µÑ ´Ù Áö¿øÇÏ´Â Äڵ带 ½±°Ô ÀÛ¼ºÇÒ ¼ö ÀÖµµ·Ï ÇØ ÁØ´Ù. `module_init()` ¸ÅÅ©·Î´Â (ÆÄÀÏÀÌ ¸ðµâ·Î ÄÄÆÄÀϵǴ °æ¿ì) ¸ðµâÀÌ Ãß°¡µÉ ¶§, ȤÀº ºÎÆýÿ¡ ¾î¶² ÇÔ¼ö°¡ ºÒ·Á¾ß ÇÒÁö¸¦ °áÁ¤ÇÑ´Ù: ÆÄÀÏÀÌ ¸ðµâ·Î ÄÄÆÄÀϵÇÁö ¾Ê´Â´Ù¸é `module_init()` ¸ÅÅ©·Î´Â `__initcall()` ¸ÅÅ©·Î¿Í µ¿ÀÏÇÑ ¿ªÇÒÀ» Çϴµ¥ ÀÌ°ÍÀº ¸µÄ¿¿¡ ÀÇÇØ ºÎÆýÿ¡ ÇÔ¼ö°¡ ºÒ·ÁÁöµµ·Ï ¼³Á¤ÇØ ÁØ´Ù. ÀÌ ÇÔ¼ö´Â ¸ðµâÀ» ·ÎµùÇÏ´Â µ¥ ½ÇÆÐÇÏ´Â °æ¿ì À½¼ö°ªÀÎ ¿¡·¯ ¹øÈ£¸¦ ¸®ÅÏÇÒ ¼ö ÀÖ´Ù (ºÒÇàÈ÷µµ Ä¿³Î¿¡ Á¤ÀûÀ¸·Î Æ÷ÇԵǴ °æ¿ì¿¡´Â ¾Æ¹«·± ¿µÇâÀ» ¹ÌÄ¡Áö ¸øÇÑ´Ù). ¸ðµâÀÇ °æ¿ì¿¡´Â, ÀÌ ÇÔ¼ö´Â ÀÎÅÍ·´Æ®°¡ È°¼ºÈ­ µÇ¾î ÀÖ°í, Ä¿³Î lock ÀÌ °É·ÁÀÖ´Â??? »óÅÂÀÇ user context ¿¡¼­ È£ÃâµÇ¹Ç·Î sleep µÉ ¼ö ÀÖ´Ù. === module_exit() === ÀÌ ¸ÅÅ©·Î´Â ¸ðµâÀÌ Á¦°ÅµÉ ¶§ È£ÃâµÉ ÇÔ¼ö¸¦ Á¤ÀÇÇÑ´Ù (Ä¿³Î³»¿¡ Á¤ÀûÀ¸·Î Æ÷ÇԵǴ °æ¿ì¿¡´Â È£ÃâÁöÁö ¾Ê´Â´Ù). ±× ÇÔ¼ö´Â ¿ÀÁ÷ ¸ðµâÀÇ »ç¿ë Ƚ¼ö (usage count) °¡ 0 ÀÌ µÇ´Â °æ¿ì¿¡¸¸ È£ÃâµÉ °ÍÀÌ´Ù. ÀÌ ÇÔ¼öµµ ¿ª½Ã sleep µÉ ¼ö ÀÖÁö¸¸, ½ÇÆÐÇÏÁö´Â ¾Ê´Â´Ù: ¸ðµç ÀÚ·áµéÀº ¸®Å쵃 ¶§ ÇØÁ¦µÇ¾î¾ß ÇÑ´Ù. === MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT === ÀÌ ¸ÅÅ©·ÎµéÀº ¸ðµâÀÇ »ç¿ë Ƚ¼ö¸¦ °ü¸®Çؼ­ ¸ðµâÀÌ À߸ø Á¦°ÅµÇ´Â °ÍÀ» ¹æÁöÇϱâ À§ÇØ »ç¿ëµÈ´Ù. (´Ù¸¥ ¸ðµâ¿¡¼­ ÇöÀç ¸ðµâ¿¡¼­ °ø°³ÇÏ°í ÀÖ´Â ½Éº¼À» »ç¿ëÇÏ°í ÀÖ´Â °æ¿ì¿¡ ¸ðµâÀº Á¦°ÅµÉ ¼ö ¾ø´Ù: ¾Æ·¡¸¦ Âü°íÇϱ⠹ٶõ´Ù). (¼ÒÄÏÀ̳ª ¸ðµç ÀڷᱸÁ¶¿Í °°Àº) »ç¿ëÀÚ °ø°£¿¡¼­ÀÇ ¸ðµâ¿¡ ´ëÇÑ ÂüÁ¶´Â Ç×»ó ÇÔ¼ö°¡ 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` ¸¦ ¸®ÅÏÇØ¾ß ÇÑ´Ù. == ´ë±â Å¥ (Wait Queues) == [''SLEEPS''] ´ë±â Å¥´Â ƯÁ¤ Á¶°ÇÀÌ ¸¸Á·µÉ ¶§ ±ú¾î³ª¼­ ½ÇÇàµÇ±â¸¦ ¿øÇÒ ¶§ »ç¿ëµÈ´Ù. ´ë±â Å¥¸¦ »ç¿ëÇÒ ¶§´Â °æÀï Á¶°ÇÀÌ ¹ß»ýÇÏÁö ¾Êµµ·Ï Á¶½ÉÇؼ­ »ç¿ëÇØ¾ß ÇÑ´Ù. ¸ÕÀú `wait_queue_head_t` ¸¦ ¼±¾ðÇÏ°í, ƯÁ¤ Á¶°ÇÀ» ±â´Ù¸®´Â ÇÁ·Î¼¼½º µéÀ» ÀÚ½ÅÀ» ÂüÁ¶ÇÏ´Â `wait_queue_t` ·Î ¼±¾ðÇÏ¿© Å¥¿¡ ³Ö´Â´Ù. === ¼±¾ðÇϱâ === ÃʱâÈ­ ÄÚµå ºÎºÐ¿¡¼­ `DECLARE_WAIT_QUEUE_HEAD()` ¸ÅÅ©·Î³ª `init_waitqueue_head()` ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© `wait_queue_head_t` ¸¦ ¼±¾ðÇÒ ¼ö ÀÖ´Ù. === Å¥¿¡ ³Ö±â === ÀÚ½ÅÀ» ´ë±â Å¥ ¾È¿¡ ³Ö´Â °ÍÀº ²Ï º¹ÀâÇÑ ÀÏÀÌ´Ù. ¿Ö³ÄÇϸé Á¶°ÇÀ» °Ë»çÇϱâ Àü¿¡ Å¥¿¡ ³Ö¾î¾ß Çϱ⠶§¹®ÀÌ´Ù..? ÀÌ·¯ÇÑ ÀÏÀ» ÇØÁÖ´Â ¸ÅÅ©·Î°¡ ÀÖ´Ù: `wait_queue_interruptible()` . ÀÌ ¸ÅÅ©·ÎÀÇ Ã¹¹ø° ÀÎÀÚ´Â `wait queue head` °¡ µÇ°í, µÎ¹ø° ÀÎÀÚ´Â Æò°¡µÉ °è»ê½Ä (expression) ÀÌ µÈ´Ù. ÀÌ ¸ÅÅ©·Î´Â °è»ê½ÄÀÌ ÂüÀÏ ¶§ 0 À» ¸®ÅÏÇÏ°í, ½Ã±×³ÎÀ» ¹ÞÀ¸¸é -ERESTARTSYS ¸¦ ¸®ÅÏÇÑ´Ù. (interruptible ÀÌ ¾ø´Â) `wait_queue()` ¹öÀüÀº °°Àº ÀÏÀ» ÇÏÁö¸¸ ½Ã±×³ÎÀ» ¹«½ÃÇÑ´Ù. `sleep_on()` °è¿­ÀÇ ÇÔ¼öµéÀ» »ç¿ëÇÏÁö ¾Êµµ·Ï ÇÑ´Ù - ÀÌ ÇÔ¼öµéÀº °æÀï Á¶°ÇÀ» ºÒ·¯ÀÏÀ¸Å°°ï ÇÑ´Ù. °ÅÀÇ ¸ðµç °æ¿ì¿¡ À־ `wait_event()` °è¿­ÀÇ ÇÔ¼öµéÀÌ °°Àº ÀÏÀ» ÇØ ÁÙ °ÍÀÌ´Ù. ȤÀº `schedule_timeout()` ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© ·çÇÁ¸¦ µ¹¸®´Â ¹æ¹ýµµ °¡´ÉÇÏ´Ù. ¸¸¾à `schedule_timeout()` °ú ·çÇÁ¸¦ »ç¿ëÇϱâ·Î Çß´Ù¸é ¸Å ¹Ýº¹ Áֱ⸶´Ù (`set_current_state()` ¸¦ ÀÌ¿ëÇÏ¿©) ŽºÅ© »óŸ¦ ¼³Á¤ÇØ¾ß busy-looping À» ÇÇÇÒ ¼ö ÀÖ´Ù. === Å¥¿¡ µé¾îÀִ ŽºÅ© ±ú¿ì±â === `wake_up()` ¸¦ È£ÃâÇÑ´Ù; ÀÌ ÇÔ¼ö´Â Å¥¿¡ µé¾îÀÖ´Â ¸ðµç ÇÁ·Î¼¼½º¸¦ ±ú¿ì°Ô µÉ °ÍÀÌ´Ù. ¸¸¾à ¾î¶² ŽºÅ©°¡ `TASK_EXCLUSIVE` ·Î ¼³Á¤µÇ¾î ÀÖ´Ù¸é Å¥¿¡ µé¾îÀÖ´Â ³ª¸ÓÁö ÇÁ·Î¼¼½ºµéÀº ±ú¾î³ªÁö ¾ÊÀ» °ÍÀÌ´Ù. == ¿øÀÚÀû ¿¬»ê == ƯÁ¤ ¿¬»êµéÀº ¸ðµç Ç÷§Æû¿¡¼­ ¿øÀÚÀûÀ¸·Î µ¿ÀÛÇÑ´Ù. ÀÌ·¯ÇÑ ¿¬»êµéÀÇ Ã¹¹ø° ºÎ·ù´Â ¿¡ Á¤ÀÇµÈ `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 ¸Ó½Å°ú °°Àº ƯÁ¤ÇÑ Ç÷§Æû¿¡¼­´Â ´õ¿í ´À¸®°Ô µ¿ÀÛÇÑ´Ù. ¿øÀÚÀûÀ¸·Î ¼öÇàµÇ´Â ¿¬»êÀÇ µÎ¹ø° ºÎ·ù´Â ¿¡ Á¤ÀÇµÈ `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` ŸÀÔº¸´Ù Ä¿¾ß ÇÑ´Ù´Â »ç½Ç¿¡ ÁÖÀÇÇ϶ó. == ½Éº¼ == Ä¿³Î ³»¿¡¼­´Â ÀϹÝÀûÀÎ ¸µÅ· ¹ýÄ¢ÀÌ Àû¿ëµÈ´Ù. (Áï, `static` À̶ó´Â Å°¿öµå¸¦ ÅëÇØ file scope ·Î ¼±¾ðµÈ ½Éº¼ÀÌ ¾Æ´Ï¶ó¸é, Ä¿³Î ³»ÀÇ ¾î´À °÷¿¡¼­³ª »ç¿ëµÉ ¼ö ÀÖ´Ù.) ÇÏÁö¸¸, ¸ðµâ¿¡ ´ëÇؼ­´Â Ä¿³Î¿¡ ´ëÇÑ Á¢±ÙÁ¡À» Á¦ÇÑÇϱâ À§ÇØ Æ¯º°È÷ ¿ÜºÎ·Î °ø°³ (export) µÈ ½Éº¼ Å×À̺íÀ» À¯ÁöÇÑ´Ù. ¹°·Ð ¸ðµâµµ ½Éº¼À» °ø°³ÇÒ ¼ö ÀÖ´Ù. === EXPORT_SYMBOL() === ÀÌ ¹æ¹ýÀº ½Éº¼À» °ø°³ÇÏ´Â ÀϹÝÀûÀÎ ¹æ¹ýÀ̸ç, ¸ðµâÀÌ°Ç ¾Æ´Ï°Ç ´Ù »ç¿ëÇÒ ¼ö ÀÖ´Â ¹æ¹ýÀÌ´Ù. Ä¿³Î ³»¿¡¼­´Â ÀÌ·¯ÇÑ ¸ðµç ¼±¾ðµéÀº `genksyms` (Ä¿³Î ½Éº¼À» »ý¼ºÇÏ´Â ÇÁ·Î±×·¥ - ÀÌ·¯ÇÑ ¼±¾ðµéÀ» ã±â À§ÇØ ¸ðµç ÆÄÀÏÀ» °Ë»öÇÑ´Ù.) ¸¦ À§Çؼ­ ÇϳªÀÇ ÆÄÀÏ·Î ¸ð¾Æ³õ±âµµ ÇÑ´Ù. `genksyms` ³ª Makefile ÀÇ ÁÖ¼®À» »ìÆ캸±â ¹Ù¶õ´Ù. === EXPORT_NO_SYMBOLS === ¸¸¾à ¸ðµâÀÌ ¾Æ¹«·± ½Éº¼µµ °ø°³ÇÏÁö ¾Ê´Â´Ù¸é ¸ðµâ ³»ÀÇ ¾î´À°÷¿¡¼­°Ç ´ÙÀ½°ú °°ÀÌ Àû¾îÁÖ¸é µÈ´Ù. {{{ EXPORT_NO_SYMBOLS; }}} Ä¿³Î 2.4 ¹öÀüÀ̳ª ±× ÀÌÀü ¹öÀü¿¡¼­´Â, ¸ðµâÀÌ `EXPORT_SYMBOL()` À̳ª `EXPORT_NO_SYMBOLS` ¸¦ Æ÷ÇÔÇÏÁö ¾ÊÀ¸¸é ±âº»ÀûÀ¸·Î `static` ÀÌ ¾Æ´Ñ ¸ðµç Àü¿ª ½Éº¼µéÀ» °ø°³ÇÑ´Ù. Ä¿³Î 2.5 ¹öÀü ÀÌÈÄ¿¡´Â ½Éº¼À» °ø°³ÇÒÁö ¸»Áö¸¦ ¸í½ÃÀûÀ¸·Î Ç¥½ÃÇØ¾ß ÇÑ´Ù. === EXPORT_SYMBOL_GPL() === `EXPORT_SYMBOL()` °ú µ¿ÀÏÇÏÁö¸¸ `EXPORT_SYMBOL_GPL()` ·Î °ø°³µÈ ½Éº¼µéÀº GPL °ú ȣȯµÇ´Â ¶óÀ̼¾½º·Î `MODULE_LICENSE()` ¸¦ µî·ÏÇÑ ¸ðµâ¿¡¼­¸¸ º¸¿©Áø´Ù. == Routines and Conventions == === Doubly-Linked Lists === Ä¿³ÎÀÇ Çì´õ¿¡´Â ¼¼°¡Áö Á¾·ùÀÇ ¸µÅ©µå ¸®½ºÆ® ·çƾÀÌ Á¸ÀçÇÑ´Ù. ±×Áß¿¡¼­µµ °¡Àå ¸¹ÀÌ »ç¿ëµÇ´Â °ÍÀÌ ¹Ù·Î À§ÀÇ °ÍÀÌ´Ù. (Linus µµ ÀÌ°ÍÀ» »ç¿ëÇÑ´Ù) ¸¸¾à ´ç½ÅÀÌ ¹Ýµå½Ã ´Ü¼ø ¸µÅ©µå ¸®½ºÆ®¸¦ »ç¿ëÇØ¾ß ÇÏ´Â »óȲÀÌ ¾Æ´Ï¶ó¸é ÀÌ°ÍÀ» »ç¿ëÇÏ´Â °ÍÀÌ ÁÁÀº ¼±ÅÃÀÏ °ÍÀÌ´Ù. »ç½Ç, ³ª´Â ÀÌ°ÍÀÌ ÁÁÀ¸³Ä ÁÁÁö ¾ÊÀ¸³Ä¸¦ ¶°³ª¼­, ´ÜÁö ´Ù¸¥ ¸µÅ©µå ¸®½ºÆ® ±¸ÇöµéÀ» ¾ø¾Ö¹ö¸± ¸ñÀûÀ¸·Î »ç¿ëÇÏ°í ÀÖ´Ù. === ¸®ÅÏ°ª¿¡ ´ëÇÑ ÀüÅë === user context ³»¿¡¼­ È£ÃâµÇ´Â ÇÔ¼öµéÀº ´ëºÎºÐ C ¾ð¾îÀÇ ÀüÅë (Convention) À» ¹«½ÃÇÑ´Ù - ¼º°ø½Ã¿¡´Â 0 À», ½ÇÆнÿ¡´Â (-EFAULT °°Àº) À½¼ö°ªÀÎ ¿¡·¯ Äڵ带 ¸®ÅÏÇÑ´Ù. óÀ½¿¡´Â ÀÌ°ÍÀÌ Á÷°üÀûÀÌÁö ¾ÊÀ» ¼öµµ ÀÖ°ÚÁö¸¸, ³×Æ®¿öÅ© ÇÁ·Î±×·¡¹Ö °°Àº °÷¿¡¼­´Â ²Ï ³Î¸® »ç¿ëµÇ°í ÀÖ´Ù. ÆÄÀÏ ½Ã½ºÅÛ Äڵ忡¼­´Â `ERR_PTR()` ¸ÅÅ©·Î¸¦ ÀÌ¿ëÇÑ´Ù; À½¼ö°ªÀÎ ¿¡·¯ Äڵ带 Æ÷ÀÎÅÍ·Î ÀÎÄÚµùÇÑ ÈÄ, `IS_ERR()` ³ª `PTR_ERR()` ¿Í °°Àº ¸ÅÅ©·Î¸¦ ÀÌ¿ëÇÏ¿© ´Ù½Ã ¾ò¾î¿Â´Ù; À̸¦ ÀÌ¿ëÇÏ¸é ¿¡·¯ Äڵ带 ¾ò±âÀ§ÇÑ Æ÷ÀÎÅ͸¦ µû·Î ÀÎÀÚ·Î ³Ñ±âÁö ¾Ê¾Æµµ µÈ´Ù. Á» ÀÌ»óÇØ º¸ÀÌÁö¸¸, ÁÁÀº ¹æ¹ýÀÌ´Ù. === Breaking Compilation === Linus ³ª ´Ù¸¥ Ä¿³Î °³¹ßÀÚµéÀº °¡²û °³¹ßÁßÀÎ Ä¿³Î³»ÀÇ ÇÔ¼ö³ª ±¸Á¶Ã¼ À̸§À» ¹Ù²Ù±âµµ ÇÑ´Ù. ÀÌ°ÍÀº ºÎºÐÀûÀÎ º¯È­¸¸ÀÌ ¾Æ´Ñ ±âº»ÀûÀÎ º¯È­¸¦ ¸»ÇÏ´Â °ÍÀÌ´Ù. (Áï, ´õÀÌ»ó ÀÎÅÍ·´Æ®°¡ È°¼ºÈ­ µÈ »óÅ¿¡¼­ È£ÃâµÇ°Å³ª, º°µµÀÇ Ã¼Å©°¡ ÀÌ·ç¾îÁö´Â ºÎºÐ, ÀÌÀü¿¡ üũÇß´ø ºÎºÐ µîÀÌ °Ë»çµÇÁö ¾ÊÀ» ¼öµµ ÀÖ´Ù´Â °ÍÀ» ¸»ÇÑ´Ù) º¸Åë ÀÌ·¯ÇÑ º¯È­°¡ ÀϾ´Â °æ¿ì¿¡´Â ¸®´ª½º Ä¿³Î ¸ÞÀϸµ¸®½ºÆ®¿¡ ±×¿¡ ÇØ´çÇÏ´Â ¼³¸íÀÌ ÀÖÀ» °ÍÀÌ´Ù; ¾ÆÄ«À̺긦 °Ë»öÇØ º¸ÀÚ. ´Ü¼øÈ÷ ÆÄÀÏ ³»¿¡¼­ Àü¿ªÀûÀÎ ¹®ÀÚ¿­ ġȯÀ» ÇÏ´Â °ÍÀº ¹®Á¦¸¦ ´õ¿í Ä¿Áö°Ô ÇÒ °ÍÀÌ´Ù. === ±¸Á¶Ã¼ º¯¼ö ÃʱâÈ­ === ±¸Á¶Ã¼ÀÇ ¸â¹ö¸¦ ÃʱâÈ­ÇÏ´Â ÁÁÀº ¹æ¹ýÀ¸·Î´Â 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` À¸·Î °Ë»öÇÏ´Â °ÍÀ» ´õ¿í ¿ëÀÌÇÏ°Ô ÇØÁÖ¸ç, ¾î¶°ÇÑ ¸â¹öµéÀÌ ÁöÁ¤µÇ´ÂÁö¸¦ ¸íÈ®ÇÏ°Ô º¸¿©ÁØ´Ù. ´ç½Åµµ ÀÌ ¹æ¹ýÀ» »ç¿ëÇÏ´Â °ÍÀÌ ÁÁÀ» °ÍÀÌ´Ù. === 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.) === C++ === Ä¿³Î ³»¿¡¼­ C++ ¸¦ »ç¿ëÇÏ´Â °ÍÀº º¸Åë ÁÁÁö ¾ÊÀº »ý°¢ÀÌ´Ù. Ä¿³Î ³»¿¡¼­´Â ÇÊ¿äÇÑ runtime environment ¸¦ Á¦°øÇÏÁö ¾ÊÀ¸¸ç Å×½ºÆ®µÇÁö ¾ÊÀº ÆÄÀϵéÀ» Æ÷ÇÔÇØ¾ß Çϱ⠶§¹®ÀÌ´Ù. C++ ¸¦ »ç¿ëÇÏ´Â °ÍÀº °¡´ÉÇÏÁö¸¸, ±ÇÇÏ°í ½ÍÁö ¾Ê´Ù. ¸¸¾à ´ç½ÅÀÌ ÁøÁ¤ C++ ¸¦ »ç¿ëÇÏ°í ½Í´Ù¸é, ÃÖ¼ÒÇÑ ¿¹¿Ü (exception) ¿¡ °üÇÑ °ÍµéÀº Àر⸦ ¹Ù¶õ´Ù. === `#if` === ÀϹÝÀûÀ¸·Î ¼Ò½º ÄÚµå ³»¿¡¼­ `#if` Àü󸮱â Áö½Ã¹®À» »ç¿ëÇÏ´Â °Íº¸´Ù Çì´õ ÆÄÀÏ ³»¿¡¼­ (ȤÀº ¼Ò½º ÆÄÀÏÀÇ ÃÖ»óÀ§ ºÎºÐ¿¡¼­) ¸ÅÅ©·Î¸¦ »ç¿ëÇÏ¿© ÇÔ¼öÀÇ ±âº»ÇüÀ» »Ì¾ÆµÎ´Â °ÍÀÌ ´õ ±ò²ûÇÏ´Ù. == ´ç½ÅÀÇ Äڵ带 Ä¿³Î³»¿¡ ³Ö´Â ¹æ¹ý == ´ç½ÅÀÌ ÀÛ¼ºÇÑ Äڵ带 Ä¿³Î ³»¿¡ Á¤½ÄÀ¸·Î Æ÷ÇԵǴ ÇüÅ·Π¸¸µé°í ½Í°Å³ª, ´ÜÁö ÆÐÄ¡ÀÇ ÇüÅÂÀÇ ¸¸µé°í ½ÍÀ»¶§¶óµµ ´ÙÀ½°ú °°Àº °ü¸®ÀûÀÎ Â÷¿øÀÇ ÀÛ¾÷ÀÌ ÇÊ¿äÇØ Áø´Ù: * ´ç½ÅÀÌ ÀÛ¾÷ÇÑ ºÎºÐ¿¡ ´ëÇÑ °ü¸®¸¦ ¸Ã°íÀÖ´Â »ç¶÷ÀÌ ´©±¸ÀÎÁö È®ÀÎÇ϶ó. ¼Ò½º ÆÄÀÏÀÇ ¸Ç À­ºÎºÐ°ú, `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` ÆÄÀÏÀ» Àд °ÍÀ» ÀØÁö ¸»ÀÚ. == 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. */ }}} == °¨»çÀÇ ±Û == ¾ÆÀ̵ð¾î¸¦ ÁÖ°í, ³» Áú¹®¿¡ ´äÇØ ÁÖ¾úÀ¸¸ç, ½Ç¼ö¸¦ °íÃÄÁÖ°í, ³»¿ëÀ» dzºÎÇÏ°Ô ÇØ ÁÖ´Â µî ¸¹Àº ÀÏÀ» µµ¿ÍÁØ Andi Kleen ¿¡°Ô °¨»çÇÑ´Ù. öÀÚ¸¦ È®ÀÎÇØ ÁÖ°í, ºÒ¸í·áÇÑ ºÎºÐ¿¡ ´ëÇØ ÁöÀûÇØ ÁØ Philipp Rumpf ¿¡°Ôµµ °¨»çÇÑ´Ù. `disable_irq()` ºÎºÐÀ» Àß Á¤¸®ÇØ ÁØ Werner Almesberger ¿Í, ƯÇã±Ç º¸È£ ½Åû? (caveat) À» Ãß°¡ÇØÁØ Jes Sorensen ¿Í Andrea Arcangeli ¿¡°Ôµµ °¨»çÇÑ´Ù. Michael Elizabeth Chastain Àº ¼³Á¤ ºÎºÐ¿¡ ´ëÇØ °Ë»çÇØÁÖ°í ³»¿ëÀ» Ãß°¡ÇØ ÁÖ¾ú´Ù. DocBook À» °¡¸£ÃÄÁØ Telsa Gwynne ¿¡°Ôµµ °¨»çÇÑ´Ù.