· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
Linux Kernel Procfs Guide


Linux Kernel Procfs Guide

ÀúÀÚ: Eric (J.A.K.) Mouw (<J.A.K.Mouw@its.tudelft.nl>, Delft University of Technology, Faculty of Information Technology and Systems)

¹ø¿ª: ±è³²Çü (<pastime@ece.uos.ac.kr>, ¼­¿ï½Ã¸³´ëÇб³ ÀΰøÁö´É¿¬±¸½Ç)




1. Preface

ÀÌ ¹®¼­¿¡¼­´Â ¸®´ª½º Ä¿³Î¿¡ Æ÷ÇÔµÈ proc ÆÄÀÏ ½Ã½ºÅÛÀ» »ç¿ëÇÏ´Â ¹æ¹ý¿¡ ´ëÇØ ¼³¸íÇÑ´Ù. ÀÌ ¹®¼­°¡ ¾²¿©Áú ¼ö ÀÖµµ·Ï ¾ÆÀ̵ð¾î°¡ ¶°¿À¸¥ °ÍÀº #kernelnewbies IRC ä³Î¿¡¼­ (http://www.kernelnewbies.org Âü°í) Jeff Garzik ÀÌ procfs ÀÇ »ç¿ë¹ýÀ» ¼³¸íÇÏ°í Alexander Viro °¡ ¸®´ª½º Ä¿³Î ¸ÞÀϸµ ¸®½ºÆ®¿¡ ¿Ã¸° ±ÛÀ» ³ª¿¡°Ô º¸³»ÁÖ¾úÀ» ¶§ÀÌ´Ù.

