4. µð¹ÙÀ̽º µå¶óÀ̹ö
µð¹ÙÀ̽º µå¶óÀ̹ö¶õ?.
- ÀåÄ¡¸¦ Á÷Á¢ÀûÀ¸·Î ´Ù·ç´Â ¼ÒÇÁÆ®¿þ¾î·Î Çϵå¿þ¾îÀûÀÎ ÀåÄ¡°¡ ¾Æ´Ï´õ¶óµµ ½ºÇÁÆ®¿þ¾î ÀûÀÎ ÀåÄ¡¸¦ ¸¸µé¾î ´Ù·ê ¼öµµ ÀÖ´Ù.
- Ä¿³Î ¸ðµå¿¡¼ ½ÇÇàµÇ°í,¸Þ¸ð¸®¿¡ »óÁÖÇϸç, ½º¿ÒµÇÁö ¾Ê´Â´Ù.
-µð¹ÙÀ̽º µå¶óÀ̹ö¸¦ ÅëÇÏ¿© ÀåÄ¡¸¦ ÆÄÀÏó·³ ´Ù·ê ¼ö ÀÖ´Ù.
4.1. ÀåÄ¡ÀÇ Á¾·ù.
4.1.1 ¹®ÀÚ ÀåÄ¡(character device)
¹öÆÛ¸¦ ÅëÇÏÁö ¾Ê°í,¹Ù·Î ÀÐ°í ¾µ ¼ö ÀÖ´Â ÀåÄ¡ÀÌ´Ù.
terminal, serial, parallel, keyboard, mouse, PC speaker µîÀÌ ÀÖ´Ù.
4.1.2 ºí·Ï ÀåÄ¡(block device)
¹öÆÛ Ä³½Ã¸¦ ÅëÇØ ÀÔÃâ·ÂÀ» Çϸç,ÀåÄ¡ÀÇ ¾îµðµç Á¢±ÙÀÌ °¡´ÉÇÏ´Ù.
ºí·Ï´ÜÀ§·Î ÀÔ・Ãâ·ÂÀ» Çϸç ÆÄÀϽýºÅÛÀ» ±¸ÃàÇÒ ¼ö ÀÖ´Ù.
floppy disk, hard disk, Ram disk, CD-ROM µîÀÌ ÀÕ´Ù.
4.1.3 ³×Æ®¿÷ ÀåÄ¡(network device)
³×Æ®¿÷ ÆÐŶÀ» ¼Û・¼ö½ÅÇÒ ¼ö ÀÖ´Â ÀåÄ¡
ehternet, ppp µîÀÌ ÀÖ´Ù.
4.2 Ä¿³Î ¸ðµâ(kernel module)
¸®´ª½º ½Ã½ºÅÛ ºÎÆÃÈÄ¿¡ µ¿ÀûÀ¸·Î ·Îµå,¾ð·ÎµåÇÒ ¼ö ÀÖ´Â Ä¿³ÎÀÇ ±¸¼º ¿ä¼ÒÀÌ´Ù.Ä¿³ÎÀ» ´Ù½Ã ÄÄÆÄÀÏÇϰųª ½Ã½ºÅÛÀ» ¸®ºÎÆÃÇÏÁö ¾Ê°íµµ Ä¿³ÎÀÇ ÀϺκÐÀ» ±³Ã¼ÇÒ ¼ö ÀÖ´Ù.
µð¹ÙÀ̽º µå¶óÀ̹Ù, ÆÄÀÏ ½Ã½ºÅÛ, ³×Æ®¿÷ ÇÁ·ÎÅäÄÝ µîÀÌ ¸ðµâ·Î ¸¸µé¾îÁø´Ù.
4.3 ¸ðµâ ÇÁ·Î±×·¥°ú ÀÏ¹Ý ÀÀ¿ë ÇÁ·Î±×·¥ÀÇ Â÷ÀÌ
: main() ÇÔ¼ö°¡ ¾ø´Ù
·Îµå¿Í ¾ð·Îµå½Ã¿¡ ºÒ¸®´Â startup / cleanup ÇÔ¼ö°¡ Á¸ÀçÇÑ´Ù.
- startup : ini init_module(void)
¼º°øÇϸé 0, ½ÇÆÐÇÏ¸é ±× ¿ÜÀÇ °ªÀ» µ¹·ÁÁØ´Ù.
- cleanup : void cleanup_module(void)
: ¸ðµâ ÇÁ·Î±×·¡¹Ö½Ã¿¡ ÁÖÀÇÇÒ »çÇ×
- fault handling -¸ðµâÀº Ä¿³Î¸ðµå¿¡¼ µ¿ÀÛÇϹǷΠ¸Þ¸ð¸® Á¢±Ù¿¡ ´ëÇÑ ¾î¶°ÇÑ º¸È£µµÇÏÁö ¾ÊÀ¸¸ç, ¸ðµâ¿¡¼ ¹ß»ýÇÑ ¿¡·¯´Â ½Ã½ºÅÛ¿¡ Ä¡¸íÀûÀ̹ǷΠ¸Þ¸ð¸®¸¦ ´Ù·ê ¶§ ÁÖÀÇ ÇÏ°í, Ä¿³Î ÇÔ¼ö È£Ãâ½Ã¿¡´Â ¹Ýµå½Ã ¿¡·¯Äڵ带 °Ë»çÇÏ°í ¿¡·¯¸¦ ó¸®ÇØ¾ß ÇÑ´Ù.
-½Ç¼ö ¿¬»êÀ̳ªMMX ¸í·ÉÀº »ç¿ëÇÒ ¼ö ¾ø´Ù. ½Ç¼ö ¿¬»êÀº Á¤¼ö ¿¬»êÀ¸·Î ´ëüÇÏ¿© ó¸®Çϵµ·Ï ÇÑ´Ù.
-Ä¿³ÎÀÌ »ç¿ëÇÏ´Â ½ºÅà ũ±â´Â Á¦ÇѵǾî ÀÖ°í(2 page), ÀÎÅÍ·´Æ® Çڵ鷯µµ µ¿ÀÏÇÑ ½ºÅÃÀ» »ç¿ëÇϹǷΠ½ºÅÃÀ» ¸¹ÀÌ »ç¿ëÇÏ¸é ¾ÈµÈ´Ù. ½ºÅÿ¡ Å« ¹è¿À» ÀâÀ¸¸é ¾ÈµÇ°í(µ¿ÀûÀ¸·Î ÇÒ´ç¹Þµµ·Ï ÇØ¾ß ÇÑ´Ù). recursionÀÌ ¸¹ÀÌ ÀϾÁö ¾Êµµ·Ï ÁÖÀÇÇÑ´Ù.
-´Ù¸¥ Ç÷§Æû°ú °í·ÁÇØ¾ß ÇÑ´Ù.¸®´ª½º´Â ¿©·¯ ȯ°æ¿¡¼ »ç¿ëµÉ ¼ö ÀÖÀ¸¹Ç·Î 32ºñÆ®¿Í 64ºñÆ® ȯ°æ°ú byte order µîÀ» ¸ðµÎ °í·ÁÇØ¾ß Çϸç CPU¿¡ Æ¯ÈµÈ ÄÚµå´Â ÁÙÀ̵µ·ÏÇÑ´Ù.
4.4 ¸ðµâ °ü·Ã ÇÁ·Î±×·¥
- lsmod : ·ÎµåµÈ ¸ðµâÀÇ ¸ñ·ÏÀ» º¸¿©ÁØ´Ù.
- indmos : Ä¿³Î ¸ðµâÀ» ·ÎµåÇÑ´Ù.
- rmmod : Ä¿³Î ¸ðµâÀ» ¾ð·ÎµåÇÑ´Ù.
- depmod : Ä¿³Î ¸ðµâ°£ÀÇ ÀÇÁ¸¼ºÀ» °Ë»çÇÑ´Ù.
- modprobe : ¸ðµâÀ» º¸´Ù ³ôÀº ¼öÁØ¿¡¼ ´Ù·ç´Â ÇÁ·Î±×·¥À¸·Î ÀÇÁ¸¼º¿¡ µû¶ó¼ ÇÊ¿äÇÑ °æ¿ì ´Ù¸¥ ¸ðµâÀ» ·Îµå, ¾ð·Îµå¸¦ ÇÑ´Ù.
- kerneld : Ä¿³Î ¸ðµâ ·Î´õ, ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ ¾Æ´Ñ Ä¿³Î ¾²·¹µåÀÇ ÀÏÁ¾À¸·Î Ä¿³Î¿¡¼ ¸ðµâÀ» ÇÊ¿ä·Î ÇÒ ¶§ ÀÚµ¿À¸·Î ¸ðµâÀ» ·Î±×ÇÏ°í, ÇÊ¿ä¾øÀ» ¶§ ¾ð·ÎµåÇÑ´Ù. modprobe ÇÁ·Î±×·¥À» ÀÌ¿ëÇÏ¿© ·Îµå, ¾ð·Îµå¸¦ ÇÑ´Ù.
4.2. µð¹ÙÀ̽º µå¶óÀ̹ö ¸¸µé±â
4.2.1 °£´ÜÇÑ ¸ðµâ ÇÁ·Î±×·¥¹ÖÇϱâ-1
¸®´ª½º¿¡ Àͼ÷ÇÏÁö ¾ÊÀº »ç¶÷Àº µð¹ÙÀ̽º µå¶óÀ̹ö°¡ Ä¿³ÎÇÔ¼öÀ̱⠶§¹®¿¡ µð¹ÙÀ̽º µå¶óÀ̹ö¸¦ ¸¸µé±âÀ§Çؼ ´Â Àüü Ä¿³ÎÀ» ´Ù½Ã ÄÄÆÄÀÏÇØ¾ß ÇÑ´Ù°í »ý°¢ÇÒÁö ¸ð¸£³ª, ¸®´ª½º¿¡¼´Â ÀÌ·¯ÇÑ µð¹ÙÀ̽º µå¶óÀ̹ö¸¦ Ä¿³Î¿¡ ½±°Ô »ðÀÔÇÒ ¼ö ÀÖµµ·Ï Ä¿³Î¸ðµâ¹æ½ÄÀ» Áö¿øÇÏ°í ÀÖ´Ù. ¿ì¸®°¡ »ç¿ëÇÏ°í ÀÖ´Â ´ëºÎºÐÀÇ ¸®´ª½º ½Ã½ºÅÛ¿¡´Â ÀÌ¹Ì °¢Á¾ Çϵå¿þ¾î Ä«µå¿¡ ´ëÇÑ µð¹ÙÀ̽º µå¶óÀ̹ö ¸ðµâÀÌ ¼³Ä¡µÇ¾î Àֱ⠶§¹®¿¡ ´ÙÀ½°ú °°Àº ¸í·ÉÀ¸·Î ÇöÀç ¼³Ä¡µÇ¾î ÀÖ´Â ¸ðµâÀ» È®ÀÎÇØ º¼ ¼ö ÀÖ´Ù.
/sbin/lsmod
±×·³ ÀÌÁ¦ºÎÅÍ °£´ÜÇÑ Ä¿³Î¸ðµâÀ» ¸¸µé°í ÀÌ°ÍÀ» Ä¿³Î¿¡ ¼³Ä¡ÇØ º¸ÀÚ.
Ä¿³Î¸ðµâÀ» ¸¸µé±â À§Çؼ´Â ¹Ýµå½Ã init_module()°ú cleanup_module() ÇÔ¼ö°¡ Á¤ÀǵǾî¾ß ÇÏ°í, kernel_version ¿¡ °üÇÑ Á¤º¸¸¦ ´ã°íÀÖ´Â character º¯¼ö kernel_version[] ÀÌ Á¤ÀǵǾî¾ß ÇÑ´Ù.¾Æ·¡¿¡ ¼Ò½º¸¦ Àû¾î ³õ¾Ò´Ù.
kernel_version.c ÇÁ·Î±×·¥¼Ò½º
char kernel_version[]="2.0.35";
make_module.c ÇÁ·Î±×·¥¼Ò½º
#include <linux/kernel.h>
int init_module(void)
{
extern char kernel_version[];
return 0;
}
void cleanup_module(void)
{
}
À§ÀÇ ¼Ò½ºÄڵ带 º¸µí ÆíÀÇ»ó µÎ°³ÀÇ ÈÀÏ·Î ºÐ¸®ÇßÀ¸¸ç, Ä¿³Î¹öÀüÀº ÀÚ½ÅÀÇ ¸®´ª½º ½Ã½ºÅÛÀÇ Ä¿³Î¹öÀüÀ» ÀÔ·ÂÇÏ¸é µÈ´Ù. ÀÌ Äڵ带 ÄÄÆÄÀÏÇϱâ À§Çؼ ´ÙÀ½°ú °°Àº Makefile À» »ç¿ëÇÏ¿´´Ù.
MakefileÀÇ ¿¹
LD= ld -r
CFLAGS=$(INCLUDE) -D__KERNEL__ -DLINUX -O6
SRCS=kernel_version.c make_module.c
OBJS=kernel_version.o make_module.o
my_driver.o: $(OBJS)
$(LD) -o my_driver.o $(OBJS)
clean:
rm -f *.o
À̻󿡼 º¸µíÀÌ Ä¿³Î¸ðµâÀº main ÇÔ¼ö¸¦ °®°í ÀÖÁö ¾ÊÀ¸¸ç, ½ÇÇàÈÀÏÀÌ ¾Æ´Ñ ¿ÀºêÁ§Æ®ÈÀÏ·Î ¸¸µé¾îÁø´Ù. ÀÌÁ¦ make ¸¦ ½ÇÇà½ÃÅ°¸é my_driver.o ¿ÀºêÁ§Æ®ÈÀÏÀÌ »ý¼ºµÉ°ÍÀÌ´Ù.
ÀÌÁ¦ ÀÌ ¿ÀºêÁ§Æ®ÈÀÏÀ» Ä¿³Î¿¡ »ðÀÔ½ÃÄÑ¾ß Çϴµ¥ ±× ¸í·ÉÀº ´ÙÀ½°ú °°´Ù.
/sbin/insmod my_driver.o
¸ðµâÀ» »ðÀÔÇÏ¿´À¸¸é
/sbin/lsmod
¸¦ ÀÔ·ÂÇÏ¿© »ðÀÔµÈ ¸ðµâÀ» È®ÀÎÇÒ ¼ö ÀÖ´Ù.
ÀÌÁ¦ init_moduleÀ» ´ÙÀ½°ú °°ÀÌ ¼öÁ¤ÇÏ¿©, ¸ðµâ »ðÀԽÿ¡ ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÏ°í·Ï Çغ¸ÀÚ.
int init_module(void)
{
extern char kernel_version[];
printk("module test₩n");
return 0;
}
¿©±â¼ ÁÖÀÇÇÒ Á¡Àº ÀϹÝÀûÀΠǥÁØÃâ·ÂÇÔ¼ö printf ´ë½Å printk¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù´Â °ÍÀÌ´Ù.ÀÌÁ¦ Ä¿³Î ¸ðµâÀ» °íÃƱ⠶§¹®¿¡make ¸¦ ÀÔ·ÂÇÏ¿© ÀçÄÄÆÄÀÏ ÇÑ ÈÄ »õ·Î¿î my_driver.o ¸¦ Ä¿³Î¿¡ »ðÀÔ½ÃÄÑ¾ß ÇÑ´Ù. ±×·¯±â À§Çؼ´Â ±âÁ¸¿¡ ¼³Ä¡µÈ my_driver.o ¸¦ Á¦°ÅÇØ¾ß ÇÑ´Ù.ÀÌ ÀÛ¾÷Àº ´ÙÀ½°ú °°´Ù.
/sbin/rmmod my_driver (my_driver.o °¡ ¾Æ´Ô)
ÀÌÁ¦ ´Ù½Ã
/sbin/insmod my_driver.o
¸¦ ÀÔ·ÂÇÏ¿© Ä¿³Î¿¡ ¸ðµâÀ» »ðÀÔÇغ¸ÀÚ.ÀÌÁ¦ ¸ðµâ »ðÀÔ°ú µ¿½Ã¿¡ Å͹̳ο¡ ¸Þ¼¼Áö°¡ Ãâ·ÂµÇ´Â °ÍÀ» È®ÀÎÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù.(Ä¿³Î ¸Þ½ÃÁö¸¦ È®ÀÎÇÏ·Á¸é X server °¡ ¶° Àִ ȸ鿡¼´Â º¼ ¼ö ¾ø°í,Å͹̳ηΠȸéÀ» ÀüȯÇؾßÇÑ´Ù.)
4.2.2. ¸ðµâ ÇÁ·Î±×·¥¹ÖÇϱâ-2
4.2.1Àå¿¡¼´Â ´Ü¼øÇÑ Ä¿³Î¸ðµâÀ» ¸¸µé°í ¼³Ä¡ÇÏ´Â ¹æ¹ýÀ» ´Ù·ç¾ú´Âµ¥, À̹ø¿¡´Â ½ÇÁ¦ µð¹ÙÀ̽º¿Í ÀÌ Ä¿³Î ¸ðµâÀ» ¿¬°á½ÃÅ°´Â ¼Ò½ºÄڵ带 ¸¸µé¾îº¸ÀÚ.
¸®´ª½º¿¡¼´Â ¸ðµç Çϵå¿þ¾î ÀåÄ¡´Â ÈÀÏ·Î Ãë±ÞÇÏ°í ´Ù·ç°Ô µÈ´Ù. /dev/ µð·ºÅ丮¸¦ º¸¸é °¢Á¾Çϵå¿þ¾î ÀåÄ¡¿¡ ¿¬°áµÈ ÈÀÏÀ» º¼ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î ½Ã¸®¾óÆ÷Æ®ÀÇ °æ¿ì´Â /dev/cua0 ¿Í °°Àº ÀåÄ¡ÈÀÏ·Î Á¤ÀǵǴµ¥, ´ÙÀ½ °ú °°ÀÌ list¸¦ Çغ¸¸é
ls -l /dev/cua0
´ÙÀ½°ú °°Àº Ãâ·ÂÀ» ¾òÀ» ¼ö ÀÖ´Ù.
crw-rw---- 1 root uucp 5, 64 Aug 23
11:57 /dev/cua0
¿©±â¿¡¼ ÀϹÝÀûÀÎ º¸ÅëÈÀÏÀ̳ª µð·ºÅ丮ÈÀÏÀÌ - ³ª d ·Î ½ÃÀ۵Ǵµ¥ ºñÇØ c ·Î ½ÃÀ۵Ǵ °ÍÀ» º¼ ¼ö ÀÖ´Ù. ÀÌ´Â ½Ã¸®¾óÆ÷Æ®°¡ ¹®ÀÚÇü(character) µð¹ÙÀ̽º ÀÓÀ» ³ªÅ¸³½´Ù. µð¹ÙÀ̽º´Â ÀϹÝÀûÀ¸·Î ºí·Ï µð¹ÙÀ̽º¿Í ¹®ÀÚÇü µð¹ÙÀ̽º·Î ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. ÀÌ´Â Çϵå¿þ¾îÀÚü°¡ ¹®ÀÚ µð¹ÙÀ̽º¿Í ºí·Ïµð¹ÙÀ̽º·Î ³ª´©¾îÁ® ÀÖ´Ù´Â °ÍÀÌ ¾Æ´Ï¶ó µð¹ÙÀ̽º ÈÀÏÀ̳ª µð¹ÙÀ̽º µå¶óÀ̹ö¸¦ Á¤ÀÇÇÒ ¶§, ¹®ÀÚÇüÀ̳ª ºí·ÏÇüÀ¸·Î ¼³Á¤ÇÒ ¼ö ÀÖ´Ù´Â ¸»ÀÌ´Ù.(ÇÑ Çϵå¿þ¾î¿¡ ´ëÇÏ¿© µ¿½Ã¿¡ ¹®ÀÚÇü°ú ºí·ÏÇüÀÇ ÁöÁ¤µµ °¡´É) ¹®ÀÚÇü µð¹ÙÀ̽º´Â À¯ÀúÇÁ·Î±×·¥ÀÌ read ³ª write µîÀÇ ½Ã½ºÅÛ ÄÝÀ» È£ÃâÇÒ ¶§¸¶´Ù Ä¿³ÎÀÇ Àбâ,¾²±â ·çƾÀÌ È£ÃâµÇ´Â ¹æ½ÄÀÌ°í,ºí·ÏÇüÀÇ °æ¿ì ¼³Á¤µÈ Á¶°ÇÀÌ ¸¸Á·µÇ¸é Ä¿³ÎÀÌ ÀÚµ¿ÀûÀ¸·Î ƯÁ¤ ·çƾÀ» È£ÃâÇÏ´Â ¹æ½ÄÀÌ´Ù. ¿ì¸®´Â °£´ÜÈ÷ ¹®ÀÚÇü µð¹ÙÀ̽º µå¶óÀ̹ö¿¡ ´ëÇؼ¸¸ ¾ð±ÞÇϱâ·Î ÇÏ°Ú´Ù.
µð¹ÙÀ̽º¸¦ À§ÇÑ ÀåÄ¡ÈÀÏÀ» ¸¸µé¾î º¸ÀÚ.½© »ó¿¡¼ ´ÙÀ½°ú °°ÀÌ ÀÔ·ÂÇÏ¿©º¸ÀÚ.
mknod /dev/mydev c 120 0
¿©±â¼ c ´Â ¹®ÀÚ µð¹ÙÀ̽º¸¦ ¸¸µé±â À§ÇÑ °ÍÀÌ°í, 120 Àº µð¹ÙÀ̽ºÀÇ major ¹øÈ£ 0 minor ¹øÈ£ÀÌ´Ù.
major ¹øÈ£¿Í minor ¹øÈ£ÀÇ µÎ°³¸¦ »ç¿ëÇÏ´Â ÀÌÀ¯´Â °°Àº Çϵå¿þ¾îÄ«µå¿¡ ¿©·¯°³ÀÇ ÀåÄ¡°¡ ºÎÂøµÉ ¼ö Àֱ⠶§¹®Àε¥,¿ì¸®ÀÇ °æ¿ì´Â ÇÑ°³¸¸À» °í·ÁÇÑ0À» ÀÔ·ÂÇÏ¿´´Ù.
major ¹øÈ£´Â ¸®´ª½ºÀÇ °æ¿ì 1 ºÎÅÍ 255 ±îÁö ÇÒ´çÇÒ ¼ö Àִµ¥ ´Ù¸¥ µð¹ÙÀ̽ºÀÇ major ¹øÈ£¿Í Ãæµ¹µÇ¾î¼´Â ¾ÊµÇ±â ¶§¹®¿¡ Å×½ºÆ®¸¦ À§ÇØ ÇÒ´çµÈ 60-63, 120-127, 240-254 ÁßÀÇ ÇÑ ¹øÈ£¸¦ »ç¿ëÇÏ´Â °ÍÀÌ ÁÁ´Ù. ±×·± ´ÙÀ½ ÀÌ ÀåÄ¡ÈÀÏÀÌ Àß ¸¸µé¾îÁ³´ÂÁö ´ÙÀ½°ú °°Àº ¸í·ÉÀ¸·Î È®ÀÎÇغ¸ÀÚ
ls -l /dev/mydev
crw-r--r-- 1 root root 120, 0 Aug 30
11:24 /dev/mydev
´ÙÀ½°ú °°Àº Ãâ·ÂÀ» ¾ò´Â´Ù¸é,ÀåÄ¡ÈÀÏÀÌ ¼º°øÀûÀ¸·Î ¸¸µé¾îÁø °ÍÀÌ´Ù.
ÀÌÁ¦ ÀÌ µð¹ÙÀ̽º¿Í ¿ì¸®°¡ ÀÛ¼ºÇÑ Ä¿³Î¸ðµâÀ» ¿¬°á½ÃÅ°±â À§ÇØ make_module.c ¸¦ ´ÙÀ½°ú °°ÀÌ ¼öÁ¤ÇÏ°Ú´Ù.
make_module.c ¼Ò½ºÄÚµå
#include <linux/kernel.h>
#include <linux/fs.h>
extern int mydevread(struct inode *, struct file *, char *,int);
extern int mydevwrite(struct inode *, struct file *,char *,int);
extern int mydevioctl(struct inode *, struct file *, unsigned int, unsigned long);
extern int mydevopen(struct inode *, struct file *);
extern void mydevclose(struct inode *, struct file *);
struct file_operations mydev_fops = {
NULL,
mydevread,
mydevwrite,
NULL,
NULL,
mydevioctl,
NULL,
mydevopen,
mydevclose
};
int mydevmajor = 120;
int init_module(void)
{
extern char kernel_version[];
if( register_chrdev
(mydevmajor,"mydev",&mydev_fops) ){
printk(" cannot get Major O₩n", mydevmajor);
}
return 0;
}
void cleanup_module(void)
{
unregister_chrdev(mydevmajor,"mydev");
}
ÀÌ Äڵ忡¼ º¸µí ÀåÄ¡ÈÀÏ°ú µð¹ÙÀ̽ºµå¶óÀ̹ö¸¦ ¿¬°á½ÃÄÑÁÖ´Â ¿ªÇÒÀ» ÇÏ´Â ÇÔ¼ö´Â ¹Ù·Î
register_chrdev(mydevmajor,"mydev",&mydev_fops))
ÀÌ´Ù. ÀÌ ÇÔ¼öÀÇ Ã¹¹ø° Àμö´Â ¹Ù·Î µð¹ÙÀ̽º ÈÀÏÀÇ major ¹øÈ£(=120) ,ÀÌ°í µÎ¹ø° Àμö´Â ÀåÄ¡ÈÀÏ À̸§ÀÌ´Ù. 3¹ø° Àμö´Â file_operations ±¸Á¶Ã¼ÀÇ Æ÷ÀÎÅÍÀε¥ ÀÌ Æ÷ÀÎÅÍ´Â »ç¿ëÀÚ ÇÁ·Î¼¼½º°¡ ½Ã½ºÅÛÄÝÀ» ÇÒ ¶§ ´ëÀÀÇؼ È£ÃâµÇ´Â ÇÔ¼öÀÇ ÇÚµé(ÁÖ¼Ò)¸¦ ´ã°íÀÖ´Ù. ÀÌ ±¸Á¶
ü¿¡ ¸ðµç ÇÔ¼ö¸¦ ´Ù Á¤ÀÇÇÒ ÇÊ¿ä´Â ¾ø°í, µð¹ÙÀ̽ºÁ¦¾î¿¡ ÇÊ¿äÇÑ ÇÔ¼ö¸¸À» Á¤ÀÇÇÏ°í ±× ÇÚµéÀ» ÇÒ´çÇØ ÁÖ¸é µÇ´Âµ¥, ¿ì¸®´Â ±âº»ÀûÀÎ ÇÔ¼ö read, write, open, close ±×¸®°í À¯¿¬ÇÑ ½Ã½ºÅÛ ÄÝÀ» °¡´ÉÇÏ°Ô ÇØÁÖ´Â ioctl À» Æ÷ÇԽðå´Ù.
ÀÌÁ¦ ÀÌ·¯ÇÑ ½Ã½ºÅÛ ÄÝ¿¡ ´ëÀÀÇÏ´Â ÇÔ¼ö¿¡ ´ëÇÑ Äڵ带 ÀÛ¼ºÇØ¾ß Çϴµ¥, ÀÌ ÄÚµå´Â mydev_fops.c ÈÀÏ·Î º°µµ·Î ºÐ¸®½ÃÄ×´Ù.
mydev_fops.c ÀÇ ¼Ò½º
#define OK 0
int mydevread(struct inode *inode, struct file *file,char *buffer,int count)
{
printk("read₩n");
return(OK);
}
int mydevwrite(struct inode *inode, struct file *file, char *buffer,int count)
{
printk("write₩n");
return(OK);
}
int mydevioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
long arg)
{
printk("ioctl₩n");
return(OK);
}
int mydevopen(struct inode *inode, struct file *file)
{
printk("open₩n");
return(OK);
}
void mydevclose(struct inode *inode, struct file *file)
{
printk("close₩n");
}
À§¿¡¼ º¸µíÀÌ ½Ã½ºÅÛ ÄÝÀÇ ´ëÀÀÇÔ¼öÀÌÁö¸¸ ¾ÆÁ÷Àº ¾Æ¹«·± Çϵå¿þ¾î¿Íµµ ¿¬°ü½ÃÅ°Áö ¾Ê¾ÒÀ¸¸ç, ´Ü¼øÈ÷ ÇÔ¼ö°¡ ÀÌ»ó¾øÀÌ È£ÃâµÇ´ÂÁö¸¦ üũÇϱâ À§ÇØ °£´ÜÇÑ Ãâ·Â¸¸À» Çϵµ·Ï ±¸¼ºÇÏ¿´´Ù.
»õ·Î¿î ÈÀÏÀ» ÀÛ¼ºÇÏ¿´À¸¹Ç·Î Makefile ¿¡ ÀÌ ÈÀÏÀ» Ãß°¡ÇÏ¿© ´ÙÀ½°ú °°ÀÌ ¼öÁ¤ÇÏ¿´´Ù.
¼öÁ¤µÈ Makefile
LD= ld -r
CFLAGS=$(INCLUDE) -D__KERNEL__ -DLINUX -O6
SRCS=kernel_version.c make_module.c mydev_fops.c
OBJS=kernel_version.o make_module.o mydev_fops.o
my_driver.o: $(OBJS)
$(LD) -o my_driver.o $(OBJS)
clean:
rm -f *.o
ÀÌÁ¦ 'make clean' À¸·Î *.o ÈÀÏÀ» »èÁ¦ÇÑ ÈÄ'make' ·Î »õ·Î¿î my_driver.o ¸¦ ¸¸µé
¾î¶ó.
´ÙÀ½À¸·Î
/sbin/rmmod my_driver
/sbin/insmod my_driver.o
¸¦ ÇÏ¿© »õ·Î¿î µå¶óÀ̹ö¸ðµâÀ» Ä¿³Î¿¡ ¼³Ä¡ÇÏ¿´´Ù.
ÀÌÁ¦ ÀÌ µð¹ÙÀ̽º µå¶óÀ̹ö¸¦ È£ÃâÇÏ°Ô µÉ À¯Àú ÇÁ·Î±×·¥À» ÀÛ¼ºÇغ¸ÀÚ. °¢ ¼ºê·çƾÀÌ Àß È£ÃâµÇ´ÂÁö¸¦ º¸±âÀ§Çؼ open, read, ioctl, write, close µîÀ» Çѹø¾¿ È£ÃâÇϵµ·Ï Çغ¸¾Ò´Ù.
user.c ¼Ò½ºÄÚµå
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
main()
{
int fd;
unsigned int cmd;
unsigned long arg;
char buf[100];
int count=0;
fd=open("/dev/mydev",O_RDWR);
read(fd,buf,1);
write(fd,buf,1);
ioctl(fd,cmd,arg);
close(fd);
}
ÀÌ ÄÚµå´Â °£´ÜÇϹǷΠº°µµÀÇ MakefileÀº ¸¸µéÁö ¾Ê°í ´ÙÀ½°ú °°ÀÌ ÄÄÆÄÀÏ ¸µÅ©½ÃÄѺ¸ÀÚ
gcc user.c -o user.exe
ÀÌÁ¦ ./user.exe ¸¦ ½ÇÇà½ÃÅ°¸é ÄܼÖȸé(X-server ȸ鿡¼´Â º¸ÀÌÁö ¾ÊÀ½, Å͹̳ηΠÀüȯÇؼ È®ÀÎ) ȸ鿡
open
read
write
ioctl
close
µîÀÇ ¸Þ½ÃÁö°¡ ³ª¿À¸é Áö±Ý±îÁöÀÇ °úÁ¤ÀÌ ¿Ï¼ºµÈ °ÍÀÌ´Ù.
Áö±Ý±îÁöÀÇ ³»¿ëÀ» ÀÌÇØÇÑ ´«Ä¡ºü¸¥ ÇÁ·Î±×·¡¸Ó¶ó¸é »ç¿ëÀÚ ÇÁ·Î±×·¥ÀÌ ¾î¶»°Ô Çϵå¿þ¾î¸¦ Á¦¾îÇÒ ¼ö ÀÖ´ÂÁö¸¦ ÁüÀÛÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù.
1. »ç¿ëÀÚ ÇÁ·Î±×·¥¿¡¼´Â Çϵå¿þ¾î¸¦ Á÷Á¢Á¦¾îÇÒ ¼ö ¾øÀ¸¹Ç·Î open, read,.. µîÀÇ ½Ã½ºÅÛÄÝÀ» È£ÃâÇÑ´Ù.
2. µð¹ÙÀ̽º µå¶óÀ̹ö´Â °¢ ½Ã½ºÅÛ ÄÝ¿¡ ¸Â´Â ÇÔ¼ö·çƾÀ» °®°í ÀÖÀ¸¹Ç·Î ½Ã½ºÅÛ ÄÝ¿¡ ´ëÀÀÇØ ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù. µð¹ÙÀ̽º µå¶óÀ̹ö´Â Ä¿³ÎÀÇ ÀϺÎÀ̱⠶§¹®¿¡ À̵é ÇÔ¼ö¿¡¼´Â Çϵå¿þ¾î¿¡ Á÷Á¢ Á¢±ÙÇÒ ¼ö ÀÖ´Ù.
3. ¸ðµâ ÇÁ·Î±×·¡¹ÖÇϱâ -Ä¿³Î¿¡ Æ÷ÇÔÇÏ¿© ÄÄÆÄÀÏÇÑ´Ù
ÇϳªÀÇ ¸ðµâÀ» ¸¸µé¾î Ä¿³Î°ú ÇÔ²² ÄÄÆÄÀÏ ÇÏ´Â ¹æ¹ý¿¡ ´ëÇؼ ¾Ë¾Æº»´Ù.
¿ì¼± °¡»óÀÇ Çϵå¿þ¾î¸¦ Çϳª Á¤Çϱâ·Î ÇÑ´Ù.ÀÌ Çϵå¿þ¾îÀÇ ¼º°ÝÀº ´ÙÀ½°ú °°´Ù.
¹®ÀÚ µð¹ÙÀ̽º(character device)ÀÌ´Ù.
ÀÎÅÍ·´Æ® ¹æ½ÄÀÌ´Ù.
Çϵå¿þ¾î¿¡´Â ÀÚüÀûÀÎ CPU°¡ ÀÖ´Ù.
PCÀÇ ¿î¿µÃ¼Á¦¿Í´Â shared memory ¹æ½ÄÀ¸·Î ±³½ÅÇÑ´Ù.
ÀÎÅÍ·´Æ®¿Í shared memory ´Â Ä«µå ¼³Á¤¿¡ µû¶ó ¹Ù²ð ¼ö Àֱ⠶§¹®¿¡
ºÎÆÃÇÒ ¶§³ª ¸ðµâ ÀûÀç ½Ã¿¡ ¿É¼ÇÀ¸·Î ¹Ù²Ü ¼ö ÀÖ´Ù.
µ¿½Ã¿¡ °°Àº Çϵå¿þ¾î¸¦ ´Ù¸¥ ÀÎÅÍ·´Æ®¸¦ ÁÖ°í2°³ ÀÌ»ó »ç¿ëÇÒ ¼ö ÀÖ´Ù.
À§¿Í ºñ½ÁÇÑ Çϵå¿þ¾î Áß¿¡ Ä¿³Î¿¡ Æ÷ÇÔ µÈ °ÍÀº Áö´ÉÇü ¸ÖƼ ½Ã¸®¾ó Æ÷Æ® Á¾·ù°¡ ÀÖ´Ù.Å©°Ô ¸»ÇÏ¸é »ç¿îµå µå¶óÀ̹öµµ Æ÷ÇÔ µÉ ¼ö ÀÖÀ» °ÍÀÌ´Ù.ÀÌ Á¤µµÀÇ Çϵå¿þ¾î¸¦ °¡Á¤ÇÑ´Ù¸é Ä¿³Î ÇÁ·Î±×·¡¹Ö¿¡ ÇÊ¿äÇÑ ´ëºÎºÐÀÇ Å×Å©´ÐÀÌ ¸ðµÎ µ¿¿øµÇ¾î¾ß ÇÒ °ÍÀÌ´Ù.
¹®ÀÚ µð¹ÙÀ̽º º¸´Ù ºí·° µð¹ÙÀ̽º°¡ Á»´õ º¹ÀâÇÏÁö¸¸ ¹öÆÛ ÀÔÃâ·Â¸¸ Á¦¿ÜÇÑ´Ù¸é Å©°Ô ´Ù¸£Áö ¾Ê´Ù. ÀÌ Çϵå¿þ¾î¸¦ my_device ¶ó°í ¸í¸íÇÏ°í ¸®´ª½º Ä¿³Î¿¡¼ Á¦´ë·Î µ¿ÀÛÇÏ°Ô Çϱâ À§Çؼ ÇÊ¿äÇÑ ÀÛ¾÷À» Çغ¸µµ·Ï ÇÑ´Ù.
4.3.1 ÀåÄ¡ Ư¼öÆÄÀÏ
ÇÁ·Î±×·¡¹ÖÀ» ÇÒ ¶§ ¾î¶² ÀåÄ¡¸¦ ¿±â À§ÇØ open ÇÔ¼ö¸¦ È£Ãâ ÇÑ´Ù°í ÇÏÀÚ. Ç¥ÁØ ¶óÀ̺귯¸®¿¡ ÀÖ´Â open À̶ó´Â ÇÔ¼ö¸¦ »ç¿ëÇϸé ÀÌ ÇÔ¼ö´Â Ä¿³Î¿¡ ½Ã½ºÅÛ È£ÃâÀ» ÇÏ°í Ä¿³ÎÀº ÀÌ È£ÃâÀÌ ¿ä±¸ÇÏ´Â ÆÄÀÏ¿¡ ´ëÇÑ ¿äû ÀÛ¾÷À» ó¸®ÇÑ´Ù. À¯´Ð½ºÀÇ Æ¯¼º»ó ¸ðµç µð¹ÙÀ̽ºÀÇ ÀÔÃâ·ÂÀº ÆÄÀÏ ÀÔÃâ·Â°ú Â÷ÀÌ°¡ ¾ø´Ù. ¿ì¸®°¡ ¸¸µé¾î¾ß ÇÏ´Â °ÍÀº Ãß»óȵǾî ÀÖ´Â ÆÄÀÏ ÀÔÃâ·ÂÀÌ ÃÖÁ¾ÀûÀ¸·Î È£ÃâÇÏ°Ô µÉ °¢ ÀåÄ¡¿¡ °íÀ¯ÇÑ ¿±â ¹æ¹ý¿¡ °üÇÑ°ÍÀÌ´Ù. ¾î¶² ÀåÄ¡¿¡ Á¢±Ù Çϱâ À§Çؼ °¡Àå ¸ÕÀú ÇؾßÇÒ ÀÛ¾÷Àº ÀåÄ¡¸¶´Ù ´Ù¸¦ °ÍÀÌ
´Ù. open À̶ó´Â È£ÃâÀÌ ¿À¸é ÇÊ¿äÇÑ ÀÏÀ» ÇÏ°í write/read È£Ãâ¿¡ ´ëºñÇؼ Áغñ¸¦ÇÏ´Â ÀÛ¾÷¸¸ ÇÏ¸é µÈ´Ù.
ÀÌ ÀÛ¾÷Àº ÇÁ·Î±×·¥ ¾ð¾î¸¸ C¸¦ »ç¿ëÇÒ »Ó C ¶óÀ̺귯¸® ÇÔ¼ö¸¦ Çϳªµµ »ç¿ëÇÒ ¼ö ¾ø´Â Ư¼ö ÀÛ¾÷À̹ǷΠÀÀ¿ë ÇÁ·Î±×·¡¹Ö°ú ¿ÏÀüÈ÷ ´Ù¸¥ ÀÛ¾÷À̶ó°í ÇÒ ¼ö ÀÖ´Ù. ÆÄÀÏ ÀÔÃâ·ÂÀÇ »óÀ§ ÀÎÅÍÆäÀ̽º´Â ¸®´ª½º¿¡¼µµ ´Ù ¿Ï¼ºµÇ¾î Àֱ⠶§¹®¿¡ ¿ì¸®°¡ ½Å°æÀ» ¾µ ÇÊ¿ä´Â ¾ø´Ù. ÀåÄ¡ Ư¼öÆÄÀÏÀ» Á¤ÀÇÇÏ°í Ç¥ÁØ ÆÄÀÏ ÀÔÃâ·Â¿¡ »ç¿ëµÇ´Â ½Ã½ºÅÛ È£ÃâÀÌ »ç¿ëÇÒ ÀûÀýÇÑ ÇÔ¼ö¸¦ ¸¸µé¾î ³»´Â ÀÛ¾÷¸¸À¸·Î ÃæºÐÇÏ´Ù.
ÀåÄ¡ Ư¼öÆÄÀÏÀ» À§Çؼ ÆÄÀÏÀ¯Çü, ÁÖ(major) ¹øÈ£¿Í ºÎ(minor) ¹øÈ£°¡ ÇÊ¿äÇÏ´Ù. ÁÖ¹øÈ£´Â ÀåÄ¡À¯ÇüÀ»,ºÎ¹øÈ£´Â ±× À¯ÇüÀÇ ´ÜÀ§±â±â¸¦ ³ªÅ¸³½´Ù.
¸®´ª½º¿¡¼´Â 255 ¹ø±îÁöÀÇ ÀåġƯ¼öÆÄÀÏ ÁÖ¹øÈ£°¡ ÀÖ´Ù. ¼ö¸¹Àº Çϵå¿þ¾î Áö¿øÀÌ °è¼Ó Ãß°¡µÇ°í ÀÖ¾î¼ 100¹ø ÀÌÇÏ´Â °ÅÀÇ ´Ù ÇÒ´çÀÌ µÇ¾ú´Ù. ƯÁ¤ÇÑ Çϵå¿þ¾î¸¦ À§ÇÑ µð¹ÙÀ̽ºµå¶óÀ̹ö¸¦ ¸¸µé°í °ø½ÄÀûÀ¸·Î ¸®´ª½ºÀÇ ÁÖ¹øÈ£¸¦ ¹Þ°í ½ÍÀ¸¸é Documentation/devices.txt ¸¦ Âü°íÇÏ¿© ¸®´ª½º ÁÖ¹øÈ£ °ü¸®¸¦ ÇÏ´Â »ç¶÷¿¡°Ô ¿¬¶ôÀ» ÃëÇÏ¸é µÈ´Ù. ÀÓÀÇ·Î ¹øÈ£¸¦ ºÎ¿©ÇÑ´Ù¸é Ä¿³ÎÀÌ ¾÷±×·¹À̵åµÇ¾î ´Ù¸¥ µð¹ÙÀ̽ºµå¶óÀÌ
¹ö°¡ ÀÌ ¹øÈ£¸¦ »ç¿ëÇÒ ¶§ Ãæµ¹ÀÌ ÀÖÀ» ¼ö ÀÖ´Ù.
¸®´ª½º¸¦ Å×½ºÆ®Çϰųª ½ÇÇèÀûÀ¸·Î µð¹ÙÀ̽ºµå¶óÀ̹ö¸¦ ¸¸µå´Â »ç¶÷À» À§Çؼ 60-63, 120-127, 240-254 ¹øÀÌ ¿¹¾àµÇ¾î ÀÖ´Ù. ÀÌ ¹øÈ£ Áß¿¡¼ Àӽ÷ΠÀû´çÇÑ ¹øÈ£¸¦ »ç¿ëÇÏ¿© Å×½ºÆ® ÇÏ°í ³ªÁß¿¡ Á¤½ÄÀ¸·Î ¹øÈ£¸¦ ÇÒ´ç ¹ÞÀ¸¸é µÈ´Ù. ¿ì¸®°¡ ¸¸µå´Â ÀåÄ¡¸¦ À§Çؼ 125¹øÀ» ¼±ÅÃÇÏ¿© MY_DEVICE_MAJOR·Î Á¤ÇÏÀÚ.
ÀÌ ¹øÈ£¸¦ Ä¿³Î¿¡ µî·ÏÇϱâ À§Çؼ´Â include/linux/major.h ¿¡ ÀÌ °ªÀ» ±â·ÏÇÑ´Ù. À§Ä¡´Â »ó°ü¾ø´Ù. ¸¸¾à °è¼Ó Ä¿³Î ¾÷±×·¹À̵忡 µû¶ó °¥ ¿¹Á¤ÀÌ°í ¾ÆÁ÷ Á¤½ÄÀ¸·Î Ä¿³Î ¹èÆ÷º»¿¡ µî·ÏÀÌ ¾ÈµÈ Å×½ºÆ® µå¶óÀ̹ö¶ó¸é Ä¿³Î ÆÐÄ¡¸¦ ÇÒ ¶§ ¹®Á¦°¡ »ý±âÁö ¾Êµµ·Ï µÇµµ·Ï °¡´ÉÇÑ °¡Àå µÞºÎºÐ¿¡ ¹èÄ¡ÇÏ´Â °ÍÀÌ ÁÁÀ» °ÍÀÌ´Ù. ¿ì¸®°¡ »ðÀÔÇÑ Äڵ忡 ÀÎÁ¢ÇÑ °÷¿¡¼ Ä¿³Î º¯°æ »çÇ×ÀÌ »ý±ä´Ù¸é ÆÐÄ¡ÇÒ ¶§ ¹®Á¦°¡ »ý±æ ¼ö ÀÖ´Ù.
#define MY_DEVICE_MAJOR 125
±×¸®°í ÀÌ ¹øÈ£·Î µÈ ÀåÄ¡ Ưº°ÆÄÀÏÀ» ¸¸µç´Ù.
mknod /dev/my_device0 c 125 0
mknod /dev/my_device1 c 125 1
mknod /dev/my_device2 c 125 2
mknod /dev/my_device3 c 125 3
chown root.root /dev/my_device
chmod 660 /dev/my_device
ÀÌÁ¦ my_device ´Â ÀÌ ÆÄÀÏÀ» ¿°í ¾²°í ÀÐÀ½À¸·Î½á Á¶ÀÛÇÒ ¼ö ÀÖ´Ù. Âü°í·Î c´Â ¹®ÀÚ Æ¯¼öÆÄÀÏÀÓÀ» ³ªÅ¸³»°í 125´Â ÁÖ¹øÈ£, [0-3]Àº ºÎ¹øÈ£ÀÌ´Ù.
4.3.2 MY_DEVICE¸¦ Ä¿³Î ÄÄÆÄÀÏ ¿É¼Ç¿¡ »ðÀÔ
make config ½Ã¿¡ MY_DEVICE Ç׸ñÀÌ ³ª¿À°Ô Çϱâ À§Çؼ ÇÊ¿äÇÑ ÀÛ¾÷À» ÇÏÀÚ. µð¹ÙÀ̽º µå¶óÀ̹ö´Â °èÃþ»ó °¡Àå ÇÏÀ§¿¡ À§Ä¡ Çϱ⠶§¹®¿¡ µð·ºÅ丮 À§Ä¡µµ »ìÆì¾ß ÇÑ´Ù.
MY_DEVICE´Â ¹®ÀÚ Æ¯¼öÆÄÀÏÀ̸ç isdnµî°ú °°ÀÌ Æ¯¼öÇÑ ºÐ·ù¿¡ µé¾î°¡Áö ¾Ê±â ¶§¹®¿¡ drivers/char µð·ºÅ丮¿¡¼ ÀÛ¾÷À» ÇÏ¸é µÈ´Ù.
make config ¸¦ ÇßÀ» ¶§ MY_DEVICE Ç׸ñÀÌ ³ª¿À°Ô Çϱâ À§Çؼ´Â drivers/char/Config.in ¿¡ my_driver¿¡ ÇØ´çÇÏ´Â Á¶°ÇÀ» ¸í½ÃÇØ¾ß ÇÑ´Ù.
tristate 'insert my device driver in kernel' CONFIG_MY_DEVICE
if [ "$CONFIG_MY_DEVICE" = "y" -o "$CONFIG_MY_DEVICE" = "m" ]; then
int ' my device value' CONFIG_MY_DEVICE_VALUE 1
bool ' support my device something' CONFIG_MY_DEVICE_SUPPORT
fi
tristate´Â Ä¿³Î¿¡ Á÷Á¢»ðÀԵǰųª(y), ¸ðµâ·Î ¸¸µé°Å³ª (m), ÄÄÆÄÀÏÇÏÁö ¾Ê´Â(n)´Ù´Â °ÍÀ» Á¤ÇÏ´Â °ÍÀ̸ç bool Àº (y,n) µÎ°¡Áö Áß¿¡ ¼±ÅÃÇÏ´Â °ÍÀÌ°í int ´Â ÇÊ¿äÇÑ ¼öÄ¡°ªÀÌ ÀÖÀ¸¸é Àû¾î ÁÖ´Â ºÎºÐÀÌ´Ù.
if-fi ´Â ¿©·¯ °èÃþÀ» µÑ ¼ö ÀÖ´Ù. ´Ù¸¥ if-fi ¹®Àå »çÀ̸¸ ¾Æ´Ï¶ó¸é ÀÌ ¹®ÀåÀ» »ðÀÔÇÏ´Â À§Ä¡´Â »ó°üÀÌ ¾ø´Ù.
help ¹öÆ°À» ´·¶À» ¶§ ¼³¸íÀÌ ³ª¿À°Ô Çϱâ À§Çؼ Documentation/Configure.help¿¡ ÀûÀýÇÑ ¼³¸íÀ» ³Ö¾î ÁØ´Ù.
My device support
CONFIG_MY_DEVICE
This text is help message for my device driver
4.3.3 Ä¿³Î ºÎÆà ¿É¼ÇÀÇ Ã³¸®
Ä¿³ÎÀÌ ºÎÆÃÇÒ ¶§ µð¹ÙÀ̽º µå¶óÀ̹öµéÀº Á¦¾îÇÒ ¼ö ÀÖ´Â Çϵå¿þ¾î¿¡ ´ëÇÑ ¼³Á¤°ªÀ» ½º½º·Î ã°Å³ª °íÁ¤µÈ °ªÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¸¸¾à »ç¿ëÀÚ°¡ ¾î¶² µð¹ÙÀ̽º¿¡ ´ëÇÑ ÀÎÅÍ·´Æ®°ªÀ̳ª º£À̽º ¾îµå·¹½ºµîÀ» ¹Ù²Ù¾ú´Ù¸é Ä¿³Î¿¡°Ô ¾Ë·Á ÁÖ¾î¾ß ÇÑ´Ù. ¼³Á¤°ªÀ» ½º½º·Î ãÀ» ¼ö ¾ø´Â µð¹ÙÀ̽ºµå¶óÀ̹öµµ ¸¶Âù°¡Áö·Î »ç¿ëÀÚ°¡ Çϵå¿þ¾î ¼³Á¤°ªÀ» ¾Ë·Á ÁÖ¾î¾ß ÇÑ´Ù.À̸¦ À§ÇØ ¸®´ª½º Ä¿³ÎÀº ºÎÆà ¿É¼ÇÀ» Áö¿øÇÑ´Ù.
µð¹ÙÀ̽º µå¶óÀ̹ö¸¦ À§ÇÑ ÆÄÀÏ drivers/char/my_device.cÀ» ¸¸µé°í Çì´õÆÄÀÏ include/linux/my_device.h¸¦ ¸¸µç´Ù. ÄÄÆÄÀÏ ÇÒ ¶§ ÀÌ ÇÁ·Î±×·¥µµ ÄÄÆÄÀÏ ½ÃÅ°±â À§Çؼ drivers/char/MakefileÀÇ Àû´çÇÑ °÷¿¡ ÀÌ ÆÄÀÏÀ» Àû¾îÁØ´Ù.
ifeq ($(CONFIG_MY_DEVICE),y)
L_OBJS += my_device.o
else
ifeq ($(CONFIG_MY_DEVICE),m)
M_OBJS += my_device.o
endif
endif
Ä¿³Î¿¡ Á÷Á¢ »ðÀÔ(y)Ç϶ó´Â ¿É¼Ç°ú ¸ðµâ·Î ¸¸µé(m)¶ó´Â ¿É¼ÇÀÏ ¶§ °¢°¢¿¡ ´ëÇؼ ´Ù¸¥Ã³¸®¸¦ ÇÑ´Ù. ±×¿Ü¿¡ Makefile À» »ìÆ캸¸é ¼ºêµð·ºÅ丮¸¦ Æ÷ÇÔÇ϶ó´Â ¿É¼ÇµîÀÌ ÀÖ´Ù.
drivers/char/mem.c ¿¡¼ ¹®ÀÚ µð¹ÙÀ̽ºµå¶óÀ̹ö¸¦ ÃʱâÈÇÑ´Ù. µå¶óÀ̹ö ÃʱâÈ ÇÔ¼ö´Â ´ëºÎºÐ *_init Çü½ÄÀ̹ǷΠmy_driver_init¶ó°í Á¤ÇÏ°í Àû´çÇÑ °÷¿¡ ³Ö¾î ÁÖ¸é µÈ´Ù.
ºñ½ÁÇÑ µå¶óÀ̹ö ÃʱâÈ ·çƾÀÌ »ðÀԵǾî ÀÖ´Â À§Ä¡¿¡ ´Ù¸¥ ifdef-endif¿Í »ó°ü¾ø´Â °÷¿¡ µÎ¸é µÈ´Ù.
#ifdef CONFIG_MY_DEVICE
my_device_init();
#endif
±×¸®°í À ºÎºÐ¿¡ ÇÔ¼öÀÇ ¿øÇüÀ» ¼±¾ðÇØ¾ß ÇÑ´Ù. ´ÙÀ½°ú °°ÀÌ.
extern int my_device_init(void);
my_device_init ÇÔ¼ö´Â my_device¸¦ ÃʱâÈ ½Ãų ¶§ ÇÊ¿äÇÑ °¢Á¾ ÀÛ¾÷À» ÇÒ ¶§ ÇÑ ¹ø ½ÇÇàµÇ´Â ÇÔ¼öÀÌ´Ù. my_device_init ÇÔ¼ö¿¡¼ my_device_open, my_device_write ÇÔ¼ö
¸¦ Ä¿³Î¿¡ µî·ÏÇÏ°Ô µÈ´Ù.
make dep °úÁ¤¿¡¼ Config.in À» ÂüÁ¶ÇÏ¿© Makefile ¿¡ Á¤ÀÇµÈ µð¹ÙÀ̽º µå¶óÀ̹ö ÆÄÀÏÀ» ÄÄÆÄÀÏ ÇÏ¿© Ä¿³Î¿¡ »ðÀÔÇÒ °ÍÀÎÁö,¸ðµâ·Î ¸¸µé °ÍÀÎÁö ¿©ºÎ¸¦ °áÁ¤ÇÑ´Ù.
ºÎÆðúÁ¤À» ÁøÇàÇÑ ÈÄ¿¡ Ä¿³ÎÀº µð¹ÙÀ̽º µå¶óÀ̹ö ÃʱâÈ ·çƾ(drivers/char/mem.c)À¸·Î ¶Ù¾î °¢ µð¹ÙÀ̽º¸¦ ½ÇÁ¦·Î ÃʱâÈ(my_device_init) ÇÑ´Ù. °¢°¢ÀÇ µð¹ÙÀ̽º ÃʱâÈ ÇÔ¼ö´Â Çϵå¿þ¾î µð¹ÙÀ̽º°¡ ÄÄÇ»ÅÍ¿¡ Á¸ÀçÇÏ´ÂÁö °Ë»çÇÏ°í, Çϵå¿þ¾î°¡ ÇÊ¿ä·Î ÇÏ´Â Ãʱâȸ¦ ÇÑ ÈÄ¿¡ system call ·çƾÀ» À§Çؼ read, write, release, ioctl µîÀÇ ÇÔ¼ö°¡ Á¤ÀÇµÈ file_operation ÇÔ¼ö¹è¿À» µî·ÏÇÑ´Ù.
¸ðµâ·Î ¸¸µé¾úÀ» ¶§´Â Ä¿³Î ºÎÆðúÁ¤À» insmod°¡ ÇØ ÁØ´Ù. ÀÎÀÚ ÆĽ̵µ ¸¶Âù°¡Áö·Î insmod ¸òÀÌ´Ù. µð¹ÙÀ̽º µå¶óÀ̹ö´Â ÀÎÀÚ ¹è¿À» ³Ñ°Ü ¹Þ°Ô µÇ°í init_module(my_device_init)¿¡¼ ¸¶Âù°¡Áö·Î Çϵå¿þ¾î °Ë»ö, ÃʱâÈ, ÀÎÀÚ¸¦ »ç¿ëÇÑ ¼³Á¤°ª º¯°æÀ» ÇÑ´Ù. ¸ðµâ·Î ÇßÀ» ¶§´Â µå¶óÀ̹ö ÇÁ·Î±×·¥¿¡¼ ¾à°£ÀÇ ºÎ°¡ ÀÛ¾÷ÀÌ ÇÊ¿äÇÒ »Ó Á÷Á¢ »ðÀÔµÈ µå¶óÀ̹ö¿Í ´Ù¸£Áö ¾Ê´Ù.
4.4 µð¹ÙÀ̽º µå¶óÀ̹öÀÇ ÀûÀç¿Í »èÁ¦
4.4.1 µå¶óÀ̹ö ÃʱâÈ ÇÔ¼ö
ÃʱâÈ ÇÔ¼ö¿¡¼´Â ƯÁ¤ ÁÖ¼Ò·Î °ªÀ» º¸³»±â,¹ÙÀÌ¿À½º ´Ù¿î·Îµå,Áö¿ø µð¹ÙÀ̽º Áß¿¡¼ ÀåÂøµÈ µð¹ÙÀ̽º¸¦ ±¸º°ÇÏ´Â ÀÛ¾÷ µéÀ» ÇØ¾ß ÇÑ´Ù.Ä¿³Î ÂÊÀ¸·Î´Â ÀÎÅÍ·´Æ® µî·Ï, µå¶óÀ̹ö µî·Ï,µð¹ÙÀ̽º °¹¼ö¿Í ¹øÁö¸¦ ÁöÁ¤ÇÏ´Â ÀÛ¾÷ÀÌ ÇÊ¿äÇÏ´Ù.°³¹ß Ãʱ⿡´Â ¸ðµâÀûÀç ¹æ¹ýÀ» »ç¿ë ÇØ¾ß Ä¿³Î ÀçÄÄÆÄÀÏ ½Ã°£À» ÁÙÀÏ ¼ö ÀÖÀ¸¹Ç·Î ¸ðµâ ÀûÀç ¹æ¹ýÀ» Áß½ÉÀ¸·Î »ìÆ캸ÀÚ.
my_device_init
¿ì¼± my_device µå¶óÀ̹ö¸¦ µî·ÏÇÏÀÚ. µî·Ï ÇÔ¼ö´Â register_chrdevÀÌ´Ù. ÀÌ ÇÔ¼ö´Â ÁÖ ÀåÄ¡ ¹øÈ£, µð¹ÙÀ̽º À̸§, ÆÄÀÏ Á¶ÀÛ ÇÔ¼ö ÀÎÅÍÆäÀ̽º¸¦ µî·ÏÇÑ´Ù. Ä¿³Î¿¡¼ ÀÌ µð¹ÙÀ̽º¸¦ »ç¿ëÇÏ´Â ÀÎÅÍÆäÀ̽º´Â ´ÙÀ½°ú °°´Ù.
static struct file_operations my_device_fops = {
my_device_lseek,
my_device_read,
my_device_write,
my_device_readdir,
my_device_select,
my_device_ioctl,
my_device_mmap,
my_device_open,
my_device_release
};
Ä¿³Î¿¡¼´Â ¾î¶² µð¹ÙÀ̽º¶óµµ ÆÄÀÏ°ú °°ÀÌ Á¢±ÙÇϹǷΠfile_operations ±¸Á¶Ã¼·Î Á¤ÀÇÇÏ°í read/write ·çƾÀ» my_device¿¡ °íÀ¯ÇÑ ¹æ¹ýÀ¸·Î ÀÛ¼ºÇÏ¸é µÈ´Ù. ¹®ÀÚ µð¹ÙÀ̽º¿Í ºí·° µð¹ÙÀ̽º¿¡ µû¶ó Áö¿øÇÏ´Â ÇÔ¼ö´Â Â÷ÀÌ°¡ ÀÖ´Ù. ¿¹¸¦ µé¾î, my_device_readdir ÇÔ¼ö´Â ¹®ÀÚ µð¹ÙÀ̽ºÀÎ my_device¿¡¼´Â ÀüÇô Àǹ̰¡ ¾ø´Ù. ÀÌ ÇÔ¼ö´Â Ä¿³Î ÀÚü¿¡¼ ÀüÇô »ç¿ëÇÏÁö ¾ÊÀ¸¹Ç·Î NULL·Î Á¤ÀÇÇصµ ¾Æ¹« »ó°üÀÌ ¾ø´Ù.
¾î¶² ÇÔ¼ö°¡ ÇÊ¿äÇÏ°í ¾î¶² ÇÔ¼ö°¡ ÇÊ¿ä ¾ø´ÂÁö´Â Å©°Ô ºí·Ïµð¹ÙÀ̽º¿Í ¹®ÀÚ µð¹ÙÀ̽º¿¡ µû¶ó Â÷ÀÌ°¡ ³´Ù. ¸¸µé·Á´Â µð¹ÙÀ̽ºÀÇ Æ¯¼ºÀ» °í·ÁÇÏ¿© ¿¬°üÀÌ ÀÖ´Â µå¶óÀ̹ö¸¦ Á¶»çÇØ ÆľÇÇϱ⠹ٶõ´Ù.
µð¹ÙÀ̽º°¡ »ç¿ëÇÒ ¹øÁö ÁÖ¼Ò°¡ À¯È¿ÇÑÁö´Â °Ë»çÇÏ´Â ÇÔ¼ö´Â check_region ÀÌ´Ù. ÁÖ¼Ò°¡ À¯È¿ÇÏ´Ù¸é request_region À¸·Î ÀÌ ÁÖ¼Ò¸¦ Á¡À¯ÇÑ´Ù. ÇØÁ¦´Â release_regionÀÌ´Ù. ÃʱâÈ °úÁ¤¿¡¼ µå¶óÀ̹ö³ª µð¹ÙÀ̽º°¡ ¹®Á¦°¡ ÀÖÀ¸¸é ¹Ýµå½Ã ÀÌ ÇÔ¼ö·Î ¿µ¿ªÀ» ¹ÝȯÇÏ¿©¾ß ÇÑ´Ù.ÇÔ¼ö Á¤ÀÇ´Â ¼Ò½º¸¦ ã¾Æ º¸±â ¹Ù¶õ´Ù.¾Õ¿¡¼ Ä¿³Î Äڵ带 »ý·«ÇÑ´Ù°í ¸»ÇßµíÀÌ ÇÔ¼ö ¼³¸íµµ °¡´ÉÇÑÇÑ ÇÔ¼ö¸í¸¸À» º¸ÀÌ°í Á¤È®ÇÑ Á¤ÀÇ´Â »ý·«ÇÑ´Ù.
ÀÎÅÍ·´Æ®¸¦ »ç¿ëÇÑ´Ù¸é ÀÌ°ÍÀ» »ç¿ëÇÏ°Ú´Ù°í ¿äûÇØ¾ß ÇÑ´Ù. request_irq/free_irq¸¦ »ç¿ëÇÏ¸é µÈ´Ù. request_irq ÀÇ ¼¼¹ø° ÀÎÀÚ´Â SA_INTERRUPT¸¦ »ç¿ëÇÑ´Ù.
SA_INTERRUPT´Â ºü¸¥ irq¶ó°í Á¤ÀǵǾî ÀÖ´Ù. ÀÌ Ç÷¡±×´Â ½Å¼ÓÇÑ ÀÎÅÍ·´Æ® ¼ºñ½º¸¦ À§Çؼ ´Ù¸¥ ÀÎÅÍ·´Æ®¸¦ ±ÝÁöÇÏ°í °¡Àå ¿ì¼±À¸·Î ÀÎÅÍ·´Æ® ó¸® ·çƾÀ» ¼öÇàÇÑ´Ù.
¹®¸Æ±³È¯, ÀçÀÎÅÍ·´Æ®, ÇÁ·Î¼¼½º blockingÀÌ ÀϾÁö ¾Ê´Â´Ù. ¿©±â¿¡ 0À» ¾²¸é ´À¸° irq·Î ÀÛµ¿µÈ´Ù. ÀÌ ÀÎÅÍ·´Æ®´Â ÀÎÅÍ·´Æ®¸¦ ±ÝÁö ÇÏÁö ¾ÊÀ¸¹Ç·Î ¶Ç ´Ù½Ã ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù. SA_SHIRQ´Â pci µð¹ÙÀ̽º°¡ ÀÎÅÍ·´Æ®¸¦ °øÀ¯ÇÒ ¶§ »ç¿ëÇÑ´Ù. ÇÔ¼ö ¿øÇü°ú ÀÚ¼¼ÇÑ ¿É¼Ç Ç÷¡±× ¼³¸íÀº include/asm/sched.h ¿¡¼ ã¾Æ º¼ ¼ö ÀÖ´Ù.
request_region, request_irq ¸¦ ¼öÇàÇßÀ» ¶§ ¿äûÇÑ °ªÀ» »ç¿ëÇÒ ¼ö ÀÖÀ¸¸é µð¹ÙÀ̽º°¡ ½ÇÁ¦·Î ÀåÂøµÇ¾î ÀÖ´ÂÁö °Ë»çÇØ¾ß ÇÑ´Ù. µð¹ÙÀ̽ºÀÇ Á¤ÇØÁø ÁÖ¼Ò¿¡ ÀåÄ¡ Á¾·ù¸¦ ³ªÅ¸³»´Â ¹®ÀÚ¿ °°Àº ½Äº°ÀÚ°¡ ÀÖ´Ù¸é ±× °ÍÀ» ÀÐ¾î ¿À¸é µÈ´Ù. ÀÎÅÍ·´Æ®¸¦ »ç¿ëÇÑ´Ù¸é Å×½ºÆ®¸¦ À§ÇØ Ä«µå°¡ ÀÎÅÍ·´Æ®¸¦ ÀÏÀ¸Å°µµ·Ï ÇÑ ´ÙÀ½¿¡ µ¹¾Æ¿À´Â ÀÎÅÍ·´Æ®¸¦ °Ë»çÇÏ¸é µÈ´Ù. ÀÌ ¹æ¹ýÀº register_chardev(¶Ç´Â register_blkdev,tty_register_driver)¸¦ »ç¿ëÇÏ¿© ¹Ì¸® ÀÎÅÍ·´Æ® ÇÔ¼ö¸¦ µî·ÏÇÏ°í »ç¿ëÇØ¾ß ÇÑ´Ù. ÀÌ·± ¹æ¹ýÀ» ¾µ ¼ö ¾ø´Ù¸é ÁöÁ¤ÇÑ ¹øÁö¿¡ µð¹ÙÀ̽º°¡ ÀÖ´Ù°í °¡Á¤ÇÏ°í Ãʱâȸ¦ ÇؾßÇÑ´Ù. lilo ¿É¼ÇÀÌ Æ²¸®Áö ¾Ê¾Ò´Ù´Â °¡Á¤À» ÇØ¾ß Çϱ⠶§¹®¿¡ ´Ù¸¥ ÀåÄ¡¿Í Ãæµ¹ÇÑ´Ù¸é ½É°¢ÇÑ ¹®Á¦°¡ »ý±æ ¼ö ÀÖÀ¸¹Ç·Î °¡´ÉÇÏ´Ù¸é È®½ÇÇÑ ¹æ¹ýÀ» °±¸ÇØ¾ß ÇÑ´Ù. ÁöÁ¤ÇÑ ÀåÄ¡°¡ ½ÇÁ¦·Î ÀÖ´ÂÁö °Ë»çÇÏ´Â ·çƾÀº ¸ðµç µå¶óÀ̹ö¿¡ ÀÖÀ¸¹Ç·Î Àß »ìÆ캸±â ¹Ù¶õ´Ù.
µå¶óÀ̹ö°¡ »ç¿ëÇÒ ¸Þ¸ð¸® ¿µ¿ªÀÌ ÇÊ¿äÇÏ´Ù¸é kmalloc ÇÔ¼ö·Î ÀÏÁ¤ ¿µ¿ªÀ» È®º¸ÇØ ³õ´Â´Ù. kmallocÀº µ¥ÀÌŸ¸¦ ÀúÀåÇÒ ¸Þ¸ð¸® ¿µ¿ªÀ» È®º¸Çϴµ¥ »ç¿ëÇÏ°í request_region ÇÔ¼ö´Â ƯÁ¤ ÁÖ¼ÒÀÇ ¸Þ¸ð¸® ¿µ¿ªÀ» È®º¸Çϴµ¥ »ç¿ëÇÑ´Ù.
µð¹ÙÀ̽º¿¡ ¹ÙÀÌ¿À½º¸¦ ´Ù¿î·Îµå ÇÏ¿© È°¼ºÈ ½ÃÄÑ¾ß ÇÑ´Ù¸é »ó´çÇÑ °í¹ÎÀ» ÇØ¾ß ÇÑ´Ù. ¹ÙÀÌ¿À½ºÀÇ Å©±â°¡ Àû´Ù¸é ¹ÙÀ̳ʸ® ÆÄÀÏÀ» ¹ÙÀÌÆ® ¹è¿·Î ¸¸µé¾î Á¤ÀÇÇØ µÎ°í memcpy_toio ÇÔ¼ö¸¦ ÀÌ¿ëÇؼ ´Ù¿î·Îµå ÇÒ ¼ö ÀÖ´Ù.(drivers/char/digi_bios.h) ¸î ¸Þ°¡¾¿ µÇ´Â µ¥ÀÌŸ¸¦ ´Ù¿î·Îµå ÇØ¾ß ÇÑ´Ù¸é ÀÌ ¹æ¹ýÀ» »ç¿ëÇÒ ¼ö ¾ø´Ù. ¹ÙÀÌÆ® ¹è¿Àº Á¤Àû µ¥ÀÌŸ°¡ µÇ¾î Ä¿³ÎÀ» ÀûÀçÇÒ ¼öµµ ¾øµµ·Ï Å©°Ô ¸¸µé°Ô µÇ±â ¶§¹®ÀÌ´Ù. °¡´ÉÇÑ ¹æ¹ýÀº ÀÏ´Ü µå¶óÀ̹ö¸¦ µî·ÏÇÏ°í ioctl·çƾÀ» ÀÌ¿ëÇؼ µð¹ÙÀ̽º¸¦ ¿¾î¼ ´Ù¿î·ÎµåÇÏ°í ±× °á°ú¿¡ µû¶ó µå¶óÀ̹ö¸¦ È°¼ºÈ°Å³ª ¿ìȸÀûÀ¸·Î µå¶óÀ̹ö¸¦ »ç¿ë±ÝÁö ¶Ç´Â °Á¦ »èÁ¦¸¦ ÇØ¾ß ÇÑ´Ù.
4.4.2 µå¶óÀ̹ö »èÁ¦ ÇÔ¼ö
¸ðµâ ¹æ½ÄÀ¸·Î µå¶óÀ̹ö¸¦ ÀûÀç ÇßÀ¸¸é rmmod ·Î ¸ðµâÀ» »èÁ¦ÇÏ´Â ÇÔ¼ö¸¦ ÀÛ¼ºÇØ¾ß ÇÑ´Ù. cleanup_module·Î ÇÔ¼ö ¸íÀÌ ÅëÀϵǾî ÀÖ°í ¸ðµâÀÏ ¶§¸¸ ÇÊ¿äÇϹǷΠ#ifdef MODULE - #endif ¾È¿¡¼ Á¤ÀÇÇØ¾ß ÇÑ´Ù. ¿ì¼± kmallocÀ¸·Î ÇÒ´ç¹ÞÀº ¸Þ¸ð¸®¸¦ kfree ÇÔ¼ö·Î ¹Ý³³ÇÑ´Ù. request_region À¸·Î È®º¸ÇÑ ÁÖ¼Ò´Â release_regionÀ¸·Î ÇØÁ¦ÇÏ°í request_irq·Î ÀÎÅÍ·´Æ®¸¦ »ç¿ëÇß´Ù¸é free_irq·Î ¹Ý³³ÇÑ´Ù. ¸¶Áö¸·À¸·Î ÀåÄ¡ Ư¼ö ¹øÈ£¸¦ ÇØÁ¦ÇÏ¿© Ä¿³ÎÀÌ µð¹ÙÀ̽º¸¦ »ç¿ëÇÏÁö ¾Êµµ·Ï ÇÑ´Ù. ÀÌ ÇÔ¼ö´Â unregister_chrdev/tty_unregister_device ÀÌ´Ù.
±×¿Ü¿¡ ioremapµîÀÇ ÇÔ¼ö¸¦ »ç¿ëÇßÀ¸¸é À̵é°ú ¦ÀÌ µÇ´Â iounmap µîÀÇ ÇÔ¼ö¸¦ »ç¿ëÇÏ¿© ¸ðµç ÀÚ¿øÀ» ¹Ý³³ÇØ¾ß ÇÑ´Ù. ÀÚ¿øÀ» Á¦´ë·Î ¹Ý³³ÇÏÁö ¾Ê°í ¸ðµâÀ» »èÁ¦ÇÏ¸é ¾öû³ ¾çÀÇ ¿¡¶ó ¸Þ¼¼Áö /var/log/messages¿¡ ½×ÀÌ°Ô µÈ´Ù. Á» ´õ ½É°¢ÇÑ »óȲÀÌ »ý°Ü¼ ÆÄÀÏ ½Ã½ºÅÛ Àüü¸¦ ÀÒ°Ô µÉ ¼öµµ Àֱ⠶§¹®¿¡ ÇÒ´ç¹ÞÀº ÀÚ¿øÀº ¹Ýµå½Ã ¹Ý³³ÇÏ´Â ÇÔ¼ö¸¦ öÀúÈ÷ È®ÀÎÇÏ¿© »ç¿ëÇØ¾ß ÇÑ´Ù.
4.4.3 Çì´õÆÄÀÏÀÇ ±¸Á¶
Çì´õÆÄÀÏÀº ¹Ýµå½Ã ¾Æ·¡¿Í °°ÀÌ ½ÃÀÛÇÏ°í ³¡³»¾ß ÇÑ´Ù.
#ifndef __LINUX_MY_DEVICE
#define __LINUX_MY_DEVICE
...
...
#endif
ÀÌ·¸°Ô ÇØ¾ß ¿©·¯ ÆÄÀÏ¿¡ Çì´õÆÄÀÏÀÌ ÀÎŬ·çµå µÇ¾ú¾îµµ ¹®Á¦°¡ »ý±âÁö ¾Ê´Â´Ù. Ä¿³Î¿¡¼ »ç¿ëÇÏ´Â º¯¼öÀÌÁö¸¸ »ç¿ëÀÚ ÇÁ·Î±×·¥¿¡¼ º¸¿©¼´Â ¾ÈµÇ´Â º¯¼ö°¡ ÀÖ´Ù¸é ¾Æ·¡¿Í °°ÀÌ ¸·¾Æ ³õ¾Æ¾ß ÇÑ´Ù.
#ifdef __KERNEL__
...
#endif
±×¸®°í my_device_init ´Â ¿ÜºÎ¿¡¼ ÂüÁ¶ ÇÒ ¼ö ÀÖµµ·Ï Çì´õÆÄÀÏ¿¡ ²À ¼±¾ðÇØ¾ß ÇÑ´Ù.
init ÇÔ¼ö´Â Ä¿³Î¿¡¼¸¸ »ç¿ëÇϹǷΠ__KERNEL__ ³»ºÎ¿¡ Á¸ÀçÇصµ »ó°üÀº ¾ø´Ù.
4.4.4 ÃʱâÈ ÇÒ ¶§ ¸¹ÀÌ ¾²´Â ÇÔ¼öµé
outb/outw, inb/inw ÇÔ¼ö´Â ¹°¸® ÁÖ¼Ò¿¡ ¾²±â/Àбâ ÇÔ¼öÀÌ´Ù. À̸§ÀÌ º¸¿© ÁÖµíÀÌ ¹ÙÀÌÆ®,¿öµå¸¦ ÀÐ°í ¾´´Ù. readb/writeb ÇÔ¼ö´Â memory mapped I/O Àåºñ¿¡ ÀÐ°í ¾²´Â ÇÔ¼öÀÌ´Ù. memcpy_toio/memcpy_fromio ÇÔ¼ö´Â ƯÁ¤ ÁÖ¼Ò¿¡ µ¥ÀÌŸ¸¦ ÀÎÀÚ·Î ÁØ ¹ÙÀÌÆ®¸¸Å ¾´´Ù.°¢ Ç÷§Æû¿¡ µû¶ó Ä¿³ÎÀÌ º¸´Â ÁÖ¼Ò¿Ícpu°¡ º¸´Â ÁÖ¼Ò, ±×¸®°í ¹°¸®ÁÖ¼ÒÀÇ Â÷À̸¦ ¾ø¾Ö´Â ¿ªÈ°À» ÇÑ´Ù. ¹°¸® ÁÖ¼Ò¿Í °¡»óÁÖ¼Ò ½Ã½ºÅÛ ¹ö½º¿ÍÀÇ °ü°è°¡ º¹ÀâÇÏ°í ¿©·¯ Ç÷§Æû¿¡ µû¶ó ÁÖ¼Ò ÁöÁ¤¹ýÀÌ ´Ù¸£´Ù. x86 ¾ÆÅ°ÅØÃÄ¿¡¼´Â ¹°¸®ÁÖ¼Ò¿Í memory mapped ÁÖ¼Ò°¡ µ¿ÀÏÇÏÁö¸¸ ´Ù¸¥ Ç÷§Æû¿¡¼´Â x86°ú ´Ù¸£±â ¶§¹®¿¡ ȣȯ¼º
À» À§Çؼ »ó´çÇÑ ÁÖÀǸ¦ ÇØ¾ß ÇÑ´Ù. Documentation/IO-mapping.txt¸¦ »ìÆ캸¸é ¶óÀ̳ʽº°¡ ¸Þ¸ð¸® Á¢±ÙÇÔ¼ö »ç¿ë½Ã ÁÖÀÇÇÒ Á¡¿¡ ´ëÇؼ ¼³¸íÇØ ³õ¾Ò´Ù. µð¹ÙÀ̽º°¡ ¹ü¿ë Ç÷§Æû¿¡¼ µ¿ÀÛÇϱ⸦ ¹Ù¶õ´Ù¸é ²À ÀÐ¾î º¸¾Æ¾ß ÇÑ´Ù.
cli()ÇÔ¼ö¸¦ »ç¿ëÇÏ¿© ÀÎÅÍ·´Æ®¸¦ ±ÝÁö ½ÃÅ°°í Áß¿äÇÑ ÀÛ¾÷À» ÇÑ ´ÙÀ½¿¡ sti() ÇÔ¼ö·Î ÀÎÅÍ·´Æ®¸¦ °¡´ÉÇÏ°Ô ¸¸µç´Ù. µå¶óÀ̹ö ÇÁ·Î±×·¥À» ºÎ¸£´Â ÇÔ¼ö¿¡¼ ºÎ¸£±â ÀüÈÄ¿¡ Ç÷¡±× »óÅ°¡ º¯ÈÇÑ´Ù¸é ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö Àֱ⠶§¹®¿¡ cil/sti ¦À¸·Î¸¸ ¾²Áö´Â ¾Ê°í save_flags(flags); cli(); sti(); restore_flags(flags); Çü½ÄÀ¸·Î ¾´´Ù. ÀÌ·¸°Ô ÇÏ¸é ºÒ¸®±â ÀüÀÇ »óÅ°¡ º¸Á¸µÇ¹Ç·Î µå¶óÀ̹ö ÇÁ·Î±×·¥ ¾È¿¡¼ ¾È½ÉÇÏ°í Ç÷¡±×¸¦ Á¶ÀÛÇÒ ¼öÀÖ´Ù. sti()´Â µå¶óÀ̹ö ÇÁ·Î±×·¥ ¾È¿¡¼ ÀÎÅÍ·´Æ®¸¦ °¡´ÉÇÏ°Ô ÇÒ ÇÊ¿ä°¡ ÀÖÀ» ¶§ »ç¿ëÇÏ¸é µÈ´Ù. ÀÎÅÍ·´Æ® °¡´É ºÒ°¡´É¿¡ °ü°è¾øÀÌ µå¶óÀ̹ö°¡ ºÒ¸± ¶§ÀÇ »óÅ¿¡¼ µ¿ÀÛÇصµ »ó°ü¾ø´Ù¸é
save_flags;cli;restore_flags¸¦ »ç¿ëÇÏ¸é µÈ´Ù. ¿ø »óÅ°¡ ÀÎÅÍ·´Æ® °¡´ÉÀ̶ó¸é restore_flags°¡ sti ÇÔ¼ö ¿ªÈ°µµ Çϱ⠶§¹®ÀÌ´Ù. ÁÖÀÇ ÇÒ °ÍÀº µå¶óÀ̹ö ÇÔ¼ö¿¡¼ ¿©·¯ ÇÏÀ§ ·çƾÀ¸·Î ¶Ù´Â µ¿¾È¿¡ save_flags;cli;restore_flags ¼ø¼°¡ À¯ÁöµÇ¾î¾ß ÇÏ´Â °ÍÀÌ´Ù.ÇÔ¼ö°¡ Á¶°Ç¹® µîÀ¸·Î ºÐ±â ÇÒ ¶§ Â÷Ä©restore_flags ÇÔ¼ö°¡ ¼öÇàµÇÁö ¾Ê´Â µîÀÇ ¿À·ù°¡ ÀÖÀ¸¸é ½Ã½ºÅÛÀÌ Á¤ÁöÇÏ°Ô µÈ´Ù.
ÀÌ·± ¿¡·¯´Â »ó´çÈ÷ ¹ß°ßÇϱ⠾î·Á¿î °ÍÀÌ´Ù. ¾îµð¼ ½Ã½ºÅÛÀÌ Á¤Áö Çß´ÂÁö Á¤º¸¸¦ ¾ò±â°¡ Èûµé´Ù. printkÇÔ¼ö¸¦ »ç¿ëÇؼ ¼Ò½ºÀÇ À§Ä¡¸¦ ÃßÀûÇÏ´õ¶óµµ ã±â Èûµé´Ù. printk ÇÔ¼ö´Â ¼öÇàµÇ´Â Áï½Ã ¹®ÀÚ¿À» /var/log/messages ³ª ÄÜ¼Ö È¸é¿¡ ¾²Áö ¾Ê°í ¾µ µ¥ÀÌÅÍ°¡ ¸¹°Å³ª ½Ã½ºÅÛÀÌ ¹Ù»ÚÁö ¾ÊÀº µ¿¾È¿¡ flash ¸¦ ÇϹǷΠprintk ÇÔ¼ö°¡ ¾ÆÁ÷ ¿ÏÀüÈ÷ ¼öÇàµÇÁö ¾ÊÀº »óÅ¿¡¼ ½Ã½ºÅÛÀÌ Á¤ÁöÇÏ´Â °æ¿ì°¡ ¸¹±â ¶§¹®ÀÌ´Ù. ±×·¯¹Ç·Î ÄÚµù½Ã¿¡ öÀúÈ÷ save_flags;cli;restore_flagsÀÇ ¼ø¼¿Í È帧À» µûÁ®¼ »ç¿ëÇØ¾ß ÇÑ´Ù.
µð¹ÙÀ̽º¿¡ ¾î¶² Á¶ÀÛÀ» ÇÏ°í ÀÏÁ¤ ½Ã°£À» ±â´Ù¸± ¶§¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Â ´Ù¾çÇÑ ÇÔ¼ö°¡ Á¸ÀçÇÑ´Ù. µð¹ÙÀ̽º¸¦ Á¶ÀÛÇÏ°í °á°ú¸¦ üũÇÏ´Â ÀÏÀ» ¼ö ¹Ð¸® ÃÊÀÇ °£°Ý ¾È¿¡ ¸ðµÎÇØ¾ß ÇÏ´Â °æ¿ì°¡ ÀÖ´Ù. MY_DEVICE¿¡ Â÷ü cpu°¡ µé¾î ÀÖ°í ÀÌ cpu¸¦ È°¼ºÈ ½ÃÅ°±â À§Çؼ´Â MY_DEVICE ÀÇ base ÁÖ¼Ò¿¡ 0À» ¾²°í 400ms ¿Í 500ms »çÀÌ¿¡ 1À» ½á¾ß ÇÑ´Ù°í ÇÏÀÚ.À̶§¿¡´Â Àý´ëÀûÀÎ ´ë±â ÇÔ¼ö¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù.¿©·¯ ¹®¼¿¡ ´ë±â¿¡ ´ëÇÑ ÇÔ¼ö ¼³¸íÀÌ ÀÖÁö¸¸ ÇÊÀÚÀÇ °æÇèÀ¸·Î´Â __delay() ÇÔ¼ö ¸¸ ÀÌ·± ±â´ÉÀ» Á¤»óÀûÀ¸·Î ¼öÇàÇß´Ù. ÀÎÀÚ´Â __delay((loops_per_sec/100) * (¿øÇÏ´Âms))¸¦ »ç¿ëÇÏ¸é µÈ´Ù.
ÀÌ ÇÔ¼ö´Â ¹®¸Æ±³È¯ÀÌ ÀϾÁö ¾Ê±â ¶§¹®¿¡ ½ÇÇàµÇ´Â µ¿¾È ½Ã½ºÅÛÀÌ Á¤ÁöÇØ ÀÖ°Ô µÈ´Ù µå¶óÀ̹öÀÇ . ÀÏ¹Ý ÀÛ¾÷¿¡ »ç¿ëÇϸé È¿À²ÀÌ ¾öû³ª°Ô ¶³¾î Áö¹Ç·Î Àý´ëÀûÀÎ ½Ã°£ÀÌ ÇÊ¿äÇÑ ÃʱâÈ ÀÛ¾÷ °°Àº °æ¿ì¸¦ Á¦¿ÜÇÏ°í´Â ÀÌ ÇÔ¼ö¸¦ »ç¿ëÇؼ´Â ¾ÈµÈ´Ù.
ÀÏ¹Ý ÀÛ¾÷¿¡¼ ´ë±â ÇÔ¼ö°¡ ÇÊ¿äÇÏ¸é ´ÙÀ½°ú °°ÀÌ »ç¿ëÇÏ¸é µÈ´Ù.
current->state = TASK_INTERRUPTIBLE;
current->timeout = jiffies + HZ * 3;
schedule();
current ¶õ ÇöÀç ¼öÇàµÇ°í ÀÖ´Â ÇÁ·Î¼¼½º¸¦ ¸»ÇÑ´Ù. ÀÌ ÇÁ·Î¼¼½º´Â ÀÏÁ¤ÇÑ ½Ã½ºÅÛ ½Ã°£À» ÇÒ´ç¹Þ¾Æ ÇöÀç ÀÌ ¶óÀÎÀ» ¼öÇàÇÏ°í ÀÖ´Ù. ÀÎÅÍ·´Æ®°¡ °¡´ÉÇÏ°Ô ¸¸µé°í (TASK_INTERRUPTIBLE) ±ú¾î³ª´Â ½Ã°£À» ¾ÕÀ¸·Î 3ÃÊ ÈÄ·Î Á¤ÇÏ°í (HZ*3) Àáµé°Ô (schedule)ÇÑ´Ù. jiffies¶õ ½Ã½ºÅÛÀÇ ÇöÀç ½Ã°£À» ÀǹÌÇÑ´Ù. HZ´Â 1ÃÊ¿¡ ÇØ´çÇÏ´Â °ªÀÌ°í scheduleÀº ÇöÀçÀÇ ÇÁ·Î¼¼½º¸¦ ºí·° ½ÃÅ°´Â ÇÔ¼öÀÌ´Ù. Ä¿³ÎÀº ÀÌ ÇÁ·Î¼¼½º°¡ Àáµé
°í ÀÖ´Â µ¿¾È ´Ù¸¥ ÀÛ¾÷À» ÇÒ ¼ö ÀÖ°Ô µÇ±â ¶§¹®¿¡ È¿À²À» ³ôÀÏ ¼ö ÀÖ´Ù. timeoutÀÌ 3ÃÊ·Î µÇ¾î ÀÖÁö¸¸ ¹Ýµå½Ã ÀÌ ½Ã°¢¿¡ ±ú¾î³´Ù´Â º¸ÀåÀº ¾ø´Ù. ±ú¾î³¯ ¼ö ÀÖ´Â º¸ÀåÀÌ 3ÃÊ ÈÄ ºÎÅͶó´Â °ÍÀÏ »ÓÀÌ´Ù.timeout °ªÀÌ ³Ê¹« ÀÛÀ¸¸é ¹®¸Æ±³È¯ÀÌ ÀÚÁÖ ÀϾ¼ È¿À²ÀÌ ¶³¾îÁö°í ³Ê¹« Å©¸é µå¶óÀ̹ö ÀÛ¾÷ ¼öÇà ¼º´ÉÀÌ ¶³¾îÁö¹Ç·Î ´ë±â ½Ã°£À» Àß Á¶»çÇؼ Àû´çÇÑ °ªÀ» ¼³Á¤ÇØ¾ß ÇÑ´Ù.
Ä¿³ÎÀº ÇÁ·Î¼¼½º¿¡°Ô °¢Á¾ signal À» ÁÙ ¼ö ÀÖ´Ù. include/asm/signal.h¿¡¼ Á¤ÀÇµÈ ¿©·¯ ½Ã±×³ÎÀ» ¹ÞÀº ÇÁ·Î¼¼½º´Â °¡´ÉÇÑÇÑ ½Å¼ÓÇÏ°Ô ÀÛ¾÷À» ³¡³»±â À§Çؼ ºí·°µÇÁö ¾ÊÀ¸¹Ç·Î schedule ÀÌ ¹«½ÃµÇ±â ¶§¹®¿¡ ÄÚµùÀ» ÇÒ ¶§ ÀÌ °ÍÀ» ¿°µÎ¿¡ µÎ°í ±ú¾î ³µÀ» ¶§ Á¤»ó»óÅ¿¡¼ ±ú¾î³ °ÍÀÎÁö signalÀ» ¹Þ¾Ò´ÂÁö ±¸º°Çؼ µ¿ÀÛÇÏ°Ô ÇØ¾ß ÇÑ´Ù. signal À» ¹Þ¾Ò´ÂÁö´Â ±ú¾î³ ÈÄ¿¡ ´ÙÀ½°ú °°ÀÌ ¾Ë¾Æ ³¾ ¼ö ÀÖ´Ù.
if(current->signal & ~current->blocked)
//signal
else
// no signal
½Ã±×³ÎÀ» ¹ÞÀº ÇÁ·Î¼¼½º´Â ´õ ÀÌ»ó ÀÛ¾÷À» ÁøÇàÇÏ´Â °ÍÀÌ Àǹ̰¡ ¾ø±â ¶§¹®¿¡ µð¹ÙÀ̽º¸¦ ¿¬ ÇÁ·Î¼¼½ºÀÇ °¹¼ö°¡ ±â·ÏµÈ º¯¼öÀÇ Ã³¸®µî ²À ÇÊ¿äÇÑ Àϸ¸ ÇÏ°í ½Å¼ÓÇÏ°Ô ³¡³»¾ß ÇÑ´Ù. 2.2 ¹öÀü¿¡¼´Â signal_pending(current)·Î ¹Ù²î¾ú´Ù.
¾Õ¿¡¼ ¸»ÇÑ ´ë±â ÇÔ¼ö´Â ´ë±âÇÏ´Â ÇÁ·Î¼¼½º°¡ ÀÏÁ¤ ½Ã°£ ÀÌÈÄ¿¡ ±ú¾î³ª¼ ¹Ù²ï Á¶°ÇÀ» °Ë»çÇÏ´Â °ÍµéÀÌ´Ù. ´ë±âÇÏ°í ÀÖ´Â µ¿¾È¿¡ ´Ù¸¥ ·çƾ¿¡¼ Á¶°ÇÀ» º¯È ½ÃÅ°°í ´ë±â ÇÁ·Î¼¼½º¸¦ ±ú¿ö Áشٸé Á¶°ÇÀÌ ¸¸Á·Çϱâ Àü¿¡ ±ú¾î³µ´Ù°¡ ´Ù½Ã Àáµå´Â ¿À¹öÇìµå¸¦ ÁÙÀÏ ¼ö ÀÖÀ» °ÍÀÌ´Ù. À̸¦ À§Çؼ sleep/wake_up ÇÔ¼ö°¡ ÀÖ´Ù.
sleep_on/interruptible_sleep_on, wake_up/wake_up_interruptible ÇÔ¼ö´Â Àáµé°í ±ú¿ì´Â ÀÏÀ» ÇÑ´Ù. interruptible_sleep_on ÇÔ¼ö´Â signalÀÌ ¿À°Å³ª wake_up_interruptible ÇÔ¼ö°¡ ±ú¿ö Áְųª current->timeout °ª¿¡ ½Ã½ºÅÛ ½Ã°£ÀÌ À̸£¸é ±ú¾î³´Ù. ÀÌ ÇÔ¼ö¸¦ ½ÇÇàÇϱâ Àü¿¡ timeout °ªÀ» Á¶Á¤ÇØ ÁÙ ¼ö ÀÖÀ¸¹Ç·Î ±ú¿ì´Â ÇÔ¼ö°¡ Á¦´ë·Î ½ÇÇàµÇÁö ¾Ê¾Ò´Ù°í ÆÇ´ÜÇÒ ¸¸Å ÃæºÐÇÑ ½Ã°£À» ÁÖ°í Àáµé°Ô ÇÏ¸é µÈ´Ù. ÀÌ ÇÔ¼ö´Â ´ë±â Å¥°¡ ÇÊ¿äÇϹǷΠ»ç¿ëÇϱâ Àü¿¡ Àü¿ªº¯¼ö·Î Å¥¸¦ Á¤ÀÇÇÏ°í ÃʱâÈ ½ÃÄÑ ³õ¾Æ¾ß ÇÑ´Ù. ÇÔ¼ö
¸íÀº init_waitqueue ÀÌ´Ù.
interruptible_sleep_on/wake_up_interruptible ÇÔ¼ö´Â ÀÎÅÍ·´Æ®¸¦ »ç¿ëÇÏ´Â µå¶óÀ̹ö¿¡¼ µð¹ÙÀ̽º¿¡ ÀÎÅÍ·´Æ®¸¦ °É¾î ³õ°í Àáµé¸é µð¹ÙÀ̽º°¡ 󸮸¦ ³¡³»°í ÀÎÅÍ·´Æ®¸¦ °É¾î ±ú¿ö ÁÖ´Â °æ¿ì¿¡ ¸¹ÀÌ »ç¿ëÇÑ´Ù. ÀÌ ÇÔ¼öµµ schedule °ú ¸¶Âù°¡Áö·Î signalÀ» ¹ÞÀ¸¸é ¹«Á¶°Ç ±ú¾î ³ª±â ¶§¹®¿¡ ²À »óŸ¦ üũÇØ¾ß ÇÑ´Ù.
sleep_on/wake_up ¦Àº wake_up ÇÔ¼ö°¡ ¹Ýµå½Ã ¼öÇàµÈ´Ù´Â È®½ÅÀÌ ÀÖ´Â °æ¿ì¿¡ »ç¿ëµÈ´Ù. sleep_on À¸·Î Àáµé¸é timeout °ªÀÌ Áö³ª°Å³ª ½Ã±×³ÎÀÌ ¿Íµµ ±ú¾î ³ªÁö ¾Ê°í ¿À·ÎÁö wake_up ¸¸ÀÌ ±ú¿ï ¼ö ÀÖ´Ù. wake_up ÇÔ¼ö°¡ ¼öÇàµÇÁö ¾Ê´Â´Ù¸é ½Ã½ºÅÛÀÌ ±³Âø»óÅ¿¡ ºüÁú ¼ö Àֱ⠶§¹®¿¡ 100% È®½ÅÀÌ ¾øÀ¸¸é »ç¿ëÇÏÁö ¾Ê´Â °ÍÀÌ ÁÁ´Ù.
drivers/char/lp.c ¿¡¼ »ç¿ëµÇ¾úÁö¸¸ 2.0.33¿¡¼´Â interruptible·Î ¹Ù²î¾ú´Ù.
drivers/block ÀÇ ÀϺΠµå¶óÀ̹ö¿¡ »ç¿ë¿¹°¡ ÀÖÀ¸¹Ç·Î Âü°íÇϱ⠹ٶõ´Ù.
±×¿Ü¿¡ Ä¿³Î ÇØÄ¿ °¡À̵åÀÇ Áö¿øÇÔ¼ö ºÎºÐ¿¡ ³ª¸ÓÁö ´ë±â ÇÔ¼ö¿¡ ´ëÇÑ ¼³¸íÀÌ ÀÖ´Ù.
ÇÔ¼ö ¼³¸íÀ» ÀÐ°í µå¶óÀ̹ö¸¦ Á¶»çÇؼ »ç¿ë ¹æ¹ýÀ» ¾Ë¾Æ µÎ±â ¹Ù¶õ´Ù. µå¶óÀ̺갡 shared memory ¹æ½ÄÀ¸·Î µð¹ÙÀ̽º¿Í ±³½ÅÇϱâ À§ÇØ ¸Þ¸ð¸®¸¦ È®º¸ÇÏ°í ÀÌ °ÍÀ» »ç¿ëÇÑ´Ù°í ÇÏÀÚ.ÀÌ ¸Þ¸ð¸® ¿µ¿ªÀ» ¸ÞÀϹڽº¶ó°í ºÎ¸¥´Ù.ÀÌ ¸ÞÀϹڽº¸¦ À§Çؼ ÀÏÁ¤ÇÑ ¾çÀÇ ¸Þ¸ð¸®°¡ ÇÊ¿äÇÏ´Ù. ¸ÞÀϹڽº¸¦ ¸¸µé¶§ ¸¶´Ù ¸Þ¸ð¸®¸¦ ÇÒ´ç¹Þ´Â´Ù¸é »ó´çÇÑ ¿À¹öÇìµå°¡ »ý±â¹Ç·Î µð¹ÙÀ̽º ÃʱâÈ ¶§¿¡ ¿µ¿ªÀ» È®º¸ÇØ ³õ°í °è¼Ó »ç¿ëÇϸé ÁÁÀ» °ÍÀÌ´Ù. ÀÌ ¶§ »ç¿ëÇÒ ¼ö ÀÖ´Â ÇÔ¼ö´Â kmallocÀÌ´Ù. kmallocÀÌ ÇÑ ¹ø¿¡ ÇÒ´çÇÒ ¼ö ÀÖ´Â ¸Þ¸ð¸® ¾çÀº 16KB·Î Á¦ÇѵǾî ÀÖ´Ù.
ÇÒ´ç¹ÞÀº ¸Þ¸ð¸® ¿µ¿ªÀ» ÃʱâÈ ÇÒ ¶§´Â memset ÇÔ¼ö¸¦ ¾µ ¼ö ÀÖ´Ù. ÀÎÀÚ·Î ÁÖ´Â °ªÀ¸·Î ¸Þ¸ð¸® ¿µ¿ªÀ» ä¿î´Ù.¸Þ¸ð¸®¿¡¼ ¸Þ¸ð¸®·Î µ¥ÀÌŸ¸¦ º¹»çÇÒ ¶§´Âmemcpy¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.ÀÌ ÇÔ¼ö´Â Ä¿³Î ¸Þ¸ð¸®»çÀÌ¿¡¼ º¹»çÇÒ ¶§¸¸ ¾²´Â ÇÔ¼öÀÌ´Ù.Àý´ë·Î À¯Àú µ¥ÀÌŸ ¿µ¿ª°ú Ä¿³Î ¸Þ¸ð¸®»çÀÌÀÇ º¹»ç¿¡¼ »ç¿ëÇؼ´Â ¾ÈµÈ´Ù.
°³¹ß Ãʱ⿡´Â insmod ÀÎÀÚ°¡ Á¤»óÀûÀ¸·Î Àü´ÞµÇ¾ú´ÂÁö È®ÀÎÇÑ´ÙµçÁö ¾î¶² µð¹ÙÀ̽º°¡ ÀνĵǾú´ÂÁö º¸¿© ÁÖ´Â Ãâ·Â·çƾÀ» °¡´ÉÇÑ ¸¹ÀÌ »ðÀÔÇÏ´Â °ÍÀÌ ÁÁ´Ù. C ¶óÀ̺귯¸® ·çƾÀÇ printf ´Â »ç¿ëÇÒ ¼ö ¾øÁö¸¸ Ä¿³Î ÇÁ·Î±×·¡¹ÖÀ» À§Çؼ printk °¡ ÀÖ´Ù. ¸î°¡Áö Á¦ÇÑÀÌ ÀÖÁö¸¸ printf ¿Í °ÅÀÇ À¯»çÇÏ´Ù. Á¤È®ÇÑ Çü½ÄÀº lib/vsprintf.c¿¡¼ º¼ ¼ö ÀÖ´Ù.
4.4.5 µð¹ÙÀ̽ºÀÇ I/O ÄÁÆ®·Ñ
µð¹ÙÀ̽º µå¶óÀ̹ö°¡ Á¦´ë·Î ÀûÀç µÇ°í ³ª¼ ¼³Á¤°ªÀ» ¹Ù²Ü ÇÊ¿ä°¡ ÀÖÀ» ¶§ ioctl ÇÔ¼ö¸¦ ºÎ¸¥´Ù. C ¶óÀ̺귯¸®ÀÇ ioctl ÇÔ¼ö¸¦ ÀÌ¿ëÇؼ Ä¿³Î µå¶óÀ̹öÀÇ ioctl ÇÔ¼ö¿¡ Á¢±ÙÇÒ ¼ö ÀÖ´Ù. C ¶óÀ̺귯¸®ÀÇ ioctl ÇÔ¼ö ¿øÇüÀº ´ÙÀ½°ú °°´Ù.
int ioctl(int d, int request,...);
d´Â ÆÄÀϱâ¼úÀÚÀ̸ç /dev/my_device0 ¿¡ ÇØ´çÇÑ´Ù. ¿ì¼± open ÇÔ¼ö·Î my_device0¸¦ ¿¾î º¸°í Á¤»óÀûÀ¸·Î ¿¸®¸é ioctlÀ» ½ÇÇàÇÒ ¼ö ÀÖ´Ù. ioctlÀÇ µÎ¹ø° ÀÎÀÚ¿¡ ¿øÇÏ´Â ¸í·ÉÀ» ³Ö´Â´Ù. ¸¸¾à my_device0 ÀÇ ¾î¶² °ªÀ» ¹Ù²Ù°Ô ÇÏ°í ½ÍÀ¸¸é include/linux/my_device.h ¿¡ ¾Æ·¡¿Í °°ÀÌ Á¤ÀÇÇÏ°í À¯Àú ÇÁ·Î±×·¥¿¡¼ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ÇÏ¸é µÈ´Ù.
#define MY_DEVICE_CHANGE_VALUE _IOWR(MY_DEVICE_MAJOR, 1, int[2])
_IOWR/_IOR ¸ÅÅ©·Î´Â include/asm/ioctl.h ¿¡ Á¤ÀǵǾî ÀÖ°í ¿©·¯°¡Áö ºñ½ÁÇÑ ¸ÅÅ©·Î°¡ ÀÖ´Ù. ÇÔ¼ö¸íÀÌ º¸¿©ÁÖ´Â ´ë·Î ¼¼¹ø° ÀÎÀÚ¿¡¼ ÁöÁ¤ÇÑ ¿µ¿ªÀ» Àб⸸ °¡´É/ÀÐ°í ¾²±â °¡´ÉÇÑ ÇüÅ·ΠĿ³Î¿¡ Àü´ÞÇÏ°Ô µÈ´Ù. ÀÌ ¸ÅÅ©·Î´Â ù¹ø° ÀÎÀÚ¿Í µÎ¹ø° ÀÎÀÚ¸¦ °áÇÕÇؼ Ä¿³Î¿¡ Àü´ÞÇÑ´Ù. µÎ¹ø° ÀÎÀÚ¿¡ µé¾î °¥ ¼ö ÀÖ´Â °ªÀÇ Å©±â°¡ ¾ó¸¶³ª µÇ´Â°¡´Â ioctl.h¸¦ Á¶»çÇØ ½º½º·Î ¾Ë¾Æº¸±â ¹Ù¶õ´Ù.
ioctlÀÇ ¼¼¹ø° ÀÎÀÚ´Â Ä¿³Î¿¡ Àü´ÞÇÏ´Â °ªÀ̳ª °ªÀÇ ¹è¿ ¶Ç´Â Ä¿³Î·Î ºÎÅÍ ¹ÞÀ» µ¥ÀÌŸ ¿µ¿ªÀÌ´Ù. Ä¿³Î¿¡ °ª(°ª¹è¿)À» Àü´ÞÇÏ°í °°Àº °÷¿¡ Ä¿³Î·Î ºÎÅÍ °ªÀ» ¹ÞÀ» ¼öµµ ÀÖ´Ù.
Ä¿³ÎÀÇ ioctlÀº º¸³»¿Â ¸í·É¿¡ µû¶ó ¿ÏÀüÈ÷ µ¶¸³µÈ ÀÛ¾÷À» ÇØ¾ß Çϱ⠶§¹®¿¡ °¡Àå ÁöÀúºÐÇÑ ºÎºÐÀÌ´Ù.´ëºÎºÐÀÇ µå¶óÀ̹öµéÀÌswitch ¹®À» »ç¿ëÇؼ ¸í·É¿¡ µû¸¥ ÀÛ¾÷À» ÇÏ´Â Äڵ带 ÀÛ¼ºÇØ ³õ¾Ò´Ù. ÇØ¾ß ÇÏ´Â ÀÛ¾÷¿¡ µû¶ó ³»¿ëÀÌ ´Ù¸£Áö¸¸ Ä¿³Î ÇÁ·Î±×·¡¹Ö°ú Å©°Ô Â÷ÀÌ°¡ ³ª´Â °ÍÀº ¾Æ´Ï´Ù.°¡Àå Áß¿äÇÑ °ÍÀºC¶óÀ̺귯¸® ÇÔ¼öÀÎ ioctl¿¡¼ º¸³»¿Â µ¥ÀÌŸ¸¦ ÁÖ°í ¹Þ´Â ¹æ¹ýÀÌ´Ù. Ä¿³ÎÀÌ º¸´Â ¸Þ¸ð¸® ¿µ¿ª°ú »ç¿ëÀÚ ÇÁ·Î±×·¥ÀÌ º¸´Â ¸Þ¸ð¸® ¿µ¿ªÀº ¿ÏÀüÈ÷ ´Ù¸£±â ¶§¹®¿¡ memcpyµîÀÇ ÇÔ¼ö¸¦ »ç¿ëÇؼ´Â ¾ÈµÈ´Ù.
Ä¿³Î¿¡¼ À¯Àú ÇÁ·Î±×·¥¿¡¼ µ¥ÀÌŸ¸¦ ÀÐ¾î ¿À°Å³ª ¾²±â À§Çؼ´Â ¿ì¼± ÀÐ¾î ¿Ã ¼ö ÀÖ´ÂÁö È®ÀÎÇØ¾ß ÇÑ´Ù. verify_area(VERIFY_READ/VERIFY_WRITE ..) ÇÔ¼ö¸¦ »ç¿ëÇؼ Àаųª ¾²´Âµ¥ ¹®Á¦°¡ ¾øÀ¸¸é memcpy_fromfs/memcpy_tofs ÇÔ¼ö¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
ÀÌ ÇÔ¼ö¸íÀº »ç¿ëÀÚ µ¥ÀÌŸ ¼¼±×¸ÕÆ®¿Í Ä¿³Î µ¥ÀÌŸ ¼¼±×¸ÕÆ®¸¦ ±¸º°ÇÏ´Â ÀÎÅÚ CPUÀÇ ·¹Áö½ºÅÍ ¸íÀÌ fs Àε¥¼ À¯·¡Çß´Ù. 2.2 À̻󿡼´Â ¿©·¯ Ç÷§Æû¿¡¼ ÀÏ¹Ý ¸íĪÀ¸·Î »ç¿ëÇϱâ À§Çؼ copy_from_user/copy_to_user·Î ¹Ù²î¾ú´Ù. 2.2¿¡¼´Â ¶ÇÇÑ verify_area¸¦ ÇÒ ÇÊ¿ä°¡ ¾ø´Ù.
ioctl ÇÔ¼ö´Â »ç¿ëÇϱ⿡ µû¶ó ¼ö¸¹Àº ÀÏÀ» ÇÒ ¼ö ÀÖ´Ù. ioctlÀ» »ç¿ëÇÏ¿© ÇÒ´ç¹ÞÀº ÀÎÅÍ·´Æ®¸¦ ¹Ù²Ü ¼öµµ ÀÖ°í Á¡À¯ÇÏ°í ÀÖ´Â ¹°¸® ÁÖ¼Òµµ º¯°æÇÒ ¼ö ÀÖ´Ù. linux-ggi ÇÁ·ÎÁ§Æ® ±×·ì¿¡¼´Â ¸ðµç VGAµå¶óÀ̹ö¸¦ ´ÜÀÏÈ ½ÃÅ°°í ioctlÀ» »ç¿ëÇؼ °¢ VGAÄ«µåÀÇ Æ¯¼ºÀ» Á¶Á¤Çؼ »ç¿ëÇÏÀÚ°í Á¦¾ÈÇÏ°í ÀÖ´Ù.ÀÌ ¹æ¹ýÀº ¸®´ª½ºVGAµå¶óÀ̹ö ÀÛ¼ºÀ» À§ÇÑ ³ë·ÂÀ» ´ëÆø ÁÙÀÏ ¼ö Àִ ȹ±âÀûÀÎ ¹æ¹ýÀÌ´Ù
4.4.6 µð¹ÙÀ̽º µå¶óÀ̹ö ÀÔÃâ·Â ÇÔ¼ö
ÀÌÁ¦ µð¹ÙÀ̽º µå¶óÀ̹öÀÇ ÇÙ½ÉÀÎ ÀÔÃâ·Â ·çƾ¿¡ ´ëÇؼ ¾Ë¾Æº¸ÀÚ. ÀÌ ºÎºÐÀº Çϵå¿þ¾î¿Í °¡Àå ¹ÐÁ¢ÇÑ ºÎºÐÀ¸·Î Çϵå¿þ¾îÀÇ ±â°èÀûÀÎ ÀÛµ¿±îÁöµµ °í·ÁÇØ¾ß ÇÏ´Â º¹ÀâÇÏ°í Èûµç ÀÛ¾÷À» ÇÊ¿ä·Î ÇÑ´Ù.°Ô´Ù°¡ Ã¥¿¡¼¸¸ º¸´ø ¼¼¸¶Æ÷,±³Âø»óÅ ½ºÄÉÁ층µî ¿î¿µÃ¼Á¦¿¡¼ °¡Àå Áß¿äÇÑ ºÎºÐÀ» Á÷Á¢ ±¸ÇöÇØ¾ß ÇÏ´Â ÀÏÀ̱⵵ ÇÏ´Ù. ¿Â°® °³¹ßÅøÀÌ ³¹«ÇÏ°í ¸¶¿ì½º¸¸À¸·Î ÇÁ·Î±×·¡¹ÖÀ» ³¡³¾ ¼ö ÀÖ´Â ÃÖ»óÀ§ ÀÀ¿ëÇÁ·Î±×·¥ °³¹ß ȯ°æÀÌ Áö¹èÇÏ´Â ¿äÁîÀ½, ÀÌ·¸°Ô ¿ø·ÐÀûÀÌ°í ±Ùº»ÀûÀÎ ÀÛ¾÷À» ÇÒ ¼ö ÀÖ´Ù´Â °ÍÀº Áñ°Å¿òÀ̱⵵ ÇÏ
´Ù. ½É°¢ÇÑ ¼ÒÇÁÆ®¿þ¾î À§±â°¡ ´ÚÄ¡¸é ´ÚÄ¥ ¼ö·Ï ÄÄÇ»Å͸¦ ¹è¿ì´Â »ç¶÷µé, ÄÄÇ»Å͸¦ »ç¿ëÇÏ¿© ¹«¾ùÀΰ¡¸¦ ÀÌ·ç¾î º¼·Á´Â »ç¶÷µéÀº °¡Àå ±Ùº»ÀûÀÎ ºÎºÐÀ» ´Ù½Ã µé¿©´Ù º¸¾Æ¾ß ÇÒ ÇÊ¿ä°¡ ÀÖ´Ù. ƯÈ÷ ÄÄÇ»Å͸¦ ¹è¿ì°í ÀÖ´Â ÇлýÀ̶ó¸é ¹Ýµå½Ã ¸®´ª½º Ä¿³Î¿¡ °ü½ÉÀ» °¡Á®¾ß ÇÏ´Â ÀÌÀ¯°¡ ¹Ù·Î ¿©±â¿¡ ÀÖ´Â °ÍÀÌ´Ù.
Ä¿³ÎÀÌ ¹ßÀüÇÏ¸é¼ ÇÊ¿ä¿¡ µû¶ó º¯¼ö¸íÀ̳ª ÇÔ¼ö¸íµéÀ» ¹Ù²Ü ÇÊ¿ä°¡ »ý±ä´Ù. À¯ÀúÇÁ·Î±×·¡¹Ö¿¡¼´Â ¶óÀ̺귯¸® ÇÔ¼ö ÀÎÅÍÆäÀ̽º°¡ ¹Ù²ð ¼öµµ ÀÖÁö¸¸ write°°Àº °¡Àå ±âº»ÀûÀÎ ÀÎÅÍÆäÀ̽º´Â °ÅÀÇ ¹Ù²îÁö ¾Ê´Â´Ù.
static ssize_t my_device_write(struct file *, const char *, size_t count, loff_t *);
4.4.6.1 MY_DEVICE_OPEN ÇÔ¼ö
µð¹ÙÀ̽º µå¶óÀ̹ö¸¦ ÀÌ¿ëÇÏ´Â ÀÀ¿ëÇÁ·Î±×·¥
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
void main(int argc, char*argv[])
{
int w_dev;
char read_value[4096];
w_dev = open(¡°dev/my_device0", O_WRONLY | O_APPEND);
read(r_dev, read_value, 1024);
write(w_dev, read_value, 1024);
}
¶óÀ̺귯¸®ÀÇ open("/dev/my_device0",...) È£ÃâÀÌ ¿À¸é Ä¿³ÎÀÌ ÃÖÁ¾ÀûÀ¸·Î ºÎ¸£´Â ·çƾÀº my_device_open ÇÔ¼öÀÌ´Ù. ¿©±â¼´Â µð¹ÙÀ̽º »óŸ¦ Á¡°ËÇÏ°í ¿ ¼ö ÀÖ´ÂÁö È®ÀÎÇÑ ´ÙÀ½ ÇÊ¿äÇÑ ¸Þ¸ð¸®µîÀ» ÁغñÇÏ°í ´Ù¸¥ ·çƾ¿¡¼ »ç¿ëÇÏÁö ¸øÇϵµ·Ï busy ¼¼ÆÃÀ» ÇÏ¸é µÈ´Ù.
¸ðµâ ¹æ½ÄÀ¸·Î ÀûÀç ÇßÀ» ¶§¸¦ »ý°¢Çغ¸ÀÚ. ¸¸¾à open,read/write ·çƾÀ» ¼öÇà ÁßÀÎ »óÅ¿¡¼ rmmod ¸¦ »ç¿ëÇؼ ¸ðµâÀ» »èÁ¦ÇÏ¸é µð¹ÙÀ̽ºµå¶óÀ̹ö ·çƾÀ» ¼öÇàÇÒ ¼öµµ,Á¤»óÀûÀ¸·Î Áß´ÜÇÒ ¼öµµ ¾ø°Ô µÇ¾î Ä¿³ÎÀÌ Á¤ÁöÇÏ°Ô µÈ´Ù.±×·¯¹Ç·Î µð¹ÙÀ̽ºµå¶óÀ̹ö ·çƾÀ» ¼öÇà ÁßÀÎ ÇÁ·Î¼¼½º°¡ ÀÖÀ¸¸é À̸¦ ¾Ë·ÁÁÖ´Â º¯¼ö¸¦ Áõ°¡½ÃÄѼ ¸ðµâ »èÁ¦ ÇÔ¼ö°¡ Âü°íÇÏ°Ô ÇÏ¸é µÈ´Ù.ÀÌ º¯¼ö °ªÀ» Áõ°¡/°¨¼Ò ½ÃÅ°´Â ¸ÅÅ©·Î´Â
MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT ÀÌ´Ù. my_device_openÇÔ¼ö¸¦ ¼öÇàÇÏ¸é¼ ¿±â¿¡ ¹®Á¦°¡ ¾ø´Ù¸é ÀÌ °ªÀ» Áõ°¡½ÃŲ´Ù. ¸¸¾à ÀÌ °ªÀ» Áõ°¡½ÃŲ ÈÄ¿¡ open ·çƾÀ» ¼öÇàÇÏ¸é¼ ¹®Á¦°¡ »ý°Ü ¿¡·¯ ¸®ÅÏÇÒ ¶§¿¡´Â ¹Ýµå½Ã °ªÀ» °¨¼Ò½ÃÄÑ¾ß ÇÑ´Ù. Áõ°¡/°¨¼Ò ¦ÀÌ ¸ÂÁö ¾ÊÀ¸¸é µå¶óÀ̹ö¸¦ »èÁ¦ÇÒ ¼ö ¾ø´Ù.Á¤»óÀûÀ¸·Î ÀÛµ¿µÈ´Ù¸é release ·çƾ¿¡¼ °¨¼Ò½ÃÅ°¸é µÈ´Ù. write/read ¼öÇà µµÁß¿¡ ¿¡¶ó·Î ¸®ÅÏÇϸé Ä¿³ÎÀÌ release¸¦ ºÎ¸£±â ¶§¹®¿¡ write ·çƾ¿¡¼´Â ½Å°æ¾µ ÇÊ¿ä´Â ¾ø´Ù.
Ä¿³ÎÀÌ openÀ» È£Ãâ ÇÒ ¶§¿¡´Â ÁÖÀåÄ¡¹øÈ£¸¦ º¸°í È£ÃâÇϹǷΠ³»ºÎ¿¡¼ ºÎÀåÄ¡¹øÈ£¸¦ ±¸ÇØ¾ß ÇÑ´Ù. ºÎÀåÄ¡¹øÈ£´Â MINOR(inode->i_rdev) ¸ÅÅ©·Î·Î ±¸ÇÒ ¼ö ÀÖ´Ù. »ç¿ëÀÚ°¡ open("/dev/my_device255"..) ó·³ È£ÃâÇÒ ¼öµµ ÀÖÀ¸¹Ç·Î ÀÌ °ªÀÌ À¯È¿ÇÑ °ªÀÎÁö ±×¸®°í ½ÇÁ¦·Î »ç¿ë°¡´ÉÇÑ °ªÀÎÁö È®ÀÎÇØ¾ß ÇÑ´Ù. Àü¿ªº¯¼ö·Î MY_DEVICE_MAX¸¦ ¼±¾ðÇϰųª my_device ±¸Á¶Ã¼ ¹è¿À» ¼±¾ðÇÏ°í exist Çʵ带 Á¤ÀÇÇÑ ´ÙÀ½ À¯È¿ÇÑ ºÎÀåÄ¡ ¹øÈ£ÀÇ existÇʵ带 ¼¼ÆÃÇÏ¸é µÈ´Ù. drivers/char/lp.c¸¦ º¸¸é lp[0-3]±îÁö¸¦ ÀÌ·± ¹æ½Ä
À¸·Î »ç¿ëÇÏ°í ÀÖ´Ù.
Ä¿³ÎÀº ºÎÀåÄ¡°¡ ´Ù¸¥ ·çƾ¿¡¼ »ç¿ëÁßÀÎÁö °Ë»çÇÏÁö ¾Ê´Â´Ù. ¿±â ¿äûÀÌ ¿À¸é ¹«Á¶°Ç open·çƾÀ¸·Î Á¦¾î°¡ À̵¿Çϱ⠶§¹®¿¡ ´Ù¸¥ ·çƾ¿¡¼ »ç¿ëÇÏÁö ¸øÇÏ°Ô Çϰųª »ç¿ëÀÌ ³¡³ª´Â ½ÃÁ¡À̶ó´Â °ÍÀ» ¾Ë·Á ÁÖ´Â ÀÏÀº µå¶óÀ̹öÀÇ ¸òÀÌ´Ù. ¸¶Âù°¡Áö·Î my_device ±¸Á¶Ã¼ ¾È¿¡ busy Çʵ带 Á¤ÀÇÇÏ°í À̸¦ »ç¿ëÇÏ¸é µÈ´Ù. °£´ÜÈ÷ my_device¿¡ ÇÊ¿äÇÑ Á¤º¸¸¦ ´ã´Â ±¸Á¶Ã¼¸¦ ¸¸µé¾îº¸ÀÚ.
my_device´Â Ä«µå¿¡ CPU°¡ ÀÖ°í ÀÌ Ä«µå°¡ 2°³ ÀÌ»óÀÇ ºÎÀåÄ¡¹øÈ£¸¦ Á¦¾îÇÑ´Ù. ¸¸ÀÏ ¸ÖƼ½Ã¸®¾óÆ÷Æ®¶ó¸é 8-64°³±îÁöÀÇ ½Ã¸®¾óÆ÷Æ®¸¦ ÇÑ Ä«µå°¡ Á¦¾îÇÏ°Ô µÉ °ÍÀÌ´Ù. ±×¸®°í °¢ Æ÷Æ®´Â Æ÷Æ®º°·Î ÇÊ¿äÇÑ Á¤º¸¿Í ÀÌ Æ÷Æ®°¡ ¾î´À Ä«µå¿¡ ÀÖ´Â °ÍÀÎÁö ¾Ë·ÁÁÖ´Â Á¤º¸°¡ ÀÖ¾î¾ß ÇÒ °ÍÀÌ´Ù.¿ì¼± Ä«µå Á¤ÀǸ¦ ÇÑ´Ù.
struct MY_DEVICE_CARD {
int number; /* Ä«µå¹øÈ£ */
u_int flag; /* »óÅ Ç÷¡±× */
int base; /* base ÁÖ¼Ò */
u_int irq; /* ÀÎÅÍ·´Æ® ¹øÈ£ */
u_int address; /* memory mapped I/O ÁÖ¼Ò */
u_char *mailbox_kernel; /* Ä¿³Î¿¡¼ º¸³¾ ¸ÞÀϹڽº */
u_char *mailbox_card; /* Ä«µå¿¡¼ º¸³»¿Â ¸ÞÀϹڽº */
struct semaphore semaphore; /* ÁÖÀåÄ¡ÀÇ ¼¼¸¶Æ÷ */
struct wait_queue *queue; /* ÁÖÀåÄ¡ÀÇ ´ë±âÅ¥ */
};
struct MY_DEVICE_CARD my_device_card[MY_DEVICE_CARD_MAX];
ÀÌ¿¡ µû¸¥ Æ÷Æ®ÀÇ Á¤ÀÇ´Â ´ÙÀ½°ú °°ÀÌ ÇÒ ¼ö ÀÖ´Ù.
struct MY_DEVICE_PORT {
int number; /* Æ÷Æ® ¹øÈ£ */
int card_number; /* Æ÷Æ®°¡ ¼ÓÇÑ Ä«µå ¹øÈ£ */
u_int flag; /* »óÅ Ç÷¡±× */
u_char *buffer; /* ¹öÆÛ Æ÷ÀÎÅÍ */
};
struct MY_DEVICE_PORT my_device_port[MY_DEVICE_PORT_MAX];
À§ÀÇ ³»¿ëÀº ¿©Å±îÁö ¼³¸íÇß´ø ±Û¿¡¼ ÇÊ¿äÇÏ´Ù°í »ý°¢µÇ´Â µ¥ÀÌÅ͸¦ ¸ð¾Æº» °ÍÀÌ´Ù.
¿ì¼± card->irq, card->base´Â ÀÎÀÚ·Î ¹ÞÀ» ¼ö ÀÖÀ¸¹Ç·Î ÃʱⰪÀ» 0·Î µÎ¾î¼ Ä«µå°¡ Á¸ÀçÇÏ´ÂÁö ÆÇ´ÜÇÒ ¼ö ÀÖ°Ô ÇÑ´Ù. ÀÌ °ª¿¡ µû¶ó Æ÷Æ®°¡ »ç¿ë°¡´ÉÀÎÁö Á¤ÇØÁö¹Ç·Î ÃʱâȽÿ¡ Ä«µå¿¡ µþ¸° Æ÷Æ®¸¦ °Ë»çÇؼ port->flagÀÇ existÇʵ带 ¼¼ÆÃÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù. card->address´Â ¸Þ¸ð¸®¸ã ¹æ½Ä I/O¿¡¼ »ç¿ëÇÒ ÁÖ¼Ò°ªÀÌ°í mailbox_* ´Â Ä«µå¿Í µå¶óÀ̹ö°¡ ±³½ÅÇÏ¸é¼ »ç¿ëÇÒ ¸ÞÀϹڽº (Documentations/IO-mapping.txtÂüÁ¶)ÀÌ´Ù.
ÀÌ °ÍÀº µ¥ÀÌŸ¸¦ ÁÖ°í ¹Þ´Â °ÍÀÌ ¾Æ´Ï°í ÁÖÀåÄ¡ÀÇ »óŸ¦ Á¡°ËÇÏ°í Ä«µå°¡ »óŸ¦ º¸°íÇÏ´Â ¿ëµµ·Î »ç¿ëµÇ´Â °ÍÀ̹ǷΠºÎÀåÄ¡°¡ ¾Æ´Ñ ÁÖÀåÄ¡¿¡ ÀÖ¾î¾ß ÇÑ´Ù. ´ë±âÅ¥µµ ÇÑ ÁÖÀåÄ¡¹øÈ£¿¡ ÇÒ´çµÇ¾î¼ °¢ ºÎÀåÄ¡¿¡¼ µ¹¾Æ°¡´Â ÇÁ·Î¼¼½ºµéÀÌ °øÀ¯ÇÏ°Ô µÈ´Ù. ¸ÖƼ½Ã¸®¾óÆ÷Æ®³ª °°Àº ÀåÄ¡¸¦ ¿©·¯°³ ´Þ ¼ö ÀÖ´Â Çϵå¿þ¾î´Â ºÎÀåÄ¡¹øÈ£¸¦ °¡Áö°í ÁÖÀåÄ¡¹øÈ£¸¦ ±¸ÇØ ³¾ ¼ö ÀÖ¾î¾ß ÇϹǷΠport->card_number°¡ ¹Ýµå½Ã ÇÊ¿äÇÏ´Ù. ¹öÆÛ´Â ½ÇÁ¦ µ¥ÀÌÅ͸¦ º¸³»´Â °ÍÀ̹ǷΠºÎÀåÄ¡µéÀÌ Çϳª¾¿ °¡Áö°Ô µÈ´Ù.
ÀÌ·± ÇüÅ°¡ ¸ÖƼ ½Ã¸®¾óÀ̳ª µ¿ÀÏ Çϵå¿þ¾î¸¦ ¿©·¯°³ ºÙÀÏ °æ¿ì¿¡ ÀϹÝÀûÀ¸·Î »ç¿ëµÇ´Â ¹æ¹ýÀÌ´Ù.°¢Çʵ忡 Á¢±ÙÇÏ´Â ¹æ¹ýÀº ´ÙÀ½Ã³·³ ÇÏ°Ô µÈ´Ù.
struct MY_DEVICE_CARD *card =
my_device_card[my_device_port[minor].card_number];
u_char *mailbox = card->mailbox_kernel;
ÀÌ·± ¹æ¹ýÀÌ Äڵ带 º¹ÀâÇÏ°Ô ¸¸µé±â ¶§¹®¿¡ ÀϺΠµå¶óÀ̹ö¿¡¼´Â ¸ÅÅ©·Î Á¤ÀǷΠó¸®
ÇÏ°í ÀÖ´Ù.
#define MY_CARD(minor) my_device_card[my_device_port[(minor)].card_number]
...
struct MY_DEVICE_CARD *card = MY_CARD(minor);
...
C ÇÁ·Î±×·¡¹ÖÀÇ ±âÃÊÀûÀÎ À̾߱⸦ ¿©±â¼ ÇÏ´Â ÀÌÀ¯´Â Ä¿³Î¿¡¼ ÄÚµåÀÇ °¡µ¶¼º°ú È¿À²À» ³ôÀ̱â À§Çؼ »ç¿ëÇÏ´Â ¸ÅÅ©·ÎµéÀÌ ¿ÀÈ÷·Á °¡µ¶¼ºÀ» ¶³¾î¶ß¸®°í ¸¶Ä¡ ¼Ò½º°¡ ¾ÏÈ£¿Í °°Àº ¸ð¾çÀ» ¶ç°Ô Çϱ⠶§¹®¿¡, ÀÌ·± ¸ÅÅ©·ÎµéÀÌ ³ª¿À¸é ¼±¾ðºÎ¸¦ ã¾Æ º¸°í ±×³»¿ëÀ» ÀÍÈ÷¶ó´Â ¸»À» Çϱâ À§ÇؼÀÌ´Ù. ¸®´ª½º Ä¿³Î¿¡¼ »ç¿ëµÇ´Â ´ë¹®ÀÚ º¯¼öµéÀº °ÅÀÇ°¡ »ó¼ö°ªÀÌ ¾Æ´Ï¶ó º¹ÀâÇÑ ¸ÅÅ©·ÎÀÎ °æ¿ì°¡ ´ëºÎºÐÀ̱⠶§¹®ÀÌ´Ù.
my_device°¡ ÃëÇÒ ¼ö ÀÖ´Â »óÅ°ªÀº ¿©·¯°¡Áö°¡ ÀÖÀ» ¼ö ÀÖ´Ù. °£´ÜÇÏ°Ô ¸î°¡Áö¸¸ »ý°¢Çغ¸ÀÚ.
#define MY_DEVICE_PORT_IDLE 0x00001
#define MY_DEVICE_PORT_BUSY 0x00002
#define MY_DEVICE_PORT_ERROR 0x00003
#define MY_DEVICE_STATUS_EXIST 0x00010
#define MY_DEVICE_STATUS_BUSY 0x00020
#define MY_DEVICE_STATUS_ERROR 0x00040
À§¿¡¼ »ç¿ëÇÑ µÎ°¡Áö ¹æ¹ýÀº ¾à°£ ´Ù¸£´Ù.¿ì¼± ù¹ø°·Î °ªÀ»10Áø¼ö·Î Áõ°¡½ÃÅ°´Â ¹æ¹ýÀº Çϵå¿þ¾î°¡ »óŸ¦ º¸³»¿Ã ¶§ »ç¿ëÇÒ ¼ö ÀÖ´Ù. my_deviceÄ«µå°¡ º¸³»¿À´Â °ªÀÌ 10Áø¼ö °ªÀ̶ó´Â ¸»ÀÌ´Ù. À̶§ »óŸ¦ ÆÇ´ÜÇϱâ À§Çؼ´Â ´ÙÀ½°ú °°ÀÌ ÇØ¾ß ÇÒ °ÍÀÌ´Ù.
if(status==MY_DEVICE_PORT_IDLE || status==MY_DEVICE_PORT_BUSY)
...
ÀÌ·¸°Ô 10Áø¼ö¸¦ »ç¿ëÇÏ´Â ¹æ¹ýÀº µå¶óÀ̹ö°¡ ¹Þ´Â Á¤º¸°¡ 10Áø¼ö ÀÏ ¶§¸¦ Á¦¿ÜÇÏ°í´Â »ç¿ëÇÏÁö ¾Ê´Â °ÍÀÌ ÁÁ´Ù. ¿Ö³ÄÇÏ¸é °¢ºñÆ®¸¦ »óÅ°ªÀ¸·Î ÀÌ¿ëÇÏ´Â °Í¿¡ ºñÇؼ ´ÜÁ¡ÀÌ ¸¹±â ¶§¹®ÀÌ´Ù.¿ì¼± »óÅÂÁ¤º¸¸¦ ºÐ·ùÇÒ ¼ö ¾ø´Ù.ºñÆ®ÀÌ¿ë¹ýÀº óÀ½ 4ºñÆ®´Â µå¶óÀ̹ö ÀÚü ¿¡·¯
´ÙÀ½ 4ºñÆ®´Â Çϵå¿þ¾î ¿¡·¯µîÀ¸·Î ºÐ·ùÇؼ ½±°Ô ¿¡·¯ Á¾·ù¸¦ ±¸Çس¾ ¼ö ÀÖ´Ù.
if((status & 0xf0) != 0) // hardware error
else if((status & 0x0f) != 0) // driver error
10Áø¼ö »ç¿ë¹ýÀº »óÅÂÁ¤º¸ÀÇ Ãß°¡/º¯°æÀÌ Èûµé´Ù. idle(1)¿¡¼ busy(2)·Î ¹Ù²Ù´Â °ÍÀº ¹®Á¦°¡ ¾øÁö¸¸ card_error, card_waitµîÀÇ µå¶óÀ̹ö¿¡¼ »óŸ¦ À¯ÁöÇØ¾ß ÇÏ´Â Á¤º¸¸¦ À§Çؼ´Â º¹ÀâÇÑ ¹æ¹ýÀ» »ç¿ëÇÏ´øÁö card_status Çʵ带 ¶ÇÇϳª Ãß°¡Çؼ »ç¿ëÇØ¾ß ÇÑ´Ù. ¸®´ª½º¿¡¼ unsigned int´Â 32ºñÆ®À̹ǷΠµ¿½Ã¿¡ 32°³ÀÇ »óŸ¦ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.
ºñÆ® ÀÌ¿ë¹ýÀº 32°³ÀÇ »óűîÁö´Â ºñÆ®¿ Á¤ÀǸ¸À¸·Î °£´ÜÈ÷ ÇØ°áÇÒ ¼ö ÀÖ´Ù. ¼Óµµ¿Í È¿À²¼º ±×¸®°í ¸Þ¸ð¸® »ç¿ë·®ÀÇ ÃÖÀûȸ¦ ¿ä±¸ÇÏ´Â Ä¿³Î ÇÁ·Î±×·¡¹Ö¿¡¼ ÇÊ¿äÇÒ ¶§¸¶´Ù ÀÚ¿øÀ» Ãß°¡ÇØ ³ª°¡´Â °ÍÀº ÁÁÀº ¹æ¹ýÀÌ ¾Æ´Ï´Ù.
10Áø¼ö »ç¿ë¹ýÀº ¼Óµµ°¡ ´À¸®´Ù. ¿©·¯ »óÅÂÁ¤º¸¸¦ ¾ò±â À§Çؼ »ç¿ëÇØ¾ß ÇÒ ¿¬»êÀÌ ¸¹¾ÆÁö°Ô µÇ¹Ç·Î ºñÆ®ÀÌ¿ë¹ýº¸´Ù ´À¸®°í Äڵ尡 º¹ÀâÇØÁø´Ù. ÇÑ Çϵå¿þ¾î°¡ ÀÌ ÀÌ»óÀÇ »óÅÂÁ¤º¸°¡ ÇÊ¿äÇÑ °æ¿ì°¡ º°·Î ¾øÀ¸¹Ç·Î my_device_card¿¡¼ ó·³ »óÅÂÁ¤º¸´Â flag ÇʵåÀÇ ºñÆ®À§Ä¡·Î ºü¸£°í °£´ÜÇÏ°Ô ÆÇ´ÜÇÒ ¼ö ÀÖ°Ô ÇÏ´Â °ÍÀÌ ÁÁ´Ù.
µå¶óÀ̹ö¿¡¼ ¸®ÅÏÇÏ´Â ¿¡·¯°ªÀº include/asm/errno.h ¿¡ Á¤ÀÇµÈ °ª¿¡ (-)ºÎÈ£¸¦ ºÙ¿©¼ µ¹·Á ÁÖ¸é µÈ´Ù.Ä¡¸íÀûÀÎ ¿¡·¯¿¡´ÂEIO, ENOMEM µîÀÌ ÀÖÀ» ¼ö ÀÖ°í Ä¿³Î¿¡¼ 󸮸¦ ÇÏ°í µå¶óÀ̹ö ¿±â¸¦ Àç½Ãµµ ÇÒ ¼ö ÀÖ°Ô ÇÏ´Â EAGAIN µîÀÌ ÀÖÀ» ¼ö ÀÖ´Ù. ¿¡¶ó Á¾·ù¿Í ¸®ÅÏ°ªÀº ¿©·¯ µå¶óÀ̹ö ¼Ò½º¸¦ º¸°í ÆľÇÇϱ⠹ٶõ´Ù.
my_device_open¿¡¼ ÇؾßÇÏ´Â ÀÏÀ» ¿ä¾àÇÏÀÚ¸é ´Ù¸¥ ÇÁ·Î¼¼½º°¡ ºÎÀåÄ¡¹øÈ£¸¦ »ç¿ëÁßÀÎÁö °Ë»çÇÏ°í ÀÌ ¹øÈ£°¡ À¯È¿ÇÑ °ÍÀÎÁö üũÇÑ ´ÙÀ½ MOD_INC_USE_COUNT¸¦ »ç¿ëÇؼ ¸ðµâ »èÁ¦½Ã¿¡ Âü°íÇÏ°Ô ÇÑ ÈÄ¿¡ ÇÊ¿äÇÑ ÀÚ¿øÀ» ÇÒ´ç¹Þ°í ´Ù¸¥ ÇÁ·Î¼¼½º°¡ ÀÌ ÀåÄ¡¸¦ »ç¿ëÇÒ ¼ö ¾øµµ·Ï busy¼¼ÆÃÀ» ÇÏ¸é µÈ´Ù.
4.4.6.2 MY_DEVICE_READ/WRITE ÇÔ¼ö
¿±â ÇÔ¼ö¸¦ ¼öÇàÇß´Ù¸é Ä¿³Î¿¡¼ Àбâ/¾²±â ÇÔ¼ö¸¦ È£ÃâÇÒ ¼ö ÀÖ´Ù.¿±â/¾²±â ÇÔ¼öÀÇ ¿øÇüÀº 2.2.x¿¡¼ ´ÙÀ½°ú °°´Ù.
static ssize_t my_device_read(struct file * file, char * buf, size_t count, loff_t
*ppos);
static ssize_t my_device_write(struct file * file, const char * buf, size_t
count, loff_t *ppos);
¾²±âÇÔ¼ö¿¡¼´Â ¾µ µ¥ÀÌŸ°¡ ÀÖ´Â ÁÖ¼Ò buf°¡ Àü´ÞµÇ¾î ¿À°í Àбâ ÇÔ¼ö¿¡¼´Â Àо µ¥ÀÌÅÍ ¿µ¿ªÀÎ bufÁÖ¼Ò°¡ Àü´ÞµÇ¾î ¿Â´Ù. ¾²±âÇÔ¼öÀÇ µ¥ÀÌŸ´Â Ä¿³Î¿¡¼ 󸮰¡ µÇ¾î Ä¿³Î ¸Þ¸ð¸® ¿µ¿ªÀ¸·Î »ý°¢ÇÏ°í »ç¿ëÇÏ¸é µÈ´Ù. ioclt ÇÔ¼ö »ç¿ë¹ý¿¡¼ ¸»ÇßµíÀÌ memcpyµîÀ» »ç¿ëÇÒ ¼ö ¾ø°í copy_to_user¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. Âü°í·Î Çѹø¿¡ buf·Î ³Ñ¾î¿À´Â µ¥ÀÌŸÀÇ ÃÖ´ë°ªÀº 4096¹ÙÀÌÆ®ÀÌ´Ù.
read/write¿¡¼ ¹°·Ð ºÎÀåÄ¡¹øÈ£¸¦ üũÇØ¾ß ÇÑ´Ù. »ç¿ëÇÒ ¼ö ¾ø´Â ºÎÀåÄ¡¿¡ Á¢±Ù ¿ä±¸°¡ ¿À¸é ¿¡¶ó°ªÀ» °¡Áö°í ¸®ÅÏÇØ¾ß ÇÑ´Ù. inode°¡ ³Ñ¾î¿ÀÁö ¾ÊÀ¸¹Ç·Î file ±¸Á¶Ã¼¿¡¼ ã¾Æ¾ß ÇÑ´Ù.¾î¶»°Ô ã´ÂÁö´Â ¿©·¯ ¼Ò½º¸¦ ã¾Æº¸±â ¹Ù¶õ´Ù.count´Â Àаųª ¾µ µ¥ÀÌŸÀÇ ¾çÀ» ³ªÅ¸³»°í ppos´Â ±× ÁöÁ¡ÀÇ ÁÖ¼Ò°ªÀÌ´Ù. ppos´Â ºí·° µð¹ÙÀ̽º¿¡ ÁÖ·Î ¾²°Ô µÇ¸ç ¹®ÀÚ µð¹ÙÀ̽º¿¡¼´Â °ÅÀÇ »ç¿ëµÇÁö ¾Ê´Â´Ù.
¾µ µ¥ÀÌŸ°¡ ÀÖ°í ¾µ·Á´Â ºÎÀåÄ¡°¡ À¯È¿ÇÑ °ÍÀ̶ó¸é ÀÌÁ¦ Çϵå¿þ¾î¸¦ °Ë»çÇÑ ÈÄ¿¡ µ¥ÀÌŸ¸¦ ¾²¸é µÈ´Ù. Çϵå¿þ¾î °Ë»ç´Â µå¶óÀ̹ö¿¡¼ ¾µ ¶§¸¶´Ù ÇÒ ¼öµµ ÀÖ°í Çϵå¿þ¾î°¡ »óź¯È¸¦ º¸°íÇÒ ¼öµµ ÀÖ´Ù. ¿©·¯°¡Áö ¹æ¹ýÀº Çϵå¿þ¾î Ư¼º¿¡ µû¶ó ´Ù¸£°í °¢ µð¹ÙÀ̽º°¡ »ç¿ëÇÏ´Â ¹æ¹ýÀÌ ´Ù¸£¹Ç·Î ¸¸µé·Á´Â µå¶óÀ̹ö¿¡ ¸Â°Ô ÀÛ¼ºÇØ¾ß ÇÑ´Ù. »óÅ°¡ Á¤»óÀ̶ó¸é ¹®ÀÚµð¹ÙÀ̽ºÀÏ ¶§ ÇÑ ¹ø¿¡ ÇÑ ¹ÙÀÌÆ®¾¿À» ¾²°í °á°ú¸¦ º¸¸é¼ ±× ´ÙÀ½ ¹ÙÀÌÆ®¸¦ º¸³»°Å³ª(lp.c), Çϵå¿þ¾î°¡ ¹®ÀÚµð¹ÙÀ̽º¸¦ ´Ù·çÁö¸¸ ³»ºÎÀûÀ¸·Î ´ë·®ÀÇ µ¥ÀÌ
Ÿ¸¦ ¹ÞÀ» ¼ö ÀÖ´Â ÀåÄ¡¶ó¸é ÀÏÁ¤ ´ÜÀ§ÀÇ µ¥ÀÌŸ¸¦ º¸³»¸é µÈ´Ù. ºí·°µð¹ÙÀ̽º¶ó¸é ÀÚüÀûÀ¸·Î µ¥ÀÌŸ¸¦ º¸³¾ ¼öµµ ÀÖ°í block_write¶ó´Â ºí·°µð¹ÙÀ̽º °ø¿ë ·çƾÀ» »ç¿ëÇÒ¼öµµ ÀÖ´Ù.
¾²°Å³ª ÀÐÀ» µ¥ÀÌŸ ¾çÀ» ¸ðµÎ ó¸®ÇÏ´Â µ¿¾È ¹®Á¦°¡ »ý±âÁö ¾Ê¾ÒÀ¸¸é ¾²°Å³ª ÀÐÀº µ¥ÀÌŸ ¾çÀ» Àμö·Î ÇÏ¿© ¸®ÅÏÇÏ¸é µÈ´Ù. ½Ã±×³ÎÀ» ¹Þ¾ÒÀ¸¸é -EINTR °ªÀ» »ç¿ëÇÏ°í ±× ¿Ü¿¡ ¿¡¶ó°¡ ¹ß»ýÇÏ¿´À¸³ª Ä¿³Î ÂÊ¿¡¼ Àç½Ãµµ¸¦ Çϱ⸦ ¿øÇÑ´Ù¸é ±× ¶§±îÁö ÀÐÀº/¾´ µ¥ÀÌŸ ¾çÀ» Àμö·Î ÇÏ¿© ¸®ÅÏÇÑ´Ù.°¢Á¾ ¿¡¶ó°¡ ¹ß»ýÇß°í Ä¿³Î ÂÊ¿¡¼ Àбâ/¾²±â¸¦ Àç ½Ãµµ ÇÒ ¼ö ¾ø´Â ¿¡¶óÀ̸é Ä¿³Î¿¡¼ my_device_release¸¦ ½º½º·Î È£ÃâÇÏ°Ô µÇ¾îÀÖÀ¸¹Ç·Î open/read,write/release Àüü¿¡ °ÉÄ£ º¯¼ö°ªµîÀ» read/write ·çƾ¿¡¼ ½Å°æ ¾µ ÇÊ¿ä´Â ¾ø´Ù. read/write ·çƾ ¾È¿¡¼ »ç¿ëÇÑ °ª°ú ÀÌ ·çƾÀÌ Á¤»óÀûÀ¸·Î ³¡³µÀ»¶§ º¯°æµÇ´Â Àü¿ª º¯¼ö¿¡ ´ëÇؼ¸¸ ½Å°æÀ» ¾²¸é µÈ´Ù.
4.4.6.3 MY_DEVICE_RELEASE ÇÔ¼ö
release ÇÔ¼ö¿¡¼´Â open¿¡¼ Çß´ø ÀÏÀ» ¿ªÀ¸·Î ÇÏ¸é µÈ´Ù. ¿ì¼± ¸Þ¸ð¸®¿µ¿ªÀ» ÇÒ´ç¹Þ¾Æ¼ »ç¿ëÇß´Ù¸é ¹Ý³³ÇÑ´Ù.ºÎÀåÄ¡¿¡ ´ëÇؼbusy¼¼ÆÃÀ» Çß´Ù¸é À̸¦ ÇØÁ¦ÇÑ´Ù. ¸ðµâÀ» »ç¿ëÇß´Ù¸é MOD_DEC_USE_COUNT¸¦ ½ÇÇàÇؼ ¸ðµâ »ç¿ë°ªÀ» °¨¼Ò½ÃŲ´Ù. ÀÌ ¸ÅÅ©·Î´Â ÀÚüÀûÀ¸·Î ¸ðµâ·Î ÀûÀçµÇ¾ú´ÂÁö Ä¿³Î¿¡ °°ÀÌ ÄÄÆÄÀϵǾú´ÂÁö ±¸º°Çϱ⠶§¹®¿¡ #ifdef MODULE À» »ç¿ëÇÏÁö ¾Ê¾Æµµ µÈ´Ù. ÀÎÅÍ·´Æ®¸¦ open¿¡¼ ÇÒ´ç¹Þ¾Ò´Ù¸é ¿©±â¼ ÇØÁ¦ÇÑ´Ù.ÀÎÅÍ·´Æ®¸¦ °øÀ¯ÇÏ´Â ÀåÄ¡µéÀº ÀÌ·¸°Ô »ç¿ëÇÏ°í ÀÖ´Ù.
2.0.x¿¡¼´Â ¸®ÅÏ°ªÀÌ ¾ø¾úÀ¸³ª 2.2.x¿¡¼´Â ¸®ÅÏ°ªÀÌ »ý°å´Ù. Á¤»óÀûÀ¸·Î ÁøÇàµÇ¾ú´Ù¸é 0À» ¸®ÅÏÇÏ¸é µÇ°í ±×·¸Áö ¾Ê´Ù¸é ¿¡·¯°ªÀ» °¡Á®¾ß ÇÑ´Ù.¾î¶² °ªÀ» °¡Áú ¼ö ÀÖ´ÂÁö´Â ´Ù¸¥ µå¶óÀ̹ö¸¦ Âü°íÇϱ⠹ٶõ´Ù. ÀÌ ·çƾ¿¡¼ °¡Àå Áß¿äÇÏ°Ô °í·ÁÇØ¾ß ÇÒ °ÍÀº ¸ðµç ÀÛ¾÷ÀÌ ¶Ç´Ù¸¥ openÀÌ °¡´ÉÇÏ°Ô ¸¸µé¾î¾ß ÇÑ´Ù´Â °ÍÀÌ´Ù. »õ·Î¿î openÇÔ¼ö°¡ ½ÇÇàµÇ¾î¼ »ç¿ëÇÒ º¯¼ö³ª °ªµéÀÌ ÃÖÃÊ·Î openÀÌ ½ÇÇàµÇ´Â °æ¿ì¿Í µ¿ÀÏÇÏ°Ô µÇ¾î ÀÖ¾î¾ß ÇÑ´Ù. ±×·¯¹Ç·Î open, read, write ÇÔ¼ö¿¡¼ »ç¿ëµÈ º¯¼öµéÀ» öÀúÈ÷ Á¶»çÇؼ ¹Ýµå½Ã Á¦ÀÚ¸®·Î µ¹·Á ³õ´Âµ¥ ½Å°æÀ» ½á¾ß ÇÒ °ÍÀÌ´Ù. ÀÌ ÀÏÀ» Á¦´ë·Î ÇÏÁö ¸øÇÏ¸é »ç¿ëÇÒ ¼ö ÀÖ´Â µð¹ÙÀ̽º Àε¥µµ ºÒ±¸ÇÏ°í ÇÑ ¹ø¸¸ »ç¿ëÇÏ°í ³ª¸é ´õ ÀÌ»ó ¾µ ¼ö ¾ø´Â »óÅ·ΠµÈ´Ù. ÀÌ·± ¿¡·¯´Â openÀ» ½ÇÇà ÇÒ ¶§ ³ªÅ¸³ª±â ¶§¹®¿¡ release·çƾ¿¡¼ À߸øÇß´Ù°í »ý°¢ÇÏÁö ¾Ê°í open ÂÊÀ» ¸ÕÀú »ý°¢ÇÏ¿© ½Ã°£À» ³¶ºñÇÏ°Ô µÇ¹Ç·Î ¸¹Àº µð¹ö±ë ³ë·ÂÀÌ µé¾î°£´Ù.
4.4.7 MY_DEVICE_INTERRUPT ÇÔ¼ö
ÀÎÅÍ·´Æ®´Â µð¹ÙÀ̽º°¡ ÀÎÅÍ·´Æ®¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Â ÀåÄ¡¸¦ Á¦¾îÇÒ ¶§ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
ÀÎÅÍ·´Æ®¸¦ »ç¿ëÇÏ¸é ´ë±â½Ã°£ µ¿¾È Ä¿³Î¿¡¼ ´Ù¸¥ ÀÛ¾÷À» ÇÒ ¼ö ÀÖÀ¸´Ï±î È¿À²ÀÌ ³ô´Ù. ±×¸®°í µð¹ÙÀ̽º°¡ ÀÛ¾÷À» ³¡³»´Â Áï½Ã µå¶óÀ̹öÀÇ ÀÎÅÍ·´Æ® ·çƾÀ» ¼öÇàÇؼ ´ë±â ÇÁ·Î¼¼½º¸¦ È°¼ºÈ ÇØÁֱ⠶§¹®¿¡ ´ë±â½Ã°£À» ÃÖ¼ÒÈ ÇÒ ¼ö ÀÖ´Ù. µå¶óÀ̹ö¿¡¼ µð¹ÙÀ̽ºÀÇ »óŸ¦ üũÇÏ´Â Æú¸µ(polling)¹æ½ÄÀº ÀÎÅÍ·´Æ® ¹æ½ÄÀÇ ÀåÁ¡À» ¹Ý´ë·Î »ý°¢ÇÏ¸é µÈ´Ù. ´ë±â ÇÁ·Î¼¼½º°¡ ÀÛ¾÷ÀÌ ³¡³ªÁö ¾Ê¾Ò´Âµ¥µµ ±ú¾î³ª¼ µð¹ÙÀ̽º¸¦ üũÇØ¾ß ÇÏ´Â ¿À¹öÇìµå°¡ ÀÖÀ¸¸ç ´ë±â ÁßÀÎ ÇÁ·Î¼¼½º´Â µð¹ÙÀ̽º°¡ ÀÛ¾÷À» ³¡³Â´Âµ¥µµ ÁöÁ¤µÈ
´ë±â½Ã°£À» ¸ðµÎ ¼Ò¸ðÇØ¾ß ´ÙÀ½ ÀÛ¾÷À» ÁøÇàÇÒ ¼ö ÀÖ´Ù. Áï Æú¸µ¹æ½ÄÀº È¿À²ÀÌ ³ª»Ú°í ´ë±â½Ã°£ÀÌ ±æ´Ù. Æú¸µ¹æ½ÄÀ¸·Î ÇÑ ¹ÙÀÌÆ®¾¿ µ¥ÀÌŸ¸¦ ¾²´Â ÇÁ¸°Æ® µå¶óÀ̹ö ·çƾÀÌ ½ÇÇà Áß ÀÏ ¶§ x-window¿¡¼ ¸¶¿ì½º ¿òÁ÷ÀÓµµ ´À·ÁÁö´Â °ÍÀ» º¼ ¼ö ÀÖ´Ù.
ÀÌ·± ´ÜÁ¡¿¡µµ ºÒ±¸ÇÏ°í Æú¸µ¹æ½ÄÀº Äڵ尡 ÀÌÇØÇϱ⠽±°í °£´ÜÇϱ⠶§¹®¿¡ µå¶óÀ̹ö Á¦ÀÛÀÚ°¡ °ü½ÉÀ» °¡Áø´Ù. ¹Ý´ë·Î ÀÎÅÍ·´Æ® ¹æ½ÄÀº ÀýÂ÷Àû ÇÁ·Î±×·¡¹Ö¿¡ Àͼ÷ÇÑ ÀÀ¿ëÇÁ·Î±×·¥À» ¸¸µé´ø °³¹ßÀÚµéÀÌ °¡Àå ¾î·Á¿öÇÏ´Â ¹æ½ÄÀÌ´Ù. Á¦¾î°¡ ÇÑ ±ºµ¥¿¡¼ ÀÌ·ç¾îÁöÁö ¾Ê°í Àü¿ª º¯¼ö°¡ µ¿½Ã¿¡ ¿©·¯ ±ºµ¥¿¡¼ ÂüÁ¶°¡ µÇ¸é¼ °³¹ßÀÚµéÀ» È¥¶õ½º·´°Ô ¸¸µé±â ¶§¹®ÀÌ´Ù.Æú¸µ ¹æ½ÄÀº °£´ÜÈ÷ ÀÌÇØÇÒ ¼ö Àֱ⠶§¹®¿¡ ¾ð±ÞÀ» ÇÏÁö ¾Ê°Ú´Ù.Ä¿³ÎÇØÄ¿°¡À̵åÀÇ Áö¿øÇÔ¼ö ºÎºÐÀ» º¸¸é ÀÚ¼¼ÇÏ°Ô ³ª¿ÍÀÖÀ¸´Ï±î À̸¦ ÂüÁ¶Çϱ⠹ٶõ´Ù.
ÀÎÅÍ·´Æ® ¹æ½ÄÀ» »ç¿ëÇϱâ À§Çؼ ¸ÕÀú »ý°¢ÇØ¾ß ÇÒ °ÍÀº ÀÎÅÍ·´Æ® ÇÔ¼öÀÇ ½ÇÇà½Ã°£À» °¡´ÉÇÑÇÑ Âª°Ô ¸¸µé¾î¾ß ÇÑ´Ù´Â °ÍÀÌ´Ù. °°Àº ÀÛ¾÷À» °¡Àå ½Å¼ÓÇÏ°Ô ³¡³¾ ¼ö ÀÖ´Â ¹æ¹ýÀ» »ý°¢ÇØ¾ß ÇÑ´Ù. "ºü¸¥"ÀÎÅÍ·´Æ®´Â Àڱ⺸´Ù ¿ì¼±¼øÀ§°¡ ³·°Å³ª °°Àº ÀÎÅÍ·´Æ®¸¦ ±ÝÁöÇϱ⠶§¹®¿¡ ÀÎÅÍ·´Æ® ó¸® ·çƾÀÌ ºñÈ¿À²ÀûÀÌ°í ½Ã°£ÀÌ ¸¹ÀÌ °É¸®¸é ½Ã½ºÅÛÀÌ ´À·ÁÁö°í Ãß°¡ ÀÎÅÍ·´Æ®°¡ »ç¶óÁö´Â µî ½Å·Ú¼ºµµ ³ªºüÁö±â ¶§¹®ÀÌ´Ù. ¿©·¯ ¼Ò½º¸¦ ã¾Æº¸´Ù º¸¸é ÀÎÅÍ·´Æ® ·çƾÀÇ ½ÇÇà½Ã°£À» ÁÙÀ̱â À§Çؼ °í¹ÎÇÑ °³¹ßÀÚµéÀÇ ±ÛÀ» ã¾Æº¼ ¼ö ÀÖ´Ù.
ÀÎÅÍ·´Æ® ·çƾ¿¡¼´Â °øÅë·çƾÀÌ ÀÖ´Ù°í À̵éÀ» ¸ð¾Æ¼ ½ÇÇàÇÑ ÈÄ¿¡ ´Ù¸¥ ºÎºÐ¸¸ µÚ¿¡ ³ª´©¾î¼ ½ÇÇàÇÏ°Ô ÇÏ´Â µîÀÇ"Äڵ带 º¸±â ÁÁ°Ô"ÇÏ´Â ÀÛ¾÷À» Çؼ´Â ¾ÈµÈ´Ù. Äڵ尡 ÁöÀúºÐÇÏ°Ô µÇ´õ¶óµµ ¿©·¯ Á¶°Ç¿¡ µû¶ó ´Ù¸¥ ÀÛ¾÷ÀÌ ÀÖ´Ù¸é ÀÌµé °¢°¢ÀÇ ÀÛ¾÷¿¡ °¡Àå È¿À²ÀûÀÎ ÇüÅ·ΠÄÚµùÀ» ÇØ¾ß ÇÑ´Ù. ÀÎÅÍ·´Æ® ·çƾÀº ¾Æ¸§´Ù¿ò º¸´Ù´Â È¿À²ÀÌ ¿ì¼±µÇ±â ¶§¹®ÀÌ´Ù.ÀϺΠµå¶óÀ̹ö´Â À̸¦ À§Çؼgoto¹®Àåµµ ¾Æ¹« °Å¸®³¦ ¾øÀÌ »ç¿ëÇÏ°í ÀÖ´Ù.
ÀÎÅÍ·´Æ®·çƾ¿¡¼ ¿ì¼± ÇØ¾ß ÇÒ °ÍÀº ³Ñ¾î¿Â ÀÎÅÍ·´Æ®°¡ ÀÌ µð¹ÙÀ̽º¿¡¼ ó¸®ÇÒ °ÍÀΰ¡¸¦ Á¶»çÇÏ´Â °ÍÀÌ´Ù. my_device_cardÀÇ ÁöÁ¤µÈ ÀÎÅÍ·´Æ®¿Í ÀÌ ÀÎÅÍ·´Æ®°¡ ÀÏÄ¡ÇÏ´ÂÁö °Ë»çÇÑ´Ù.¹°·Ð ÀÌ ÀÎÅÍ·´Æ®°¡ ¾Æ´Ò °æ¿ì´Â ¸Å¿ì Èñ¹ÚÇÏ´Ù.ÀÎÅÍ·´Æ®¸¦ ºñ±³ÇÏ´Â Áß¿äÇÑ ¸ñÀûÀº my_device_card°¡ ¿©·¯ µð¹ÙÀ̽º¸¦ µ¿½Ã¿¡ Áö¿øÇÒ ¶§¿¡ ÀÌ Ä«µå Áß¿¡¼ ¾î´À °ÍÀ¸·Î ºÎÅÍ ÀÎÅÍ·´Æ®°¡ Àü´ÞµÈ °ÍÀÎÁö È®ÀÎÇϱâ À§ÇؼÀÌ´Ù.
ÀÎÅÍ·´Æ®¿¡ µû¶ó ÁÖÀåÄ¡¹øÈ£¸¦ ±¸ÇßÀ¸¸é ÁÖÀåÄ¡¹øÈ£¸¦ ´ë»óÀ¸·Î ÀÛ¾÷À» ó¸®ÇØ¾ß ÇÑ´Ù ÀÎÅÍ·´Æ® . ·çƾ¿¡¼´Â ºÎÀåÄ¡¹øÈ£¸¦ ¾Ë¾Æ³»±â ¾î·Æ´Ù.ÁÖÀåÄ¡¿¡ µû¸¥ ºÎÀåÄ¡°¡ ¿©·¯°³ ÀÖ´Ù¸é À̵é Áß¿¡¼ ÇÑ°³ ÀÌ»óÀÇ ºÎÀåÄ¡°¡ µð¹ÙÀ̽º¿¡ ´ëÇؼ ÀÛ¾÷À» ÇÏ°í µð¹ÙÀ̽ºÀÇ ÀÀ´äÀ» ±â´Ù¸®°í ÀÖÀ» °ÍÀÌ´Ù. ÁÖÀåÄ¡ ±¸Á¶Ã¼¿¡ ´ë±â ÁßÀÎ ºÎÀåÄ¡ÀÇ ¼ø¼¸¦ Á¤ÇØ ³Ö°Å³ª µð¹ÙÀ̽º°¡ ½º½º·Î ÀÎÅÍ·´Æ®¸¦ °É¸é¼ ºÎÀåÄ¡¹øÈ£¸¦ ¾Ë·Á ÁÙ ¼öµµ ÀÖÁö¸¸ À̸¦ ó¸®ÇÏ´Â °ÍÀº ¸¹Àº ½Ã°£ÀÌ °É¸°´Ù. ÁÖÀåÄ¡ÀÇ wait_queue¿¡ ´ë±â ÁßÀÎ ºÎÀåÄ¡µéÀº ÀÚµ¿ÀûÀ¸·Î ¼ø¼¸¦ ºÎ¿©¹ÞÀ¸¹Ç·Î ¸ðµç 󸮸¦ ÁÖÀåÄ¡ÀÇ ¸®¼Ò½º¿¡ ´ëÇؼ ÇÏ°í wait_queue¸¦ È°¼ºÈ ½ÃÄѼ ±ú¾î³ ºÎÀåÄ¡ÀÇ ·çƾ¿¡¼ ÀÌ ¸®¼Ò½º¸¦ ó¸®ÇÏ°Ô Çϴ°ÍÀÌ ÀÎÅÍ·´Æ® ·çƾ¿¡¼ ¼Ò¿äµÇ´Â ½Ã°£À» ÁÙÀÏ ¼ö ÀÖ´Â ¹æ¹ýÀÌ´Ù.
ÀÎÅÍ·´Æ® ·çƾ¿¡¼ ¸Þ¸ð¸®¸¦ ÇÒ´ç¹Þ´Â kmallocµîÀ» »ç¿ëÇÒ ¼ö ¾ø´Ù. kmallocÀº ÇÒ´ç¿¡ ½ÇÆÐÇßÀ» ¶§ ½º½º·Î ÇÊ¿äÇÑ ½Ã°£ ¸¸Å ±â´Ù¸®°í Àç½Ãµµ¸¦ Çϱ⠶§¹®¿¡ ½Ã½ºÅÛÀ» Á¤Áö½Ãų °¡´É¼ºÀÌ Àֱ⠶§¹®ÀÌ´Ù.¸¶Âù°¡Áö·Î ÀÎÅÍ·´Æ® Áß¿¡schedule °°Àº ÇÁ·Î¼¼½º ºí·° ÇÔ¼öµµ »ç¿ëÇÒ ¼ö ¾ø´Ù. ÀÌ °ÍÀº ÀÎÅÍ·´Æ®¶ó´Â Ư¼º»ó ºí·°ÀÌ °¡´ÉÇÏÁö ¾ÊÀ½À» »ý°¢ÇÏ¸é ´ç¿¬ÇÑ °ÍÀÌ´Ù. ¶ÇÇÑ save_flags-cli-sti-restore_flags ·çƾµµ »ç¿ëÇÒ ¼ö ¾ø´Ù.
ÀÎÅÍ·´Æ® ·çƾÀº ÀÎÅÍ·´Æ® ºÒ°¡´É »óÅ¿¡¼ ¼öÇàµÇ±â ¶§¹®¿¡ ¾î¶²ÇÑ °æ¿ì¿¡µµ sti¸¦ ½ÇÇàÇؼ´Â ¾ÈµÈ´Ù.¸¸ÀÎ ÀÎÅÍ·´Æ® ¼öÇà µµÁß¿¡sti¸¦ ½ÇÇàÇؼ ÀÎÅÍ·´Æ®¸¦ °¡´ÉÇÏ°Ô ¸¸µé¾ú´Ù¸é °°Àº ÀÎÅÍ·´Æ®°¡ ¶Ç´Ù½Ã °É¸®°Å³ª ´Ù¸¥ ÀÎÅÍ·´Æ®°¡ °É¸± ¼ö ÀÖ´Ù. ÀÎÅÍ·´Æ®´Â ÇÑ ¹ø¿¡ ¼öÇàµÇ°í ±× µ¿¾È ¹æÇع޾Ƽ´Â ¾ÈµÇ´Â ·çƾÀ̱⠶§¹®¿¡ ÀÌ °æ¿ì ¸¹Àº ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù. ÀÌ °ÍÀ» »ý°¢ÇÏ°í ÀÖ´Ù°í ÇÏ´õ¶óµµ ÀÎÅÍ·´Æ® ÇÔ¼öµµ ºÎ¸¦ ¼öÀÖ°í ´Ù¸¥ ·çƾ¿¡¼µµ »ç¿ëÇÒ ¼ö ÀÖ´Â ÀÛÀº ÇÔ¼ö¸¦ ¸¸µé¾î ¾²´Ù°¡ ÇÊ¿ä¿¡ µû¶ó ÀÌ ÇÔ¼ö¸¦ °íÄ¡´Â °æ¿ì°¡ ÀÖ´Ù. ÀÌ ¶§ ¹«½ÉÄÚ ´Ù¸¥ ·çƾ¿¡¼ÀÇ ÇÊ¿ä¿¡ ÀÇÇؼ ÀÌ ÇÔ¼ö¿¡ save_flags-sti-restore_flags¸¦ ¾²°Ô µÉ ¼ö µµ ÀÖ´Ù. ±×·¯¹Ç·Î ÄÚµå À¯Áöº¸¼ö¸¦ À§Çؼ ÀÎÅÍ·´Æ® ÇÔ¼ö´Â °¡´ÉÇÑÇÑ ÇÊ¿äÇÑ ÀÛ¾÷À» ´Ù¸¥ ÇÔ¼ö¸¦ ºÎ¸£Áö ¾Ê°í ³»ºÎÀûÀ¸·Î ¸ðµç ÀÏÀ» ó¸®ÇÏ´Â °ÍÀÌ ¹Ù¶÷Á÷ÇÏ´Ù. CÀÇ ÇÔ¼ö È£ÃâÀº ¿À¹öÇìµå°¡ ¸¹À¸¹Ç·Î ½Ã°£ÀûÀ¸·Îµµ ÀåÁ¡ÀÌ ÀÖ´Ù.
ÀÎÅÍ·´Æ®´Â ¸®ÅÏ°ªÀÌ ¾ø´Ù.ÀÎÅÍ·´Æ®´Â ÇÊ¿äÇÑ ÀÏÀ» ¼öÇàÇÏ°í ¸®ÅÏÇÒ »ÓÀÌ´Ù.±× °á°ú´Â ÀÎÅÍ·´Æ®¸¦ È£ÃâÇÑ ÇÁ·Î¼¼½º¿¡ ÇÊ¿äÇÑ °ÍÀÌ ¾Æ´Ï¶ó ÀÎÅÍ·´Æ®¸¦ ±â´Ù¸®´ø ·çƾ¿¡¼ ÇÊ¿äÇÑ °ÍÀÌ´Ù. ÀÌ °ªÀº ÀÎÅÍ·´Æ® ¼öÇà°úÁ¤¿¡¼ ¼¼ÆÃµÇ°í ±ú¾î³ ÇÁ·Î¼¼½º°¡ ±× °ªÀ» ½º½º·Î ã¾Æ¼ ÀÌ¿ëÇØ¾ß ÇÑ´Ù.
4.4.8 WRITE,READ/INTERRUPT ÇÔ¼öÀÇ ¼öÇà °úÁ¤
¾²±â(Àбâ)·çƾ¿¡¼ µ¥ÀÌŸ¸¦ µð¹ÙÀ̽º¿¡ ¾²°Å³ª µð¹ÙÀ̽ºÀÇ »óŸ¦ ¾Ë¾Æº¸±â À§Çؼ ÀÎÅÍ·´Æ®¸¦ »ç¿ëÇÑ´Ù. ÀÌ ¶§ ÁÖÀåÄ¡¿¡ ºÎ¼ÓµÈ ºÎÀåÄ¡°¡ ¿©·¯°³¶ó¸é À̵éÀº °æÀïÀûÀ¸·Î ÀÚ¿øÀ» ÇÒ´ç¹ÞÀ¸·Á°í ÇÒ °ÍÀÌ´Ù. °°Àº ÀÚ¿ø¿¡ ´ëÇؼ µ¿½Ã¿¡ ¿©·¯ ÇÁ·Î¼¼½º°¡ Á¢±ÙÇÑ´Ù¸é Ãæµ¹ÀÌ ÀϾÙ. ¿î¿µÃ¼Á¦ÀÇ °¡Àå Áß¿äÇÑ ÁÖÁ¦ÀÎ »óÈ£¹èÁ¦ ¹®Á¦¸¦ ¸®´ª½º¿¡¼´Â ¾î¶»°Ô ÇØ°áÇßÀ»±î. °á·ÐÀûÀ¸·Î ¸»ÇÏ¸é ¸ÖƼÇÁ·Î¼¼¼ ȯ°æ¿¡¼µµ Àß ÀÛµ¿ÇÏ´Â ¼¼¸¶Æ÷ÇÔ¼ö°¡ ÁغñµÇ¾î ÀÖ´Ù. ¼¼¸¶Æ÷ ÇÔ¼ö´Â µ¶¸³ÀûÀ¸·Î °³¹ßÀÚ°¡ °³¹ßÇÏ¿© Ä¿³Î¿¡ Æ÷ÇÔ½ÃÅ°
°í ÀÖÀ¸¸ç Å×½ºÆ® ÇÁ·Î±×·¥µµ ±¸ÇÒ ¼ö ÀÖ´Ù(include/asm/semaphore.h ÂüÁ¶). ¿©·¯ ºÎ ÀåÄ¡°¡ °æÀïÀûÀ¸·Î ÇÑ ÀÚ¿øÀ» Á¢±ÙÇÏ´Â ·çƾÀÌ ÀÖÀ¸¸é ÀÌ ·çƾÀÇ ¾ÕµÚ·Î ¼¼¸¶Æ÷¸¦ ¼³Á¤ÇÑ´Ù.
down(&card->semaphore);
Áß¿ä·çƾ ½ÇÇà
up(&card->semaphore);
¹°·Ð ÀÌ·¸°Ô »ç¿ëÇϱâ À§Çؼ´Â my_device_card ±¸Á¶Ã¼¿¡ ¼¼¸¶Æ÷ Çʵ带 ¼³Á¤ÇØ¾ß ÇÑ´Ù.±×¸®°í ¼¼¸¶Æ÷ÀÇ ÃʱⰪÀ» ¹Ýµå½ÃMUTEX·Î ÁöÁ¤ÇØ ³õ¾Æ¾ß ÇÑ´Ù.
card->semaphore=MUTEX;
ÀÎÅÍ·´Æ® ÇÔ¼ö¿Í ¸¶Âù°¡Áö·Î ¼¼¸¶Æ÷°¡ Àû¿ëµÇ´Â ·çƾÀº °¡´ÉÇÑÇÑ »¡¸® ³¡³¯ ¼ö ÀÖµµ·Ï ¼³Á¤ÇØ¾ß ÇÑ´Ù. ³»ºÎ·çƾÀÌ ¸¹Àº ½Ã°£À» ¼Ò¿äÇÑ´Ù¸é downºÎºÐ¿¡ ´Ù¸¥ ÇÁ·Î¼¼½º°¡ °è¼Ó ¸ØÃß¾î ÀÖ°Ô µÈ´Ù. Æí¸®ÇÑ ·çƾÀÌ ÀÖ´Ù°í ³»ºÎ¸¦ µé¿©´Ù º¼ »ý°¢À» ÇÏÁö ¾Ê°í ±×³É »ç¿ëÇÏ´Â µ¥ ¸¸Á·ÇÏ¸é ¾ÈµÈ´Ù.¼¼¸¶Æ÷ ³»ºÎ ó¸® °úÁ¤À» º¸¸é ÇÁ·Î¼¼½º´ë±â,Ÿ½ºÅ©¿¡ ´ëÇÑ Ã³¸®, ½Ã±×³Î°úÀÇ °ü°è, ¿©·¯ Á¾·ùÀÇ CPU¿¡ ´ëÇÑ ¾î¼Àºí·¯ ¼öÁØÀÇ ºñ±³±îÁö ¾Ë¾Æº¼ ¼ö ÀÖ´Ù. ¸®´ª½º ¼¼¸¶Æ÷ ó¸® ·çƾÀº À¯´Ð½º ÇÁ·Î¼¼½º¿¡ ´ëÇÑ °³³ä°ú ±× ½ÇÁ¦ Àû
¿ëÀ» ÆľÇÇÒ ¼ö ÀÖ´Â ÁÁÀº ±³Àç¶ó°í »ý°¢µÈ´Ù. À̱ÛÀ» º¸´Â µ¶ÀÚ¶ó¸é arch/*/lib/semaphore.S, kernel/sched.cµîÀ» Á¶»çÇØ º¸±â ¹Ù¶õ´Ù.
¼¼¸¶Æ÷°¡ º¸ÁõÇϹǷΠÀÌÁ¦ Ãæµ¹¾øÀÌ ÀÎÅÍ·´Æ®¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ºÎÀåÄ¡¸¶´Ù Ä«µå¿¡ ¾µ µ¥ÀÌŸ¸¦ À§ÇÑ ¹öÆÛ¸¦ ÇÒ´ç¹Þ°í Ä«µå»óŵîÀÇ µå¶óÀ̹ö¿¡ ÇÊ¿äÇÑ Á¤º¸¸¦ ¸ð¾Æ ³õ´Â°ÍÀº ÀÚ¿øÀÇ ³¶ºñÀÏ »ÓÀÌ´Ù. ¿©·¯ ºÎÀåÄ¡°¡ ÇÑ µð¹ÙÀ̽º¸¦ Á¢±ÙÇÏ°í ¼¼¸¶Æ÷°¡ µ¿½Ã¿¡ Á¢±ÙÇÏ´Â °ÍÀ» ¸·¾Æ ÁֹǷΠÀÎÅÍ·´Æ®¸¦ ÁÖ°í ¹Þ´Â µð¹ÙÀ̽º´Â ÃÖ¼ÒÇÑÀÇ µ¥ÀÌŸ¸¸À» À¯ÁöÇÏ°í ³ª¸ÓÁö µ¥ÀÌŸ´Â ÁÖÀåÄ¡¿¡ ÇÒ´çÇÏ´Â °ÍÀÌ ÁÁ´Ù.
my_device_card¿¡ ÇÒ´çÇÏ´Â ¸®¼Ò½º
struct MY_DEVICE_CARD {
...
u_int flag; /* »óÅ Ç÷¡±× */
u_char *mailbox_kernel; /* Ä¿³Î¿¡¼ º¸³¾ ¸ÞÀϹڽº */
u_char *mailbox_card; /* Ä«µå¿¡¼ º¸³»¿Â ¸ÞÀϹڽº */
struct semaphore semaphore; /* ÁÖÀåÄ¡ÀÇ ¼¼¸¶Æ÷ */
struct wait_queue *queue; /* ÁÖÀåÄ¡ÀÇ ´ë±âÅ¥ */
};
ÁÖÀåÄ¡ÀÎ my_device_card¿¡ µð¹ÙÀ̽º¿¡ ÁÖ°í¹ÞÀ» µ¥ÀÌŸ¿Í µð¹ÙÀ̽º »óÅÂÁ¤º¸¸¦ º¸°üÇÒ Çʵ带 Á¤ÀÇÇß´Ù.ÀÎÅÍ·´Æ®¸¦ »ç¿ëÇؼ µ¥ÀÌŸ¸¦ µð¹ÙÀ̽º·Î º¸³»±â À§Çؼwrite ·çƾÀº ¹Ì¸® ÇÒ´çµÈ mailbox_kernel¿¡ µ¥ÀÌŸ¸¦ º¸³»°í µð¹ÙÀ̽º¿¡ ÀÎÅÍ·´Æ®¸¦ °Ç´Ù.
µ¹¾Æ¿Â ÀÎÅÍ·´Æ®¿Í´Â ´Þ¸® µð¹ÙÀ̽º¿¡ ÀÎÅÍ·´Æ®¸¦ °Å´Â °ÍÀº write·çƾÀÇ ¸òÀÌ´Ù.
my_device¿¡ ÀÎÅÍ·´Æ®¸¦ °Å´Â °ÍÀÌ ´ÙÀ½°ú °°´Ù°í ÇÏÀÚ
memcpy_toio(card->address + DATA_ADDR, card->mailbox_kernel, length);
outb(0x01, card->base+INTERRUPT_ADDR);
current->timeout = jiffies + HZ * 3;
interruptible_sleep_on(&card->queue);
base ÁÖ¼Ò¿¡¼ INTERRUPT_ADDR ¹ÙÀÌÆ®¸¦ ´õÇÑ ÁÖ¼Ò¿¡ 1À» ¾²´Â °ÍÀÌ ÀÌ µð¹ÙÀ̽º¿¡ ÀÎÅÍ·´Æ®¸¦ °Å´Â ÇàÀ§ÀÌ´Ù. ÀÌ Àü¿¡ È°¼ºÈµÈ µð¹ÙÀ̽º°¡ »ç¿ëÇÒ µ¥ÀÌŸ¸¦ Àü¼ÛÇÑ´Ù. memcpy_toio°¡ ±× ÀÖÀ» ÇÏ°Ô µÈ´Ù. º¸³¾ ÁÖ¼Ò, º¸³¾ µ¥ÀÌÅÍ°¡ ÀÖ´Â ÁÖ¼Ò, ±æÀÌ¿¡ µû¶ó µ¥ÀÌŸ°¡ Àü¼ÛµÈ´Ù. ¸¶Áö¸·À¸·Î µð¹ÙÀ̽º°¡ È°¼ºÈ µÇ¾î º¸³½ µ¥ÀÌŸ¿¡ ´ëÇÑ Ã³¸®¸¦ ³¡³»°í Ä¿³Î¿¡ ÀÎÅÍ·´Æ®¸¦ °É¾î ÀÌ ·çƾÀÌ È°¼ºÈ µÉ ¶§±îÁö ±â´Ù¸®±â À§Çؼ Àáµç´Ù(interruptible_sleep_on) ÀÌ ·çƾÀº ±ú¿öÁÙ ´ë»óÀÌ ´©±¸¸¦ ±ú¿ö¾ß ÇÏ´ÂÁö ¾Ë ¼ö ÀÖµµ·Ï card->queue¿¡ ÀÚ½ÅÀ» µî·ÏÇÑ´Ù.
ÀÎÅÍ·´Æ®°¡ °É¸° µð¹ÙÀ̽º´Â ÀϹÝÀûÀ¸·Î ¼ö½Ê¹Ð¸®ÃÊ¿¡¼ ¼ö¹é¹Ð¸®ÃÊ ¾È¿¡ 󸮸¦ ³¡³»°í ÀÎÅÍ·´Æ®¸¦ µ¹·Á Áֱ⠶§¹®¿¡ Çö ÇÁ·Î¼¼½ºÀÇ Å¸ÀӾƿô°ªÀ» Å©°Ô ÀâÀ» ÇÊ¿ä´Â ¾ø´Ù.
¹°·Ð ±× °ªÀº Çϵå¿þ¾î µð¹ÙÀ̽ºÀÇ Æ¯¼ºÀ» ÆľÇÇÑ ÈÄ¿¡ ÀûÀýÇÑ °ªÀ» Á¤ÇØÁÖ¾î¾ß ÇÑ´Ù.
ÀÎÅÍ·´Æ®°¡ Á¤»óÀûÀ¸·Î µ¹¾Æ¿À¸é ¹Ù·Î ÀÌ ÇÁ·Î¼¼½º°¡ È°¼ºÈ µÇ¹Ç·Î ´ë±â°ªÀ» ¸¹ÀÌ Àâ´Â ´Ù°í ¿À¹öÇìµå°¡ Áõ°¡ÇÏ´Â °ÍÀº ¾Æ´Ï´Ù. ¿©±â¿¡¼´Â my_device¿¡ ´ëÇؼ¸¸ ¾ê±âÇßÁö¸¸ Çϵå¿þ¾î¿¡ µû¶ó ´Ù¾çÇÑ ÀÎÅÍ·´Æ® °É±â°¡ Á¸ÀçÇÒ ¼ö ÀÖ´Ù. ¸¶Âù°¡Áö·Î ¿©·¯ µå¶óÀ̹ö¸¦ ã¾Æº¸°í ÇÊ¿äÇÑ ¹æ¹ýÀ» ¿¬±¸Çϱ⠹ٶõ´Ù.
´ë±â ÈÄ¿¡ È°¼ºÈµÈ ÇÁ·Î¼¼½º´Â ÇÁ·Î¼¼½º°¡ ±ú¾î³ »óÅ¿¡ ´ëÇÑ Á¡°ËÀÌ ÇÊ¿äÇÏ´Ù. ½Ã±×³Î¿¡ ÀÇÇؼ ±ú¾î³ ÇÁ·Î¼¼½º´Â ÀÛ¾÷À» Áß´ÜÇÏ°í ÀÚ½ÅÀ» ºÎ¸¥ »óÀ§ ·çƾÀ¸·Î º¹±ÍÇØ¾ß ÇÑ´Ù. ¹°·Ð ¼¼¸¶Æ÷¿¡ ´ëÇÑ Á¤¸®ÀÛ¾÷ °°Àº Áß¿äÇÑ ÀÛ¾÷Àº ¹Ýµå½Ã ¼öÇà ÇØ¾ß ±× ´ÙÀ½ ÇÁ·Î¼¼½º°¡ ¿µÇâÀ» ¹ÞÁö ¾Ê´Â´Ù. ¸¸¾à ŸÀӾƿô°ªÀÌ Áö³ª¼ È°¼ºÈ µÇ¾ú°í ½Ã±×³ÎÀÌ ¾ø´Ù¸é µð¹ÙÀ̽º¿¡ ÀÌ»óÀÌ ÀÖ´Â °ÍÀÎÁö ŸÀӾƿô°ªÀÌ ÃæºÐÇÏÁö ¾Ê¾Ò´ÂÁö È®ÀÎÇØ¾ß ÇÑ´Ù. ŸÀӾƿô°ªÀÌ ÀûÀº °ÍÀ̶ó¸é ´Ã¿© ÁÖ¸é µÇ°í µð¹ÙÀ̽º°¡ ÀÎÅÍ·´Æ®¸¦ µ¹·Á ÁÖÁö ¸ø
ÇÑ °ÍÀ̶ó¸é ÀÌ¿¡ µû¸¥ 󸮸¦ ÇØ¾ß ÇÒ °ÍÀÌ´Ù.
ÇÊÀÚÀÇ °æÇèÀ¸·Î´Â µð¹ÙÀ̽º°¡ ÀÎÅÍ·´Æ®¸¦ µ¹·Á ÁÖÁö ¸øÇÏ´Â °æ¿ì°¡ »ý±ä ÀûÀÌ ÀÖ¾ú´Ù. ´ë»ó µð¹ÙÀ̽º°¡ ºñÁ¤»óÀûÀÎ ÀÛµ¿À» ÇÒ ¶§ ±× ¹®Á¦¸¦ Çϵå¿þ¾îÀûÀÎ ¹®Á¦¶ó°í »ý°¢ÇÏ°í ÇØ°á ¹æ¹ýÀÌ ¾ø´Ù°í »ý°¢ÇßÁö¸¸ ³ªÁß¿¡ ¾Ë¾Æ³½ °á°ú ÀÎÅÍ·´Æ®¸¦ ÁÖ°í ¹ÞÀ» ¶§ÀÇ ±Ô¾àÀ» Á¤È®È÷ ÁöÅ°Áö ¸øÇ߱⠶§¹®À̾ú´Ù. ´Ù¸¥ ¿î¿µÃ¼Á¦¿¡¼ Á¤»óÀûÀ¸·Î »ç¿ëÇÏ´ø Çϵå¿þ¾î´Â ±× ±Ô¾à¸¸ Á¤È®È÷ ÁöŲ ´Ù¸é ¸®´ª½º¿¡¼ ¾Æ¹« ¹®Á¦ ¾øÀÌ »ç¿ëÇÒ ¼ö ÀÖ´Ù. Ä¿³Î ÇÁ·Î±×·¡¹ÖÀ» ÇÒ ¶§ Á¾Á¾ ¿î¿µÃ¼Á¦°¡ ´Þ¶ó¼ ¾î¿ ¼ö ¾ø´Ù´Â ¸»À» µè°í´Â Çϴµ¥ ÀÌ °ÍÀº ¸®´ª½ºÀÇ ÇѰ踦 ¸»ÇÏ´Â °ÍÀÌ ¾Æ´Ï°í Çϵå¿þ¾î Á¦Àۻ簡 Á¤¸» ÇÊ¿äÇÑ Á¤º¸¸¦ °ø°³ÇÏÁö ¾Ê°í ÀÖÀ½À» ¸»Çϴ°ÍÀÌ´Ù. Á¦´ë·Î ¸¸µé¾îÁø Çϵå¿þ¾î »ç¾çÀ» °¡Áö°í ÇÁ·Î±×·¡¹ÖÀ» ÇÑ´Ù¸é Àý´ë·Î ½ÇÆÐÇÒ ¼ö ¾øÀ¸¸ç ¸®´ª½º¿¡¼ ÈǸ¢È÷ µ¿ÀÛ½Ãų ¼ö ÀÖ´Ù.
ÇÁ·Î¼¼½º°¡ È°¼ºÈ µÈ ÈÄ¿¡ µð¹ÙÀ̽º°¡ ÀÎÅÍ·´Æ®¸¦ Á¦´ë·Î µ¹·Á ÁÖ¾î¼ µå¶óÀ̹öÀÇ ÀÎÅÍ·´Æ® ·çƾÀÌ ¼öÇàµÈ °á°ú·Î È°¼ºÈ µÈ °ÍÀ̶ó¸é µð¹ÙÀ̽º¿¡¼ º¸³½ µ¥ÀÌŸ¸¦ ó¸®ÇØ¾ß ÇÑ´Ù . ¾Õ¿¡¼ ¸»ÇßµíÀÌ ÀÎÅÍ·´Æ® ·çƾÀº ÃÖ¼ÒÇÑÀÇ ÀÛ¾÷¸¸À» Çϱ⠶§¹®¿¡ ¸ðµç 󸮴 write¿¡¼ ÇÏ°Ô ÇØ¾ß ÇÑ´Ù.
¿©±â¿¡ ´ëÀÀµÇ´Â ÀÎÅÍ·´Æ® ·çƾ ÂÊÀÇ ÄÚµå´Â ´ÙÀ½°ú °°´Ù.
memcpy_fromio(card->mailbox_card, buf, buf_size);
card->flag |= MY_DEVICE_ANSWERED;
if (waitqueue_active (&card->queue))
wake_up_interruptible(&card->queue);
return;
ÀÎÅÍ·´Æ® ·çƾ¿¡¼ ÇÏ´Â ÀÏÀº Á¤´çÇÑ ÀÎÅÍ·´Æ®ÀÎÁö È®ÀÎÇÑ ÈÄ¿¡ µð¹ÙÀ̽º¿¡ ÀÖ´Â µ¥ÀÌŸ¸¦ º¹»çÇÏ°í µð¹ÙÀ̽º°¡ Á¤»óÀûÀ¸·Î ÀÀ´äÇßÀ½À» ¾Ë·Á ÁØ ÈÄ¿¡ ´ë±â ÁßÀÎ ÇÁ·Î¼¼½º°¡ ÀÖÀ¸¸é wake_up_interruptible ÇÔ¼ö°¡ ÀÌ ÇÁ·Î¼¼½º¸¦ ±ú¿î´Ù.
2.0¹öÀü¿¡¼´Â Å¥¿¡ ´ë±â ÁßÀÎ ÇÁ·Î¼¼½º°¡ ÀÖ´ÂÁö È®ÀÎÇÏ´Â ÇÔ¼ö°¡ ¾ø¾úÁö¸¸ 2.2¿¡¼´Â waitqueue_active¶ó´Â È®ÀÎ ÇÔ¼ö°¡ »ý°å´Ù. card->flag ¸¦ ¼¼ÆÃÇÏ´Â ÀÌÀ¯´Â ´ë±â ÇÁ·Î¼¼½º°¡ Á¦´ë·Î µÈ ÀÀ´äÀ» µð¹ÙÀ̽º·Î ºÎÅÍ ¹Þ¾ÒÀ½À» È®ÀÎ ½ÃÅ°±â À§ÇÑ °ÍÀÌ´Ù.
¿¡·¯ Äڵ忡 ´ëÇؼ µå¶óÀ̹ö¸¦ ÀÛ¼ºÇÏ¸é¼ ¿©·¯ ¿¡·¯°¡ »ý±æ ¼ö ÀÖ´Ù. °¢°¢ÀÇ ¿¡¶ó¿¡ ´ëÇؼ ¸®ÅÏ°ªÀ» °¡Á®¾ß ÇÑ´Ù. µå¶óÀ̹ö ·çƾ¿¡¼ ¸¹ÀÌ ¾²´Â ¿¡¶ó¿¡ ´ëÇؼ °£´ÜÇÏ°Ô ¼³¸íÀ» ÇÏ°Ú´Ù.¿©±â¼ º¸ÀÎ ¿¡¶ó¸¦ ¸®ÅÏÇÒ ¶§´Â(-)°ªÀ» ÃëÇÑ´Ù.
¿ÏÀüÇÑ ¿¡·¯ °ªÀº include/asm/errno.h ¿¡ ÀÖ´Ù.
EINTR : ÇÁ·Î¼¼½º ¼öÇà µµÁß¿¡ Ä¿³Î·Î ºÎÅÍ ½Ã±×³ÎÀ» ¹Þ¾ÒÀ» ¶§ »ç¿ëÀÚ°¡ ÇÁ·Î¼¼½º¸¦ Áß´ÜÇ߰ųª Ä¿³Î¿¡¼ °Á¦·Î Áß´Ü ½Ãų °æ¿ì¿¡ »ç¿ëµÈ´Ù. ÇØ´ç ÇÁ·Î¼¼½º´Â ½Å¼ÓÇÏ°Ô ÀÛ¾÷À» ³¡³»¾ß ÇÑ´Ù.
ENOMEM : Ä¿³Î ¸Þ¸ð¸® ¿µ¿ª¿¡ ¿©À¯°¡ ¾øÀ» ¶§ kmalloc ÇÔ¼ö¸¦ È£ÃâÇÑ ÈÄ¿¡ ¿¡·¯°¡ ³µÀ» ¶§ ¸®ÅÏ°ªÀ¸·Î ¾´´Ù.
ENXIO : À߸øµÈ ºÎÀåÄ¡¸¦ È£ÃâÇ߰ųª »ç¿ëÇÒ ¼ö ¾ø´Â ÁÖ¼Ò°¡ ÂüÁ¶ µÇ¾úÀ» ¶§
ENODEV : ÁÖÀåÄ¡¿¡ µþ¸° ºÎÀåÄ¡°¡ ¹üÀ§¸¦ ³Ñ¾úÀ» ¶§
EAGAIN : ÀϽÃÀûÀ¸·Î µå¶óÀ̹ö¿¡¼ µð¹ÙÀ̽º¸¦ »ç¿ëÇÒ ¼ö ¾øÀ» ¶§
´Ù¸¥ ·çƾ¿¡¼ ÀÌ µð¹ÙÀ̽º¸¦ »ç¿ë ÁßÀÏ ¶§ Àá½Ã ±â´Ù¸° ÈÄ¿¡ ´Ù½Ã ½ÃµµÇÒ ¼ö ÀÖ°Ô ÇÑ´Ù.
EBUSY : ÀÌ¹Ì ´Ù¸¥ ·çƾ¿¡¼ µð¹ÙÀ̽º¸¦ »ç¿ë ÁßÀÏ ¶§
ENOSYS : ioctlµîÀÇ ·çƾ¿¡¼ ¾ø´Â ÇÔ¼ö¸¦ ºÎ¸¦ ¶§
EIO : ÀåÄ¡¸¦ µî·ÏÇÒ ¼ö ¾ø°Å³ª µð¹ÙÀ̽º°¡ Á¤»óÀÛµ¿À» ÇÏÁö ¾Ê°í ÀÖÀ» ¶§
ÀÌ ¿¡·¯´Â À§ÀÇ °æ¿ì¿¡ ÇØ´çÇÏÁö ¾Ê´Â Æ÷°ýÀûÀÎ »óȲ¿¡¼ »ç¿ëµÈ´Ù
. ÇÁ·Î±×·¡¹Ö½Ã ÁÖÀÇÁ¡°ú ±âŸ Á¤º¸
¸®´ª½º µð¹ÙÀ̽º µå¶óÀ̹ö¸¦ ¸¸µé±â À§Çؼ ÇÊ¿äÇÑ ÃÖ¼ÒÇÑÀÇ Âü°í »çÇ×Àº ¸ðµÎ ¼³¸íÇß´Ù. ¹°·Ð ÀÌ °ÍÀ¸·Î´Â ¾Æ¹« °Íµµ ÇÒ ¼ö ¾øÀ» °ÍÀÌ´Ù.ÀÌ ±Û¿¡¼ ¼³¸íÇÑ °ÍÀ» Âü°í·Î ¹Ýµå½Ã ¸¸µé°íÀÚ ÇÏ´Â µð¹ÙÀ̽º¿Í °ü·ÃµÈ µå¶óÀ̹ö ÆÄÀÏÀ» Á¶»çÇØ¾ß ÇÑ´Ù. ¿©ÀüÈ÷ µå¶óÀ̹ö ÆÄÀÏÀÇ ³»¿ëÀÌ ¾î·Æ°Ô ´À²¸Áö°ÚÁö¸¸ ÀÌ ±Û¿¡¼ ¾ð±ÞÇÑ °ÍµéÀÌ µµ¿òÀÌ µÉ °ÍÀÌ´Ù. ÀÌÁ¦ µå¶óÀ̹ö¸¦ ÀÛ¼ºÇÒ ¶§ ÀüüÀûÀ¸·Î °ü½ÉÀ» °¡Á®¾ß ÇÒ »çÇ׿¡ ´ëÇÑ ¼³¸íÀ» Çϵµ·Ï ÇÏÀÚ. ±× ¿Ü¿¡ ¿Õ¼ºÇÏ°Ô °³¹ßµÇ°í ÀÖ´Â ¸®´ª½º Ä¿³Î °ü·Ã ÇÁ·ÎÁ§Æ®µé¿¡ ´ëÇؼ
¾ð±ÞÇÏ°í ¸¶Áö¸·À¸·Î ²À ã¾Æ º¸¾Æ¾ß ÇÒ Á¤º¸¿¡ ´ëÇؼ ¾Ë¾Æº¸ÀÚ.
4.5 ÀýÂ÷Àû ÇÁ·Î±×·¡¹Ö°ú Ä¿³Î ÇÁ·Î±×·¡¹Ö
ÇÁ·Î±×·¡¹Ö ¾ð¾îC´Â Äڵ忡 µû¶ó ¼øÂ÷ÀûÀ¸·Î ÁøÇàµÇ´Â ÇÁ·Î±×·¥À» ¸¸µç´Ù.¸ÖƼ½º·¹µå °³³äµµ µ¿±âȵîÀÇ ÀÛ¾÷À» ÇÁ·Î±×·¡¸Ó°¡ Á¦¾îÇÏ°Ô µÇ¹Ç·Î ¼øÂ÷ÀûÀ̶ó´Â °³³äÀ» ¹þ¾î³ªÁö´Â ¾Ê´Â´Ù. X-window¶Ç´Â win32¿¡¼ À̺¥Æ® Áß½ÉÀÇ ÇÁ·Î±×·¡¹ÖÀ» ÇÏ°Ô µÇ´Âµ¥ ÀÌ °Íµµ ¹ß»ýÇÒ ¼ö ÀÖ´Â »ç°Ç¿¡ ´ëÇØ ÇÁ·Î±×·¡¸Ó°¡ ¸ðµÎ ÆľÇÇÏ°í 󸮸¦ ÇÏ°Ô µÈ´Ù.
ÀÀ¿ëÇÁ·Î±×·¥ÀÌ ½ÇÇàµÈ ÀÌÈÄ¿¡ ¹ß»ýÇÒ ¼ö ÀÖ´Â ¿ÜºÎ »ç°ÇÀº ½Ã½ºÅÛ¿¡¶ó Á¤µµÀÌ´Ù. Áï ÇÁ·Î±×·¡¸Ó°¡ ½Å°æ¾µ ºÎºÐÀº ÀÀ¿ëÇÁ·Î±×·¥ÀÇ ³»ºÎ ·ÎÁ÷ÀÌ¸ç ¿ÜºÎ ¿äÀο¡ ½Å°æ¾µ ÇÊ¿ä¾øÀÌ ½Ã½ºÅÛ Àüü¸¦ ÀÀ¿ëÇÁ·Î±×·¥ÀÌ Á¦¾îÇÏ°í ÀÖ´Ù°í »ý°¢ÇÏ¸é¼ ÇÁ·Î±×·¥¹ÖÀ» ÇϸéµÈ´Ù.
Ä¿³Î ÇÁ·Î±×·¡¹ÖÀ» ÇÒ ¶§´Â ÇÁ·Î±×·¡¸Ó°¡ ½Å°æ¾µ ºÎºÐÀÌ Å©°Ô Áõ°¡ÇÑ´Ù. Áõ°¡ÇÏ´Â ºÎºÐÀº ÁÖ·Î µð¹ÙÀ̽º µå¶óÀ̹öÀÇ ¿ÜºÎ ¿äÀο¡ ´ëÇÑ °ÍÀÌ´Ù. Ä¿³ÎÀº ½ÃÀÛµµ ³¡µµ ¾ø´Â Á¦¾î±¸Á¶·Î µÇ¾îÀÖ´Ù.Ä¿³Î¿¡¼ ÁÖ·Î ÇÏ´Â ÀÛ¾÷Àº ÀÚ¿øÅ×À̺íÀÇ À¯Áö¿Í °»½ÅÀÌ´Ù.¿¹¸¦ µé¾î ÇÒ´çµÈ ¸Þ¸ð¸®¿Í ÀÚÀ¯¸Þ¸ð¸®¿¡ ´ëÇÑ ÀÚ¿øÅ×À̺íÀ» À¯ÁöÇϱâ À§ÇØ ¸Þ¸ð¸®¸¦ ȸ¼öÇϰųª ÇÒ´çÇßÀ» ¶§ ÀÌ º¯°æ»çÇ×À» °»½ÅÇÏ°í ¸Þ¸ð¸® È¸¼ö¿¡ ÇÊ¿äÇÑ Ãß°¡ÀÛ¾÷À» ÇÑ´Ù. ÀÌ·± ÀÚ¿ø¿¡ ´ëÇÑ ¿ä±¸´Â ¾ðÁ¦ ¾îµð¼µçÁö ÀϾ ¼ö ÀÖ°í ÀÚ¿ø ÇØÁ¦ ¿ä±¸ ¶ÇÇÑ ¸¶Âù°¡Áö´Ù.Ä¿³ÎÀº ²÷ÀÓ¾øÀÌ ÀÌ·± ¿ä±¸¸¦ ó¸®Çϴµ¥ ÁÖ·Î ½Ã°£À» º¸³½´Ù.µ¿½Ã¿¡ ÀϾ´Â ¼ö¸¹Àº ¿ä±¸¿¡ ´ëÇÑ Á¶Á¤Àº ¸Å¿ì Èûµç ÀÏÀ̱⠶§¹®¿¡ °¡´ÉÇÑ ÃÖ¼ÒÇÑÀÇ ÀÛ¾÷¸¸À» ÇÏ°í ±×¿Ü ´ëºÎºÐÀÇ ÀÛ¾÷Àº µð¹ÙÀ̽º µå¶óÀ̹ö°¡ ó¸®Çϵµ·Ï Çß´Ù. ÇÑ µð¹ÙÀ̽ºÀÇ ºÎÀåÄ¡¸¦ ¾ï¼¼½ºÇÏ´Â ÇÁ·Î¼¼½º°¡ È°µ¿ ÁßÀÏ ¶§¿¡µµ Ä¿³ÎÀº À̸¦ Á¶»çÇÏÁö ¾Ê°í °°Àº ºÎÀåÄ¡¿¡ ´ëÇÑ ¾ï¼¼½º ¿äûÀÌ ÀÖÀ» ¶§ Á¦¾î¸¦ ³Ñ°Ü ÁØ´Ù. À̸¦ Çã¿ëÇϰųª ¸·´Â °ÍÀº µð¹ÙÀ̽º µå¶óÀ̹öÀÇ ¸òÀÌ´Ù.
±×¿Ü¿¡µµ µå¶óÀ̹ö¸¦ ¸¸µé ¶§ ½Å°æÀ» ½á¾ßÇÒ ¸¹Àº ºÎºÐÀÌ ÀÖ´Ù.Ä¿³ÎÀÇ ¸ÖƼÇÁ·Î¼¼½º, ½ÃºÐÇÒ ¹æ½ÄÀ̶ó´Â Ư¼º°ú ºñÀýÂ÷ÀûÀÎ ¿ÜºÎ ¿äÀÎÀÌ °ãÃļ ÇÁ·Î±×·¡¹ÖÀ» º¹ÀâÇÏ°Ô ÇÑ´Ù.
4.6 °æÀïÀÇ Á¦°Å
µð¹ÙÀ̽º¸¦ openÇÑ ÇÁ·Î¼¼½º°¡ °¡Àå ¸ÕÀú ÇØ¾ß ÇÒ °ÍÀº µ¿ÀÏÇÑ ºÎÀåÄ¡¿¡ ´ëÇؼ ¶Ç´Ù¸¥ ÇÁ·Î¼¼½º°¡ Á¢±ÙÇÏ´Â °ÍÀ» ¸·¾Æ¾ß ÇÏ´Â °ÍÀÌ´Ù.ÀÌ °ÍÀº ºÎÀåÄ¡ÀÇ Ç÷¡±×¸¦busy·Î ¼¼ÆÃÇÏ´Â °ÍÀ¸·Î ½±°Ô ÇØ°áÇÒ ¼ö ÀÖ´Ù. open ÇÔ¼ö¿¡¼ ¿©·¯ Á¶°ÇÀ» °Ë»çÇÑ ÈÄ¿¡ busy¼¼ÆÃÀ» ÇÏ¸é µÈ´Ù. ÀÌ µð¹ÙÀ̽º¸¦ µÎ¹ø°·Î openÇÑ ÇÁ·Î¼¼½º°¡ busy¼¼ÆÃÀÌ µÇ¾ú´ÂÁö °Ë»çÇÑ ÈÄ¿¡ busy¶ó¸é EBUSY °ªÀ» °¡Áö°í ¸®ÅÏÇÏ°Ô µÈ´Ù. Ç÷¡±× °ªÀÌ busyÀ϶§ Áï½Ã EBUSY °ªÀ¸·Î ¸®ÅÏÇÏÁö ¾Ê°í ¾Õ¼ ÀÌ µð¹ÙÀ̽º¸¦ ¿¬ ÇÁ·Î¼¼½ºÀÇ »óÅ¿¡ µû¶ó(¾ÕÀÇ ÇÁ·Î¼¼½º°¡ release ·çƾÀ» ¼öÇà ÁßÀ̶ó¸é) Ä¿³Î¿¡¼ ´Ù½Ã openÀ» ½ÃµµÇϵµ·Ï EAGAIN °ªÀ¸·Î ¸®ÅÏÇÏ°Ô ÇÒ ¼öµµ ÀÖ´Ù. ½Ã¸®¾ó Æ÷Æ® Á¦¾î µð¹ÙÀ̽º µéÀÌ ÀÌ ¹æ¹ýÀ» »ç¿ëÇÏ°í ÀÖ´Ù.
ÀÌ °ÍÀº ÇÑ °³ÀÇ ºÎÀåÄ¡¿¡ ´ëÇÑ ÇÁ·Î¼¼½ºÀÇ Á¢±ÙÀ» ¸·±â À§ÇØ °í·ÁÇؾßÇÒ Á¡ÀÌ´Ù. ½Ã½ºÅÛ ½Ã°£À» ÇÒ´ç¹ÞÀº ÇÁ·Î¼¼½º°¡ ¾î¶² ·çƾÀ» ¼öÇà ÇÏ´Â µµÁß¿¡ Ä¿³Î·ÎºÎÅÍ °£¼·À» ¹Þ¾Æ¼´Â ¾ÈµÇ´Â °æ¿ì°¡ ÀÖ´Ù. Áß¿äÇÑ Àü¿ªº¯¼ö¸¦ ¹Ù²Ù°í Áß´Ü ¾øÀÌ ÇÊ¿äÇÑ ÀÛ¾÷À» ÇØ¾ß Çϰųª, Áß¿ä ·çƾ ¼öÇà µµÁß¿¡ Á¦¾î°¡ ³Ñ¾î°¡°Ô µÇ¾î¼ ´Ù¸¥ ÇÁ·Î¼¼½º°¡ ÀÌ ÇÁ·Î¼¼½º°¡ º¯°æÇÑ ÀÚ¿øÀ» ¶Ç ´Ù½Ã ¹Ù²ÙÁö ¸øÇÏ°Ô ÇØ¾ß ÇÒ ¶§ µîÀÌ´Ù.
ÀÌ·¸°Ô Ä¿³Î ÇÁ·Î¼¼½ºÀÇ ¸ðµç °æÀïÀ» ¸·°í ¿ÏÀüÈ÷ ÇÁ·Î¼¼½º ¼öÇàÀ» µ¶Á¡ÇØ¾ß ÇÒ ¶§¿¡´Â ´ÙÀ½°ú °°ÀÌ ÇØ¾ß ÇÑ´Ù.
...
u_long flags;
save_flags(flags);
cli();
change_variable();
do_critical_job();
recover_variable();
restore_flags(flags);
...
cli°¡ ¼öÇàµÇ´Â ¼ø°£ restore_flagsÇÔ¼öÀÇ ¼öÇàÀÌ ³¡³¯ ¶§±îÁö´Â Ä¿³ÎÀÇ ºí·°¸í·ÉÀ̳ª ÀÎÅÍ·´Æ®°¡ ¹«½ÃµÇ°í ¿À·ÎÁö ÀÌ ÇÁ·Î¼¼½º¸¸ÀÌ ½Ã½ºÅÛ ½Ã°£À» »ç¿ëÇÏ°Ô µÈ´Ù. Ä¿³Î ÇÁ·Î¼¼½º´Â Á¦ÇÑµÈ ½Ã½ºÅÛ ½Ã°£À» ¹Þ°í ÀÛ¾÷À» ¼öÇàÇϱ⠶§¹®¿¡ Ç×»ó º¯¼öÀÇ º¯°æ°ú °°Àº ºÎºÐ¿¡¼´Â ¿¬¼ÓµÈ ÀÛ¾÷ÀÌ ´Ù¸¥ ÇÁ·Î¼¼½ºÀÇ ¹æÇظ¦ ¹Þ¾Æµµ µÇ´Â °ÍÀÎÁö È®ÀÎÇØ¾ß ÇÑ´Ù.
save_flags-cli-restore_flags ÀÇ »ç¿ëÀº ÇÁ·Î¼¼½º ÀÚ¿øÇÒ´çÀ» ¹æÇØÇÏ¿© Ä¿³ÎÀÇ ¼º´ÉÀ» ÀúÇϽÃŲ´Ù. À§¿Í °°Àº ºÒƯÁ¤ ´Ù¼ö ÇÁ·Î¼¼½º¿ÍÀÇ °æÀïÀÌ ¾Æ´Ï°í ÀÏÁ¤ ÀÚ¿øÀ» °øÀ¯ÇÏ´Â ÇÁ·Î¼¼½ºÀÇ °£¼·À» ¸·±â À§Çؼ¶ó¸é ¼¼¸¶Æ÷¸¦ »ç¿ëÇÏ´Â °ÍÀÌ ÁÁ´Ù. ÁÖÀåÄ¡¿¡ µ¿ÀÏÇÑ ºÎÀåÄ¡°¡ ¿©·¯°³ ÀÖÀ» ¶§ ÀÌµé ºÎÀåÄ¡¸¦ Á¢±ÙÇÏ´Â ÇÁ·Î¼¼½ºµéÀº ÁÖÀåÄ¡¿¡ ´ëÇØ ¼·Î °æÀïÀ» ÇÑ´Ù..
struct MY_DEVICE_CARD {
...
u_char *mailbox_kernel; /* ÁÖÀåÄ¡ÀÇ ¸ÞÀϹڽº*/
...
}
my_device_write(..) {
...
get_mailbox_and_write();
...
}
my_device¿¡´Â ÇÑ°³ÀÇ ÁÖÀåÄ¡¿¡ ´ëÇؼ 4°³ÀÇ ºÎÀåÄ¡°¡ ÀÖ´Ù. my_device_write ÇÔ¼ö´Â °¢ ºÎÀåÄ¡(my_device[0-3])¿¡ µ¿½Ã¿¡ Á¢±ÙÇÑ 4°³ÀÇ ÇÁ·Î¼¼½º°¡ °°ÀÌ ½ÇÇàÇÏ°í ÀÖ´Ù. get_mailbox_and_write ÇÔ¼ö¿¡ ´ëÇÑ Á¢±Ù°ú °æÀïÀÌ Á¸ÀçÇÏ°Ô µÇ´Â °ÍÀÌ´Ù. ÀÌ ¶§¿¡´Â °æÀïÇÏ°í ÀÖ´Â ÇÁ·Î¼¼½º°¡ ¸íÈ®ÇÏ°í ÇÑ ÇÁ·Î¼¼½º°¡ µ¶Á¡ÀûÀ¸·Î ½ÇÇà