6.4. ¾Ë¾Æ¾ßÇÒ °Í µé

µð¹ÙÀ̽º µå¶óÀ̹ö¸¦ ¸¸µé±â À§ÇÑ ¾ÆÁÖ ±âº» ÀûÀÎ °ÍÀº ÀÌ¹Ì ¾Ë¾ÒÀ» °ÍÀÌ´Ù. ÀÌÁ¦´Â Á»´õ º¹ÀâÇÏÁö¸¸ ¾Ë¾Æ¾ß¸¸ ÇÏ´Â °Íµé¿¡ ´ëÇØ ¾ê±âÇØº¸ÀÚ.

¹öÀü

¸ðµâÀ» ¸¸µå´Â °ÍÀº Ä¿³ÎÀÇ ¹öÀü°ú ¹ÐÁ¢ÇÑ °ü°è°¡ ÀÖ°í Ä¿³ÎÀÇ ¹öÀüÀÌ º¯°æµÇ¸é¼­ µð¹ÙÀ̽º µå¶óÀ̹öÀÇ ±¸Á¶ ÀÚüµµ Á¶±Ý¾¿ º¯ÇϹǷΠ¿©·¯ ¹öÀüÀÇ Ä¿³Î¿¡¼­ µ¿½Ã¿¡ »ç¿ëµÉ ¼ö ÀÖµµ·Ï ¸¸µé±â À§Çؼ± Ä¿³ÎÀÇ ¹öÀüÀ» ±¸ºÐÇØ ÄÄÆÄÀÏµÇ°í µ¿À۵ǵµ·Ï ÇØÁà¾ßÇÑ´Ù.

¸®´ª½º¿¡¼± ÇöÀç Ä¿³ÎÀÇ ¹öÀüÀ» LINUX_VERSION_CODE·Î ³ªÅ¸³½´Ù. ±×¸®°í KERNEL_VERSIONÀ̶õ ¸ÅÅ©·Î°¡ ÀÖ¾î ÀÌ °ÍÀ» »ç¿ëÇϸé LINUX_VERSION_CODE¿Í ºñ±³ÇÒ ¼ö ÀְԵȴÙ.

µð¹ÙÀ̽º ¹øÈ£ µ¿Àû ÇÒ´ç

µð¹ÙÀ̽º ¹øÈ£°¡ ÀÌ¹Ì Á¤ÇØÁø °ÍÀÌ ¸¹±â ¶§¹®¿¡ ±× °ªÀ» Á¤ÇØ ¾µ Çʿ䰡 ¾ø´Â °æ¿ì¿£ ÇöÀç ½Ã½ºÅÛ¿¡¼­ »ç¿ëÇÏÁö ¾Ê´Â ¹øÈ£¸¦ ã¾Æ »ç¿ëÇÏ¸é µÇ±â ¶§¹®¿¡ ¸ðµâÀ» µî·ÏÇÏ´Â ´ç½Ã¿¡ ºñ¾î ÀÖ´Â ¹øÈ£¸¦ µ¿ÀûÀ¸·Î ¾Ë¾Æ³» ±× °ÍÀ» »ç¿ëÇÑ´Ù. »ç¿ëÀº init_module()¿¡¼­ ´ÙÀ½ ÇÔ¼ö¸¦ »ç¿ëÇØ ÁÖ¹øÈ£¸¦ ¾ò¾î ¿Â´Ù.

#define DEVICE_NAME "char_dev"

static int Major;

...

int init_module()
{
	Major = module_register_chrdev(0, DEVICE_NAME, &Fops);

	...
}

...

module_register_chrdev() ÇÔ¼öÀÇ Ã³À½ °ªÀÎ ÁÖ¹øÈ£¿¡ 0À» ³Ñ°ÜÁÖ¸é µ¿ÀûÀ¸·Î ÇÒ´çÇØ ÁØ´Ù. ¸®ÅÏµÇ¾î ¿À´Â °ªÀÌ À½¼öÀÎ °æ¿ì´Â ¿¡·¯°¡ ÀÖ´Â °ÍÀÌ°í ¾ç¼öÀÎ °æ¿ì´Â ±× °ÍÀ» ±×´ë·Î »ç¿ë ÇÏ¸é µÈ´Ù. cleanup_module()¿¡¼± ¾ò¾îÁ® ÀúÀåµÇ¾î ÀÖ´Â Major º¯¼öÀÇ °ªÀ» »ç¿ëÇÏ¸é µÈ´Ù.