³ª´Â ÀÌ µ¿±â¸¦ ¸¶·ÃÇØ ÁÖ¾ú´ø Jeff Garzik <jgarzik@mandrakesoft.com> °ú Alexander Viro <viro@math.psu.edu> ¿¡°Ô °¨»çÇÏ°í, ¶ÇÇÑ SelfDocbook (http://people.redhat.com/twaugh/docbook/selfdocbook) À» ÅëÇØ µµ¿òÀ» ÁÖ¾ú´ø Tim Waugh <waugh@redhat.com> °ú ¹®¼­¸¦ È®ÀÎÇØ ÁÖ¾ú´ø Marc Joosen <marcj@historia.et.tudelft.nl> ¿¡°Ô °¨»çÀÇ ¸»À» ÀüÇÑ´Ù.

ÀÌ ¹®¼­´Â Mobile Multi-media Communications (http://www.mmc.tudelft.nl) °ú Ubiquitous Communications (http://www.ubicom.tudelft.nl) ¿¡¼­ Áö¿ø¹ÞÀº LART computing board (http://www.lart.tudelft.nl) ¿¡¼­ Å×½ºÆ®ÇÏ°í ÀÛ¼ºµÇ¾ú´Ù.

Erik


2. ¼Ò°³

/proc ÆÄÀÏ ½Ã½ºÅÛ (procfs) Àº ¸®´ª½º Ä¿³Î ³»¿¡ Á¸ÀçÇϴ Ưº°ÇÑ ÆÄÀÏ ½Ã½ºÅÛÀÌ´Ù. ÀÌ°ÍÀº °¡»óÀÇ ÆÄÀÏ ½Ã½ºÅÛÀ¸·Î ½ÇÁ¦ ºí·Ï µð¹ÙÀ̽º¿¡ ¿¬°áµÇ¾î ÀÖ´Â °ÍÀÌ ¾Æ´Ï¶ó ¿ÀÁ÷ ¸Þ¸ð¸® »ó¿¡¸¸ Á¸ÀçÇÑ´Ù. procfs ³»ÀÇ ÆÄÀÏÀº »ç¿ëÀÚ °ø°£ÀÇ ÇÁ·Î±×·¥ÀÌ Ä¿³ÎÀÇ Æ¯Á¤ Á¤º¸¸¦ Àоî¿À°Å³ª (/proc/[0-9]+/ [1] ¿¡¼­ ÇØ´ç ÇÁ·Î¼¼½ºÀÇ Á¤º¸¸¦ ¾Ë¾Æ³¾ ¼ö ÀÖ´Â °Íó·³), µð¹ö±ëÀÇ ¸ñÀûÀ¸·Î (/proc/ksyms ¿Í °°ÀÌ) »ç¿ëµÉ ¼ö ÀÖ´Ù.

ÀÌ ¹®¼­¿¡¼­´Â ¸®´ª½º Ä¿³Î ³»ÀÇ proc ÆÄÀÏ ½Ã½ºÅÛÀÇ »ç¿ë ¹æ¹ý¿¡ ´ëÇØ ¼³¸íÇÑ´Ù. ¸ÕÀú proc ÆÄÀÏ ½Ã½ºÅÛ ³»ÀÇ ÆÄÀÏÀ» ´Ù·ç´Âµ¥ °ü·ÃµÈ ¸ðµç ÇÔ¼öµéÀ» ¼Ò°³Çϵµ·Ï ÇÑ´Ù. ±×¸®°í »ç¿ëÀÚ °ø°£ÀÇ ÇÁ·Î±×·¥°ú ¾î¶»°Ô Åë½ÅÇÏ´ÂÁö¸¦ ¼³¸íÇÏ°í, ¸î°¡Áö ÆÁµéÀ» ¼Ò°³ÇÑ ÈÄ¿¡ ¸¶Áö¸·À¸·Î´Â À̸¦ ÀÌ¿ëÇÑ ¿ÏÀüÇÑ ¿¹Á¦¸¦ Çϳª º¸À̵µ·Ï ÇÏ°Ú´Ù.

/proc/sys ³»ÀÇ ÆÄÀϵéÀº ½Ã½ºÅÛÀÇ ¼³Á¤¿¡ °ü·ÃµÈ ÆÄÀÏÀÓ¿¡ ÁÖÀÇÇϱ⠹ٶõ´Ù: ÀÌ ÆÄÀϵéÀº proc ÆÄÀÏ ½Ã½ºÅÛ¿¡ ¼ÓÇÑ °ÍÀÌ ¾Æ´Ï°í Kernel API Book »óÀÇ ¿ÏÀüÈ÷ ´Ù¸¥ API µé¿¡ ÀÇÇØ °ü¸®µÈ´Ù.

3. Procfs ´Ù·ç±â

ÀÌ Àå¿¡¼­´Â procfs ¿¡ ÆÄÀÏ, ½Éº¼¸¯ ¸µÅ©, ÀåÄ¡ ³ëµå, µð·ºÅ丮 µîÀÇ ¿©·¯ Ä¿³Î ÄÄÆ÷³ÍÆ® µéÀ» »ý¼ºÇÏ°í Á¦°ÅÇÏ´Â ÇÔ¼öµéÀ» ¼³¸íÇÑ´Ù.

½ÃÀÛÇϱâ Àü¿¡ ÇÑ°¡Áö ÁÖÀÇÇÒ »çÇ×ÀÌ ÀÖ´Ù: ¸¸¾à procfs ÀÇ ÇÔ¼öµéÀ» »ç¿ëÇϱâ À§Çؼ­´Â ¿Ã¹Ù¸¥ Çì´õÆÄÀÏÀ» Æ÷ÇÔ½ÃÄÑ¾ß ÇÑ´Ù! ÄÚµåÀÇ ½ÃÀۺκп¡ ´ÙÀ½°ú °°Àº ºÎºÐÀÌ µé¾î¾ß ÇÒ °ÍÀÌ´Ù.

#include <linux/proc_fs.h>

3.1. ÀÏ¹Ý ÆÄÀÏ »ý¼ºÇϱâ

struct proc_dir_entry* create_proc_entry(const char* name, mode_t mode,
                                         struct proc_dir_entry* parent);

ÀÌ ÇÔ¼ö´Â parent ¶ó´Â µð·ºÅ丮 ¾È¿¡ ÆÄÀÏ ¸ðµå·Î mode ¸¦ °¡Áö´Â name À̶ó´Â À̸§ÀÇ ÀÏ¹Ý ÆÄÀÏ(regular file) À» »ý¼ºÇÑ´Ù. procfs ÀÇ °¡Àå »óÀ§¿¡ ÆÄÀÏÀ» »ý¼ºÇϱâ À§Çؼ­´Â parent ÀÚ¸®¿¡ NULL À» ³ÖÀ¸¸é µÈ´Ù. ¼º°ø½Ã ÇÔ¼öÀÇ ¸®ÅÏ°ªÀº »õ·Î »ý¼ºµÈ struct proc_dir_entry ÀÇ Æ÷ÀÎÅÍ°¡ µÇ¸ç, ½ÇÆнÿ¡´Â NULL ÀÌ µÈ´Ù. 3Àå ¿¡¼­´Â ÀÌ·¯ÇÑ ÆÄÀÏÀ» °¡Áö°í ÇÒ ¼ö ÀÖ´Â ÀϵéÀ» ¼³¸íÇÑ´Ù.

ÇÑ°¡Áö Ưº°ÇÑ Á¡Àº ¿©·¯ °³ÀÇ µð·ºÅ丮¸¦ ³Ñ¾î¼­ ÆÄÀÏÀ» »ý¼ºÇÏ´Â °ÍÀ» Çã¿ëÇÑ´Ù´Â °ÍÀÌ´Ù. ¿¹¸¦ µé¾î, create_proc_entry("drivers/via0/info") ¿Í °°ÀÌ »ç¿ëÇÑ °æ¿ì via0 ¶ó´Â µð·ºÅ丮°¡ ¾ø´Ù¸é 0755 ÀÇ ±ÇÇÑÀ¸·Î ÀÌ µð·ºÅ丮¸¦ »ý¼ºÇÏ°Ô µÈ´Ù.

¸¸¾à ¿ÀÁ÷ ÆÄÀÏÀ» Àб⸸ ÇÒ ¸ñÀûÀ̶ó¸é, 4.1 Àý¿¡¼­ ¼Ò°³ÇÒ create_proc_read_entry ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© »ý¼º°ú ÃʱâÈ­¸¦ Çѹø¿¡ ó¸®ÇÒ ¼ö ÀÖ´Ù.

3.2. ½Éº¼¸¯ ¸µÅ© »ý¼ºÇϱâ

struct proc_dir_entry* proc_symlink(const char* name,
                        struct proc_dir_entry* parent, const char* dest);

ÀÌ ÇÔ¼ö´Â parent µð·ºÅ丮 ³»¿¡ name À¸·ÎºÎÅÍ dest ¸¦ °¡¸®Å°´Â ½Éº¼¸¯ ¸µÅ©¸¦ »ý¼ºÇÑ´Ù. ÀÌ°ÍÀº »ç¿ëÀÚ °ø°£¿¡¼­ÀÇ ln -s dest name ¸í·ÉÀ¸·Î »ý°¢ÇÒ ¼ö ÀÖ´Ù.

3.3. ÀåÄ¡ ³ëµå »ý¼ºÇϱâ

struct proc_dir_entry* proc_mknod(const char* name, mode_t mode,
                                 struct proc_dir_entry* parent, kdev_t rdev);

ÀÌ ÇÔ¼ö´Â parent µð·ºÅ丮 ³»¿¡ ÆÄÀÏ ¸ðµå·Î mode ¸¦ °¡Áö´Â name À̶ó´Â ÀåÄ¡ ³ëµå (device file) ¸¦ »ý¼ºÇÑ´Ù. ÀåÄ¡ ³ëµå´Â linux/kdev_t.h ³»ÀÇ MKDEV ¶ó´Â ¸ÅÅ©·Î¸¦ ÅëÇØ ¸¸µé¾îÁö´Ârdev ¶ó´Â ÀåÄ¡¿Í ÇÔ²² µ¿ÀÛÇÒ °ÍÀÌ´Ù. mode ¿¡´Â ÀåÄ¡ ³ëµå¸¦ »ý¼ºÇϱâ À§ÇØ ¹Ýµå½Ã S_IFBLK ³ª S_IFCHR ÁßÀÇ Çϳª¸¦ Æ÷ÇÔÇØ¾ß ÇÑ´Ù. ÀÌ°ÍÀº »ç¿ëÀÚ °ø°£¿¡¼­ÀÇ mknod --mode=mode name rdev ¸í·ÉÀ¸·Î »ý°¢ÇÒ ¼ö ÀÖ´Ù.

3.4. µð·ºÅ丮 »ý¼ºÇϱâ

struct proc_dir_entry* proc_mkdir(const char* name,
                                  struct proc_dir_entry* parent);

ÀÌ ÇÔ¼ö´Â parent µð·ºÅ丮 ¾È¿¡ name À̶ó´Â À̸§ÀÇ µð·ºÅ丮¸¦ »ý¼ºÇÑ´Ù.

3.5. ¿£Æ®¸® »èÁ¦Çϱâ

void remove_proc_entry(const char* name, struct proc_dir_entry* parent);

ÀÌ ÇÔ¼ö´Â procfs ³»ÀÇ parent µð·ºÅ丮 ¾È¿¡ ÀÖ´Â name À̶ó´Â À̸§ÀÇ ¿£Æ®¸® [2] ¸¦ »èÁ¦ÇÑ´Ù. °¢ ¿£Æ®¸®´Â name À» ÅëÇØ »èÁ¦µÇ¸ç, °¢°¢ÀÇ »ý¼º ÇÔ¼öµéÀ» ÅëÇØ ¹ÝȯµÈ proc_dir_entry ±¸Á¶Ã¼·Î´Â Áö¿ï ¼ö ¾ø´Ù. ÇÑ°¡Áö ÁÖÀÇÇÒ »çÇ×Àº ÀÌ ÇÔ¼ö´Â Àç±ÍÀûÀ¸·Î ¿£Æ®¸®¸¦ »èÁ¦ÇÏÁö ¾Ê´Â´Ù´Â Á¡ÀÌ´Ù.

¸¸¾à ¿£Æ®¸®¿¡ °ü·ÃµÈ µ¥ÀÌŸ°¡ ÇÒ´çµÇ¾ú´Ù¸é, remove_proc_entry ÇÔ¼ö¸¦ È£ÃâÇϱâ Àü¿¡ µ¥ÀÌŸ¸¦ ÇØÁ¦ÇØ¾ß ÇÑ´Ù. 3.3 Àý¿¡¼­ ÀÌ·¯ÇÑ µ¥ÀÌŸ¸¦ »ç¿ëÇÏ´Â ¹ý¿¡ ´ëÇØ ´õ ÀÚ¼¼È÷ ¾Ë¾Æº¸°Ú´Ù.


4. »ç¿ëÀÚ °ø°£°ú Åë½ÅÇϱâ

procfs ¿¡¼­´Â Ä¿³ÎÀÇ ¸Þ¸ð¸®¸¦ Á÷Á¢ Á¢±ÙÇÏ¿© Á¤º¸¸¦ ¾ò¾î¿À´Â ´ë½Å¿¡ ÆÄÀÏÀÇ Äݹé ÇÔ¼ö ¸¦ ÅëÇØ µ¿ÀÛÇÑ´Ù: ÀÌ·¯ÇÑ ÇÔ¼öµéÀº ƯÁ¤ ÆÄÀÏÀ» Àаųª ¾µ ¶§ È£ÃâµÈ´Ù. À̸¦ ÀÌ¿ëÇϱâ À§Çؼ­´Â procfs ÀÇ ÆÄÀÏÀ» »ý¼ºÇÑ ÈÄ¿¡ create_proc_entry ÇÔ¼ö¸¦ ÅëÇØ ¹ÝȯµÈ proc_dir_entry ±¸Á¶Ã¼ÀÇ read_proc À̳ª write_proc µîÀÇ Çʵ带 ÃʱâÈ­ ÇØ ÁÖ¾î¾ß ÇÑ´Ù:

struct proc_dir_entry* entry;

entry->read_proc  = read_proc_foo;
entry->write_prpc = write_proc_foo;

¸¸¾à read_proc ¸¸À» »ç¿ëÇÏ´Â °æ¿ì¶ó¸é, 4.1 Àý¿¡¼­ ¼Ò°³ÇÒ create_proc_read_entry ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¸é »ý¼º°ú ÃʱâÈ­¸¦ Çѹø¿¡ ¼öÇàÇÒ ¼ö ÀÖ´Ù.

4.1. µ¥ÀÌŸ Àбâ

read ÇÔ¼ö´Â »ç¿ëÀÚ °ø°£ÀÇ ÇÁ·Î¼¼½º°¡ Ä¿³Î ¿µ¿ªÀÇ µ¥ÀÌŸ¸¦ ÀÐÀ» ¼ö ÀÖµµ·Ï ÇØÁÖ´Â Äݹé ÇÔ¼öÀÌ´Ù. read ÇÔ¼ö´Â ´ÙÀ½°ú °°Àº ÇüÅ°¡ µÉ °ÍÀÌ´Ù:

int read_func(char* page, char **start, off_t off,
              int count, int* eof, void* data);

read ÇÔ¼ö´Â Á¤º¸¸¦ Àоî¿Í¼­ page ¿¡ ÀúÀåÇÑ´Ù. ÀÌ ÇÔ¼ö¿¡¼­ off ´Â page ³»ÀÇ Á¤º¸¸¦ ±â·ÏÇÒ ½ÃÀÛÀ§Ä¡¸¦, count ·Î Àоî¿Ã ¹ÙÀÌÆ® ¼ö¸¦ ¸í½ÃÇÒ ¼ö ÀÖÁö¸¸, ´ëºÎºÐÀÇ read ÇÔ¼ö´Â ´Ü¼øÇÑ ÇüÅ°¡ µÇ°í, ¿ÀÁ÷ ÀûÀº ¾çÀÇ Á¤º¸ ¸¸À» ¹ÝȯÇϱ⠶§¹®¿¡ ÀϹÝÀûÀ¸·Î ÀÌ µÎ ÀÎÀÚ´Â ¹«½ÃµÈ´Ù. (ÀÌ°ÍÀº more ³ª less °°Àº ÆäÀÌÁö¸¦ Á¶ÀýÇÏ´Â ÇÁ·Î±×·¥À» ¹«½ÃÇÏ°Ô µÇÁö¸¸, cat Àº ¿©ÀüÈ÷ µ¿ÀÛÇÑ´Ù.)

¸¸¾à off ³ª count ÀÎÀÚ°¡ ÀûÀýÈ÷ »ç¿ëµÇ¸é, eof ÀÎÀÚ´Â ÆÄÀÏÀÇ ³¡ (End Of File) ¿¡ µµ´ÞÇß´ÂÁö¸¦ ³ªÅ¸³»´Â ½ÅÈ£·Î »ç¿ëµÉ °ÍÀÌ´Ù. (EOF ÀÎ °æ¿ì eof °¡ °¡¸®Å°´Â °÷ÀÇ °ªÀÌ 1·Î ¼³Á¤µÉ °ÍÀÌ´Ù.)

start ÀÎÀÚ´Â Ä¿³Î³»ÀÇ ¾î´À °÷¿¡¼­µµ »ç¿ëµÇÁö ¾Ê´Â °ÍÀ¸·Î º¸ÀδÙ. data ÀÎÀÚ´Â ¿©·¯ ÆÄÀϵ鿡 ´ëÇÑ ÇϳªÀÇ Äݹé ÇÔ¼ö¸¦ »ý¼ºÇϴµ¥ ¾²ÀÏ ¼ö ÀÖ´Ù. - 3.3 Àý Âü°í

read_func ´Â ¹Ýµå½Ã page ¿¡ ±â·ÏµÈ ¹ÙÀÌÆ® ¼ö¸¦ ¸®ÅÏÇØ¾ß ÇÑ´Ù.

5Àå¿¡¼­ read Äݹé ÇÔ¼ö°¡ ¾î¶»°Ô »ç¿ëµÇ´ÂÁö º¸°ÔµÉ °ÍÀÌ´Ù.

4.2. µ¥ÀÌŸ ¾²±â

write Äݹé ÇÔ¼ö´Â »ç¿ëÀÚ °ø°£ÀÇ ÇÁ·Î¼¼½º°¡ Ä¿³Î °ø°£¿¡ µ¥ÀÌŸ¸¦ ±â·ÏÇÒ ¼ö ÀÖµµ·Ï ÇØÁØ´Ù. µû¶ó¼­ ÀÌ ÇÔ¼ö´Â ÀÏÁ¾ÀÇ Ä¿³Î¿¡ ´ëÇÑ Á¦¾î±ÇÀ» °¡Áø´Ù. write ÇÔ¼ö´Â ´ÙÀ½°ú °°Àº ÇüÅ°¡ µÉ °ÍÀÌ´Ù:

int write_func(struct file* file, const char* buffer,
               unsigned long count, void* data);

write ÇÔ¼ö´Â buffer ·Î ºÎÅÍ ÃÖ´ë count ¸¸Å­ÀÇ ¹ÙÀÌÆ®¸¦ ÀоîµéÀδÙ. ÁÖÀÇÇÒ »çÇ×Àº buffer ´Â Ä¿³Î ¸Þ¸ð¸® °ø°£¿¡ ¼ÓÇÑ °ÍÀÌ ¾Æ´Ï¶ó´Â °ÍÀÌ´Ù. µû¶ó¼­ ¸ÕÀú copy_from_user ¸¦ ÅëÇØ Ä¿³Î ¿µ¿ªÀ¸·Î µ¥ÀÌŸ¸¦ º¹»çÇØ¾ß ÇÑ´Ù. file ÀÎÀÚ´Â º¸Åë ¹«½ÃµÈ´Ù. 3.3 Àý¿¡¼­ data ÀÎÀÚ¸¦ ¾î¶»°Ô »ç¿ëÇÏ´ÂÁö¸¦ º¸¿©ÁØ´Ù.

´Ù½Ã ¸»ÇÏÁö¸¸, 5Àå¿¡¼­ ÀÌ ÄݹéÇÔ¼ö°¡ ¾î¶»°Ô »ç¿ëµÇ´ÂÁö º¸°Ô µÉ °ÍÀÌ´Ù.

4.3. ¿©·¯ ÆÄÀÏ¿¡¼­ ÇϳªÀÇ ÄݹéÇÔ¼ö ¾²±â

°ÅÀÇ ºñ½ÁÇÑ ÆÄÀÏÀÌ ¾ÆÁÖ ¸¹ÀÌ »ç¿ëµÉ ¶§, °¢°¢ÀÇ ÆÄÀÏ ¸¶´Ù °¢°¢ÀÇ Äݹé ÇÔ¼öµéÀ» »ç¿ëÇØ¾ß ÇÑ´Ù¸é ²Ï ºÒÆíÇÑ ÀÏÀÌµÉ °ÍÀÌ´Ù. À̸¦ À§ÇØ ÇϳªÀÇ Äݹé ÇÔ¼ö°¡ struct proc_dir_entry ÀÇ data Çʵ带 ÅëÇØ °¢°¢ÀÇ ÆÄÀϵéÀ» ±¸ºÐÇؼ­ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ÇÏ°í ÀÖ´Ù. ¸ÕÀú data Çʵ尡 ÃʱâÈ­ µÇ¾î¾ß ÇÑ´Ù.

struct proc_dir_entry* entry;
struct my_file_data *file_data;

file_data = kmalloc(sizeof(struct my_file_data), GFP_KERNEL);
entry->data = file_data;

data Çʵå´Â void * ÇüÀ̹ǷÎ, ¾î¶°ÇÑ ÇüÅ·εçÁö ÃʱâÈ­ µÉ ¼ö ÀÖ´Ù.

ÀÌÁ¦ data Çʵ带 ¼³Á¤Çؼ­, read_proc °ú write_proc ÇÔ¼ö¿¡¼­ ÆÄÀϵéÀ» ±¸ºÐÇÒ ¼ö ÀÖ°Ô ÇÒ ¼ö ÀÖ´Ù.

int foo_read_func(char *page, char **start, off_t off,
                  int count, int *eof, void *data)
{
        int len;

        if(data == file_data) {
                /* special case for this file */
        } else {
                /* normal processing */
        }

        return len;
}

procfs ÀÇ ¿£Æ®¸®¸¦ »èÁ¦ÇÒ ¶§ data Çʵ带 ÇØÁ¦ÇÏ´Â °ÍÀ» ÀØÁö¸»ÀÚ.


5. ¸î°¡Áö ÆÁµé

5.1. Æí¸®ÇÑ ÇÔ¼ö

struct proc_dir_entry* create_proc_read_entry(const char* name, mode_t mode,
          struct proc_dir_entry* parent, read_proc_t* read_proc, void* data);

ÀÌ ÇÔ¼ö´Â 2.1 Àý¿¡¼­ ¼³¸íÇÑ create_proc_entry ¸¦ ÀÌ¿ëÇÑ °Í°ú ¿ÏÀüÈ÷ µ¿ÀÏÇÑ ¹æ½ÄÀ¸·Î ÀÏ¹Ý ÆÄÀÏÀ» »ý¼ºÇÏ°í read_proc À» ÅëÇØ read ÇÔ¼ö¸¦ ¼³Á¤ÇÑ´Ù. ÀÌ ÇÔ¼ö¿¡¼­µµ ¹°·Ð 3.3 Àý¿¡¼­ ¼³¸íÇÑ data ÀÎÀÚ¸¦ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.

5.2. ¸ðµâ

¸¸¾à procfs °¡ ¸ðµâ ³»¿¡¼­ »ç¿ëµÈ´Ù¸é, struct proc_dir_entry ³»ÀÇ owner Çʵ带 THIS_MODULE À̶ó´Â ¸ÅÅ©·Î¸¦ ÀÌ¿ëÇØ ¼³Á¤ÇØ¾ß ÇÑ´Ù.

struct proc_dir_entry* entry;

entry->owner = THIS_MODULE;

5.3. ÆÄÀÏ ¸ðµå¿Í ¼ÒÀ¯±Ç

¶§¶§·Î procfs ¿£Æ®¸®ÀÇ ÆÄÀÏ ¸ðµå³ª ¼ÒÀ¯±ÇÀ» º¯È¯ÇØ¾ß ÇÒ ¶§°¡ ÀÖ´Ù. ÀÌ·¯ÇÑ °æ¿ìÀÇ ¿¹¸¦ ¾Æ·¡¿¡ º¸ÀδÙ:

struct proc_dir_entry* entry;

entry->mode =  S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH;
entry->uid = 0;
entry->gid = 100;


6. ¿¹Á¦

/*
 * procfs_example.c: an example proc interface
 *
 * Copyright (C) 2001, Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
 *
 * This file accompanies the procfs-guide in the Linux kernel
 * source. Its main use is to demonstrate the concepts and
 * functions described in the guide.
 *
 * This software has been developed while working on the LART
 * computing board (http://www.lart.tudelft.nl/), which is
 * sponsored by the Mobile Multi-media Communications
 * (http://www.mmc.tudelft.nl/) and Ubiquitous Communications
 * (http://www.ubicom.tudelft.nl/) projects.
 *
 * The author can be reached at:
 *
 *  Erik Mouw
 *  Information and Communication Theory Group
 *  Faculty of Information Technology and Systems
 *  Delft University of Technology
 *  P.O. Box 5031
 *  2600 GA Delft
 *  The Netherlands
 *
 *
 * This program is free software; you can redistribute
 * it and/or modify it under the terms of the GNU General
 * Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be
 * useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place,
 * Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
#include <asm/uaccess.h>


#define MODULE_VERSION "1.0"
#define MODULE_NAME "procfs_example"

#define FOOBAR_LEN 8

struct fb_data_t {
        char name[FOOBAR_LEN + 1];
        char value[FOOBAR_LEN + 1];
};


static struct proc_dir_entry *example_dir, *foo_file,
        *bar_file, *jiffies_file, *tty_device, *symlink;


struct fb_data_t foo_data, bar_data;


static int proc_read_jiffies(char *page, char **start,
                             off_t off, int count,
                             int *eof, void *data)
{
        int len;

        MOD_INC_USE_COUNT;
        
        len = sprintf(page, "jiffies = %ld\n",
                      jiffies);

        MOD_DEC_USE_COUNT;

        return len;
}


static int proc_read_foobar(char *page, char **start,
                            off_t off, int count,
                            int *eof, void *data)
{
        int len;
        struct fb_data_t *fb_data = (struct fb_data_t *)data;

        MOD_INC_USE_COUNT;
        
        len = sprintf(page, "%s = '%s'\n",
                      fb_data->name, fb_data->value);

        MOD_DEC_USE_COUNT;

        return len;
}


static int proc_write_foobar(struct file *file,
                             const char *buffer,
                             unsigned long count,
                             void *data)
{
        int len;
        struct fb_data_t *fb_data = (struct fb_data_t *)data;

        MOD_INC_USE_COUNT;

        if(count > FOOBAR_LEN)
                len = FOOBAR_LEN;
        else
                len = count;

        if(copy_from_user(fb_data->value, buffer, len)) {
                MOD_DEC_USE_COUNT;
                return -EFAULT;
        }

        fb_data->value[len] = '\0';

        MOD_DEC_USE_COUNT;

        return len;
}


static int __init init_procfs_example(void)
{
        int rv = 0;

        /* create directory */
        example_dir = proc_mkdir(MODULE_NAME, NULL);
        if(example_dir == NULL) {
                rv = -ENOMEM;
                goto out;
        }
        
        example_dir->owner = THIS_MODULE;
        
        /* create jiffies using convenience function */
        jiffies_file = create_proc_read_entry("jiffies",
                                              0444, example_dir,
                                              proc_read_jiffies,
                                              NULL);
        if(jiffies_file == NULL) {
                rv  = -ENOMEM;
                goto no_jiffies;
        }

        jiffies_file->owner = THIS_MODULE;

        /* create foo and bar files using same callback
         * functions
         */
        foo_file = create_proc_entry("foo", 0644, example_dir);
        if(foo_file == NULL) {
                rv = -ENOMEM;
                goto no_foo;
        }

        strcpy(foo_data.name, "foo");
        strcpy(foo_data.value, "foo");
        foo_file->data = &foo_data;
        foo_file->read_proc = proc_read_foobar;
        foo_file->write_proc = proc_write_foobar;
        foo_file->owner = THIS_MODULE;
                
        bar_file = create_proc_entry("bar", 0644, example_dir);
        if(bar_file == NULL) {
                rv = -ENOMEM;
                goto no_bar;
        }

        strcpy(bar_data.name, "bar");
        strcpy(bar_data.value, "bar");
        bar_file->data = &bar_data;
        bar_file->read_proc = proc_read_foobar;
        bar_file->write_proc = proc_write_foobar;
        bar_file->owner = THIS_MODULE;
                
        /* create tty device */
        tty_device = proc_mknod("tty", S_IFCHR | 0666,
                                example_dir, MKDEV(5, 0));
        if(tty_device == NULL) {
                rv = -ENOMEM;
                goto no_tty;
        }
        
        tty_device->owner = THIS_MODULE;

        /* create symlink */
        symlink = proc_symlink("jiffies_too", example_dir,
                               "jiffies");
        if(symlink == NULL) {
                rv = -ENOMEM;
                goto no_symlink;
        }

        symlink->owner = THIS_MODULE;

        /* everything OK */
        printk(KERN_INFO "%s %s initialised\n",
               MODULE_NAME, MODULE_VERSION);
        return 0;

no_symlink:
        remove_proc_entry("tty", example_dir);
no_tty:
        remove_proc_entry("bar", example_dir);
no_bar:
        remove_proc_entry("foo", example_dir);
no_foo:
        remove_proc_entry("jiffies", example_dir);
no_jiffies:                          
        remove_proc_entry(MODULE_NAME, NULL);
out:
        return rv;
}


static void __exit cleanup_procfs_example(void)
{
        remove_proc_entry("jiffies_too", example_dir);
        remove_proc_entry("tty", example_dir);
        remove_proc_entry("bar", example_dir);
        remove_proc_entry("foo", example_dir);
        remove_proc_entry("jiffies", example_dir);
        remove_proc_entry(MODULE_NAME, NULL);

        printk(KERN_INFO "%s %s removed\n",
               MODULE_NAME, MODULE_VERSION);
}


module_init(init_procfs_example);
module_exit(cleanup_procfs_example);

MODULE_AUTHOR("Erik Mouw");
MODULE_DESCRIPTION("procfs examples");

EXPORT_NO_SYMBOLS;


----
  • [1] ¼ýÀÚ´Â pid °ªÀ» ÀǹÌ
  • [2] À§ÀÇ ÇÔ¼öµé·Î ¸¸µé¾îÁø °Íµé - ÀϹÝÆÄÀÏ, ½Éº¼¸¯ ¸µÅ©, ÀåÄ¡³ëµå, µð·ºÅ丮



ID
Password
Join
You have a will that can be influenced by all with whom you come in contact.


sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2005-03-02 15:36:03
Processing time 0.0124 sec