Kernel Module Programming Guide
|
¸®´ª½º Ä¿³Î ¸ðµâ ÇÁ·Î±×·¡¹Ö °¡À̵å
Peter Jay Salzman
Ori Pomerantz
Copyright © 2001 Peter Jay Salzman
2003-04-04 ver 2.4.0
¹ø¿ª ¿îÇü cloudshape (at) hanafos.com
2003-07-11 ver 2.4.0-trans-0.1
Contents
[edit]
1.1 °¨»ç¸» ¶Ori Pomerantz´Â Yoav WeissÀÇ ¸¹Àº Á¶¾ð°ú ¹®¼ °ø°³Àü¿¡ ¹®¼¿¡¼ À߸øµÈ ºÎºÐµéÀ» ã¾Æ ÁØ °Í¿¡ °¨»çÀÇ ¸»À» ÀüÇÑ´Ù. ¶ÇÇÑ ³×´ú¶õµåÀÇ Frodo Looijaard, ´ºÁú·£µåÀÇ Stehpen Judd, ½º¿þµ§ÀÇ Ahltorp, ±×¸®°í ij³ª´Ù Äùº¤ÀÇ Emmanuel Papirakis¿¡°Ôµµ °¨»çÇÑ´Ù.
³»°¡ ÀÌ ¹®¼¸¦ °ü¸®ÇÒ ¼ö ÀÖµµ·Ï ÇØÁØ Á¡¿¡ ´ëÇØ Ori Pomerantz¿¡°Ô °¨»çÇÑ´Ù. ±×¿¡°Ô ÀÖ¾î À̰ÍÀº »ó´çÇÑ ³ë·ÂÀ̾ú´Ù. ³»°¡ ÀÌ ¹®¼¿¡ ÀÛ¾÷ÇÑ °ÍÀ» ±×°¡ ÁÁ¾ÆÇÏ±æ ¹Ù¶õ´Ù.
³ª¸¦ ÁöµµÇØÁØ Jeff Newmiller¿Í Rhonda Bailey¿¡°Ôµµ °¨»çÇÑ´Ù. ±×µéÀÌ ¹Ù»Ý¿¡µµ ºÒ±¸Çϰí Àγ»½ÉÀ» °¡Áö°í ³ª¿¡°Ô ±×µéÀÇ °æÇèÀ» ÀüÇØ ÁÖ¾ú´Ù. David Porter´Â LaTeX ¼Ò½º¸¦ DocBookÀ¸·Î ÄÁ¹öÆÃÇÏ´Â Áö·çÇÏ°í °ñÄ¡ ¾ÆÇ Á÷¾÷À» °¡Áö°í ÀÖÁö¸¸ ´©±º°¡´Â ±× ÀÏÀ» ÇØ¾ß¸¸ ÇÑ´Ù. David¿¡°Ôµµ °¨»çÇÑ´Ù.
http://www.tldp.org/LDP/lkmpg/www.kernelnewbies.org ÀÇ »ç¶÷µé¿¡°Ôµµ °¨»ç¸¦ ÇÑ´Ù. ƯÈ÷, kernelnewbies.org¿¡ µå³ªµé¸ç Ãʺ¸µé °¡¸£Ä¡´Â °Í ¿Ü¿¡µµ ÇÒ ÀÏÀÌ ¹«Ã´ ¸¹À» °ÍÀÓÀÌ ºÐ¸íÇÑ Mark McLoughlin°ú John Levon¿¡°Ô °¨»ç¸¦ º¸³½´Ù. If this guide teaches you anything, they are partially to blame. ¸¸¾à ÀÌ ¹®¼°¡ ´ç½Å¿¡°Ô º° Àǹ̰¡ ¾ø´Ù¸é ±×µé¿¡°Ôµµ Ã¥ÀÓÀÌ ÀÖ´Ù(¿ªÁÖ: ±×¸¸Å ±×µéÀÇ ¿ªÇÒÀÌ Áß¿äÇßÀ½ ).
Ori¿Í ³ª´Â Richard M. Stallman°ú Linus Tovalds¿¡°Ô ¼º´É ÁÁÀº OS¸¦ »ç¿ëÇÏ°Ô ÇØÁØ °Í°ú ±×°ÍÀÌ ¾î¶»°Ô ÀÛµ¿ÇÏ´ÂÁö ÀÚ¼¼È÷ ¾Ë ¼ö ÀÖ´Â ±âȸ¸¦ ÁØ Á¡¿¡ ´ëÇØ °¨»çÇÑ´Ù. ³ª´Â Linus¸¦ ¸¸³ Àûµµ ¾ø°í, ¾ÕÀ¸·Îµµ ¸ø ¸¸³ª°ÚÁö¸¸, ±×´Â ³ªÀÇ Àλý¿¡ »ó´çÇÑ º¯È¸¦ ÁÖ¾ú´Ù.
´ÙÀ½Àº ³ª¿¡°Ô ÁÁÀº Á¦¾ÈÀ» Çϰųª ¿À·ù¼öÁ¤ÀÇ ¸Þ½ÃÁö¸¦ º¸³½ »ç¶÷µéÀÌ´Ù. Ignacio Martin and David Porter
[edit]
1.2 Nota Bene ¶Ori's original document was good about supporting earlier versions of Linux, going all the way back to the 2.0 days. I had originally intended to keep with the program, but after thinking about it, opted out. My main reason to keep with the compatibility was for Linux distributions like LEAF, which tended to use older kernels. However, even LEAF uses 2.2 and 2.4 kernels these days.
Both Ori and I use the x86 platform. For the most part, the source code and discussions should apply to other architectures, but I can't promise anything. One exception is Chapter 12, Interrupt Handlers, which should not work on any architecture except for x86.
[edit]
2.1 Ä¿³Î ¸ðµâÀ̶õ ¶´ç½ÅÀº Ä¿³Î ¸ðµâÀ» ÀÛ¼ºÇÏ·Á°í ÇÑ´Ù. C¸¦ ¾Ë°í ÇÁ·Î¼¼½º·Î ÀÛµ¿ÇÏ´Â ÀϹÝÀûÀÎ ÇÁ·Î±×·¥À» ÀÛ¼ºÇØ ºÃ°í ÀÌÁ¦´Â ¾îµð¼ ½ÇÁúÀûÀÎ ÀÛ¾÷ÀÌ ÇàÇØÁö´ÂÁö, ÇϳªÀÇ ¿ÍÀÏµå Æ÷ÀÎÅͰ¡ ÆÄÀÏ ½Ã½ºÅÛÀ» ¿ÏÀüÈ÷ Áö¿ï ¼ö ÀÖ°í ÄÚ¾î ´ýÇÁ°¡ ½Ã½ºÅÛÀÇ ¸®ºÎÆÃÀ» ÀǹÌÇÑ´Ù´Â °ÍÀ» ¾Ë°í ÀÖ´Ù.
Ä¿³Î ¸ðµâÀ̶õ Á¤È®È÷ ¹«¾ùÀΰ¡? ¸ðµâÀ̶õ ¿ä±¸¿¡ µû¶ó Ä¿³Î¿¡ ÀûÀç µÇ°Å³ª ÇØÁ¦ µÉ ¼ö ÀÖ´Â ÄÚµå´Ù. ½Ã½ºÅÛÀÇ Àç°¡µ¿ ¾øÀÌ Ä¿³ÎÀÇ ±â´ÉÀ» È®ÀåÀ» °¡´ÉÄÉÇÏ´Â °ÍÀÌ´Ù. ¿¹·Î ¸ðµâÀÇ ÇÑ Á¾·ù´Â µð¹ÙÀ̽º µå¶óÀ̹ö´Ù. ±×¸®°í ±×°ÍÀº ½Ã½ºÅÛ¿¡ ¿¬°áµÈ Çϵå¿þ¾î¿¡ Ä¿³ÎÀÌ Á¢±ÙÇÒ ¼ö ÀÖµµ·Ï ÇØ ÁØ´Ù. ¸ðµâÀÌ ¾ø´Ù¸é ¿ì¸®´Â ¸ð³î¸®Æ½ Ä¿³ÎÀ» ´Ù½Ã ºôµå ÇØ¾ß Çϸç, Ä¿³Î À̹ÌÁö¿¡ »õ·Î¿î ±â´ÉÀ» Á÷Á¢ÀûÀ¸·Î Ãß°¡ ½ÃÄÑ¾ß ÇÑ´Ù. ´ë±Ô¸ð Ä¿³Î¿¡¼´Â, ¿ì¸®°¡ ¿øÇÏ´Â »õ·Î¿î ±â´ÉÀ» Ãß°¡ Çϱâ À§Çؼ ¸Å¹ø Ä¿³ÎÀ» ´Ù½Ã ºôµåÇØ¾ß Çϰí, ´Ù½Ã ºÎÆÃÇØ¾ßÇÏ´Â ´ÜÁ¡À» °®°Ô µÈ´Ù.
[edit]
2.2 ¾î¶»°Ô ¸ðµâÀ» Ä¿³Î¿¡ ³ÖÀ» °ÍÀΰ¡? ¶lsmod¸¦ ½ÇÇàÇÔÀ¸·Î½á ´ç½ÅÀº ÀÌ¹Ì Ä¿³Î¿¡ ÀûÀçµÇÀÖ´Â ¸ðµâÀ» º¼ ¼ö ÀÖÀ¸¸ç, lsmod´Â /proc/modules ÆÄÀÏÀ» Àоî Á¤º¸¸¦ ¾ò¾î ¿Â´Ù.
¸ðµâÀº Ä¿³Î¿¡¼ ¾î¶»°Ô ÀÚ½ÅÀÇ À§Ä¡¸¦ ã¾Æ³¾±î? Ä¿³Î ³»ºÎ¿¡ Á¸ÀçÇÏÁö ¾Ê´Â Ư¡À» Ä¿³ÎÀÌ ¾Ë Çʿ䰡 ÀÖÀ» ¶§, Ä¿³Î ¸ðµâ µ¥¸óÀÎ kmod(ÀÌÀü ¹öÀüÀÇ ¸®´ª½º¿¡¼´Â kerneld·Î ¾Ë·ÁÁ® ÀÖ´Ù.) ¸ðµâÀ» ·Îµå ½Ã۱â À§ÇØ modprobe¸¦ ½ÇÇà ½ÃŲ´Ù. modprobe¿¡ ´ÙÀ½ÀÇ µÎ ÇüÅ·Π¹®ÀÚ¿ÀÌ Àü´ÞµÈ´Ù.
alias char-major-10-30 softdogÀϹÝÀûÀÎ ¾ÆÀ̵§Æ¼ÆÄÀ̾î´Â softdog.o¶ó´Â ¸ðµâÀ» ÂüÁ¶ÇÑ´Ù´Â »ç½ÇÀ» ¾Ë°Ô µÈ´Ù. ´ÙÀ½À¸·Î modprobe´Â /lib/modules/version/modules.dep ÆÄÀÏÀ» Á¶»çÇØ¼ ´Ù¸¥ ¸ðµâÀÌ ¿ä±¸µÇ´Â ¸ðµâÀÌ ÀûÀçµÇ±â Àü¿¡ ¸ÕÀú ÀûÀçµÇ¾ß Çϴ°¡¸¦ º»´Ù. ÀÌ ÆÄÀÏÀº depmod -a ¿¡ ÀÇÇØ »ý¼ºµÇ¸ç, ¸ðµâÀÇ ÀÇÁ¸¼ºÀ» ´ã°í ÀÖ´Ù. ¿¹¸¦ µé¾î msdos.o´Â fat.o¸ðµâÀÌ ¸ÕÀú Ä¿³Î¿¡ ÀûÀçµÈ »óŸ¦ ¿ä±¸ÇÑ´Ù. ¿äûµÈ ¸ðµâÀÌ »ç¿ëÇÏ´Â ½Éº¼(º¯¼ö³ª ÇÔ¼ö)À» ´Ù¸¥ ¸ðµâÀÌ Á¤ÀÇ Çߴ°¡¶ó´Â, ´Ù¸¥ ¸ðµâ¿¡ ´ëÇÑ ÀÇÁ¸¼ºÀ» °®´Â´Ù.
¸¶Áö¸·À¸·Î modprobe´Â ¼±Çà ¸ðµâÀ» Ä¿³Î¿¡ ÀûÀçÇϱâ À§ÇØ insmod¸¦ »ç¿ëÇϰí, ¿ä±¸µÈ ¸ðµâÀ» ÀûÀçÇÑ´Ù. modprobe´Â insmod¿¡ Ç¥ÁØ ¸ðµâ µð·ºÅ丮ÀÎ /lib/modules/version/À» »ç¿ëÇϵµ·Ï Áö½ÃÇÑ´Ù. insmod´Â ¸ðµâÀÇ À§Ä¡¿¡ ´ëÇÑ Á¤º¸¸¦ ÀüÇô ¸ð¸£°Ô µÇÀÖ´Ù. ¹Ý¸é¿¡ modprobe´Â ¸ðµâÀÇ ±âº» À§Ä¡¸¦ ¾Ë°í ÀÖ´Ù. ¿¹¸¦ µé¾î msdos¸ðµâÀ» ÀûÀçÇϱ⠿øÇÑ´Ù¸é ´ÙÀ½ÀÇ µÎ °¡Áö¸¦ ½ÇÇàÇØ¾ß ÇÑ´Ù.
insmod /lib/modules/2.5.1/kernel/fs/fat/fat.o insmod /lib/modules/2.5.1/kernel/fs/msdos/msdos.oȤÀº "modprobe -a msdos"¸¦ ½ÇÇàÇÏÀÚ. ¸®´ª½º´Â modprobe, insmode, depmod¸¦ modutilsȤÀº mod-utils¶ó ºÒ¸®´Â ÆÐŰÁö·Î Á¦°øÇÑ´Ù
ÀÌÀåÀ» ¸¶Ä¡±â Àü¿¡ /etc/modules.conf¸¦ »ìÆìº¸ÀÚ.
#This file is automatically generated by update-modules path[misc]=/lib/modules/2.4.?/local keep path[net]=~p/mymodules options mydriver irq=10 alias eth0 eepro#À¸·Î ½ÃÀÛÇÏ´Â ÇàÀº ÁÖ¼®À̸ç, ºó ÇàÀº ¹«½ÃµÈ´Ù. path[misc] ÇàÀº modprobe¿¡ /lib/modules/2.4.?/local µð·ºÅ丮¿¡¼ misc ¸ðµâ¿¡ ´ëÇÑ °æ·Î¸¦ ã¾Æ ´ëüÇϵµ·Ï ÇÑ´Ù. º¸µíÀÌ, ½© ¸ÞŸ ij¸¯ÅͰ¡ »ç¿ë °¡´ÉÇÏ´Ù.
path[net] ÇàÀº modprobe·Î ÇÏ¿©±Ý net ¸ðµâÀ» ~p/modules/ µð·ºÅ丮¿¡¼ ãµµ·Ï ÇÑ´Ù. ±×·¯³ª pathnet¿¡ ¹Ù·Î ¼±ÇàµÇ´Â ¡°keep¡±Àº modprobe¿¡°Ô misc¸ðµâ¿¡¼ ÇÑ °Íó·³ Ç¥ÁØ °Ë»ö °æ·Î¸¦ ´ëüÇÏÁö ¾Ê°í, ÇØ´ç µð·ºÅ丮¸¦ net¸ðµâÀ» ãÀ» ¶§ Ç¥ÁØ °Ë»ö °æ·Î·Î Ãß°¡Çϵµ·Ï ÇÑ´Ù.
kmod°¡ ÀϹÝÀûÀÎ ¾ÆÀ̵§Æ¼ÆÄÀ̾îÀÎ ¡®eth0¡¯¸¦ ÀûÀçÇ϶ó´Â ¿ä±¸ÇÒ ¶§¸¶´Ù, eepro.o¸¦ ÀûÀçÇ϶ó°í ÇÑ´Ù.
/etc/modules.conf ¿¡¼ "alias block-major-2 floppy"°°Àº ÇàÀº ¹ß°ßÇÏÁö ¸øÇÒ °ÍÀÌ´Ù. ¿Ö³ÄÇá¸é, modprobe´Â ´ëºÎºÐÀÇ ½Ã½ºÅÛ¿¡¼ »ç¿ëµÇ´Â Ç¥ÁØ µå¶óÀ̹öµé¿¡ ´ëÇØ ¾Ë°í Àֱ⠶§¹®ÀÌ´Ù.
ÀÌÁ¦ ¸ðµâÀÌ ¾î¶»°Ô Ä¿³Î¿¡ ÀûÀçµÇ´ÂÁö ¾Ë¾ÒÀ» °ÍÀÌ´Ù. ¡®stacking modules¡¯¶ó°í ºÎ¸£´Â ¸ðµâ¿¡ ÀÇÁ¸ÀûÀÎ ¸ðµâÀ» ÀÛ¼ºÇÑ´Ù¸é ¸î °¡Áö ´õ ¾ð±ÞÇÒ °ÍµéÀÌ ÀÖ´Ù. À̰ÍÀº ´ÙÀ½À¸·Î ¹Ì·é´Ù. »ó´ëÀûÀ¸·Î °í ³ÀÌÀÇ ÀïÁ¡À» ´Ù·ç±â Àü¿¡ ´Ù·ï¾ß ÇÒ ºÎºÐÀÌ ¸¹ÀÌ ÀÖ´Ù.
[edit]
2.2.1 ½ÃÀÛÇϱâ Àü¿¡ ¶Äڵ带 ÆÄÇìÄ¡±â Àü¿¡ ¿ì¸®°¡ ´Ù·ï¾ßÇÒ ¸î¸î ÁÖÁ¦°¡ ´õ ÀÖ´Ù. ¸ðµç »ç¶÷ÀÇ ½Ã½ºÅÛÀÌ »óÀÌÇÏ°í ±×µé¸¸ÀÇ °ü½ÀÀÌ ÀÖ´Ù. ¡°hello world¡± ÇÁ·Î±×·¥À» ÄÄÆÄÀÏÇÏ°í ¿Ã¹Ù¸£°Ô ÀûÀçÇÏ´Â °ÍÀº ¶§·Ð trick(?)Àϼö ÀÖ´Ù. óÀ½ ¸î¸î Àå¾Ö¸¦ ±Øº¹ÇÏ°í ³ª¸é, ¼øÇ³¿¡ µÀÀ» ´Ü µí ÁøÇàµÉ °ÍÀ̶ó »ý°¢ÇÑ´Ù.
[edit]
2.2.1.1 ¸ðµâ ¹öÀü ¶CONFIG_MODVERSIONS¸¦ Ä¿³Î¿¡¼ Ȱ¼ºÈ ½ÃŰÁö ¾Ê¾Ò´Ù¸é, ƯÁ¤ Ä¿³Î¿¡¼ ÄÄÆÄÀÏÇÑ ¸ðµâÀº ´Ù¸¥ Ä¿³Î·Î ºÎÆÃÇÑ ½Ã½ºÅÛ¿¡´Â ÀûÀç µÇÁö ¾Ê´Â´Ù. À̹®¼ ÈĹݺΠ±îÁö´Â ¸ðµâ ¹öÀü¿¡ °üÇÑ ¹®Á¦¸¦ ´Ù·çÁö ¾ÊÀ» °ÍÀÌ´Ù. ÀÌ ¹®¼ÀÇ ¿¹Á¦´Â modversioning±â´ÉÀ» Ȱ¼ºÈÇÑ Ä¿³ÎÀ» »ç¿ëÇÑ´Ù¸é ÀÛµ¿ÇÏÁö ¾ÊÀ» °ÍÀÌ´Ù. ´ëºÎºÐÀÇ ¹èÆ÷ÆÇ Ä¿³ÎÀº ÀÌ ±â´ÉÀ» Ȱ¼ºÈ ½ÃŲ »óÅ·Π³ª¿Â´Ù. ¸¸¾à ¸ðµâÀ» ÀûÀçÇÒ ¶§ ¹öÀü ¹®Á¦·Î ¿¡·¯°¡ ³´Ù¸é modversioning ±â´ÉÀ» ºñȰ¼ºÈ ½ÃŲ ÈÄ Ä¿³ÎÀ» ´Ù½Ã ÄÄÆÄÀÏ ÇØ¾ß ÇÒ °ÍÀÌ´Ù.
[edit]
2.2.1.2 X »ç¿ëÇϱ⠶ÀÌ ¹®¼¿¡ ³ª¿Â ¸ðµç ¿¹Á¦¸¦ ŸÀÌÇÎÇϰí ÄÄÆÄÀÏÇϰí ÀûÀçÇØº¸±â¸¦ °·ÂÈ÷ ±ÇÇÏ´Ù. console¿¡¼ ÀÛ¾÷Çϱ⠿ª½Ã ±ÇÇÑ´Ù. X ȯ°æ¿¡¼ÀÇ ÀÛ¾÷À» ÇÏÁö ¸¶¶ó.
¸ðµâÀº printf()ó·³ ȸ鿡 Ãâ·ÂÀ» ÇÏÁö ¸øÇÏ°í ·Î±× Á¤º¸¿Í °æ°íµéÀ» Äַܼθ¸ Ãâ·ÂÇÑ´Ù. ¸¸ÀÏ xterm¿¡¼ ¸ðµâÀ» ÀûÀçÇÑ´Ù¸é, Á¤º¸¿Í °æ°íµéÀº ´ç½ÅÀÇ ·Î±× ÆÄÀÏ¿¡¸¸ ±â·ÏµÉ °ÍÀÌ´Ù. ·Î±× ÆÄÀÏÀ» È®ÀÎ Çϱâ Àü±îÁö´Â ±×°ÍÀ» º¸Áö ¸øÇÒ °ÍÀÌ´Ù. Áï°¢ÀûÀÎ Á¤º¸¸¦ À§Çؼ ¸ðµç ÀÛ¾÷À» Äֿܼ¡¼ Ç϶ó.
[edit]
2.2.1.3 ÄÄÆÄÀÏ ¹®Á¦¿Í Ä¿³Î ¹öÀü ¶Á¾Á¾ ¸®´ª½º´Â Ç¥ÁØÀÌ ¾Æ´Ñ ¹æ½ÄÀ¸·Î ´Ù¾çÇÏ°Ô ÆÐÄ¡µÇ¼ ¹èÆ÷µÇ°í ±×°ÍÀº ¹®Á¦¸¦ ¾ß±âÇÑ´Ù.
´õ ÈçÇÑ ¹®Á¦´Â ¸î¸î ¹èÆÇµéÀÌ ºÒ¿ÏÀüÇÑ Ä¿³Î Çì´õ¸¦ °¡Áö°í ¹èÆ÷µÈ´Ù´Â Á¡ÀÌ´Ù. ´ç½ÅÀÇ Äڵ带 ÄÄÆÄÀÏ ÇÒ ¶§ ¸®´ª½º Ä¿³ÎÀÇ ´Ù¾çÇÑ Çì´õ ÆÄÀÏÀ» »ç¿ëÇØ¼ ÄÄÆÄÀÏ ÇØ¾ß ÇÒ °ÍÀÌ´Ù. ¸ÓÇÇÀÇ ¹ýÄ¢Àº ¸ðµâÀÌ ÀÛµ¿Çϱ⿡ ÇÊ¿äÇÑ Çì´õ¸¸ ºüÁ®ÀÖ´Ù°í ¸»ÇÑ´Ù.(½ä·· Á¶Å©-_-¡° – ÇÊÀÚ°¡ ¾´°ÍÀÓ)
ÀÌ·± ¹®Á¦¸¦ ÇÇÇϱâ À§Çؼ´Â ¸®´ª½º Ä¿³Î ¹Ì·¯ »çÀÌÆ®¿¡¼ ´Ù¿î ¹Þ¾Æ ÄÄÆÄÀÏÇÏ°í ºÎÆÃ½ÃÄÑ ½Ã½ºÅÛÀ» »ç¿ëÇÒ °ÍÀ» °·ÂÈ÷ ±ÇÇÑ´Ù. ÀÚ¼¼ÇÑ »çÇ×Àº Linux Kernel HOWTO¸¦ Âü°íÇϱ⠹ٶõ´Ù.
¿ª¼³ÀûÀÌÁö¸¸ ÀÌ°Í ¿ª½Ã ¹®Á¦¸¦ ¸¸µç´Ù. ±âº»ÀûÀ¸·Î, ´ç½ÅÀÇ ½Ã½ºÅÛ¿¡ ÀÖ´Â GCC´Â ´ç½ÅÀÌ ¼³Ä¡ÇÑ ¹öÀüÀÇ Ä¿³Î Çì´õÆÄÀÏÀ» ã´Â °ÍÀÌ ¾Æ´Ï°í ±âº»À¸·Î ¼³Ä¡µÆ´ø Ä¿³Î Çì´õ(º¸Åë /usr/src/)¸¦ ãÀ» °ÍÀÌ´Ù. À̰ÍÀº gccÀÇ -l ¿É¼ÇÀ» »ç¿ëÇØ¼ ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.
[edit]
3.1 Hello, World (part 1): The Simplest Module ¶¿ø½Ã ÇÁ·Î±×·¡¸Ó°¡ óÀ½À¸·Î ¿ø½Ã ÄÄÇ»ÅÍ¿¡ ù ÇÁ·Î±×·¥À» »õ°Ü ³Ö¾úÀ» ¶§, ±×°ÍÀº ¡®Hello World¡¯¶ó´Â ¹®ÀÚ¸¦ ¾ç¶¼ ±×¸²¿¡ »õ°Ü ³ÖÀº ÇÁ·Î±×·¥À̾ú´Ù. ·Î¸¶ÀÇ ÇÁ·Î±×·¥ Ã¥Àº ¡®Salut Mundi¡¯(hello worldÀÇ ·Î¸¶¾îÀÎ µí.. J)·Î ½ÃÀÛÇÑ´Ù. ÀÌ·± °ü½ÀÀ» ±ú¶ß¸° »ç¶÷¿¡°Ô ¾î¶² ÀÏÀÌ ÀϾ´ÂÁö ÀßÀº ¸ð¸£Áö¸¸, º°·Î ½Å°æ ¾²Áö ¾Ê¾Æµµ µÉ µí ÇÏ´Ù. Ä¿³Î ¸ðµâÀ» ÀÛ¼ºÇÏ´Â ±âº»ÀÌ µÇ´Â ´Ù¸¥ Ãø¸é¿¡¼ÀÇ ¿¹·Î Hello World·ùÀÇ ÇÁ·Î±×·¥À» °¡Áö°í ½ÃÀÛÇØº¸ÀÚ.(¾î»öÇÑ ¹ø¿ª...)
´ÙÀ½Àº °¡Àå °£´ÜÇÑ ¸ðµâÀÌ´Ù. ¾ÆÁ÷ ÄÄÆÄÀÏÇÏÁö ¸»ÀÚ; ´ÙÀ½ Àå¿¡¼ ¸ðµâÀ» ÄÄÆÄÀÏÇÏ´Â °Í¿¡ ´ëÇØ ´Ù·ê °ÍÀÌ´Ù.
Example 2-1. hello-1.c
/* hello-1.c - The simplest kernel module. */ #include <linux/module.h> /* ¸ðµç ¸ðµâ¿¡ ÇÊ¿ä */ #include <linux/kernel.h> /* KERN_ALERT¿¡ ÇÊ¿ä */ int init_module(void) { printk("<1>Hello world 1.\n"); // 0ÀÌ ¾Æ´Ñ °ªÀ» ¸®ÅÏÇÏ´Â °ÍÀº init_moduleÀÌ ½ÇÆÐÇÑ °ÍÀ» ÀǹÌÇÑ´Ù. °í·Î ¸ðµâÀº ·ÎµåµÇÁö ¸øÇÑ´Ù. return 0; } void cleanup_module(void) { printk(KERN_ALERT "Goodbye world 1.\n"); } Ä¿³Î ¸ðµâÀº ÃÖ¼Ò µÎ °³ÀÇ ÇÔ¼ö¸¦ Æ÷ÇÔÇØ¾ß ÇÑ´Ù: ¸ðµâÀÌ Ä¿³Î¿¡ ÀûÀçµÉ ¶§ È£ÃâµÇ´Â ½ÃÀÛ(ÃʱâÈ) ÇÔ¼öÀÎ init_module() ±×¸®°í ¸ðµâÀÌ ÇØÁ¦µÇ±â Á÷Àü¿¡(rmmod) È£ÃâµÇ´Â Á¾·á(ÇØÁ¦) ÇÔ¼öÀÎ cleanup_module()ÀÌ ¹Ù·Î ±×°ÍÀÌ´Ù. ½ÇÁ¦, Ä¿³Î 2.3.13ºÎÅÍ ÀÌ·± ºÎºÐ¿¡ ¸¹Àº º¯È°¡ ÀÖ¾ú´Ù. ´ç½ÅÀº ½ÃÀÛÇϰųª Á¾·áÇÒ ¶§ ¸¶À½¿¡ µå´Â °ÍÀ» »ç¿ëÇÒ ¼ö ÀÖÀ¸¸ç, ÀÌ·± °ÍµéÀ» Section 2.3¿¡¼ ¹è¿ï °ÍÀÌ´Ù. »ç½Ç »õ·Î¿î ¹æ½ÄÀÌ ´õ ³´´Ù. ±×·¯³ª ¸¹Àº »ç¶÷µéÀÌ ¿©ÀüÈ÷ ½ÃÀÛ°ú ³¡¿¡ init_module() °ú cleanup_module()ÇÔ¼ö¸¦ »ç¿ëÇÑ´Ù.
ÀüÇüÀûÀ¸·Î init_module()ÇÔ¼ö´Â Ä¿³Î¿¡ ¾î¶² Çîµé·¯¸¦ µî·ÏÇϰųª, Ä¿³ÎÀÌ °¡Áö°í ÀÖ´Â ÇÔ¼öÀÇ Äڵ带 ´ëüÇÑ´Ù. ÀϹÝÀûÀ¸·Î ƯÁ¤ÇÑ ÀÛ¾÷À» ¼öÇàÇÑ ÈÄ, ¿ø·¡ÀÇ ÇÔ¼ö¸¦ ´Ù½Ã È£ÃâÇÑ´Ù.). cleanup_module()ÇÔ¼ö´Â init_module()ÇÔ¼ö°¡ ÇàÇÑ °ÍÀ» º¹±Í½ÃÄÑ ¸ðµâÀ» ¾ÈÀüÇÏ°Ô ÇØÁ¦(unload)ÇÒ ¼ö ÀÖ°Ô ÇÑ´Ù.
¸¶Áö¸·À¸·Î ¸ðµç Ä¿³Î ¸ðµâÀº linux/module.h¸¦ Æ÷ÇÔÇØ¾ß ÇÑ´Ù. linux/kernel.h´Â printk()ÇÔ¼öÀÇ log levelÀÎ KERN_ALERT¸¦ À§Çؼ¸¸ ¿©±â¼ ÇÊ¿äÇϸç ÀÌ·± ³»¿ëÀº printk()ÇÔ¼ö ¼Ò°³¿¡¼ ¹è¿ï °ÍÀÌ´Ù.
[edit]
3.1.1 printk()ÇÔ¼ö ¼Ò°³ ¶´ç½ÅÀÇ »ý°¢°ú ´Ù¸£°Ô printk()´Â »ç¿ëÀÚ¿Í Á¤º¸ ±³È¯À» À§ÇÑ °ÍÀº ¾Æ´Ï´Ù.(¿ì¸®°¡ ÀÌ·± ¸ñÀûÀ¸·Î hello-1¿¡¼ printk()¸¦ »ç¿ëÇÒ Áö¶óµµ) À̰ÍÀº Ä¿³Î¿¡ ±â·Ï(logging)ÇÏ´Â ¹æ½ÄÀ̸ç, °æ°í¸¦ Çϰųª Á¤º¸¸¦ ³²±â±â À§ÇØ »ç¿ëµÈ´Ù. °¢°¢ÀÇ printk()´Â ¿ì¼± ¼øÀ§¸¦ °¡Áö°í »ç¿ëµÇ¸ç, /which is the <1> and KERN_ALERT you see /À̰ÍÀº <1> ȤÀº KERN_ALERT ¿Í °°Àº ÇüÅ·Π»ç¿ëµÈ´Ù. 8°³ÀÇ ¿ì¼±¼øÀ§°¡ ÀÖÀ¸¸ç, Ä¿³ÎÀº ±×¿¡ »óÀÀÇÏ´Â ¸ÅÅ©·Î¸¦ °¡Áö°í ÀÖ¾î ÀÌÇØÇϱ⠾î·Á¿î ¹øÈ£¸¦ »ç¿ëÇÒ Çʿ䰡 ¾ø´Ù. À̵éÀº linux/kernel.h¿¡¼ ã¾Æº¼ ¼ö ÀÖ´Ù. ¿ì¼± ¼øÀ§¸¦ Á¤ÇÏÁö ¾Ê°í »ç¿ëÇÑ´Ù¸é ±âº»ÀûÀÎ ¿ì¼±¼øÀ§ÀÎ DEFAULT_MESSAGE_LOGLEVELÀÌ »ç¿ëµÉ °ÍÀÌ´Ù.
¿ì¼± ¼øÀ§ ¸ÅÅ©·Î¸¦ Àб⸦ ±ÇÇÑ´Ù. Çì´õ ÆÄÀÏÀº °¢ ¿ì¼± ¼øÀ§°¡ ÀǹÌÇÏ´Â ¹Ùµµ ¼³¸íÇØ ÁØ´Ù. ½ÇÁ¦ <4>¿Í °°Àº ¹øÈ£´Â ¾²ÀÌÁö ¾ÊÀ¸¸ç ´ë½Å KERN_WARNNING°ú °°Àº ¸ÅÅ©·Î¸¦ »ç¿ëÇÑ´Ù.
¸¸¾à int console_loglevelº¸´Ù ¿ì¼± ¼øÀ§°¡ ³·À¸¸é, ÇØ´ç ¸Þ½ÃÁö´Â ´ç½ÅÀÇ ÇöÀç Å͹̳ο¡ º¸¿©Áú °ÍÀÌ´Ù. syslogd¿Í klogd°¡ ½ÇÇà ÁßÀ̶ó¸é ¸ÞÁö½Ã°¡ ÄַܼΠÃâ·Â¿©ºÎ¿Í °ü°è ¾øÀÌ /var/log/messages¿¡ Ãß°¡µÈ´Ù. printk()ÀÇ ¸Þ½ÃÁö°¡ ·Î±× ÆÄÀÏ¿¡¸¸ ³²°ÜÁöÁö ¾Ê°í ÄַܼΠ¹Ýµå½Ã Ãâ·ÂµÇµµ·Ï Çϱâ À§ÇØ KERN_ALERT¿Í °°ÀÌ ³ôÀº ¿ì¼±¼øÀ§¸¦ »ç¿ëÇÑ´Ù. ½ÇÁ¦ ¸ðµâÀ» ÀÛ¼ºÇÒ ¶§ ÀûÀýÈ÷ »óȲ¿¡ ¸Â´Â ¿ì¼±¼øÀ§¸¦ »ç¿ëÇϱ⠿øÇÒ °ÍÀÌ´Ù.
[edit]
3.2 Ä¿³Î ¸ðµâ ÄÄÆÄÀÏ ¶Ä¿³Î ¸ðµâÀº Àç´ë·Î ÀÛµ¿Çϱâ À§Çؼ GCCÀÇ Æ¯Á¤ÇÑ ¿É¼Ç°ú ÇÔ²² ÄÄÆÄÀÏ µÇ¾ß ÇÑ´Ù. Á¤ÀÇµÈ Æ¯Á¤ÇÑ ½Éº¼°ú ÇÔ²² ÄÄÆÄÀÏ µÉ Çʿ䵵 ÀÖ´Ù. ½ÇÇà ÆÄÀÏÀ» ÄÄÆÄÀÏÇÏ´ÂÁö Ä¿³Î ¸ðµâÀ» ÄÄÆÄÀÏÇÏ´ÂÁö¿¡ µû¶ó Ä¿³Î Çì´õ ÆÄÀÏÀÌ ´Ù¸£°Ô µ¿ÀÛÇØ¾ß Çϱ⠴빮ÀÌ´Ù. GCCÀÇ –D¿É¼ÇÀ» »ç¿ëÇϰųª #define ÇÁ¸®ÇÁ·Î¼¼¼ ¸í·ÉÀ» »ç¿ëÇØ ½Éº¼À» Á¤ÀÇÇÒ ¼ö ÀÖ´Ù. ÀÌ Àå¿¡¼ Ä¿³Î ¸ðµâÀ» ÄÄÆÄÀÏÇϱâ À§ÇØ ÇÊ¿äÇÑ °ÍµéÀ» ¸ðµÎ ´Ù·é´Ù.
hello-1.c ¸ðµâ ÄÄÆÄÀÏÀ» À§ÇÑ MakefileÀ» »ìÆìº¸ÀÚ
Example 2-2. Makefile for a basic kernel module
TARGET := hello-1 WARN := -W -Wall -Wstrict-prototypes -Wmissing-prototypes INCLUDE := -isystem /lib/modules/`uname -r`/build/include CFLAGS := -O2 -DMODULE -D__KERNEL__ ${WARN} ${INCLUDE} CC := gcc-3.0 ${TARGET}.o: ${TARGET}.c .PHONY: clean clean: rm -rf {TARGET}.o ¿¬½ÀÀ¸·Î hello-1.c¸¦ ÄÄÆÄÀÏÇϰí insmod ./hello-1.o¸¦ Ä¿³Î¿¡ ¿Ã·Áº¸ÀÚ. ÀߵǴ°¡? Ä¿³Î¿¡ ÀûÀçµÈ ¸ðµç ¸ðµâÀº /proc/modules¿¡ ¸®½ºÆ®µÈ´Ù. ´ç½ÅÀÇ ¸ðµâÀÌ Ä¿³ÎÀÇ ÀϺΰ¡ µÆ´ÂÁö ¾Ë¾Æ º¸±â À§ÇØ ±× ÆÄÀÏÀ» Ãâ·ÂÇØº¸ÀÚ. ÃàÇÏÇÑ´Ù. ´ç½ÅÀº ¸®´ª½º Ä¿³ÎÄÚµåÀÇ ÀÛ¼ºÀÚ°¡ µÆ´Ù. Áñ°Å¿òÀº Àá½Ã ¹Ì·ïµÎ°í rmmod hello-1¸¦ »ç¿ëÇØ Ä¿³Î·ÎºÎÅÍ ´ç½ÅÀÇ ¸ðµâÀ» Á¦°Å ÇÏÀÚ. ´ç½ÅÀÇ ½Ã½ºÅÛ ·Î±×ÆÄÀÏ¿¡ ±â·ÏÀÌ µÆ´ÂÁö º¸±â À§ÇØ /var/log/messages ÆÄÀÏÀ» »ìÆì º¸ÀÚ.
µ¶ÀÚ¸¦ À§ÇÑ ¶Ç ´Ù¸¥ ¿¹Á¦°¡ ÀÖ´Ù. ¾Õ¼ ¾ð±ÞÇÑ init_module()ÇÔ¼öÀÇ ¸®ÅÏ °ªÀ» 0ÀÌ ¾Æ´Ñ ´Ù¸¥ °ªÀ¸·Î º¯°æÇÑ ÈÄ ´Ù½Ã ÄÄÆÄÀÏ ÇÏ°í ·ÎµåÇØ º¸ÀÚ. ¾î¶² ÀÏÀÌ ÀϾ´Â°¡
[edit]
3.3 Hello World (part 2) ¶¿©·¯ºÐÀº ¿©·¯ºÐÀÇ init ¿Í cleanup ÇÔ¼ö À̸§À» ¹Ù²Ü ¼ö ÀÖ´Ù. ÀÌÈÄ·Î ±×µéÀÇ À̸§ÀÌ ¹Ýµå½Ã init_moduel(), cleanup_module()ÀÏ ÇÊ¿ä´Â ¾ø´Ù. ÀÌ´Â module_init()¿Í module_exit()¸ÅÅ©·Î¿¡ ÀÇÇØ ÀÌ·ïÁø´Ù. ÀÌ ¸ÅÅ©·Î´Â linux/init.h¿¡ ÀúÀÇ µÇÀÖ´Ù. ¼±ÇàµÇ¾ß ÇÒ °ÍÀº ¸ÅÅ©·Î¸¦ È£ÃâÇϱâ Àü¿¡ init¿Í cleanupÇÔ¼ö¶ó Á¤ÀÇ µÅÀÖ¾î¾ß ÇÑ´Ù °Í »Ó, ±×·¸Áö ¾Ê´Ù¸é ÄÄÆÄÀÏ ¿¡·¯¸¦ ¸¸³¯ °ÍÀÌ´Ù. ÀÌ·± Å×Å©´ÐÀÇ ¿¹°¡ ÀÖ´Ù.
Example 2-3. hello-2.c
/* hello-2.c - Demonstrating the module_init() and module_exit() macros. This is the preferred over using init_module() and cleanup_module(). hello-2.c – module_init()¿Í module_exit()¸ÅÅ©·ÎÀÇ ¿¹. À̰ÍÀº init_module()°ú cleanup_moduel() º¸´Ù ³´´Ù. */ #include <linux/module.h> // Needed by all modules #include <linux/kernel.h> // Needed for KERN_ALERT#include <linux/init.h> // Needed for the macrosstatic int hello_2_init(void) { printk(KERN_ALERT "Hello, world 2\n"); return 0; } static void hello_2_exit(void) { printk(KERN_ALERT "Goodbye, world 2\n"); } module_init(hello_2_init); module_exit(hello_2_exit); ÀÌÁ¦ ¿ì¸®´Â µÎ°³ÀÇ ½ÇÁ¦ Ä¿³Î ¸ðµâÀ» üÇèÇß´Ù. »ý»ê¼ºÀ» ³ôÀ̱â À§ÇØ ¿ì¸®´Â MakefileÀ» Ȱ¿ëÇØ¾ß ÇÑ´Ù. ´ÙÀ½Àº ¾Õ µÎ °³ÀÇ ¸ðµâÀ» ¸ðµÎ ÄÄÆÄÀÏ ÇÒ ¼ö ÀÖ´Â °³¼±µÈ Makefile ÀÌ´Ù. °£°á¼º, ±Ô¸ð¸é¿¡¼ ÃÖÀûÈµÈ °ÍÀÌ´Ù. ´ÙÀ½À» ÀÌÇØÇÒ ¼ö ¾ø´Ù¸é GNU Makefile¸Å´º¾ó ȤÀº, makefile infoÆäÀÌÁö¸¦ Àб⠹ٶõ´Ù.
Example 2-4. Makefile for both our modules
WARN := -W -Wall -Wstrict-prototypes -Wmissing-prototypes INCLUDE := -isystem /lib/modules/`uname -r`/build/include CFLAGS := -O2 -DMODULE -D__KERNEL__ ${WARN} ${INCLUDE} CC := gcc-3.0 OBJS := ${patsubst %.c, %.o, ${wildcard *.c}} all: ${OBJS} .PHONY: clean clean: rm -rf *.o µ¶ÀÚµéÀ» À§ÇÑ ¿¹·Î, ¸¸¾à °°Àº µð·ºÅ丮¿¡ hello-3.c °°Àº ¸ðµâÀÌ Çϳª ´õ ÀÖ´Ù¸é ±× ¸ðµâÀ» ÀÚµ¿À¸·Î ÄÄÆÄÀÏ Çϱâ À§ÇØ ´ç½ÅÀº MakefileÀ» ¾î¶»°Ô ¼öÁ¤ÇÒ °ÍÀΰ¡?
[edit]
3.4 Hello World (part 3): The __init and __exit Macros ¶´ÙÀ½Àº Ä¿³Î 2.2³ª ȤÀº ±× ÈÄ ¹öÀü¿¡¼ÀÇ ¿¹´Ù. init¿Í cleanup ÇÔ¼öÀÇ Á¤ÀÇ¿¡¼ÀÇ º¯È¸¦ ÁÖ¸ñÇ϶ó. ³»ÀåµÈ µå¶óÀ̹ö¿¡ ´ëÇØ initÇÔ¼ö°¡ ¼öÇàµÇ¸é, __init¸ÅÅ©·Î´Â initÇÔ¼ö°¡ ¹ö·ÁÁö°í(-_-¡°) ¸Þ¸ð¸®°¡ ¹ÝȯµÈ´Ù. ±×·¯³ª ¸ðµâÀº ÀûÀç ºÒ°¡´ÉÇÏ´Ù. ¾ðÁ¦ initÇÔ¼ö°¡ È£ÃâµÇ´Â °¡¸¦ »ý°¢ÇÑ´Ù¸é À̰ÍÀº ¿ÏÀüÈ÷ Ÿ´çÇÏ´Ù°í ´À³¥ °ÍÀÌ´Ù.
initÇÔ¼ö ÀÚü¿¡ ´ëÇÑ °ÍÀ̶ó±â º¸´Ù´Â initº¯¼ö¿¡ ´ëÇØ ÀÛ¿ëÇÏ´Â __init¿Í À¯»çÇÑ ¸ÅÅ©·ÎÀÎ __initdata¶ó´Â °Íµµ ÀÖ´Ù.
__exit¸ÅÅ©·Î´Â ¸ðµâÀÌ Ä¿³Î·Î ºôÆ®ÀÎ(¸ðµâ·Î ÄÄÆÄÀÏ ÇÏ´Â °ÍÀÌ ¾Æ´Ñ Ä¿³Î ÀϺηΠÄÄÆÄÀÏ ÇÏ´Â °Í)µÉ ¶§, ÇÔ¼öÀÇ È£ÃâÀ» »ý·«Çϸç __exitó·³ ÀûÀç °¡´ÉÇÑ ¸ðµâ¿¡ ¾î¶² ¿µÇâµµ ¹ÌÄ¡Áö ¾Ê´Â´Ù. ¸¶Âù°¡Áö·Î ¾ðÁ¦ cleanupÇÔ¼ö°¡ ÀÛµ¿ÇÏ´Â °í·ÁÇÑ´Ù¸é ÀÌÇØµÉ °ÍÀÌ´Ù. ³»ÀåµÈ µå¶óÀ̹ö´Â cleanupÇÔ¼ö°¡ ÇÊ¿ä ¾ø´Ù. ¹Ý¸é¿¡ ÀûÀç °¡´ÉÇÑ ¸ðµâÀº ÇÊ¿äÇÏ´Ù.
ÀÌ ¸ÅÅ©·ÎµéÀº linux/init.h¿¡ Á¤ÀÇ µÅ ÀÖ°í »ç¿ëµÈ Ä¿³Î ¸Þ¸ð¸®¸¦ ÇØÁ¦Çϴµ¥ »ç¿ëµÈ´Ù. ºÎÆÃ ÈÄ ¡®Freeing unused kernel memory: 236k freed¡¯ ¿Í °°Àº ¸Þ½ÃÁö¸¦ º¼ ¶§ , Ä¿³ÎÀÌ ¸Þ¸ð¸®¸¦ ÇØÁ¦ÇÏ´Â °ÍÀÌ´Ù.
Example 2-5. hello-3.c
/* hello-3.c - Illustrating the __init, __initdata and __exit macros. */ #include <linux/module.h> /* Needed by all modules */ #include <linux/kernel.h> /* Needed for KERN_ALERT */ #include <linux/init.h> /* Needed for the macros */ static int hello3_data __initdata = 3; static int __init hello_3_init(void) { printk(KERN_ALERT "Hello, world %d\n", hello3_data); return 0; } static void __exit hello_3_exit(void) { printk(KERN_ALERT "Goodbye, world 3\n"); } module_init(hello_3_init); module_exit(hello_3_exit); ¸®´ª½º 2.2 Ä¿³ÎÀ» À§ÇÑ µå¶óÀ̹ö ¸ðµâ¿¡¼ __initfunction() °°Àº ÇÔ¼ö¸¦ º¸¾ÒÀ» °ÍÀÌ´Ù.
__initfunction(int init_module(void)) { printk(KERN_ALERT "Hi there.\n"); return 0; } [edit]
3.5 Hello World (prt 4): ÀúÀ۱ǰú ¸ðµâ ¹®¼ ¶Ä¿³Î ¹öÀü 2.4³ª ±× ÈÄ ¹öÀüÀ» »ç¿ëÇÑ´Ù¸é, ¾Õ¼ ¾ð±ÞÇÑ ¸ðµâ ¿¹¸¦ ÀûÀçÇÒ ¶§ ´ÙÀ½°ú °°Àº ¸Þ½ÃÁö¸¦ º¸°Ô µÉ °ÍÀÌ´Ù.
# insmod hello-3.o Warning: loading hello-3.o will taint the kernel: no license See http://www.tux.org/lkml/#export-tainted for information about tainted modules Hello, world 3 Module hello-3 loaded, with warnings 2.4¹öÀü ÀÌÈÄÀÇ Ä¿³Î¿¡¼ GPL ¶óÀ̼¾½º Äڵ带 ½Äº°Çϱâ À§ÇÑ ¸ÞÄ¿´ÏÁòÀÌ °í¾ÈµÅ¼, ¿ÀÇ ¼Ò½º°¡ ¾Æ´Ñ °æ¿ì »ç¿ëÀڵ鿡°Ô °æ°í¸¦ ÇÒ ¼ö ÀÖ°Ô µÅÀÖ´Ù. ÀÌ´Â ´ÙÀ½ Äڵ忡¼ Á¦½ÃµÈ MODULE_LICENSE() ¸ÅÅ©·Î¿¡ ÀÇÇØ ÃæÁ·µÈ´Ù. GPL¶óÀ̼¾½º·Î ¼³Á¤ÇÔÀ¸·Î½á °æ°í°¡ Ãâ·ÂµÇ´Â °ÍÀ» ¹æÁö ÇÒ ¼ö ÀÖ´Ù. ÀÌ·± ¶óÀ̼¾½º ¸ÞÄ¿´ÏÁòÀº linux/module.h¿¡ Á¤ÀǵÇÀÖ°í ¹®¼È µÇ¾î ÀÖ´Ù.
ºñ½ÁÇÏ°Ô MOUDLE_DESCRIPTION() Àº ¸ðµâÀÌ ¹«¾ùÀ» Çϴ°¡¸¦ , MOUDLE_AUTHOR()Àº ¸ðµâÀÇ ÀúÀÚ¸¦ MODULE_SUPPORTED_DEVICE()´Â ¾î¶² ŸÀÔÀÇ ÀåÄ¡¸¦ ¸ðµâÀÌ Áö¿øÇÏ´Â °¡¸¦ ¾Ë·ÁÁØ´Ù.
ÀÌ·± ¸ÅÅ©·ÎµéÀº linux/module.h¿¡ Á¤ÀǵÇÀÖ°í Ä¿³Î ÀÚü¿¡¼´Â »ç¿ëµÇÁö ¾Ê´Â´Ù. À̰͵éÀº ¹®È¸¦ °£´ÜÈ÷ Çϸç, objdump¿Í °°Àº ÅøÀ» ÀÌ¿ëÇØ º¼ ¼ö ÀÖ´Ù. µ¶ÀÚµéÀÇ ¿¬½ÀÀ» À§ÇØ linux/drivers¿¡¼ ¾î¶»°Ô ¸ðµâ ÀúÀÚµéÀÌ ¸ðµâÀ» ¹®¼È Çϱâ À§ÇØ ÀÌ ¸ÅÅ©·ÎµéÀ» »ç¿ëÇߴ°¡ ã¾Æ º¸±æ ¹Ù¶õ´Ù.
Example 2-6. hello-4.c
/* hello-4.c - Demonstrates module documentation. */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #define DRIVER_AUTHOR "Peiter Jay Salzman <p@dirac.org>" #define DRIVER_DESC "A sample driver" int init_hello_3(void); void cleanup_hello_3(void); static int init_hello_4(void){ printk(KERN_ALERT "Hello, world 4\n"); return 0; } static void cleanup_hello_4(void) { printk(KERN_ALERT "Goodbye, world 4\n"); } module_init(init_hello_4); module_exit(cleanup_hello_4); /* You can use strings, like this: */ MODULE_LICENSE("GPL"); // Get rid of taint message by declaring code as GPL.. /* Or with defines, like this: */ MODULE_AUTHOR(DRIVER_AUTHOR); // Who wrote this module? MODULE_DESCRIPTION(DRIVER_DESC); // What does this module do? /* This module uses /dev/testdevice. The MODULE_SUPPORTED_DEVICE macro might be used in the future to help automatic configuration of modules, but is currently unused other than for documentation purposes. */ MODULE_SUPPORTED_DEVICE("testdevice"); [edit]
3.6 Ä¿¸Çµå ¶óÀÎ ÀÎÀÚ ¸ðµâ¿¡ ³Ñ±â±â ¶¸ðµâÀº Ä¿¸Çµå¶óÀÎ ÀÎÀÚ¸¦ ¹ÞÀ» ¼ö ÀÖ´Ù. ±âÁ¸¿¡ »ç¿ëÇÏ´ø °Íó·³ argc/argv¸¦ °¡Áö°í ÇÒ ¼ö´Â ¾ø´Ù.
ÀÎÀÚ¸¦ ´ç½ÅÀÇ ¸ðµâ·Î ³Ñ±â±â À§Çؼ´Â Ä¿¸Çµå¶óÀÎ ÀÎÀÚÀÇ °ªÀ» ÀúÀåÇÒ º¯¼ö¸¦ Àü¿ªÀ¸·Î ¼±¾ðÇÑ ÈÄ ¸ÞÄ¿´ÏÁòÀ» Ȱ¼ºÈ ½Ã۱â À§ÇØ MODULE_PARAM()¸ÅÅ©·Î¸¦ »ç¿ëÇÑ´Ù. ½ÇÇà ½Ã°£¿¡ insmod´Â ÁÖ¾îÁø ÀÎÀÚ·Î º¯¼ö¸¦ ä¿ï °ÍÀÌ´Ù. º¯¼öÀÇ ¼±¾ð°ú ¸ÅÅ©·ÎµéÀº ¸íÈ®¼ºÀ» À§ÇØ ¸ðµâ ¼µÎ¿¡ À§Ä¡ÇØ¾ß ÇÑ´Ù. ´ÙÀ½ÀÇ ¿¹´Â ¾î´ÇÑ ³» ¼³¸íÀ» ¸í¹éÈ÷ ÇØÁØ´Ù.(³» ¹ø¿ªµµ ^^)
MODULE_PARAM() ¸ÅÅ©·Î´Â 2°³ÀÇ ÀÎÀÚ¸¦ ¹Þ´Â´Ù º¯¼öÀÇ À̸§°ú ŸÀÔ Áö¿øÇϴ ŸÀÔÀº 1byteÀΡ±b¡±, short intÀÎ ¡°h¡±, integerÀÎ ¡°i¡±, longÀÎ ¡°l¡±, stringÀÎ ¡°s¡± µî ÀÌ´Ù. ¹®ÀÚ¿(strings – string°ú strings¿Í ±¸ºÐ)Àº ¡°char *¡±·Î ÇØ¾ß Çϸç, insmod´Â ±× ¹®ÀÚ¿(strings)À» À§ÇÑ ¸Þ¸ð¸®¸¦ ÇÒ´çÇÑ´Ù. ´Ã º¯¼ö¸¦ ÃʱâÈÇÏ´Â ½À°üÀ» °®±æ ±ÇÇÑ´Ù. À̰ÍÀº Ä¿³Î ÄÚµåÀÌ´Ù. ´ç½ÅÀº ¹Ýµå½Ã ¹æ¾îÀûÀ¸·Î ÇÁ·Î±×·¡¹Ö ÇØ¾ß ÇÑ´Ù. ´ÙÀ½Àº ¿¹Á¦´Ù.
int myint = 3; char *mystr; MODULE_PARM (myint, "i"); MODULE_PARM (mystr, "s"); int myshortArray[4]; MODULE_PARM (myintArray, "2-4i"); Example 2-7. hello-5.c
/* hello-5.c - Demonstrates command line argument passing to a module. */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("Peiter Jay Salzman"); static short int myshort = 1; static int myint = 420; static long int mylong = 9999; static char *mystring = "blah"; MODULE_PARM (myshort, "h"); MODULE_PARM (myint, "i"); MODULE_PARM (mylong, "l"); MODULE_PARM (mystring, "s"); static int __init hello_5_init(void) { printk(KERN_ALERT "Hello, world 5\n=============\n"); printk(KERN_ALERT "myshort is a short integer: %hd\n", myshort); printk(KERN_ALERT "myint is an integer: %d\n", myint); printk(KERN_ALERT "mylong is a long integer: %ld\n", mylong); printk(KERN_ALERT "mystring is a string: %s\n", mystring); return 0; } static void __exit hello_5_exit(void) { printk(KERN_ALERT "Goodbye, world 5\n"); } module_init(hello_5_init); module_exit(hello_5_exit); Supercalifragilisticexpialidocious(ÀúÀÚ°¡ ¾´ ¾ÏÈ£ Áß Çϳª... -_-)
[edit]
3.7 ´ÙÁß ÆÄÀÏ ¸ðµâ ¶¶§·Î´Â Ä¿³Î ¸ðµâÀ» ¿©·¯ °³ÀÇ ¼Ò½ºÆÄÀÏ·Î ³ª´©´Â °ÍÀÌ ÁÁÀ» ¶§°¡ ÀÖ´Ù. ÀÌ·± °æ¿ì ´ÙÀ½°ú °°Àº »çÇ×ÀÌ ÇÊ¿äÇÏ´Ù.
Example 2-8. start.c
/* start.c - Illustration of multi filed modules */ #include <linux/kernel.h> /* We're doing kernel work */ #include <linux/module.h> /* Specifically, a module */ int init_module(void) { printk("Hello, world - this is the kernel speaking\n"); return 0; } Example 2-9. stop.c
/* stop.c - Illustration of multi filed modules */ #if defined(CONFIG_MODVERSIONS) && ! defined(MODVERSIONS) #include <linux/modversions.h> /* Will be explained later */ #define MODVERSIONS #endif #include <linux/kernel.h> /* We're doing kernel work */ #include <linux/module.h> /* Specifically, a module */ #define __NO_VERSION__ /* It's not THE file of the kernel module */ #include <linux/version.h> /* Not included by module.h because of __NO_VERSION__ */ void cleanup_module() { printk("<1>Short is the life of a kernel module\n"); } ¸¶Áö¸·À¸·Î Makefile
Example 2-10. Makefile for a multi-filed module
CC=gcc MODCFLAGS := -O -Wall –DMODULE -D__KERNEL__ hello.o: hello2_start.o hello2_stop.o ld -m elf_i386 -r -o hello2.o hello2_start.o hello2_stop.o start.o: hello2_start.c ${CC} ${MODCFLAGS} -c hello2_start.c stop.o: hello2_stop.c ${CC} ${MODCFLAGS} -c hello2_stop.c [edit]
4.1.1 ¸ðµâÀº ¾î¶»°Ô ½ÃÀÛÇÏ°í ³¡³ª´Â°¡ ¶ÀϹÝÀûÀ¸·Î ÇÁ·Î±×·¥Àº main()ÇÔ¼ö¿¡¼ ½ÃÀÛÇÑ´Ù, ¸í·É¾îµéÀÇ ÁýÇÕÀ» ½ÇÇàÇÏ°í ¸í·É¾îµéÀÇ ¿Ï·á ½Ã Á¾·áµÈ´Ù. Ä¿³Î ¸ðµâÀº ¾à°£ ´Ù¸£°Ô ÀÛµ¿ÇÑ´Ù. ¸ðµâÀº Ç×»ó init_module()ÇÔ¼ö, ȤÀº ´ç½ÅÀÌ module_init()¶ó´Â ÇÔ¼ö¿¡ ÁöÁ¤ÇÑ °÷¿¡¼ ½ÃÀÛÇÑ´Ù. À̰ÍÀÌ ¸ðµâÀÇ ÁøÀÔ ÇÔ¼ö´Ù(entry function); ¸ðµâÀÌ ÇÊ¿äÇØÁú ¶§ ÀÌ ÇÔ¼öµéÀº Ä¿³Î¿¡°Ô ±× ¸ðµâÀÇ ±â´ÉÀº ¹«¾ùÀÌ¸ç ¾î¶»°Ô ¼³Á¤µÇ´Â °¡¸¦ ¾Ë·Á ÁØ´Ù. ÀÌ·± ¼³Á¤ÀÌ ÀÌ·ïÁö¸é ¸ðµâÀ» ½ÃÀÛÇÏ´Â ÇÔ¼ö´Â ¸®ÅÏÇÏ°í ¸ðµâÀÌ Á¦°øÇÏ´Â Äڵ带 °¡Áö°í Ä¿³ÎÀÌ ¹«¾ùÀΰ¡¸¦ ÇÏ·ÁÇÒ ¶§±îÁö ¸ðµâÀº ¾Æ¹«·± ÀÏÀ» ÇÏÁö ¾Ê´Â´Ù.
¸ðµç ¸ðµâÀº cleanup_module(), ȤÀº module_exit()¿¡ ÁöÁ¤µÇ ÀÖ´Â ÇÔ¼ö¸¦ È£ÃâÇÒ ¶§ Á¾·áµÈ´Ù. À̰ÍÀÌ ¸ðµâÀÇ Á¾·á ÇÔ¼ö(exit function)°¡ µÈ´Ù. ÀÌ ÇÔ¼ö´Â ÁøÀÔ ÇÔ¼ö°¡ ¹«¾ùÀ» ÇÏ´ø Á¾·á ½ÃŲ´Ù. ÁøÀÔ ÇÔ¼ö¿¡ µî·ÏµÇ ÀÖ´Â ±â´ÉÀ» ÇØÁ¦ÇÑ´Ù..
¸ðµç ¸ðµâÀº ÁøÀÔÇÔ¼ö¿Í Á¾·áÇÔ¼ö¸¦ °®´Â´Ù. Çϳª ÀÌ»óÀÇ ÁøÀÔÇÔ¼ö¿Í Á¾·áÇÔ¼ö¸¦ ÁöÁ¤ÇÏ´Â ¹æ¹ýÀÌ Àֱ⿡, `ÁøÀÔÇÔ¼ö(entry function)'¿Í `Á¾·áÇÔ¼ö(exit function)'¶ó´Â ´Ü¾î¸¦ »ç¿ëÇϰڴÙ. ±×·¯³ª ³»°¡ °£´ÜÈ÷ init_module() ±×¸®°í cleanup_module()À̶ó ÇÏ´õ¶óµµ, µ¶ÀÚµéÀº ³»°¡ ¹«¾ùÀ» ÀǹÌÇÏ´ÂÁö ¾Ë °ÍÀ̶ó »ý°¢ÇϰڴÙ.
[edit]
4.1.2 ¸ðµâ¿¡ »ç¿ë °¡´ÉÇÑ ÇÔ¼öµé ¶ÇÁ·Î±×·¡¸ÓµéÀº ÀڽŵéÀÌ Á¤ÀÇÇÑ ÇÔ¼ö¸¸À» »ç¿ëÇÏ´Â °ÍÀº ¾Æ´Ï´Ù. ´ëÇ¥ÀûÀÎ ¿¹°¡ printf()´Ù. ÇÁ·Î±×·¡¸ÓµéÀº Ç¥ÁØ C¶óÀ̺귯¸®¿¡¼ Á¦°øÇÏ´Â ÀÌ·± ¶óÀ̺귯¸® ÇÔ¼öµéÀ» »ç¿ëÇÑ´Ù. ½ÇÁ¦ ÀÌ·± ÇÔ¼öµéÀÇ Á¤ÀÇ´Â ¸µÅ· ½ºÅ×ÀÌÁö(linking stage)°¡ µÉ ¶§±îÁö ÇÁ·Î±×·¥¿¡ µé¾î°¡Áö ¾Ê´Â´Ù. ±×¸®°í ÀÌ·± °ÍÀº Äڵ尡 »ç¿ë °¡´ÉÇÏ´Ù´Â °ÍÀ» º¸ÀåÇØÁÖ°í ±× À§Ä¡¿¡ ¸í·É¾î(instruction)¸¦ À§Ä¡ ½ÃÄÑÁØ´Ù.
¿©±â¼µµ Ä¿³Î ¸ðµâÀº ´Ù´Â ¾ç»óÀ» ¶í´Ù. Àü¼úÇÑ ¿¹Á¦¿¡¼, ¿ì¸®´Â printk()¶ó´Â ÇÔ¼ö¸¦ »ç¿ëÇß´Ù ±×¸®°í ±×°ÍÀº Ç¥ÁØ ¶óÀ̺귯¸® ÇÔ¼ö°¡ ¾Æ´ÔÀ» ¾Ë °ÍÀÌ´Ù. ¸ðµâÀº insmod¿¡ ÀÇÇØ ÇØ¼®µÇÁö´Â ½Éº¼À» °®´Â ¿ÀºêÁ§Æ® ÆÄÀÏÀ̱⠶§¹®ÀÌ´Ù. ½Éº¼ÀÇ Á¤ÀÇ´Â Ä¿³Î ÀÚü¿¡ ÀÖ´Ù. ´ç½ÅÀÌ »ç¿ë °¡´ÉÇÑ À¯ÀÏÇÑ ¿ÜºÎ ÇÔ¼ö´Â Ä¿³Î¿¡ ÀÇÇØ Á¦°øµÇ´Â °Íµé¿¡ ÇÑÁ¤µÇ¾îÁø´Ù. ¾î¶² ½Éº¼(¿ªÁÖ-¸ðµâ¿¡¼ Á÷Á¢ Á¤ÀÇÇÏÁö ¾Ê°í »ç¿ëÇÒ ¼ö ÀÖ´Â ÇÔ¼ö)µéÀÌ »ç¿ë°¡´ÉÇÑÁö ±Ã±ÝÇÏ´Ù¸é /proc/ksymsÀ» »ìÆìºÁ¶ó.
¶óÀ̺귯¸® ÇÔ¼ö¿Í ½Ã½ºÅÛ ÄÝÀÇ Â÷ÀÌÁ¡À» ¸í½ÉÇÏÀÚ. ¶óÀ̺귯¸® ÇÔ¼öµéÀº »óÀ§ ·¹º§¿¡ ÀÖÀ¸¸é¼, ¿Ïº®ÇÏ°Ô À¯Àú ·¹º§¿¡¼ ½ÇÇàµÇ¸ç, ÇÁ·Î±×·¡¸Ó°¡ ½ÇÁ¦ ÀÛ¾÷À» Çϴµ¥ ÆíÀǸ¦ Á¦°øÇØÁØ´Ù. ½Ã½ºÅÛ ÄÝÀº Ä¿³Î¿¡ ÀÇÇØ Á¦°øµÇ¸ç »ç¿ëÀÚÀÇ ÇàÀ§¿¡ µû¶ó Ä¿³Î ·¹º§¿¡¼ ½ÇÇàµÈ´Ù. ¶óÀ̺귯¸® ÇÔ¼öÀÎ printf()´Â °¡Àå ÀϹÝÀûÀÎ Ãâ·ÂÇÔ¼öó·³ º¸ÀδÙ. ±×·¯³ª ±×°ÍÀÌ ½ÇÁ¦·Î ÇÏ´Â ÀÏÀº µ¥ÀÌÅ͸¦ ½ºÆ®¸µÀ¸·Î Æ÷¸ËÇÏ°í ½ºÆ®¸µ µ¥ÀÌÅ͸¦ ·Î¿ì·¹º§ ½Ã½ºÅÛ ÄÝÀÎ write()¸¦ ÀÌ¿ëÇÏ´Â °ÍÀÌ´Ù, ±×¸®°í ±×°ÍÀº ±× µ¥ÀÌÅ͸¦ Ç¥ÁØ Ãâ·ÂÀ¸·Î ³»º¸³½´Ù.
Printf()°¡ ¹«¾ùÀ¸·Î ±¸¼ºµÇÀÖ´Â º¸°í ½ÍÀº°¡? ±×°ÍÀ» ¾Ë¾Æº¸´Â °ÍÀº ±²ÀåÈ÷ ½±´Ù. ´ÙÀ½ÀÇ ÇÁ·Î±×·¥À» ÄÄÆÄÀÏ ÇØº¸ÀÚ.
#include <stdio.h> int main(void) { printf("hello"); return 0; } ´ç½Åµµ Ä¿³ÎÀÇ ½Ã½ºÅÛ ÄÝÀ» ´ëüÇϱâ À§ÇØ ¸ðµàÀ» ¾µ °ÍÀÌ´Ù.(¿ì¸®°¡ °£´ÜÈ÷ ÇÒ°ÍÀÌ´Ù) Å©·¡Ä¿µéÀÌ ¹éµµ¾î¿ëÀ¸·Î ÀÌ·± Á¾·ùÀÇ °ÍµéÀ» »ç¿ëÇÑ´Ù. ´©±º°¡ ´ç½ÅÀÇ ½Ã½ºÅÛ¿¡ ÀÖ´Â ÆÄÀÏÀ» Áö¿ì·Á ½ÃµµÇÒ ¶§¸¶´Ù ´ç½ÅÀº ¸ðµâÀ» ÀÌ¿ëÇØ¼ ¡°°£Áö·¯ Àå³ Ä¡Áö¸¶¡±(¿ªÁÖTee hee, that tickles! ÀÇ¿ª)¶ó´Â ½ÄÀÇ ¿ÂÈÇÑ ´ëÀÀÀ» ÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù.
[edit]
4.1.3 »ç¿ëÀÚ °ø°£ vs Ä¿³Î °ø°£ ¶Ä¿³ÎÀº ºñµð¿À Ä«µå, ÇÏµå µå¶óÀ̺ê, ½ÉÁö¾î ¸Þ¸ð¸®±îÁö ¸ðµç ¸®¼Ò½º¿¡ Á¢±ÙÇÑ´Ù. ÇÁ·Î±×·¥Àº Á¾Á¾ °°Àº ¸®¼Ò½º¿¡ ´ëÇØ °æÀïÇÑ´Ù. ³»°¡ ÀÌ ¹®¼¸¦ ÀúÀåÇÒ ¶§, updatedb°¡ À§Ä¡¿¡´ëÇÑ µ¥ÀÌÅÍ º£À̽º¸¦ °»½ÅÇϱ⠽ÃÀÛÇÑ´Ù. ³ªÀÇ vim ¼¼¼Ç°ú updatedb°¡ °°Àº ÇÏµå µå¶óºê¸¦ µ¿½Ã¿¡ »ç¿ëÇÏ´Â °ÍÀÌ´Ù. Ä¿³ÎÀº ÀÌ·± °ÍµéÀ» ¼ø¼´ë·Î À¯ÁöÇÒ Çʿ䰡 ÀÖÀ¸¸ç, »ç¿ëÀÚ°¡ ±×µéÀÌ ¿øÇÏ´Â ÀÚ¿ø¿¡ Á÷Á¢ Á¢±ÙÇϵµ·Ï ±ÇÇÑÀ» Á־ ¾È µÈ´Ù. ÀÌ·± ÀÌÀ¯·Î CPU´Â ´Ù¸¥ ¹æ½ÄÀ¸·Î ÀÛµ¿ÇÑ´Ù. °¢ ¸ðµå´Â ´ç½ÅÀÌ ½Ã½ºÅÛ¿¡ ÇϰíÀÚ ÇÏ´Â ÀÏ¿¡ ´ëÇÑ ¼·Î ´Ù¸¥ ·¹º§ÀÇ ±ÇÇÑÀ» ÁØ´Ù. ÀÎÅÚÀÇ 30386 ¾ÆÅ°ÅØÃÄ´Â 4°³ÀÇ ¸ðµå¸¦ °¡Áö°í ÀÖ´Ù. À¯´Ð½º´Â ¸ðµç °ÍÀÌ °¡´ÉÇÑ °ü¸®ÀÚ ¸ðµå·Î ¾Ë·ÁÁø 0 ¸ðµå(ÃÖ»óÀ§ ¸ðµå – ringÀÇ ´Ü¾î¼±ÅÃÀÌ... -_-)¿Í À¯Àú ¸ðµå·Î ºÒ¸®´Â ÃÖÇÏÀ§ ¸ðµå, µÎ °¡Áö¸¸À» »ç¿ëÇÑ´Ù.
¶óÀ̺귯¸® ÇÔ¼ö¿Í ½Ã½ºÅÛ ÄÝ¿¡ ´ëÇÑ ³íÀǸ¦ »ó±âÇÏÀÚ. ´ç½ÅÀº ÀüÇüÀûÀ¸·Î »ç¿ëÀÚÀ¯Àú¸ðµå¿¡¼ ¶óÀ̺귯¸® ÇÔ¼ö¸¦ »ç¿ëÇÑ´Ù. ¶óÀ̺귯¸® ÇÔ¼ö´Â Çϳª ȤÀº ±× ÀÌ»óÀÇ ½Ã½ºÅÛ ÄÝÀ» È£ÃâÇÑ´Ù. ±×¸®°í ÀÌ·± ½Ã½ºÅÛ ÄÝÀº ¶óÀ̺귯¸® ÇÔ¼öó·³ ÇൿÇÑ´Ù. ±×·± °ü¸®ÀÚ ¸ðµå¿¡¼´Â Ä¿³ÎÀÇ ÀϺÎÀ̱⠶§¹®¿¡ ±×·¸°Ô ÇൿÇÑ´Ù. ½Ã½ºÅÛÄÝÀÌ ±× ÀÛ¾÷À» ¿Ï·áÇÏ¸é º¹±Í(return)Çϰí À¯Àúº¸µå·Î º¹±ÍÇÑ´Ù.
[edit]
4.1.4 À̸§ °ø°£ ¶´ç½ÅÀÌ CÇÁ·Î±×·¥À» ÀÛ¼ºÇÒ ¶§, ´ç½ÅÀº Äڵ带 º¸´Â »ç¶÷µéÀÇ °¡µ¶¼ºÀ» À§ÇØ º¯¼öÀ̸§À» »ç¿ëÇßÀ» °ÍÀÌ´Ù. ±Ô¸ð°¡ Å« ÇÁ·Î±×·¥ÀÇ ÀϺθ¦ ÀÛ¼ºÇϰí ÀÖÀ» ¶§, ´ç½ÅÀÇ Àü¿ªº¯¼ö°¡ °°ÀÌ ÀÏÇÏ´Â »ç¶÷ÀÇ Àü¿ªº¯¼öÀÇ À̸§°ú °°´Ù¸é º¯¼öÀ̸§À¸·Î ÀÎÇØ ¹®Á¦°¡ µÉ ¼ö ÀÖ´Ù. ¼·Î ±¸ºÐÇÒ ¸¸Å ÀÇ¹Ì ÀÖ´Â À̸§À» °®Áö ¸øÇÑ Àü¿ªº¯¼ö°¡ ¸¹ÀÌ Á¸ÀçÇÑ´Ù¸é À̸§°ø°£ÀÌ ¿À¿°µÉ °ÍÀÌ´Ù. ´ë±Ô¸ð ÇÁ·ÎÁ§Æ®¿¡¼ »ç¿ë º¸·ùµÈ À̸§¿¡ ´ëÇØ ÀÌ·± ³ë·ÂÀº ¹Ýµå½Ã ÀÖ¾î¾ß Çϸç, ½Éº¼°ú º¯¼öÀÇ À¯´ÏÅ©ÇÑ ¸í¸í ¹ý¿¡ ´ëÇÑ °èȹÀÌ ÇÊ¿äÇÏ´Ù.
Ä¿³Î Äڵ带 ÀÛ¼ºÇÒ ¶§ ±×°ÍÀÌ ¾Æ¹«¸® ÀÛÀº ¸ðµâÀÌ¶óµµ Ä¿³Î Àüü¿¡ ¸µÅ©µÇ±â ¶§¹®¿¡ À̰ÍÀº ºÐ¸í ¹®Á¦°¡ µÈ´Ù. À̰ÍÀ» ÇØ°áÇÏ´Â °¡Àå ÁÁÀº ¹æ¹ýÀº º¯¼ö¸¦ Á¤Àû º¯¼ö·Î ¼±¾ðÇϰí, Àß Á¤ÀÇµÈ Á¢µÎ¾î¸¦ ´ç½ÅÀÇ ½Éº¼¿¡ »ç¿ëÇÏ´Â °ÍÀÌ´Ù. °ü½ÀÀûÀ¸·Î Ä¿³ÎÀÇ Á¢µÎ¾î´Â ¼Ò¹®ÀÚ´Ù. ¸ðµç °ÍÀ» Á¤ÀûÀ¸·Î ¼±¾ðÇϱ⠿øÄ¡ ¾Ê´Â´Ù, symbol tableÀ» ¼±¾ðÇÏ°í ±×°ÍÀ» Ä¿³Î¿¡ µî·Ï½ÃŰ´Â ¹æ¹ýÀ» ¾´´Ù. Â÷ÈÄ¿¡ À̰ÍÀ» ÇÏ°Ô µÉ °ÍÀÌ´Ù.
/proc/ksyms´Â Ä¿³ÎÀÌ ¾Ë°í ÀÖ´Â ¸ðµç ½Éº¼À» °¡Áö°í ÀÖ°í, ±× ½Éº¼Àº Ä¿³Î ÄÚµå ½ºÆäÀ̽º¿¡¼ °øÀ¯µÇ±â ¶§¹®¿¡, ´ç½ÅÀÇ ¸ðµâÀÌ Á¢±Ù/»ç¿ëÇÒ ¼ö ÀÖ´Ù.
[edit]
4.1.5 ÄÚµå ¿µ¿ª ¶¸Þ¸ð¸® °ü¸®´Â ¸Å¿ì º¹ÀâÇÑ ÁÖÁ¦´Ù. `Understanding The Linux KernelÀÇ »ó´ç ºÎºÐÀÌ ¸Þ¸ð¸® °ü¸®¿¡ ÁßÁ¡À» µÐ´Ù. ¿ì¸®´Â ºñ·Ï ¸Þ¸ð¸® °ü¸®¿¡ Àü¹®°¡´Â ¾Æ´ÏÁö¸¸ ½ÇÁ¦ ¸ðµâÀ» ÀÛ¼ºÇϴµ¥ °í·ÁÇØ¾ß ÇÒ µÎ °¡Áö »ç½Ç¿¡ ´ëÇØ ¾Ë ÇÊ¿ä´Â ÀÖ´Ù.
½ÇÁ¦·Î ¼¼±×¸àÆ® ÆúÆ®°¡ ¹«¾ùÀ» ÀǹÌÇÏ´ÂÁö »ý°¢Çغ¸Áö ¾Ê¾Ò´Ù¸é Æ÷ÀÎÅͰ¡ ½ÇÁ¦ ¸Þ¸ð¸® À§Ä¡¸¦ Áö½ÃÇϰí ÀÖÁö ¾Ê´Ù´Â °ÍÀ» µè°Ô µÇ¸é ³î¶ö °ÍÀÌ´Ù. ¾î·µç ¾î´À Æ÷ÀÎÅ͵µ ±×·¸Áö ¾Ê´Ù. ÇÁ·Î¼¼½º°¡ »ý¼ºµÉ ¶§, Ä¿³ÎÀº ½ÇÁ¦ ¸Þ¸ð¸®ÀÇ ÀϺθ¦ ÇÒ´çÇØ, (ÄÄÇ»ÅÍ ÇÐÀÚ³ª ¾Ë¹ýÇÑ °Íµé) ÇÁ·Î¼¼½º°¡ »ç¿ëÇÏ´Â ½ÇÇàÄÚµå, º¯¼ö, ½ºÅÃ, Èü µîÀ¸·Î »ç¿ëÇϵµ·Ï ÇÁ·Î¼¼½º¿¡°Ô ³Ñ±ä´Ù. ÀÌ ¸Þ¸ð¸®´Â $0$¿¡¼ ½ÃÀÛÇØ ÇÁ·Î¼¼½º°¡ ÇÊ¿äÇÑ ¸¸Å È®ÀåµÈ´Ù. ¼·Î ´Ù¸¥ µÎ ÇÁ·Î¼¼½ºÀÇ ¸Þ¸ð¸® ¿µ¿ªÀº °ãÄ¡Áö ¾Ê±â ¶§¹®¿¡ 0xbffff978¿¡ Á¢±ÙÇÏ´Â ¸ðµç ÇÁ·Î¼¼½º´Â ½ÇÁ¦ ¹°¸®Àû ¸Þ¸ð¸®ÀÇ ¼·Î ´Ù¸¥ ÁöÁ¡¿¡ Á¢±ÙÇÒ °ÍÀÌ´Ù. ÇÁ·Î¼¼½ºµéÀº ƯÁ¤ ÇÁ·Î¼¼½º¿¡°Ô ÇÒ´çµÈ ¸Þ¸ð¸® ¿µ¿ªÀ¸·ÎÀÇ ¿ÀÇÁ¼ÂÀÇ ÇÑ Á¾·ù¸¦ Áö½ÃÇÏ´Â 0xbffff978·Î À̸§ Áö¾îÁø À妽º¿¡ Á¢±ÙÇÏ·Á ÇÒ °ÍÀÌ´Ù. ÀÌÈÄ¿¡ ´Ù·ç°Ô µÉ ¹æ¹ýÀÌ ÀÖÀ½¿¡µµ ºÒ±¸Çϰí, ¿ì¸®ÀÇ Hello, World¿Í °°Àº ´ëºÎºÐÀÇ °æ¿ì ´Ù¸¥ ÇÁ·Î¼¼½ºÀÇ ¿µ¿ª¿¡ Á¢±ÙÇÒ ¼ö ¾ø´Ù.
Ä¿³Î ¿ª½Ã ÀڽŸ¸ÀÇ ¸Þ¸ð¸® ¿µ¿ªÀÌ ÀÖ´Ù. ¸ðµâÀº µ¿ÀûÀ¸·Î Ä¿³Î¿¡ ÀûÀç µÇ°Å³ª Á¦°ÅµÉ ¼ö ÀÖ´Â ÄÚµå±â ¶§¹®¿¡, ¸ðµâÀº ÀڽŸ¸ÀÇ Ä¿³Î ÄÚµå ¿µ¿ªÀ» °¡Áö±â º¸´Ù´Â Ä¿³Î ÄÚµå ¿µ¿ªÀ» °øÀ¯ÇÑ´Ù. Áï, ¹Ý µ¶¸³Àû °´Ã¼¿¡ »ó¹ÝµÇ´Â °³³äÀÌ´Ù. (as opposed to a semi-autonomous object ÀÇ ÀÇ¿ª) ±×·¯¹Ç·Î ¿ì¸®ÀÇ ¼¼±×¸ÕÆ® ÆúÆ®´Â Ä¿³ÎÀÇ ¼¼±×¸ÕÆ® ÆúÆ®°¡ µÈ´Ù. off-by-one ¿¡·¯ ¶§¹®¿¡ µ¥ÀÌÅ͸¦ °ãÃÄ ¾²±â ½ÃÀÛÇÑ´Ù¸é, Ä¿³Î Äڵ带 ¸Á°¡Æ®¸± °ÍÀÌ´Ù. ÀÌ°Ç »ý°¢º¸´Ù ½É°¢ÇϹǷΠÁÖÀǸ¦ ±â¿ï¿©¾ß ÇÑ´Ù. ( off-by-one error : n=0¿¡¼ ½ÃÀÛÇÒ °ÍÀ» n=1¿¡¼ ½ÃÀÛÇÔÀ¸·Î ÇØ¼ ÀϾ´Â ·ùÀÇ ¿¡·¯¸¦ ÀǹÌÇÔ)
À§¿¡¼ ¾ð±ÞÇÑ »ç½ÇµéÀº ¸ð³î¸®Æ½ Ä¿³ÎÀ» »ç¿ëÇÏ´Â ¸ðµç ¿ÀÆÛ·¹ÀÌÆÃ ½Ã½ºÅÛ¿¡¼ Àû¿ëµÈ´Ù´Â °ÍÀ» ÁöÀûÇÏ°í ½Í´Ù. ÀÚ±â ÀڽŸ¸ÀÇ ÄÚµå ¿µ¿ªÀ» °®´Â ¸¶ÀÌÅ©·Î Ä¿³ÎÀ̶ó´Â °Íµµ ÀÖ´Ù. GNU Hurd¿Í QNX Neutrino°¡ ¸¶ÀÌÅ©·Î Ä¿³ÎÀÇ ¿¹´Ù.
[edit]
4.1.6 ÀåÄ¡ µå¶óÀ̹ö ¶¸ðµâÀÇ ÇÑ Á¾·ù°¡ ÀåÄ¡ µå¶óÀ̹öÀ̸ç, ±×µéÀº TVÄ«µå³ª ½Ã¸®¾ó Æ÷Æ® °°Àº Çϵå¿þ¾îÀÇ ±â´ÉÀ» Á¦°øÇÑ´Ù. À¯´Ð½º¿¡¼ ÇϳªÀÇ Çϵå¿þ¾î´Â Çϵå¿þ¾î¿Í ÀÇ»ç Åë½ÅÇÏ´Â ¼ö´ÜÀ» Á¦°øÇÏ´Â named device ÆÄÀÏ(/dev/ ¾Æ·¡ À§Ä¡ÇÑ´Ù.)·Î º¸¿©Áø´Ù. µð¹ÙÀ̽º µå¶óÀ̹ö´Â À¯Àú ÇÁ·Î±×·¥À» ´ë½ÅÇØ, ÀÇ»ç ¼ÒÅë ¼ö´ÜÀ» Á¦°øÇÑ´Ù. es1370 »ç¿îµåÄ«µå µå¶óÀ̹ö´Â Ensoniq IS1370 »ç¿îµå Ä«µå¿¡ ¿¬°áÇϱâ À§ÇØ /dev/sound device¿¡ ¿¬°áÇÑ´Ù. mp3blaster¿Í °°Àº À¯Àú ½ºÆäÀ̽º ÇÁ·Î±×·¥Àº ¾î¶² Á¾·ùÀÇ »ç¿îµå Ä«µå°¡ ¼³Ä¡µÆ´ÂÁö ¸ð¸¥ ü /dev/sound¶ó´Â ÀåÄ¡¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
[edit]
4.1.6.1 ÀåÄ¡ ÁÖ ¹øÈ£¿Í ÀåÄ¡ ºÎ ¹øÈ£ ¶µð¹ÙÀ̽º ÆÄÀÏÀ» »ìÆìº¸ÀÚ. ´ÙÀ½Àº ÇÁ¶óÀ̸Ӹ® ¸¶½ºÅÍ IDEÇÏµå µå¶óÀ̹öÀÇ Ã¹ ¼¼ °³ ÆÄƼ¼ÇÀ» ³ªÅ¸³»´Â µð¹ÙÀ̽º ÆÄÀÏÀÌ´Ù.
# ls -l /dev/hda[1-3] brw-rw---- 1 root disk 3, 1 Jul 5 2000 /dev/hda1 brw-rw---- 1 root disk 3, 2 Jul 5 2000 /dev/hda2 brw-rw---- 1 root disk 3, 3 Jul 5 2000 /dev/hda3ÄÞ¸¶¿¡ ÀÇÇØ ±¸ºÐµÈ ¹øÈ£ÀÇ ¿À» ÁÖ½ÃÇÏÀÚ Ã¹ ¹øÂ° ¹øÈ£¸¦ ÀåÄ¡ ÁÖ ¹øÈ£¶ó ºÎ¸£¸ç µÎ ¹øÂ° ¹øÈ£´Â ºÎ ¹øÈ£¶ó ºÎ¸¥´Ù. ÁÖ ¹øÈ£´Â µå¶óÀ̹ö°¡ ¾î¶² Çϵå¿þ¾î¿¡ ¿¢¼¼½ºÇÏ´ÂÁö ¾Ë·ÁÁØ´Ù. °¢ µå¶óÀ̹ö´Â À¯ÀÏÇÑ ÁÖ ¹øÈ£¸¦ ÇÒ´ç ¹ÞÀ¸¸ç, µ¿ÀÏÇÑ ÁÖ ¹øÈ£¸¦ °®´Â ¸ðµç µð¹ÙÀ̽º ÆÄÀÏÀº °°Àº µå¶óÀ̹ö¿¡ ÀÇÇØ ÄÁÆ®·Ñ µÈ´Ù. À§ÀÇ ÁÖ ¹øÈ£°¡ ¸ðµÎ 3ÀÎ °ÍÀº, ±×µéÀÌ °°Àº µå¶óÀ̹ö¿¡ ÀÇÇØ ÄÜÆ®·Ñ µÇ±â ¶§¹®ÀÌ´Ù. ºÎ ¹øÈ£´Â µå¶óÀ̹ö°¡ ÀÚ½ÅÀÌ ÄÁÆ®·ÑÇÏ´Â Çϵå¿þ¾î¸¦ ±¸ºÐÇϱâ À§ÇØ »ç¿ëµÈ´Ù. À§ÀÇ ¿¹·Î µ¹¾Æ°¡ º¸ÀÚ, ¼¼ °³ÀÇ ÀåÄ¡µéÀÌ °°Àº µå¶óÀ̹ö¿¡ ÀÇÇØ ¿î¿µµÉÁö¶óµµ ¼·Î ´Ù¸¥ °íÀ¯ÀÇ ºÎ ¹øÈ£¸¦ °®´Âµ¥, ÀÌ´Â µå¶óÀ̹ö°¡ ±×µé(ÇÏµå µð½ºÅ© ÆÄƼ¼Çµé)À» ¼·Î ´Ù¸¥ Çϵå¿þ¾î·Î ÀνÄÇϱ⠶§¹®ÀÌ´Ù.
µð¹ÙÀ̽º´Â ij¸¯ÅÍ µð¹ÙÀ̽º¿Í ºí·Ï µð¹ÙÀ̽ºÀÇ µÎ ŸÀÔÀ¸·Î ³ª´¶´Ù. ºí·Ï µð¹ÙÀ̽º´Â ¹öÆÛ¸¦ °¡Áö°í ÀÖ¾î, ¾î¶² ¼ø¼·Î ÀÀ´äÇÏ´Â °ÍÀÌ °¡Àå ÁÁÀº °ÍÀΰ¡ ¼±ÅÃÇÒ ¼ö ÀÖ´Ù´Â °ÍÀÌ Â÷ÀÌÁ¡ÀÌ´Ù. ÀÌÁ¡Àº ¹°¸®ÀûÀ¸·Î ¶³¾îÁ®ÀÖ´Â ¼½Åͺ¸´Ù °¡±îÀÌ ÀÖ´Â ¼½ÅÍ¿¡ Àбâ/¾²±â¸¦ ÇÏ´Â °ÍÀÌ ºü¸£´Ù´Â Á¡¿¡¼ ÀúÀå ÀåÄ¡¿¡ ÀÖ¾î Áß¿äÇÏ´Ù. ¶Ç ´Ù¸¥ Â÷ÀÌÁ¡Àº ºí·Ï µð¹ÙÀ̽º¸¸ÀÌ ÀÔÃâ·Â ½Ã ºí·Ï ´ÜÀ§·Î Á¢±ÙÇÒ ¼ö ÀÖ´Ù´Â Á¡ÀÌ´Ù(ºí·ÏÀÇ Å©±â´Â ÀåÄ¡¿¡ µû¶ó ´Ù¸£´Ù). ¹Ý¸é¿¡ ij¸¯ÅÍ µð¹ÙÀ̽º´Â ¸î ¹ÙÀÌÆ® µÇÁö ¾Ê´Â Å©±â¸¸À» Çã¿ëÇÑ´Ù. ´ëºÎºÐÀÇ ÀåÄ¡´Â ij¸¯ÅÍ µð¹ÙÀ̽ºÀÌ´Ù. ¿Ö³ÄÇϸé ÀåÄ¡µé ´ëºÎºÐÀÌ ÀÌ·± Á¾·ùÀÇ ¹öÆÛÀÏÀ» ÇÊ¿ä·Î ÇÏÁö ¾Ê°í °íÁ¤µÈ ºí·Ï Å©±â¿¡ ´ëÇØ ÀÛµ¿ÇÏÁö ¾Ê±â ¶§¹®ÀÌ´Ù. ls –lÀÇ °á°ú¿¡¼ ù ¹øÂ° ¹®ÀÚ¸¦ »ìÆì º½À¸·Î½á µð¹ÙÀ̽º°¡ ºí·Ï µð¹ÙÀ̽ºÀÎÁö ij¸¯ÅÍ µð¹ÙÀ̽ºÀÎÁö ±¸ºÐÇÒ ¼ö ÀÖ´Ù. ¸¸ÀΠù ¹®ÀÚ°¡ ¡®b¡¯ÀÌ¸é ºí·Ïµð¹ÙÀ̽º°í, ¡®c¡¯À̸é ij¸¯ÅÍ µð¹ÙÀ̽ºÀÌ´Ù. ´ÙÀ½Àº ij¸¯ÅÍ µð¹ÙÀ̽ºÀÇ ¿¹´Ù(½Ã¸®¾ó Æ÷Æ®).
crw-rw---- 1 root dial 4, 64 Feb 18 23:34 /dev/ttyS0 crw-r----- 1 root dial 4, 65 Nov 17 10:26 /dev/ttyS1 crw-rw---- 1 root dial 4, 66 Jul 5 2000 /dev/ttyS2 crw-rw---- 1 root dial 4, 67 Jul 5 2000 /dev/ttyS3¸¸ÀÏ ¾î¶² ÁÖ ¹øÈ£°¡ ÇÒ´çµÆ´Â°¡ ¾Ë±â¸¦ ¿øÇÑ´Ù¸é, /usr/src/linux/Documentation/devices.txt ÆÄÀÏÀ» Âü°íÇϱ⠹ٶõ´Ù. ½Ã½ºÅÛÀÌ ¼³Ä¡µÉ ¶§, ÀÌ·± µð¹ÙÀ̽º ÆÄÀϵéÀº mknod¿¡ ÀÇÇØ »ý¼ºµÈ´Ù. ÁÖ¹øÈ£/ºÎ¹øÈ£ 12, 2ÀÇ ¡®coffee¡¯¶ó´Â »õ·Î¿î ij¸¯ÅÍ µð¹ÙÀ̽º¸¦ »ý¼ºÇϰíÀÚ ÇÑ´Ù¸é, ´Ü¼øÈ÷ mknod /dev/coffee c 12 2¸¸ ½ÇÇà½ÃŰ¸é µÈ´Ù. µð¹ÙÀ̽º ÆÄÀÏÀ» /dev/¿¡ ³ÖÀ» ÇÊ¿ä´Â ¾ø´Ù. ´Ü¼øÈ÷ °ü½ÀÀÏ »ÓÀÌ´Ù. ¸®´©Áî°¡ ±×ÀÇ µð¹ÙÀ̽º ÆÄÀÏÀ» /dev/¿¡ ³Ö¾ú±â ¶§¹®¿¡ ´ç½Åµµ ±×·¸°Ô ÇÏ´Â °ÍÀÌ ³´À» °ÍÀÌ´Ù. ±×·¯³ª Å×½ºÆ® ¸ñÀûÀ¸·Î µð¹ÙÀ̽º ÆÄÀÏÀ» »ý¼ºÇÑ´Ù¸é, Ä¿³Î ¸ðµâÀ» ÄÄÆÄÀÏÇÑ ÀÛ¾÷ µð·ºÅ丮¿¡ µð¹ÙÀ̽º ÆÄÀÏÀ» ³Ö¾îµµ ¹«¹æÇÏ´Ù. µð¹ÙÀ̽º µå¶óÀ̹ö ÀÛ¼ºÀÌ ¿Ï·áµÆÀ» ¶§ ¿Ã¹Ù¸¥ À§Ä¡¿¡¸¸ ³ÖÀ¸¸é µÈ´Ù.
³ª´Â ÀÌÀü¿¡ ¾ð±ÞÇß´ø °Íµé°ú »óÃæµÇ´Â ¸î °¡Áö ÁöÀûÀ» Çϱ⸦ ÁÁ¾Æ ÇÑ´Ù. ÇÏÁö¸¸ ±×°ÍµéÀº ´ÜÁö ¸î¸î °æ¿ì¿¡¸¸ ±¹ÇѵȴÙ. µð¹ÙÀ̽º ÆÄÀÏÀÌ ¾×¼¼½ºµÉ ¶§ Ä¿³ÎÀº ÀåÄ¡ ÁÖ ¹øÈ£¸¦ ¾î¶² µå¶óÀ̹ö¸¦ ÀÌ¿ëÇØ ±× ¾×¼¼½º¸¦ ó¸®ÇÒ °ÍÀΰ¡¸¦ °áÁ¤Çϱâ À§ÇØ »ç¿ëÇÑ´Ù. ÀÌ À̾߱â´Â Ä¿³ÎÀº ÀåÄ¡ ºÎ ¹øÈ£¸¦ »ç¿ëÇÒ Çʿ䰡 ¾ø°í, ½ÉÁö¾î ¸ô¶óµµ µÈ´Ù´Â ¸»ÀÌ´Ù. ÀåÄ¡ ºÎ ¹øÈ£¿¡ °ü½ÉÀ» °®´Â °ÍÀº µå¶óÀ̹ö ÀÚü »ÓÀÌ´Ù. µ¿ÀÏÇÑ Á¾·ùÀÇ Çϵå¿þ¾î Áß¿¡ ¾î¶² ÀåÄ¡Àΰ¡¸¦ ±¸ºÐÇϱâ À§Çؼ¸¸ ÀåÄ¡ ºÎ ¹øÈ£´Â »ç¿ëµÈ´Ù.
±×·±µ¥ ³»°¡ ¡®Çϵå¿þ¾î¡¯¶ó°í ÇßÀ» ¶§, ³ ´ç½ÅÀÇ ¼Õ¿¡ ÀÖ´Â PCIÄ«µå ÀÌ»óÀÇ Á»´õ Ãß»óÀûÀÎ °ÍÀ» ÀǹÌÇÏ´Â °ÍÀÌ´Ù. ´ÙÀ½ÀÇ µð¹ÙÀ̽º ÆÄÀÏÀ» º¸ÀÚ.
% ls -l /dev/fd0 /dev/fd0u1680 brwxrwxrwx 1 root floppy 2, 0 Jul 5 2000 /dev/fd0 brw-rw---- 1 root floppy 2, 44 Jul 5 2000 /dev/fd0u1680ÀÌÁ¦ µÎ °³ÀÇ µð¹ÙÀ̽º ÆÄÀÏÀ» º¸°í ±×µéÀÌ ºí·Ï µð¹ÙÀ̽º¶ó´Â °Í°ú µ¿ÀÏÇÑ µå¶óÀ̹ö¿¡ ÀÇÇØ 󸮵ȴٴ °ÍÀ» Áï½Ã ¾Ë ¼ö ÀÖÀ» °ÍÀÌ´Ù. µÎ °³ÀÇ µð¹ÙÀ̽º ÆÄÀÏÀº ´ç½ÅÀÇ Ç÷ÎÇÇ µå¶óÀ̺긦 ³ªÅ¸³½´Ù´Â °ÍÀ» ¾Ë °ÍÀÌ´Ù. ±×·±µ¥ ´ç½ÅÀº ÇϳªÀÇ Ç÷ÎÇÇ µå¶óÀ̹ö¸¸À» °¡Áö°í ÀÖÁö ¾ÊÀº°¡. ¿Ö µÎ °³Àΰ¡? Çϳ 1.44MBÀÇ Ç÷ÎÇÇ µå¶óÀ̺긦 ³ªÅ¸³½´Ù. ´Ù¸¥ Çϳª´Â ÈçÈ÷ ¸»ÇÏ´Â ¡®superformatted¡¯ µå¶óÀ̺꿡 ÇØ´çµÇ´Â 1.68MBÀÇ µ¿ÀÏÇÑ ÀúÀå ÀåÄ¡´Ù. Ç¥ÁØ Æ÷¸Ë Ç÷ÎÇÇ º¸´Ù ¸¹Àº ¾çÀÇ µ¥ÀÌÅ͸¦ ÀúÀåÇÏ´Â °ÍÀÌ´Ù. À̰ÍÀÌ µ¿ÀÏÇÑ ½ÇÁ¦ Çϵå¿þ¾î¿¡ ¼·Î ´Ù¸¥ ÀåÄ¡ ºÎ ¹øÈ£¸¦ °®´Â °æ¿ì´Ù. ¿ì¸®ÀÇ ³íÀÇ¿¡¼ ¡®Çϵå¿þ¾î¡¯¶ó°í ÇÏ´Â ´Ü¾î°¡ »ó´çÈ÷ Ãß»óÀûÀ̶ó´Â °ÍÀ» ¾Ë±â ¹Ù¶õ´Ù. [edit]
5.1.1 file_operations ±¸Á¶Ã¼ ¶file_operations ±¸Á¶Ã¼´Â linux/fs.h¿¡ Á¤ÀÇµÇ ÀÖÀ¸¸ç ÀåÄ¡µé¿¡ ´ëÇØ ´Ù¾çÇÑ ÀÛµ¿À» ÇÏ´Â µå¶óÀ̹ö¿¡ ÀÇÇØ Á¤ÀÇµÈ ÇÔ¼öµéÀ» °¡Áö°í ÀÖ´Ù. ±¸Á¶Ã¼ÀÇ °¢ Çʵå´Â ¿ä±¸µÇ´Â ÀÛµ¿À» Çϱâ À§ÇØ µå¶óÀ̹ö¿¡ ÀÇÇØ Á¤ÀÇµÈ ÇÔ¼öµéÀÇ ÁÖ¼Ò¿¡ ´ëÀÀµÈ´Ù.
¿¹¸¦ µé¾î, ¸ðµç ¹®ÀÚ ÀåÄ¡ µå¶óÀ̹ö´Â ÀåÄ¡·ÎºÎÅÍ µ¥ÀÌÅ͸¦ ÀÐ¾î ¿À´Â ÇÔ¼ö¸¦ Á¤ÀÇ ÇÒ Çʿ䰡 ÀÖ´Ù. file_operations ±¸Á¶Ã¼´Â ±×·± ±â´ÉÀ» ÇÏ´Â ÇÔ¼ö ¸ðµâÀÇ ÁÖ¼Ò¸¦ °¡Áö°í ÀÖ´Â °ÍÀÌ´Ù. Ä¿³Î 2.4.2¿¡¼ ±× Á¤ÀÇ´Â ´ÙÀ½°ú °°´Ù.
struct file_operations { struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char *, size_t, loff_t *); ssize_t (*write) (struct file *, const char *, size_t, loff_t *); int (*readdir) (struct file *, void *, filldir_t); unsigned int (*poll) (struct file *, struct poll_table_struct *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*flush) (struct file *); int (*release) (struct inode *, struct file *); int (*fsync) (struct file *, struct dentry *, int datasync); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct file_lock *); ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *); ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *); }; ¾î¶² µ¿ÀÛµéÀº µå¶óÀ̹ö¿¡ ÀÇÇØ ±¸ÇöµÇÁö ¾Ê´Â´Ù. ¿¹·Î ºñµð¿ÀÄ«µå¸¦ ´Ù·ç´Â µå¶óÀ̹ö´Â µð·ºÅ丮 ±¸Á¶Ã¼¿¡¼ µ¥ÀÌÅ͸¦ Àоî¿Ã ÇÊ¿ä´Â ¾ø´Ù. ÀÌ °æ¿ì file_operations±¸Á¶Ã¼ÀÇ ÇØ´ç Çʵå´Â NULL·Î ¼¼ÆÃµÈ´Ù.
gccÀÇ È®Àå ¹öÀüÀº ÀÌ ±¸Á¶Ã¼¿¡ ÀÎÀÚ ÇÒ´çÀ» Á»´õ ÆíÇÏ°Ô ÇØÁØ´Ù. ÃÖ±Ù ¸¸µé¾îÁø µå¶óÀ̹öµé¿¡¼ ÀÌ·± °ÍµéÀ» º¼ ¼ö ÀÖ´Ù, ¾Æ¸¶µµ (»ç¿ë ¹æ¹ý ¶§¹®¿¡) ³î¶ó¿òÀ» ÁÙ ¼öµµ ÀÖ´Ù. ´ÙÀ½Àº ÀÌ·± »õ·Î¿î ÇÒ´ç ¹æ½ÄÀ» º¸¿©ÁØ´Ù.
struct file_operations fops = { read: device_read, write: device_write, open: device_open, release: device_release; } ±×·¯³ª C99¹æ½ÄÀÇ ±¸Á¶Ã¼ ¸â¹ö ÇÒ´ç¹æ½Äµµ ¿©ÀüÈ÷ Á¸ÀçÇϸç GNUÈ®Àå ¹öÀüÀ» »ç¿ëÇÔ¿¡ ¿ÀÈ÷·Á ÀÌ ¹æ½ÄÀÌ ¼±È£µÇ°í ÀÖ´Ù. ³»°¡ ÇöÀç »ç¿ëÇϰí ÀÖ´Â gcc 2.95¹öÀüÀº C99 ¹®¹ýÀÇ »õ·Î¿î ºÎºÐÀ» Áö¿øÇϰí ÀÖ´Ù. ´©±º°¡ ´ç½ÅÀÇ µå¶óÀ̹ö¸¦ Æ÷ÆÃÇϱ⠿øÇÏ´Â °æ¿ì ´ç½ÅÀº ÀÌ ¹®¹ýÀ» »ç¿ëÇØ¾ß ÇÒ °ÍÀÌ´Ù. ÀÌ °æ¿ì µÎ Á¾·ùÀÇ ½ÅÅØ½º°¡ °øÁ¸ÇÒ ¼ö ÀÖ´Ù.
struct file_operations fops = { .read = device_read, .write = device_write, .open = device_open, .release = device_release }; Àǹ̴ ¸íÈ®ÇÏ´Ù ±×¸®°í ´ç½ÅÀÌ ÇÒ´çÇÏÁö ¾ÊÀº ±¸Á¶Ã¼ÀÇ ¸â¹ö´Â gcc¿¡ ÀÇÇØ NULL·Î Ãʱâȵȴٴ »ç½ÇÀ» ±â¾ïÇÏÀÚ. file_operations ±¸Á¶Ã¼ÀÇ Æ÷ÀÎÅÍ´Â ÀϹÝÀûÀ¸·Î fops¶ó´Â À̸§À» °®´Â´Ù.
[edit]
5.1.2 file ±¸Á¶Ã¼ ¶°¢°¢ÀÇ ÀåÄ¡µéÀº file±¸Á¶Ã¼¿¡ ÀÇÇØ Ä¿³Î ³»ºÎ¿¡ º¸¿©Áø´Ù. ±×¸®°í ±×°ÍÀº linux/fs.h¿¡ Á¤ÀÇ µÇÀÖ´Ù. ±¸Á¶Ã¼´Â Ä¿³Î ³»ºÎ¿¡ Á¸ÀçÇÏ¸ç »ç¿ëÀÚ °ø°£ÀÇ ÇÁ·Î±×·¥¿¡¼´Â Àý´ë º¸ÀÌÁö ¾Ê´Â´Ù´Â °ÍÀ» ¸í½ÉÇÏÀÚ. ±¸Á¶Ã¼¿Í °°Áö ¾Ê´Ù. FILE±¸Á¶Ã¼´Â glibc¿¡ Á¤ÀÇµÇ ÀÖ°í Ä¿³Î¿µ¿ª¿¡´Â Àý´ë º¸ÀÌÁö ¾Ê´Â´Ù. À̸§ ¶§¹®¿¡ À߸ø ÀÌÇØµÇ±âµµ ÇÑ´Ù. ±×°ÍÀº ¿¸° ÆÄÀÏÀ» ÀǹÌÇÏÁö µð½ºÅ©»óÀÇ inode±¸Á¶Ã¼¿¡ ÀÌÇØ Áö½ÃµÇ´Â ÆÄÀÏÀ» ÀǹÌÇÏ´Â °ÍÀº ¾Æ´Ï´Ù.
file±¸Á¶Ã¼ÀÇ Æ÷ÀÎÅÍ´Â ÀϹÝÀûÀ¸·Îfilp¶ó´Â À̸§À» °®´Â´Ù. struct file file¿Í È¥µ·ÇÏÁö ¸»ÀÚ(¿ÏÀü Åë¹ä-_-)
file±¸Á¶Ã¼ÀÇ Á¤ÀǸ¦ »ìÆìº¸ÀÚ. ´ëºÎºÐÀÇ ¸â¹öµéÀÌ dentry±¸Á¶Ã¼Ã³·³ µð¹ÙÀ̽º µå¶óÀ̹ö¿¡¼ »ç¿ëµÇÁö ¾Ê´Â´Ù. ¶ÇÇÑ ±×·± ºÎºÐÀº ¹«½ÃÇØµµ ÁÁ´Ù. µð¹ÙÀ̽º µå¶óÀ̹ö´Â file±¸Á¶Ã¼¸¦ Á÷Á¢ÀûÀ¸·Î ä¿ìÁö ¾Ê°í ¾îµð¼±°¡ »ý¼ºÇÑ ÆÄÀÏ ±¸Á¶Ã¼ÀÇ ³»¿ëÀ» ´ÜÁö ÀÌ¿ëÇϱ⸸ ÇÒ »ÓÀÌ´Ù.
[edit]
5.1.3 Registering A Device ¶¾Õ¼ ³íÀÇÇÑ °Íó·³ ¹®ÀÚÀåÄ¡´Â º¸Åë dev[1] ¿¡ ÀÖ´Â µð¹ÙÀ̽º ÆÄÀÏÀ» ÅëÇØ Á¢±ÙµÈ´Ù. ÁÖÀåÄ¡ ¹øÈ£´Â ¾î´À µå¶óÀ̹ö°¡ ¾î´Â µð¹ÙÀ̽º ÆÄÀÏÀ» »ç¿ëÇϴ°¡ ¾Ë·ÁÁØ´Ù. ºÎ ÀåÄ¡¹øÈ£´Â µå¶óÀ̹ö°¡ Çϳª ÀÌ»óÀÇ ÀåÄ¡¸¦ ÀÛµ¿½Ãų ¶§, ¾î¶² ÀåÄ¡°¡ °¡µ¿µÇ´Â°¡¸¦ ±¸ºÐÇϱâ À§ÇØ µå¶óÀ̹ö ³»ºÎ¿¡¼ »ç¿ëµÈ´Ù.
½Ã½ºÅÛ¿¡ µå¶óÀ̹ö¸¦ Ãß°¡ÇÑ´Ù´Â °ÍÀº Ä¿³Î¿¡ ±×°ÍÀ» µî·Ï½ÃŰ´Â °ÍÀ» ÀǹÌÇÑ´Ù. ¸ðµâÀÌ ÃʱâȵǴ µ¿¾È ÁÖÀåÄ¡ ¹øÈ£¸¦ ºÎ¿©ÇÑ´Ù´Â °Í°úµµ °°Àº Àǹ̴Ù. linux/fs.h¿¡ Á¤ÀÇµÈ register_chrdev()ÇÔ¼ö¸¦ »ç¿ëÇÔÀ¸·Î½á ÀÌ·± ÀÛ¾÷À» ¼öÇàÇÑ´Ù.
int register_chrdev(unsigned int major, const char *name, struct file_operations *fops);
unsigned int major´Â ¿äûÇÒ ÁÖÀåÄ¡ ¹øÈ£À̰í, const char *nameÀº /proc/devices¿¡ ³ª¿À´Â ÀåÄ¡ À̸§À̰í struct file_operations *fops´Â µå¶óÀ̹ö¸¦ À§ÇÑ file_operations tableÀÇ Æ÷ÀÎÅÍ´Ù. À½¼ö¸¦ ¸®ÅÏ ÇÒ °æ¿ì ÀåÄ¡ µå¶óÀ̹ö µî·Ï¿¡ ½ÇÆÐÇÑ °ÍÀÌ´Ù. ºÎÀåÄ¡ ¹øÈ£¸¦ register_chrdev()¿¡ ³Ñ±âÁö ¾Ê´Â´Ù´Â °Í¿¡ À¯ÀÇÇÏÀÚ. Ä¿³ÎÀº ºÎÀåÄ¡ ¹øÈ£¿¡ ÀüÇô ½Å°æ¾²Áö ¾Ê±â ¶§¹®ÀÌ´Ù. ¿ì¸®ÀÇ µå¶óÀ̹ö¸¸ ±× ¹øÈ£¸¦ »ç¿ëÇÑ´Ù.
ÀÌÁ¦ ¾î¶»°Ô ÀÌ¹Ì »ç¿ëÁßÀÎ ¹øÈ£¸¦ °¡·ÎäÁö ¾Ê°í ÁÖÀåÄ¡ ¹øÈ£¸¦ ¾ò¾î¿À´À³Ä´Â »ý°¢ÀÌ µç´Ù. °¡Àå ½¬¿î ¹æ¹ýÀº Documentation/devices.txt¸¦ º¸°í »ç¿ëÇÏÁö ¾Ê´Â °ÍÀ» ¼±ÅÃÇÏ´Â °ÍÀÌ´Ù. ±×·¯³ª ÀÌ ¹øÈ£°¡ ³ªÁß¿¡ »ç¿ëµÉ ¼ö ÀÖÀ¸¹Ç·Î ÁÁÀº ¹æ¹ýÀº ¾Æ´Ï´Ù. ÇØ°áÃ¥Àº Ä¿³Î¿¡°Ô µ¿ÀûÀ¸·Î ÁÖÀåÄ¡ ¹øÈ£¸¦ ÇÒ´çÇØ ÁÙ °ÍÀ» ¿äûÇÏ´Â °ÍÀÌ´Ù.
register_chrdev()¿¡ ÁÖÀåÄ¡ ¹øÈ£ 0À¸·Î ³Ñ±â¸é, µ¿ÀûÀ¸·Î ÇÒ´çµÈ ÁÖÀåÄ¡ ¹øÈ£¸¦ ¸®ÅÏ ÇØÁØ´Ù. ÁÖÀåÄ¡ ¹øÈ£¸¦ ¾Ë ¼ö ¾ø±â ¶§¹®¿¡ ¹Ì¸® µð¹ÙÀ̽º ÆÄÀÏÀ» ¸¸µé ¼ö ¾ø´Ù´Â ´ÜÁ¡ÀÌ ÀÖ´Ù. ¸î °¡Áö ÇØ°á Ã¥ÀÌ ÀÖ´Ù. ¿ì¼±, µå¶óÀ̹ö°¡ Àڽſ¡°Ô ÇÒ´çµÈ ÁÖÀåÄ¡ ¹øÈ£¸¦ Ãâ·ÂÇÏ°í ¼öÀÛ¾÷À¸·Î ±× ÀåÄ¡ ÆÄÀÏÀ» ¸¸µå´Â °ÍÀÌ´Ù. ´ÙÀ½À¸·Î, /proc/devices¿¡ »õ·Î µî·ÏµÈ ÀåÄ¡°¡ ÀÖÀ» °ÍÀÌ´Ù. ¿ì¸®´Â Á÷Á¢ µð¹ÙÀ̽º ÆÄÀÏÀ» ¸¸µé´øÁö ȤÀº ÆÄÀÏÀ» ÀÐ¾î µé¿© µð¹ÙÀ̽º ÆÄÀÏÀ» ¸¸µå´Â ½© ½ºÅ©¸³Æ® ¸¸µé¸é µÈ´Ù. ¼¼ ¹øÂ°·Î ÀåÄ¡ µå¶óÀ̹ö¸¦ µî·ÏÇÑ ÈÄmknod¸¦ ÀÌ¿ëÇØ µð¹ÙÀ̽º ÆÄÀÏÀ» ¸¸µé°í cleanup_module()À» È£ÃâÇÑ ÈÄ rmÀ¸·Î »èÁ¦ÇÏ´Â °ÍÀÌ´Ù.
[edit]
5.1.4 ÀåÄ¡ÀÇ µî·ÏÇØÁ¦ ¶root°¡ ±×·¯°í ½Í´Ù°í ÇØ¼ Ä¿³Î ¸ðµâÀ» rmmodÇÏ°Ô ÇÒ ¼ö´Â ¾ø´Ù. ÇÁ·Î¼¼½º¿¡ ÀÇÇØ ÀåÄ¡ ÆÄÀÏÀ» ¿°í ¸ðµâÀ» Á¦°ÅÇÑ ÈÄ, ÀåÄ¡ ÆÄÀÏÀÇ »ç¿ë½Ãµµ´Â read/writeµî ¿Ã¹Ù¸¥ ÇÔ¼ö°¡ »ç¿ëÇÏ´ø ¸Þ¸ð¸®À§Ä¡¸¦ ´Ù¸¥ °ÍÀ¸·Î ÇÏ¿©±Ý »ç¿ëÇÏ°Ô ÇÒ °ÍÀÌ´Ù. ¸¸ÀÏ ¿îÀÌ ÁÁ´Ù¸é ±×°÷¿¡ ¾Æ¹«·± Äڵ嵵 ·ÎµåµÇÁö ¾ÊÀ» °ÍÀÌ°í ¿¡·¯ ¸Þ½ÃÁö¸¦ ¹ÞÀ» °ÍÀÌ´Ù. ¿ì¸®°¡ ¿îÀÌ ¾ø´Ù¸é °°Àº À§Ä¡·Î ´Ù¸¥ Ä¿³Î ¸ðµâÀÌ ¿Ã¶ó¿Ã °ÍÀÌ°í ±×°ÍÀº Ä¿³Î ³»ÀÇ ´Ù¸¥ ÇÔ¼öÀÇ Áß°£ ¾îµò°¡·Î ½ÇÇàÀ§Ä¡¸¦ ¹Ù²ã ¹ö¸± °ÍÀÌ´Ù. °á°ú´Â ¿¹»óÇÒ ¼ö ¾øÀ¸¸ç ¸Å¿ì ºÎÁ¤ÀûÀÌ´Ù.
ÀϹÝÀûÀ¸·Î ¿ì¸®°¡ ¹«¾ùÀΰ¡ Çã°¡ ÇÏ°í ½ÍÁö ¾Ê´Ù¸é ±× ÀÏÀ» ó¸®ÇÏ´Â ÇÔ¼ö¿¡¼ ¿¡·¯ÄÚµå(À½¼ö)¸¦ ¸®ÅÏÇϵµ·Ï ÇÑ´Ù. void ŸÀÔÀ̱⠶§¹®¿¡ cleanup_module()¿¡¼´Â À̰ÍÀÌ ºÒ°¡´É ÇÏ´Ù. ±×·¯³ª ¾ó¸¶³ª ¸¹Àº ÇÁ·Î¼¼½º°¡ ±× ¸ðµâÀ» ÀÌ¿ëÇϰí ÀÖ´ÂÁö ÃßÀûÇÏ´Â Ä«¿îÅͰ¡ ÀÖ´Ù. /proc/modulesÆÄÀÏÀÇ ¼¼ ¹øÂ° ÇʵåÀÇ °ªÀÌ ¹Ù·Î À̰ÍÀÌ´Ù. ÀÌ ¹øÈ£°¡ 0ÀÌ ¾Æ´Ï¶ó¸é, rmmod´Â ½ÇÆÐÇÑ´Ù. linux/module.c¿¡ Á¤ÀÇ µÇÀÖ´Â sys_delete_module()¿¡ ÀÇÇØ ±× ¼ö°¡ üũµÇ°í ÀÖÀ¸¹Ç·Î cleanup_module()¿¡¼ Ä«¿îÆ® ÇÒ Çʿ䰡 ¾ø´Ù. Á÷Á¢ÀûÀ¸·Î Ä«¿îÅ͸¦ »ç¿ëÇÏÁö ¸»ÀÚ, linux/modules.h¿¡ Á¤ÀÇµÈ ¸ÅÅ©·Î°¡ ÀÖ´Ù. ±×°ÍÀº ÀÌ Ä«¿îÅ͸¦ Áõ°¡½ÃŰ°Å³ª °¨¼Ò½ÃŰ´Â ÀÏÀ» ÇÑ´Ù.
Ä«¿îÅ͸¦ Á¤È®Çϱâ À¯Áö½ÃŰ´Â °ÍÀÌ Áß¿äÇÏ´Ù. ¸¸¾à Á¤È®ÇÑ Ä«¿îÅÍÀÇ ¼ö¸¦ ÀÒ¾î ¹ö¸°´Ù¸é, ¸ðµâÀ» ÇØÁ¦(unload)ÇÏ´Â °ÍÀº ºÒ°¡´ÉÇÏ´Ù. ºÎÆÃÀ» ´Ù½Ã ÇÏÀÚ. ¸ðµâ °³¹ßÀ» ÇÏ´Â µ¿¾È ¾ðÁ¨°¡´Â ´ÚÄ¥ ÀÏÀÌ´Ù.
[edit]
5.1.5 chardev.c ¶´ÙÀ½ÀÇ ÄÚµå´Âchardev¶ó´Â À̸§ÀÇ ¹®ÀÚ µå¶óÀ̹ö¸¦ ¸¸µå´Â °£´ÜÇÑ ¿¹Á¦´Ù. ÀåÄ¡ÆÄÀÏÀÇ ³»¿ëÀ» ȸ鿡 Ãâ·Â (ȤÀº ´Ù¸¥ ÇÁ·Î±×·¥À» ÀÌ¿ëÇØ ¿¾î º¼ ¼ö ÀÖ´Ù)ÇÒ ¼ö ÀÖ´Ù. ±×·¯¸é µå¶óÀ̹ö´Â ÆÄÀÏÀÌ ÀÐÇôÁø Ƚ¼ö¸¦ ÆÄÀÏ¿¡ ±â·ÏÇÑ´Ù. echo "hi" > /dev/hello¿Í °°ÀÌ ÆÄÀÏ¿¡ ±â·ÏÇÏ´Â °ÍÀ» Áö¿øÇÏÁö ¾Ê´Â´Ù. ±×·¯³ª ÀÌ·± ½Ãµµ¸¦ °¨ÁöÇØ »ç¿ëÀÚ¿¡°Ô ¾²±â ±â´ÉÀ» Áö¿øÇÏÁö ¾Ê´Â ´Ù´Â °ÍÀ» ¾Ë·Á ÁØ´Ù. ¿ì¸®°¡ ÀÐ¾î ¹öÆÛ¿¡ ±â·ÏÇÏ´Â µ¥ÀÌÅ͸¦ °¡Áö°í ¿ì¸®°¡ ÇÏ´Â ÀÏÀ» º¼ ¼ö ¾ø´Ù°í °ÆÁ¤ÇÏÁö ¸¶¶ó; ¿ì¸®´Â ±×°ÍÀ» °¡Áö°í ¸¹Àº ÀÏÀ» ÇÏÁö ¾Ê´Â´Ù. ´ÜÁö µ¥ÀÌÅ͸¦ ÀÐ¾î¼ ±× µ¥ÀÌÅ͸¦ ¹Þ¾Ò´Ù´Â ¸Þ½ÃÁö¸¸ Ãâ·ÂÇÑ´Ù.
Example 4-1. chardev.c
/* chardev.c: ¾ó¸¶³ª ¸¹ÀÌ µð¹ÙÀ̽º ÆÄÀÏ¿¡ Á¢±ÙÇß´ÂÁö ¾Ë·ÁÁÖ´Â ¸ðµâ */ #if defined(CONFIG_MODVERSIONS) && ! defined(MODVERSIONS) #include <linux/modversions.h> #define MODVERSIONS #endif #include <linux/kernel.h> #include <linux/module.h> #include <linux/fs.h> #include <asm/uaccess.h> /* for put_user */ /* Prototypes - this would normally go in a .h file */ int init_module(void); void cleanup_module(void); static int device_open(struct inode *, struct file *); static int device_release(struct inode *, struct file *); static ssize_t device_read(struct file *, char *, size_t, loff_t *); static ssize_t device_write(struct file *, const char *, size_t, loff_t *); #define SUCCESS 0 #define DEVICE_NAME "chardev" /* /proc/devices¿¡ ³ªÅ¸³ª´Â ÀåÄ¡ À̸§ */ #define BUF_LEN 80 /* ÀåÄ¡·ÎºÎÅÍ ¸Þ½ÃÁöÀÇ ÃÖ´ë ±æÀÌ */ /* Á¤Àû º¯¼ö·Î Àü¿ªº¯¼ö ¼±¾ð */ static int Major; /* ÁÖÀåÄ¡ ¹øÈ£ */ static int Device_Open = 0; /* ÀåÄ¡°¡ ¿·È´Â°¡? Áߺ¹»ç¿ë ¹æÁö */ /* access to the device */ static char msg[BUF_LEN]; /* ¿äûÀÌ ÀÖÀ» ¶§ ÀåÄ¡°¡ º¸³»´Â ¸Þ½ÃÁö */ static char *msg_Ptr; static struct file_operations fops = { .read = device_read, .write = device_write, .open = device_open, .release = device_release }; /* Functions */ int init_module(void) { Major = register_chrdev(0, DEVICE_NAME, &fops); if (Major < 0) { printk ("Registering the character device failed with %d\n", Major); return Major; } printk("<1>I was assigned major number %d. To talk to\n", Major); printk("<1>the driver, create a dev file with\n"); printk("'mknod /dev/hello c %d 0'.\n", Major); printk("<1>Try various minor numbers. Try to cat and echo to\n"); printk("the device file.\n"); printk("<1>Remove the device file and module when done.\n"); return 0; } void cleanup_module(void) { /* Unregister the device */ int ret = unregister_chrdev(Major, DEVICE_NAME); if (ret < 0) printk("Error in unregister_chrdev: %d\n", ret); } /* Methods */ /* "cat /dev/mycharfile" ó·³ ÇÁ·Î¼¼½º°¡ µð¹ÙÀ̽º ÆÄÀÏÀ» ¿·Á°í ÇÒ ¶§ È£ÃâµÊ */ static int device_open(struct inode *inode, struct file *file) { static int counter = 0; if (Device_Open) return -EBUSY; Device_Open++; sprintf(msg,"I already told you %d times Hello world!\n", counter++); msg_Ptr = msg; MOD_INC_USE_COUNT; return SUCCESS; } /* µð¹ÙÀ̽º ÆÄÀÏÀÌ ´ÝÈú ¶§ È£ÃâµÊ. */ static int device_release(struct inode *inode, struct file *file) { Device_Open --; /* We're now ready for our next caller */ /* »ç¿ë Ä«¿îÆ® °¨¼Ò ȤÀº Çѹø ¿¾îº» ÆÄÀÏÀÌ ¾Æ´Ï¶ó¸é ¸ðµâÀ» Á¦°ÅÇÒ ¼ö ¾øÀ½ */ MOD_DEC_USE_COUNT; return 0; } /* ÀÌ¹Ì ¿¸° ÀåÄ¡ ÆÄÀÏ¿¡¼ ¹«¾ùÀΰ¡ ÀÐÀ¸·Á ÇÒ ¶§ È£Ãâ */ static ssize_t device_read(struct file *filp, char *buffer, /* The buffer to fill with data */ size_t length, /* The length of the buffer */ loff_t *offset) /* Our offset in the file */ { /* ¹öÆÛ¿¡ ½ÇÁ¦ ¾²¿©Áø ¹ÙÀÌÆ® ¼ö */ int bytes_read = 0; /* ¸Þ½ÃÁöÀÇ ³¡¿¡ ¸Þ½ÃÁöÀÇ ³¡ÀÓÀ» ¾Ë¸®±â À§ÇØ 0¸®ÅÏ */ if (*msg_Ptr == 0) return 0; /* ¹öÆÛ¿¡ ½ÇÁ¦ µ¥ÀÌÅ͸¦ ÀÔ·Â */ while (length && *msg_Ptr) { /* ¹öÆÛ´Â Ä¿³Î ¼¼±×¸ÕÆ®°¡ ¾Æ´Ï°í »ç¿ëÀÚ ¼¼±×¸ÕÆ®´Ù * ÇÒ´çÀº ÀÏ¾î ³ªÁö ¾Ê´Â´Ù. Ä¿³Î µ¥ÀÌÅÍ¿µ¿ª¿¡¼ »ç¿ëÀÚ ¿µ¿ªÀ¸·Î * µ¥ÀÌÅ͸¦ º¹»çÇÏ´Â put_user() »ç¿ë */ put_user(*(msg_Ptr++), buffer++); length--; bytes_read++; } /* ÀÐÇôÁø µ¥ÀÌÅÍÀÇ ¹ÙÀÌÆ® ¼ö¸¦ ¹öÆÛ¿¡ ±â·Ï */ return bytes_read; } /* Called when a process writes to dev file: echo "hi" > /dev/hello */ static ssize_t device_write(struct file *filp, const char *buff, size_t len, loff_t *off) { printk ("<1>Sorry, this operation isn't supported.\n"); return -EINVAL; } [edit]
5.1.6 ¿©·¯ Ä¿³Î ¹öÀüÀ» À§ÇÑ ¸ðµâ ÀÛ¼º ¶Ä¿³Î°ú ÇÁ·Î¼¼½º »çÀÌÀÇ ÁÖ¿äÇÑ ÀÎÅÍÆäÀ̽ºÀÎ ½Ã½ºÅÛ ÄÝÀº ÀϹÝÀûÀ¸·Î ¹öÀüÀ» ÀÏÄ¡½ÃÄÑ »ç¿ëÇÑ´Ù. »õ ¹öÀüÀÇ ½Ã½ºÅÛ ÄÝÀÌ Ãß°¡µÇ´õ¶óµµ ±¸ ¹öÀüÀÇ ½Ã½ºÅÛ ÄÝÀº ¿©ÀüÈ÷ µ¿ÀÛÇÑ´Ù. À̰ÍÀº ±¸ ¹öÀü°úÀÇ °øÁ¸À» À§ÇØ ÇÊ¿äÇÏ´Ù. –»õ ¹öÀüÀÇ Ä¿³ÎÀº ÀϹÝÀûÀÎ ÇÁ·Î¼¼½º¸¦ ÁßÁö½ÃŰ·Á ÇÏÁö ¾Ê´Â´Ù. ´ëºÎºÐÀÇ °æ¿ì, ÀåÄ¡ ÆÄÀÏÀº ±×´ë·Î ³²¾ÆÀÖ´Ù. On the other hand¹Ý¸é¿¡ , Ä¿³Î ³»ºÎÀÇ ÀÎÅÍÆäÀ̽º´Â ¹öÀü¸¶´Ù ¹Ù²ï´Ù.
¸®´ª½º Ä¿³ÎÀº ¾ÈÁ¤¹öÀü°ú (n.$<$¦¼ö$>$.m) °³¹ß¹öÀüÀ¸·Î (n.$<$Ȧ¼ö$>$.m) ³ª´¶´Ù. °³¹ß ¹öÀüÀº ´ÙÀ½ ¹öÀü¿¡¼ ´Ù½Ã ±¸ÇöÇØ¾ß ÇѴٰųª ¿À·ù·Î Ãë±ÞµÉ ¼öµµ ÀÖ´Â °ÍÀ» ³»Æ÷ÇÑ ¸ðµç Âü½ÅÇÑ ¾ÆÀ̵ð¾î¸¦ Æ÷ÇÔÇϰí ÀÖ´Ù. °á°úÀûÀ¸·Î, ÀÌ·± °³¹ß¹öÀüÀÇ ÀÎÅÍÆäÀ̽º´Â ½Å·ÚÇÒ ¼ö ¾ø´Ù (³»°¡ ÀÌ ±Û¿¡¼ ±×°ÍµéÀ» ´Ù·çÁö ¾Ê´Â ÀÌÀ¯À̱⵵ ÇÏ´Ù. ±×°ÍÀº °íµÈ ÀÏÀÌ°í ¹Ù²î±âµµ »¡¸® ¹Ù²ï´Ù.). ¹Ý¸é¿¡ ¾ÈÁ¤¹öÀü¿¡¼, ¹ö±× ¼öÁ¤ ¿©ºÎ¿Í °ü°è¾øÀÌ °°Àº ÀÎÅÍÆäÀ̽º¸¦ ±â´ëÇÒ ¼ö ÀÖ´Ù.
¼·Î ´Ù¸¥ ¹öÀüÀÇ Ä¿³Î¿¡´Â ´Ù¸¥ Â÷ÀÌÁ¡µéÀÌ ÀÖ´Ù. ¸¸ÀÏ ¿©·¯ ¹öÀüÀÇ Ä¿³ÎÀ» Áö¿øÇÏ·Á ÇÑ´Ù¸é, Á¶°Ç ÁöÇâÀûÀÎ ÄÚµå ÄÄÆÄÀÏ ¹æ½ÄÀÌ ÇÊ¿äÇÔÀ» ¾Ë°Ô µÉ °ÍÀÌ´Ù.. LINUX_VERSION_CODE ¿Í KERNEL_VERSION¸¦ ºñ±³ÇÏ´Â ¹æ¹ý. Ä¿³ÎÀÇ a.b.c¹öÀü¿¡¼, ¸ÅÅ©·ÎÀÇ °ªÀº
ÀÌ´Ù. Ä¿³Î2.0.35ÀÌÀü ¿¡´Â ÀÌ ¸ÅÅ©·Î°¡ ¾ø´Ù´Â °ÍÀ» ¾Ë¾ÆµÎÀÚ. ±¸½Ä Ä¿³ÎÀ» Áö¿øÇÏ´Â ¸ðµâÀ» ÀÛ¼ºÇϰíÀÚ ÇÑ´Ù¸é, ´ÙÀ½°ú °°ÀÌ Á¤ÀÇ ÇØ¾ß ÇÑ´Ù.
Example 4-2. some title
#if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,2,0) #define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c)) #endif ¹°·Ð ÀÌ·± ¸ÅÅ©·Î°¡ Àֱ⠶§¹®¿¡, ´ç½ÅÀº ¸ÅÅ©·ÎÀÇ Á¸Àç¿©ºÎ¸¦ Å×½ºÆ®Çϱâ À§ÇØ Ä¿³Î ¹öÀüÀ» Å×½ºÆ® ÇÏ´Â °Íº¸´Ù #ifndef KERNEL_ VERSION À» »ç¿ëÇÏ´Â °ÍÀÌ ÁÁÀ» °ÍÀÌ´Ù.
[edit]
6.1 /proc File System ¶¸®´ª½º¿¡´Â Ä¿³Î°ú Ä¿³Î ¸ðµâÀÌ ÇÁ·Î¼¼½º·Î Á¤º¸¸¦ º¸³»´Â Ãß°¡ÀûÀÎ ¹æ¹ýÀÌ ÀÖ´Ù. /procÆÄÀÏ ½Ã½ºÅÛÀÌ ±×°ÍÀÌ´Ù. ¿ø·¡ À̰ÍÀº ÇÁ·Î¼¼½º¿¡ °üÇÑ Á¤º¸¿¡ ½±°Ô Á¢±ÙÇϵµ·Ï ¼³°èµÈ °ÍÀÌ´Ù(À̸§À» º¸¶ó.). ¸ðµâÀÇ ¸®½ºÆ®¸¦ °¡Áö°í ÀÖ´Â /proc/modules, ±×¸®°í ¸Þ¸ð¸® »ç¿ë·®À» º¸¿©ÁÖ´Â /proc/meminfoµî°ú °°ÀÌ Ä¿³ÎÀÌ °ü½ÉÀ» °®´Â °Íµé¿¡ »ó¿ëµÈ´Ù.
/procÆÄÀÏ ½Ã½ºÅÛÀ» »ç¿ëÇÏ´Â ¹æ¹ýÀº µð¹ÙÀ̽º µå¶óÀ̹ö¸¦ ÀÌ¿ëÇÏ´Â ¹æ¹ý°ú ¸Å¿ì À¯»çÇÏ´Ù. ¿©·¯ºÐÀº ÇÔ¼öÀÇ Çڵ鷯 Æ÷ÀÎÅ͸¦ Æ÷ÇÔÇØ /procÆÄÀÏ¿¡ ÇÊ¿äÇÑ ¸ðµç Á¤º¸¸¦ °¡Áö°í ±¸Á¶Ã¼¸¦ »ý¼ºÇÑ´Ù.( ¿ì¸®ÀÇ °æ¿ì ÇѰ¡Áö Á¤º¸, ´©±º°¡ /proc ÆÄÀϷκÎÅÍ ¹«¾ùÀΰ¡ ÀÐÀ¸·Á ½ÃµµÇÒ ¶§ ±×°ÍÀÌ È£ÃâµÈ´Ù.). ±×·± ÈÄ Ä¿³Î¿¡ init_module()ÀÌ ±× ±¸Á¶Ã¼¸¦ Ä¿³Î¿¡ µî·ÏÇϰí cleanup_moduleÀÌ µî·ÏÀ» ÇØÁ¦ÇÑ´Ù.
¿ì¸®°¡ ¿ì¸®ÀÇ ÆÄÀÏÀÌ ÀÌ¿ëÇÒ inode ¹øÈ£¸¦ °áÁ¤Çϱ⸦ ¿øÇÏÁö ¾Ê°í Ä¿³ÎÀÌ °áÁ¤ÇÏ°Ô ÇØ¼ ½Ã½ºÅÛ ´Ù¿îÀ» ¹æÁöÇϱ⠿øÇϱ⠶§¹®¿¡ ¿ì¸®´Â proc_register_dynamic()[1]ÇÔ¼ö¸¦ »ç¿ëÇÑ´Ù. ÀϹÝÀûÀÎ ÆÄÀÏÀº ¸Þ¸ð¸®¿¡ Á¸ÀçÇϱ⺸´Ù´Â µð½ºÅ©¿¡ Á¸ÀçÇÑ´Ù.(±×°ÍÀÌ /procÀÌ´Ù.), ¶ÇÇÑ ±×·± °æ¿ì ÆÄÀÏÀÇ À妽º ³ëµå(index-node, inode´Â ¾à¾î´Ù)°¡ À§Ä¡ÇÑ µð½ºÅ©¸¦ inode¹øÈ£°¡ Áö½ÃÇÑ´Ù. inode±¸Á¶Ã¼´Â ÆÄÀÏ¿¡ ´ëÇÑ Á¤º¸¸¦ ´ã°í ÀÖ´Ù, ¿¹¸¦ µé¾î ÆÄÀÏÀÇ ÆÛ¹Ì¼Ç, µð½ºÅ© ¾îµð¼ ÆÄÀÏÀÇ µ¥ÀÌÅ͸¦ ãÀ» ¼ö Àִ°¡ µîµî.
ÆÄÀÏÀÌ ¿¸®°Å³ª ´ÝÈú ¶§ ¿ì¸®°¡ È£ÃâÇÏÁö ¾Ê¾Ò±â ¶§¹®¿¡ , ¸ðµâ ³»ºÎ¿¡¼ MOD_INC_USE_COUNT¿Í MOD_DEC_USE_COUNT¿¡ Á¢±ÙÇÒ ¹æ¹ýÀÌ ¾ø´Ù. ¶ÇÇÑ ÆÄÀÏÀÌ ¿¸° »óÅ¿¡¼ ¸ðµâÀÌ Á¦°ÅµÉ ¶§ »ý±â´Â ¹®Á¦¸¦ ÇÇÇÒ ¹æ¹ýÀÌ ¾ø´Ù. ´ÙÀ½ Àå¿¡¼ ¿ì¸®´Â ´õ º¹ÀâÇÑ ±¸ÇöÀ» º»´Ù, ±×·¯³ª ±×°ÍÀº /procÆÄÀÏÀ» ´Ù·ç´Âµ¥ ÀÖ¾î ´õ À¯¿¬ÇÑ ¹æ¹ýÀ» Á¦½ÃÇØÁÙ °ÍÀÌ´Ù. ±×¸®°í ±×°ÍÀº ¹®Á¦¿¡ ºÀÂøÇÏÁö ¾Ê°Ô ÇØÁֱ⵵ ÇÑ´Ù.
Example 5-1. procfs.c
/* procfs.c - create a "file" in /proc */ #include <linux/kernel.h> /* Ä¿³Î ÀÛ¾÷ */ #include <linux/module.h> /* ¸ðµâ ÀÛ¾÷ */ /* Deal with CONFIG_MODVERSIONS */ #if CONFIG_MODVERSIONS==1 #define MODVERSIONS #include <linux/modversions.h> #endif /* proc fs¸¦ ´Ù·é´Ù */ #include <linux/proc_fs.h> /* 2.2.3 ¹öÀü ÀÌÀü¿¡´Â ´ÙÀ½ÀÇ ¸ÅÅ©·Î°¡ ¾ø´Ù. ÇÊ¿äÇÏ´Ù¸é ¿©±â¼ Á¤ÀÇ ÇÑ´Ù.*/ #ifndef KERNEL_VERSION#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c)) #endif /* proc fs¿¡ µ¥ÀÌÅÍ Àü´Þ. Argument ========= 1. µ¥ÀÌÅͰ¡ »ðÀԵǴ ¹öÆÛ, ¸¸ÀÏ »ç¿ëÇϱ⠿øÇÑ´Ù¸é 2. ¹®ÀÚ¿¿¡ ´ëÇÑ Æ÷ÀÎÅÍ, ¸¸ÀÏ Ä¿³ÎÀÌ ¹öÆÛ¸¦ ÇÒ´çÇϱ⠿øÇÏÁö ¾Ê´Â °æ¿ì »ç¿ë 3. ÆÄÀÏ¿¡¼ ÇöÀç À§Ä¡ 4. ù ÀÎÀÚ ¹öÆÛÀÇ Å©±â 5. 0(¹Ì·¡ÀÇ »ç¿ëÀ» À§ÇØ?). Usage and Return Value ====================== ¸¸ÀÏ ÀڽŸ¸ÀÇ ¹öÆÛ¸¦ ¿øÇÑ´Ù¸é ³»°¡ ÇÑ °Íó·³ µÎ¹ø ° ÀÎÀÚ¿¡ ³Ö°í ¹öÆÛ¿¡¼ »ç¿ëÇÑ ¹ÙÀÌÆ® ¼ö¸¦ ¸®ÅÏÇÏ¶ó ¸®ÅÏ °ªÀÌ NULLÀΰÍÀº ´õ ÀÌ»óÀÇ Á¤º¸°¡ ¾øÀ½À» ÀǹÌÇÑ´Ù(end of file). ¶ÇÇÑ À½¼öÀÎ °æ¿ì ¿¡·¯ »óȲÀÌ´Ù. For More Information ==================== The way I discovered what to do with this function ³»°¡ ÀÌ ÇÔ¼ö¿¡¼ ¹«¾ùÀΰ¡¸¦ ¹ß°ßÇÑ ¹æ¹ýÀº ¹®¼¸¦ Àд °ÍÀÌ ¾Æ´Ï°í, »ç¿ëµÇ´Â Äڵ带 Àд °ÍÀ̾ú´Ù. proc_dir_entry±¸Á¶Ã¼ÀÇ get_infoÇʵ带 ¾îµð´Ù ¾²´Â°¡¸¦ »ìÆìºÃ´Ù. ¶ÇÇÑ /fs/proc/array.c ÆÄÀÏÀÌ »ç¿ëµÇ´Â °ÍÀ» »ìÆì º» °ÍÀÌ´Ù. If something is unknown about the kernel, this is ¹«¾ð°¡ Ä¿³Î¿¡¼ Àß ¸ð¸£´Â ºÎºÐÀÌ ÀÖ´Ù¸é ÀÌ·± ¹æ½ÄÀÌ ÀϹÝÀûÀ¸·Î ÇàÇØÁø´Ù. ¸®´ª½º¿¡¼ ¿ì¸®´Â Ä¿³Î Äڵ带 ¾òÀ» ¼ö ÀÖ´Ù´Â °ÍÀº ´ë´ÜÇÑ ÀåÁ¡ÀÌ´Ù. Ȱ¿ëÇ϶ó. */ int procfile_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int zero) { int len; /* ½ÇÁ¦ »ç¿ëµÇ´Â ¹ÙÀÌÆ® ¼ö */ /* ¿ì¸®°¡ ÀÌ ÇÔ¼ö¸¦ ³ª°¥ ¶§µµ ÀÌ ½ºÅׯ½ º¯¼öÀ̱⠶§¹®¿¡ ¸Þ¸ð¸®¿¡ ³²°Ü Áø´Ù. */ static char my_buffer[80]; static int count = 1; /* ¿ì¸®(Á÷¿ª)´Â Çѹø¿¡ ¸ðµç Á¤º¸¸¦ Áֱ⠶§¹®¿¡ À¯Àú(?Á÷¿ª)°¡ Ãß°¡ÀûÀÎ Á¤º¸¸¦ ¿ä±¸ÇÒ ¶§ ¿ì¸®ÀÇ ´ë´äÀº NO´Ù. * Ç¥ÁØ ¶óÀ̺귯¸® ÇÔ¼ö´Â Ä¿³ÎÀÌ ´õ ÀÌ»ó ÁÙ Á¤º¸°¡ ¾ø´Ù°í ¸»ÇÒ ¶§±îÁö, ȤÀº Ç¥ÁØ ¶óÀ̺귯¸® ÇÔ¼öÀÇ ¹öÆÛ°¡ ´Ù Âû ¶§±îÁö * read ½Ã½ºÅÛ ÄÝÀ» Çϱ⠶§ ¹®¿¡ Áß¿äÇÏ´Ù. */ if (offset > 0) return 0; /* Fill the buffer and get its length */ len = sprintf(my_buffer, "For the %d%s time, go away!\n", count, (count % 100 > 10 && count % 100 < 14) ? "th" : (count % 10 == 1) ? "st" : (count % 10 == 2) ? "nd" : (count % 10 == 3) ? "rd" : "th" ); count++; /* ÇÔ¼ö¿¡ ¹öÆÛÀÇ À§Ä¡¸¦ ¾Ë¸°´Ù. */ *buffer_location = my_buffer; /* Return the length */ return len; } struct proc_dir_entry Our_Proc_File = {0, /* Inode ¹øÈ£ –¿©±â¼´Â ¹«½ÃÇÑ´Ù. À̰ÍÀº proc_register[_dynamic]¿¡ ÀÇÇØ ä¿öÁø´Ù. */ 4, /* ÆÄÀÏÀÇ À̸§ ±æÀÌ */ "test", /* ÆÄÀÏÀ̸§ */ S_IFREG | S_IRUGO, /* File mode – ÀÏ¹Ý ÆÄÀÏ, ¼ÒÀ¯ÀÚ, ±×·ì, ¸ðµç »ç¶÷µéÀÌ ÀÖÀ» ¼ö ÀÖ´Ù.*/ 1, /* ÆÄÀÏÀÌ Âü°íÇÏ´Â µð·ºÅ丮ÀÇ ¸µÅ© °³¼ö*/ 0, 0, /* uid, gid ·çÆ®¿¡°Ô ±ÇÇÑÀ» ÁØ´Ù.*/ 80, /* ls¿¡ ÀÇÇØ º¸°íµÇ´Â ÆÄÀÏÀÇ Å©±â. */ NULL, /* link, removeµî inode»ó¿¡ ÇàÇØÁö´Â ÇÔ¼ö- ¿ì¸®´Â ¾Æ¹«°Íµµ Áö¿øÇÏÁö ¾Ê´Â´Ù. */ procfile_read, /* Àбâ ÇÔ¼ö, ¹«¾ùÀΰ¡¸¦ ÀÐÀ¸·Á ÇÒ ¶§ È£ÃâµÇ´Â ÇÔ¼ö */ NULL /* ÆÛ¹Ì¼Ç, ¼ÒÀ¯±Ç µîÀ» ´Ù·ç´Â inode¸¦ ä¿ì´Â ÇÔ¼öÀÇ Æ÷ÀÎÅÍ */ }; /* Initialize the module - register the proc file */ int init_module() { /* proc_register[_dynamic]ÀÌ ¼º°øÇÏ¸é ¼º°ø, ¾Æ´Ï¸é ½ÇÆÐ */ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0) /* ±¸Á¶Ã¼¿¡¼ ±× °ªÀÌ 0À̸é 2.2¹öÀü¿¡¼´Â proc_register()ÇÔ¼ö°¡ inode¹øÈ£¸¦ µ¿ÀûÀ¸·Î ÇÒ´çÇÑ´Ù. * proc_register_dynamic()ÇÔ¼ö°¡ ÇÊ¿ä¾ø°Ô µÈ´Ù. */ return proc_register(&proc_root, &Our_Proc_File); #else return proc_register_dynamic(&proc_root, &Our_Proc_File); #endif /* proc_root´Â procÆÄÀÏ ½Ã½ºÅÛÀÇ ·çÆ®(/proc) * ¿ì¸®°¡ ÆÄÀÏÀ» À§Ä¡½ÃŰ±â ¿øÇÏ´Â À§Ä¡´Ù. */ } /* Cleanup - unregister our file from /proc */ void cleanup_module() { proc_unregister(&proc_root, Our_Proc_File.low_ino); } [edit]
7.1 ÀÔ·ÂÀ» À§ÇÑ /procÀÇ »ç¿ë ¶Áö±Ý±îÁö ¿ì¸®´Â Ä¿³Î ¸ðµâ·ÎºÎÅÍ Ãâ·ÂÀ» ¾ò´Â µÎ °¡Áö ¹æ¹ýÀ» ¾Ë¾Æ º¸¾Ò´Ù. ¿ì¸®´Â ÀåÄ¡ µå¶óÀ̹ö¿Í mknod¸¦ µî·ÏÇϰųª /proc ÆÄÀÏÀ» »ý¼ºÇÒ ¼ö ÀÖ´Ù. À̰ÍÀº Ä¿³Î ¸ðµâ·Î ÇÏ¿©±Ý ¿ì¸®¿¡°Ô ¹«¾ùÀΰ¡¸¦ Àü´ÞÇÒ ¼ö ÀÖµµ·Ï ÇØÁØ´Ù. ±× ¹Ý´ëÀÇ °æ¿ì°¡ ºÒ°¡´ÉÇÏ´Ù´Â °ÍÀÌ ¹®Á¦°¡ µÈ´Ù. ¿ì¼± Ä¿³Î ¸ðµâ¿¡ µ¥ÀÌÅ͸¦ ÀÔ·ÂÇÏ´Â °ÍÀº /proc ÆÄÀÏ¿¡ µ¥ÀÌÅ͸¦ ¾²´Â ¹æ¹ýÀ» ÅÃÇÑ´Ù.
/procÆÄÀÏ ½Ã½ºÅÛÀº Ä¿³ÎÀÌ ÇÁ·Î¼¼½ºÀÇ »óŸ¦ º¸°íÇÒ ¼ö ÀÖµµ·Ï ÇÑ °ÍÀ̱⠶§¹®¿¡ , ÀԷ¿¡ ´ëÇÑ Æ¯º°ÇÑ ¹è·Á´Â ¾ø´Ù. proc_dir_entry ±¸Á¶Ã¼¿¡´Â Ãâ·Â ÇÔ¼ö¿Í °°Àº ¹æ½ÄÀÇ ÀÔ·Â ÇÔ¼ö¿¡ ´ëÇÑ Æ÷ÀÎÅͰ¡ ¾ø´Ù. /procÆÄÀÏ¿¡ ¾²±â¸¦ ÇÏ´Â ´ë½Å, Ç¥ÁØ ÆÄÀÏ ½Ã½ºÅÛ ¸ÞÄ¿´ÏÁòÀ» »ç¿ëÇÒ Çʿ䰡 ÀÖ´Ù.
¸®´ª½º¿¡´Â ÆÄÀÏ ½Ã½ºÅÛ µî·ÏÀ» À§ÇÑ Ç¥ÁØ ¸ÞÄ¿´ÏÁòÀÌ ÀÖ´Ù. ¸ðµç ÆÄÀÏ ½Ã½ºÅÛÀº inode¿Í file operationÀ» ´Ù·ç±â À§ÇÑ °íÀ¯ÇÑ ÇÔ¼ö¸¦ °¡Áö°í ÀÖ¾î¾ß Çϱ⠶§¹®¿¡ ÀÌ ¸ðµç ÇÔ¼öÀÇ Æ÷ÀÎÅ͸¦ °¡Áö°í ÀÖ´Â inode_operations ¶ó´Â ±¸Á¶Ã¼°¡ ÀÖÀ¸¸ç, ±×¸®°í ±×°ÍÀº file_operations±¸Á¶Ã¼¸¦ Áö½ÃÇÏ´Â Æ÷ÀÎÅ͸¦ Æ÷ÇÔÇϰí ÀÖ´Ù. »õ ÆÄÀÏÀ» µî·ÏÇÒ ¶§¸¶´Ù, /proc¿¡¼ ±×°Í¿¡ Á¢±ÙÇϱâ À§ÇØ ¾î´À inode_operations ±¸Á¶Ã¼¸¦ »ç¿ëÇÒ °ÍÀÎÁö °áÁ¤ÇÑ´Ù. ¿ì¸®°¡ »ç¿ëÇÒ module_input(), module_output()ÇÔ¼ö¸¦ Áö½ÃÇÏ´Â Æ÷ÀÎÅ͸¦ Æ÷ÇÔÇÑ file_operation ±¸Á¶Ã¼¸¦ Áö½ÃÇÏ´Â Æ÷ÀÎÅ͸¦ Æ÷ÇÔÇÑ inode_operations ±¸Á¶Ã¼, À̰ÍÀÌ ¿ì¸®°¡ »ç¿ëÇÏ´Â ¸ÞÄ¿´ÏÁòÀÌ´Ù.
Àбâ¿Í ¾²±â¸¦ À§ÇÑ Ç¥ÁØ ·Ñ ¼ÂÀÌ Ä¿³Î¿¡¼´Â ¹Ý´ë·Î ÁöÁ¤µÅÀÖ´Ù´Â °ÍÀ» ¸í½ÉÇÏÀÚ. Àбâ ÇÔ¼ö´Â Ãâ·ÂÀ» À§ÇØ, ¹Ý´ë·Î ¾²±âÇÔ¼ö´Â ÀÔ·ÂÀ» À§ÇØ »ç¿ë µÈ´Ù. Àϱâ¿Í ¾²±â´Â »ç¿ëÀÚÀÇ °üÁ¡¿¡¼ º» °ÍÀ̱⠶§¹®ÀÌ´Ù. --- ¸¸ÀÏ ÇÁ·Î¼¼½º°¡ Ä¿³Î¿¡¼ ¹«¾ð°¡ Àд´ٸé Ä¿³ÎÀº ±×°ÍÀ» Ãâ·ÂÇØ ÁÖ¾î¾ß ÇÑ´Ù. ±×¸®°í ÇÁ·Î¼¼½º°¡ Ä¿³Î¿¡ ¹«¾ð°¡¸¦ ¾´´Ù¸é Ä¿³ÎÀº ±×°ÍÀ» ÀÔ·ÂÀ¸·Î ¹Þ¾Æ µé¿©¾ß ÇÑ´Ù.
Èï¹Ì ÀÖ´Â ¶Ç ´Ù¸¥ °ÍÀº module_permissions() ÇÔ¼ö´Ù. ÇÁ·Î¼¼½º°¡ /proc ÆÄÀÏ¿¡ ¹«¾ð°¡¸¦ ÇÏ·Á°í ÇÒ ¶§¸¶´Ù, ÀÌ ÇÔ¼ö´Â È£Ã⠵ȴÙ. ±×¸®°í ÀÌ ÇÔ¼ö´Â ÀÌ Á¢±ÙÀ» Çã¿ëÇÒ °ÍÀΰ¡ ¸» °ÍÀΰ¡¸¦ °áÁ¤ÇÏ°Ô µÈ´Ù. ´çÀåÀº À̰ÍÀÌ ÇöÀç »ç¿ëÀÚÀÇ uid¿Í ÇàÀ§(operation) ÀÚü¿¡¸¸ ±Ù°Å ÇÏÁö¸¸, (±×¸®°í À̰ÍÀº ÇöÀç ½ÇÇàµÇ´Â ÇÁ·Î¼¼½ºÀÇ Á¤º¸¸¦ ´ã°í ÀÖ´Â ±¸Á¶Ã¼ÀÇ Æ÷ÀÎÅÍ¿¡¼ ã¾Æ Áú ¼ö ÀÖ´Â °Íµé) À̰ÍÀº ÇÁ·Î¼¼½º°¡ ¹«¾ùÀ» ÇÏ´Â °ÍÀΰ¡, ÀÛ¾÷ ½Ã°¢, ¸¶Áö¸·À¸·Î ¹«¾ùÀ» ÀÔ·Â ¹Þ¾Ò´Â°¡ µî, ¿ì¶ó±â ¿øÇÏ´Â ¾î¶² °Í¿¡ ±Ù°ÅÇÒ ¼öµµ ÀÖ´Ù.
ÀÎÅÚ ¾ÆÅ°ÅØÃÄ¿¡¼(¹°·Ð ´Ù¸¥ ÇÁ·Î¼¼¼ ÇÏ¿¡¼´Â ´Þ¶óÁú ¼öµµ ÀÖÁö¸¸) put_user() ¸ÅÅ©·Î¿Í get_user()¸ÅÅ©·Î¸¦ »ç¿ëÇÏ´Â ÀÌÀ¯´Â ¸®´ª½ºÀÇ ¸Þ¸ð¸®°¡ ¼¼±×¸ÕÆ® À̱⠶§¹®ÀÌ´Ù. Æ÷ÀÎÅÍ ÀÚü´Â À¯´ÏÅ©ÇÑ ¸Þ¸ð¸® À§Ä¡¸¦ Áö½ÃÇÒ ¼ö ¾ø°í, ¸Þ¸ð¸® ¼¼±×¸ÕÆ® À§Ä¡¸¸ Áö½ÃÇÒ ¼ö ÀÖ´Ù. ¶ÇÇÑ ¾î´À ¸Þ¸ð¸® ¼¼±×¸ÕÆ®¸¦ »ç¿ëÇÒ ¼ö ÀÖ´ÂÁö ¾Ë Çʿ䰡 ÀÖ´Ù. Ä¿³ÎÀ» À§ÇÑ ¸Þ¸ð¸® ÇϳªÀÇ ¼¼±×¸ÕÆ®°¡ ÀÖ°í, °¢ ÇÁ·Î¼¼½ºµé¸¶´Ù ÇϳªÀÇ ¼¼±×¸ÕÆ®°¡ Á¸ÀçÇÑ´Ù.
ÇÁ·Î¼¼½º ÀÚ½ÅÀÇ ¸Þ¸ð¸® ¼¼±×¸ÕÆ®¿¡¸¸ Á¢±ÙÀÌ °¡´ÉÇÏ´Ù. ±×·¡¼ ÀϹÝÀûÀÎ ÇÁ·Î±×·¥ÀÌ ÇÁ·Î¼¼½º·Î¼ ½ÇÇàµÉ ¶§ ¼¼±×¸ÕÆ®¿¡ °üÇØ ½Å°æ ¾²Áö ¾Ê¾Æµµ µÈ´Ù. Ä¿³Î ¸ðµâÀ» ÀÛ¼ºÇÒ ¶§, ÀϹÝÀûÀ¸·Î ½Ã½ºÅÛ¿¡ ÀÇÇØ ÀÚµ¿À¸·Î ´Ù·ïÁö´Â Ä¿³Î ¸Þ¸ð¸® ¼¼±×¸ÕÆ®¿¡ Á¢±ÙÇϱ⸦ ¿øÇÑ´Ù. ±×·¯³ª ¸Þ¸Ó¸® ¹öÆÛÀÇ ³»¿ëÀÌ ÇöÀç ½ÇÇà ÁßÀÎ ÇÁ·Î¼¼½º¿Í Ä¿³Î »çÀÌ¿¡¼ Àü´Þ µÇ¾ß ÇÒ ¶§, Ä¿³Î ÇÔ¼ö´Â ÇÁ·Î¼¼½º ¼¼±×¸ÕÆ®¿¡ ÀÖ´Â ¸Þ¸ð¸® Æ÷ÀÎÅ͸¦ ¹Þ°Ô µÈ´Ù. put_user() ¸ÅÅ©·Î¿Í get_user() ¸ÅÅ©·Î°¡ ±× ¸Þ¸ð¸®¿¡ Á¢±Ù °¡´ÉÄÉ ÇØÁØ´Ù.
Example 6-1. procfs.c
/* procfs.c - create a "file" in /proc, which allows both input and output. */ #include <linux/kernel.h> /* We're doing kernel work */ #include <linux/module.h> /* Specifically, a module */ /* Necessary because we use proc fs */ #include <linux/proc_fs.h> |









ÀÌ´Ù. Ä¿³Î2.0.35ÀÌÀü ¿¡´Â ÀÌ ¸ÅÅ©·Î°¡ ¾ø´Ù´Â °ÍÀ» ¾Ë¾ÆµÎÀÚ. ±¸½Ä Ä¿³ÎÀ» Áö¿øÇÏ´Â ¸ðµâÀ» ÀÛ¼ºÇϰíÀÚ ÇÑ´Ù¸é, ´ÙÀ½°ú °°ÀÌ Á¤ÀÇ ÇØ¾ß ÇÑ´Ù.