Use Count

lsmod ¸í·ÉÀ¸·Î ÇöÀç ½Ã½ºÅÛ¿¡ µî·ÏµÈ ¸ðµâ¿¡ ´ëÇØ ¿­°ÅÇØº¸¸é ¼¼¹øÀç Ç׸ñÀÌ 'Used'Àε¥ ÀÌ °ÍÀº ÀÌ ¸ðµâÀÌ ´Ù¸¥ ¸ðµâ¿¡ ÀÇÇØ ¸Ö¸¶³ª »ç¿ëµÇ´Â °¡¸¦ ³ªÅ¸³½´Ù. ÀÌ °ªÀ» À§ÇÑ ¸ÅÅ©·Î°¡ ÁغñµÇ¾î Àִµ¥ MOD_INC_USE_COUNT, MOD_DEC_USE_COUNT ÀÌ°í °¢°¢À» open°ú release¿¡ ³Ö¾î ÁÖ¸é lsmod¸¦ »ç¿ëÇØ °ªÀ» ¾Ë ¼ö ÀÖ°Ô µÈ´Ù.

/proc

¸®´ª½º Ä¿³ÎÀº /proc À̶õ ÆÄÀÏ ½Ã½ºÅÛÀÌ Á¸ÀçÇÑ´Ù. /proc¿£ Ä¿³ÎÀÇ ³»ºÎ¿¡ Á¸ÀçÇÏ´Â Á¤º¸¸¦ ¾òÀ» ¼ö Àְųª ȤÀº Ä¿³ÎÀ̳ª ¸ðµâ ÇÁ·Î¼¼½º·Î Á¤º¸¸¦ Àü´ÞÇϰí ÀÐÀ» ¶§ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î 'cat /proc/interrupt'À» ÇØº¸¸é ÇöÀç ½Ã½ºÅÛÀÇ Àη¯Åӵ忡 ´ëÇÑ Á¤º¸¸¦ ¾Ë ¼ö Àִµ¥ ÀÌ ³»¿ëÀº ¸ðµÎ Ä¿³Î ³»ºÎ¿¡ µé¾î ÀÖ´Â °ÍµéÀÌ´Ù.

/procÀ» »ç¿ëÇϱâ À§Çؼ± init_module()¿¡¼­ ƯÁ¤ Á¤º¸¸¦ µî·ÏÇØ ÁÖ°í cleanup_module()¿¡¼­ ÇØÁ¦ÇØ ÁÖ¸éµÈ´Ù. ±×·¯³ª /procÀ¸·Î´Â Use Count¸¦ ¾Ë ¼ö ¾ø°í ƯÈ÷ ÆÄÀÏÀº ¿­¸®°í ¸ðµâÀº Á¦°ÅµÆÀ¸¸é °á°ú´Â ¿¹ÃøÇÒ ¼ö ¾ø°Ô µÈ´Ù. /procÀ» À§ÇÑ ±¸Á¶Ã¼ÀÇ Á¤ÀÇ´Â include/linux/proc_fs.h¿¡ Á¤ÀÇµÈ proc_dir_entry´Ù.

struct proc_dir_entry {
	unsigned short low_ino;
	unsigned short namelen;
	const char *name;
	mode_t mode;
	nlink_t nlink;
	uid_t uid;
	gid_t gid;
	unsigned long size;
	struct inode_operations * proc_iops;
	struct file_operations * proc_fops;
	get_info_t *get_info;
	struct module *owner;
	struct proc_dir_entry *next, *parent, *subdir;
	void *data;
	read_proc_t *read_proc;
	write_proc_t *write_proc;
	atomic_t count;		/* use count */
	int deleted;		/* delete flag */
	kdev_t	rdev;
};

½ÇÁ¦ »ç¿ëÇÏ´Â °ÍÀº ´ÙÀ½°ú °°´Ù. Ori Pomerantz°¡ ÁöÀº ' ¸®´ª½º Ä¿³Î ¸ðµâ ÇÁ·Î±×·¡¹Ö ¾È³»¼­' ¿¡¼­ ¹ßÃé Çß´Ù.

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; 
        
	if (offset > 0)  return 0; 

	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 len; 
} 

struct proc_dir_entry Our_Proc_File = 
{ 
	0,
	4,
	"test",
	S_IFREG | S_IRUGO,
	1,
	0, 0,
	80,
	NULL,
	procfile_read,
	NULL
};

int init_module()
{
	return proc_register(&proc_root, &Our_Proc_File);
}

void cleanup_module() 
{ 
	proc_unregister(&proc_root, Our_Proc_File.low_ino); 
}

º¯¼ö

¸®´ª½º¿¡¼­ Ethernet Card³ª Sound Card ¼³Á¤À» ÇØº» »ç¶÷Àº ÀÌ Ä«µåµé¿¡°Ô ƯÁ¤ °æ¿ì IO ¾îµå·¹½º³ª IRQ µîÀ» ÁöÁ¤Çϱâ À§ÇØ insmod µîÀ» »ç¿ëÇϸ鼭 °°ÀÌ ÆÄ¶ó¹ÌÅ͸¦ ³Ñ°ÜÁØ °æ ÇèÀÌ ÀÖÀ» °ÍÀÌ´Ù.

Ä¿³Î ¸ðµâÀº argc, argv¸¦ ¹ÞÀ» ¼ö ¾ø±â ¶§¹®¿¡ ´ë½Å Àü¿ª º¯¼ö¸¦ »ç¿ëÇØ °ªÀ» ³Ñ°Ü ÁÙ ¼ö ÀÖµµ·Ï µÇ¾î ÀÖ´Ù. º¯¼ö´Â Àü¿ªÀ¸·Î ¼³Á¤ÇÏ°í Æ¯Á¤ ¸ÅÅ©·Î¸¦ »ç¿ëÇØ ÁØ´Ù.

char *str1, *str2; 

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) 
MODULE_PARM(str1, "s"); 
MODULE_PARM(str2, "s"); 
#endif

À§¿¡¼­ str1°ú str2°¡ Àü¿ª º¯¼ö·Î ¼±¾ðµÇ°í ¸ðµâ ÆÄ¶ó¹ÌÅÍ·Î Á¤ÀǵƴÙ. ³ªÁß¿¡ insmod¸¦ ½ÇÇàÇÒ ¶§ 'insmod str1=abc str2=def'¿Í °°ÀÌ ÇϸéµÇ´Ù.

½Ç¼ö

¸ðµâÀº Ä¿³Î°ú °°Àº ·¹º§¿¡¼­ ½ÇÇàµÇ¹Ç·Î Ç¥ÁØ ¶óÀ̺귯¸®´Â »ç¿ëÇÒ ¼ö ¾ø´Ù. »ç¿ëÇÒ ¼ö ÀÖ´Â °ÍÀº Ä¿³Î ÇÔ¼öÀ̰í /proc/ksyms¿¡¼­ È®ÀÎÇÒ ¼ö ÀÖ´Ù.

ÀÎÅÍ·´Æ®¸¦ »ç¿ëÇÏ´Â °æ¿ì ó¸®ÇÏ´Â µ¿¾È ´Ù¸¥ ÀÎÅÍ·´Æ®°¡ °É¸®Áö ¾Êµµ·Ï Çϱâ À§ÇØ ÀÎÅÍ·´Æ®¸¦ ¸·¾Æ ³õ¾Ò´Ù¸é 󸮰¡ ´Ù ³¡³ª°í ³ª¼­´Â ¹Ýµå½Ã ÀÎÅÍ·´Æ®¸¦ °¡´ÉÇϵµ·Ï ÇØÁà¾ßÇÑ´Ù. ±×·¯Áö ¾ÊÀ¸¸é ½Ã½ºÅÛÀº ¸ÔÅëÀÌ µÉ °ÍÀÌ´Ù.