免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 11370 | 回复: 39
打印 上一主题 下一主题

我的虚拟文件系统(linux) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-05-25 18:59 |只看该作者 |倒序浏览
不知道该不该发这里,是我从proc改来的,懂内核源码的交流交流

hello.c


  1. #include "hello.h"

  2. struct inode * hello_get_inode(struct super_block *, int, struct hello_dir_entry *);

  3. /*这个函数是直接从linux复制过来的,作用就是显示目录里的文件名,没有这个
  4. 函数也行只是你用ls、dir命令看不到目录下的文件。*/
  5. int hello_readdir(struct file * filp, void * dirent, filldir_t filldir)
  6. {
  7. printk("hello_readdir\n");
  8.         struct hello_dir_entry * de;
  9.         unsigned int ino;
  10.         int i;
  11.         struct inode *inode = filp->;f_dentry->;d_inode;

  12.         ino = inode->;i_ino;
  13.         de = (struct hello_dir_entry *) inode->;u.generic_ip;
  14.         if (!de)
  15.                 return -EINVAL;
  16.         i = filp->;f_pos;
  17.         switch (i) {
  18.                 case 0:
  19.                         if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
  20.                                 return 0;
  21.                         i++;
  22.                         filp->;f_pos++;
  23.                         /* fall through */
  24.                 case 1:
  25.                         if (filldir(dirent, "..", 2, i,
  26.                                     filp->;f_dentry->;d_parent->;d_inode->;i_ino,
  27.                                     DT_DIR) < 0)
  28.                                 return 0;
  29.                         i++;
  30.                         filp->;f_pos++;
  31.                         /* fall through */
  32.                 default:
  33.                         de = de->;subdir;
  34.                         i -= 2;
  35.                         for (;;) {
  36.                                 if (!de)
  37.                                         return 1;
  38.                                 if (!i)
  39.                                         break;
  40.                                 de = de->;next;
  41.                                 i--;
  42.                         }

  43.                         do {
  44.                                 if (filldir(dirent, de->;name, de->;namelen, filp->;f_pos,
  45.                                             de->;low_ino, de->;mode >;>; 12) < 0)
  46.                                         return 0;
  47.                                 filp->;f_pos++;
  48.                                 de = de->;next;
  49.                         } while (de);
  50.         }
  51.         return 1;
  52. }

  53. int hello_d_revalidate(struct dentry *res, int i){printk("d_revalidate\n");return 0;}
  54. int hello_d_hash(struct dentry *res, struct qstr *name){printk("d_hash\n");return 0;}
  55. int hello_d_compare(struct dentry *res, struct qstr *name, struct qstr *old)
  56. {printk("d_compare\n");return 0;}
  57. int hello_d_delete(struct dentry *res){printk("d_delete\n");return 0;}
  58. void hello_d_release(struct dentry *res){printk("d_release\n");}
  59. void hello_d_iput(struct dentry *res, struct inode *inode){printk("d_iput\n");}

  60. struct dentry_operations hello_lookup_dops = {
  61.         /*d_revalidate:        hello_d_revalidate,
  62.         d_hash:                hello_d_hash,
  63.         d_compare:        hello_d_compare,*/
  64.         d_delete:        hello_d_delete,
  65.         d_release:        hello_d_release,
  66.         /*d_iput:                hello_d_iput*/
  67. };

  68. /*读文件节点,这个函数是被real_lookup函数调用的,具体调用是这里dir->;i_op->;lookup(dir, dentry);作用是从磁盘读文件节点填充inode结构。我这里用hello_dir_entry结构填充的*/

  69. struct dentry *hello_lookup(struct inode * dir, struct dentry *dentry)
  70. {
  71.         struct inode *inode;
  72.         struct hello_dir_entry * de;
  73.         int error;

  74.         error = -ENOENT;
  75.         inode = NULL;
  76.         de = (struct hello_dir_entry *) dir->;u.generic_ip;
  77.         if (de) {
  78.                 for (de = de->;subdir; de ; de = de->;next) {
  79.                         if (!de || !de->;low_ino)
  80.                                 continue;
  81.                         if (de->;namelen != dentry->;d_name.len)
  82.                                 continue;
  83.                         if (!memcmp(dentry->;d_name.name, de->;name, de->;namelen)) {
  84.                                 int ino = de->;low_ino;
  85.                                 error = -EINVAL;
  86.                                 inode = hello_get_inode(dir->;i_sb, ino, de);
  87.                                 break;
  88.                         }
  89.                 }
  90.         }

  91.         if (inode) {
  92.                 dentry->;d_op = &hello_lookup_dops;
  93.                 d_add(dentry, inode);
  94.                 return NULL;
  95.         }
  96.         return ERR_PTR(error);
  97. }
  98. /************************************************************************************************************/
  99. static struct inode_operations hello_root_inode_operations = {
  100.         lookup:                hello_lookup,
  101. };

  102. static struct file_operations hello_file_operations = {
  103.         readdir:        hello_readdir,
  104. };       

  105. struct hello_dir_entry hello_root = {
  106.         low_ino:        HELLO_ROOT_INO,
  107.         namelen:        5,
  108.         name:                "/hello",
  109.         mode:                S_IFDIR | S_IRUGO | S_IXUGO,
  110.         nlink:                2,
  111.         hello_iops:        &hello_root_inode_operations,
  112.         hello_fops:        &hello_file_operations,
  113.         parent:        &hello_root,
  114. };

  115. /*填充inode结构*/
  116. struct inode * hello_get_inode(struct super_block * sb, int ino,
  117.         struct hello_dir_entry * de)
  118. {
  119. printk("hello_get_inode\n");
  120.         struct inode * inode;

  121.         de_get(de);
  122.         inode = iget(sb, ino);
  123.         if (!inode)
  124.                 goto out_fail;
  125.         inode->;u.generic_ip = (void *) de;
  126.         if (de) {
  127.                 if (de->;mode) {
  128.                         inode->;i_mode = de->;mode;
  129.                         inode->;i_uid = de->;uid;
  130.                         inode->;i_gid = de->;gid;
  131.                 }
  132.                 if (de->;size)
  133.                         inode->;i_size = de->;size;
  134.                 if (de->;nlink)
  135.                         inode->;i_nlink = de->;nlink;
  136.                 if (de->;owner)
  137.                         __MOD_INC_USE_COUNT(de->;owner);
  138.                 if (de->;hello_iops)
  139.                         inode->;i_op = de->;hello_iops;
  140.                 if (de->;hello_fops)
  141.                         inode->;i_fop = de->;hello_fops;
  142.         }

  143. out:
  144.         return inode;

  145. out_fail:
  146.         de_put(de);
  147.         goto out;
  148. }                       

  149. /***********************************************************************************************************/

  150. void d_instantiate(struct dentry *entry, struct inode * inode)
  151. {
  152. printk("d_instantiate\n");
  153.         if (!list_empty(&entry->;d_alias)) BUG();
  154.         spin_lock(&dcache_lock);
  155.         if (inode)
  156.                 list_add(&entry->;d_alias, &inode->;i_dentry);
  157.         entry->;d_inode = inode;
  158.         spin_unlock(&dcache_lock);
  159. }
  160. /*创建根目录的dentry结构*/

  161. struct dentry * d_alloc_root(struct inode * root_inode)
  162. {
  163.         struct dentry *res = NULL;
  164. printk("d_alloc_root\n");
  165.         if (root_inode) {
  166.                 res = d_alloc(NULL, &(const struct qstr) { "/", 1, 0 });
  167.                 if (res) {
  168.                         res->;d_sb = root_inode->;i_sb;
  169.                         res->;d_parent = res;
  170.                         d_instantiate(res, root_inode);/*把根目录的inode结构安装到dentry结构里*/
  171.                 }
  172.         }
  173.         return res;
  174. }

  175. void force_delete(struct inode *inode)
  176. {
  177. printk("force_delete\n");
  178.         struct hello_dir_entry *de = inode->;u.generic_ip;
  179.        
  180.         if (atomic_read(&inode->;i_count) == 1)
  181.                 inode->;i_nlink = 0;
  182.         if (atomic_dec_and_test(&de->;count))
  183.                 printk("hello_root.count: %d\n", atomic_read(&de->;count));
  184. }

  185. static void hello_delete_inode(struct inode *inode)
  186. {
  187. printk("hello_delete_inode\n");
  188.         struct hello_dir_entry *de = inode->;u.generic_ip;
  189.         inode->;i_state = I_CLEAR;
  190.         /*if (de) {
  191.                 if (de->;owner)
  192.                         __MOD_DEC_USE_COUNT(de->;owner);
  193.                 de_put(de);
  194.         }*/
  195. }

  196. static void hello_read_inode(struct inode * inode)
  197. {
  198. printk("hello_read_inode\n");
  199.         inode->;i_mtime = inode->;i_atime = inode->;i_ctime = CURRENT_TIME;
  200. }

  201. static int hello_statfs(struct super_block *sb, struct statfs *buf)
  202. {
  203. printk("hello_statfs\n");
  204.         return 0;
  205. }

  206. void hello_write_super(struct super_block *s)
  207. {
  208.         printk("write_super\n");
  209. }

  210. static struct super_operations hello_sops = {
  211.         read_inode:        hello_read_inode,
  212.         put_inode:        force_delete,
  213.         delete_inode:        hello_delete_inode,
  214.         write_super:        hello_write_super,
  215.         /*statfs:                hello_statfs,*/
  216. };

  217. struct dentry_operations hello_dops = {
  218.         /*d_revalidate:        hello_d_revalidate,
  219.         d_hash:                hello_d_hash,
  220.         d_compare:        hello_d_compare,*/
  221.         /*d_delete:        hello_d_delete,*/
  222.         d_release:        hello_d_release,
  223.         /*d_iput:                hello_d_iput*/
  224. };

  225. /*创建超级块*/
  226. struct super_block *hello_read_super(struct super_block *s, void *data,
  227.                                     int silent)
  228. {
  229. printk("hello_read_super\n");       
  230.         struct inode * root_inode;

  231.         s->;s_blocksize = 1024;
  232.         s->;s_blocksize_bits = 10;
  233.         s->;s_magic = 0;
  234.         s->;s_op = &hello_sops;
  235.         root_inode = hello_get_inode(s, HELLO_ROOT_INO, &hello_root);
  236.         if (!root_inode)
  237.                 goto out_no_root;

  238.         s->;s_root = d_alloc_root(root_inode);
  239.         if (!s->;s_root)
  240.                 goto out_no_root;
  241.         s->;s_root->;d_op = &hello_dops;
  242.         return s;

  243. out_no_root:
  244.         printk("hello_read_super: get root inode failed\n");
  245.         iput(root_inode);
  246.         return NULL;
  247. }


复制代码


hello.h

  1. #include <linux/kernel.h>;
  2. #include <linux/module.h>;

  3. #include <linux/fs.h>;
  4. #include <linux/wrapper.h>;
  5. #include <linux/slab.h>;
  6. #include <linux/wait.h>;
  7. #include <linux/poll.h>;

  8. #include <linux/mm.h>;
  9. #include <linux/pagemap.h>;

  10. #include <asm/uaccess.h>;
  11. #include <asm/semaphore.h>;


  12. #define HELLO_ROOT_INO 1
  13.        
  14. typedef        int (read_hello_t)(char *page, char **start, off_t off,
  15.                           int count, int *eof, void *data);
  16. typedef        int (write_hello_t)(struct file *file, const char *buffer,
  17.                            unsigned long count, void *data);
  18. typedef int (get_info_t)(char *, char **, off_t, int);

  19. struct hello_dir_entry {
  20.         unsigned short low_ino;
  21.         unsigned short namelen;
  22.         const char *name;
  23.         mode_t mode;
  24.         nlink_t nlink;
  25.         uid_t uid;
  26.         gid_t gid;
  27.         unsigned long size;
  28.         struct inode_operations * hello_iops;
  29.         struct file_operations * hello_fops;
  30.         get_info_t *get_info;
  31.         struct module *owner;
  32.         struct hello_dir_entry *next, *parent, *subdir;
  33.         void *data;
  34.         read_hello_t *read_hello;
  35.         write_hello_t *write_hello;
  36.         atomic_t count;                /* use count */
  37.         int deleted;                /* delete flag */
  38.         kdev_t        rdev;
  39. };

  40. extern struct hello_dir_entry hello_root;
  41. extern struct dentry *hello_lookup(struct inode *, struct dentry *);
  42. extern int hello_misc_init(void);
  43. extern struct super_block *hello_read_super(struct super_block *, void *, int);
  44. extern void de_put(struct hello_dir_entry *);
  45. extern struct hello_dir_entry * de_get(struct hello_dir_entry *);
  46. extern int hello_readdir(struct file *, void *, filldir_t);

复制代码


/*这个文件的作用是创建虚拟文件树结构,相当于磁盘上的文件树,这里我就不注释了,有兴趣的自己看看吧,挺简单的*/
hello_entry.c

  1. #include "hello.h"

  2. static struct inode_operations hello_dir_inode_operations = {
  3.         lookup:                hello_lookup,
  4. };

  5. struct hello_dir_entry * de_get(struct hello_dir_entry *de)
  6. {
  7. printk("de_get\n");
  8.         if (de)
  9.                 atomic_inc(&de->;count);
  10.         return de;
  11. }

  12. void inline free_hello_entry(struct hello_dir_entry *de)
  13. {
  14. printk("free_hello_entry\n");
  15.         kfree(de);
  16. }

  17. void de_put(struct hello_dir_entry *de)
  18. {
  19. printk("de_put\n");
  20.         if (de) {               
  21.                 if (!atomic_read(&de->;count)) {
  22.                         printk("de_put: entry %s already free!\n", de->;name);
  23.                         return;
  24.                 }

  25.                 if (atomic_dec_and_test(&de->;count))
  26.                         free_hello_entry(de);
  27.         }
  28. }

  29. static ssize_t
  30. hello_file_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
  31. {
  32.         struct inode * inode = file->;f_dentry->;d_inode;
  33.         char         *page;
  34.         ssize_t        n;
  35.         char        *start;
  36.         struct hello_dir_entry * dp;

  37.         dp = (struct hello_dir_entry *) inode->;u.generic_ip;
  38.         if (!(page = (char*) __get_free_page(GFP_KERNEL)))
  39.                 return -ENOMEM;

  40.         n = dp->;read_hello(page, &start, *ppos,0,  NULL, NULL);
  41.         copy_to_user(buf, page, n);

  42.         free_page((unsigned long) page);
  43.         return n;
  44. }

  45. static ssize_t
  46. hello_file_write(struct file * file, const char * buffer,
  47.                 size_t count, loff_t *ppos)
  48. {
  49.         struct inode *inode = file->;f_dentry->;d_inode;
  50.         struct hello_dir_entry * dp;
  51.        
  52.         dp = (struct hello_dir_entry *) inode->;u.generic_ip;

  53.         if (!dp->;write_hello)
  54.                 return -EIO;

  55.         /* FIXME: does this routine need ppos?  probably... */
  56.         return dp->;write_hello(file, buffer, count, dp->;data);
  57. }


  58. static loff_t
  59. hello_file_lseek(struct file * file, loff_t offset, int origin)
  60. {
  61.         long long retval;

  62.         switch (origin) {
  63.                 case 2:
  64.                         offset += file->;f_dentry->;d_inode->;i_size;
  65.                         break;
  66.                 case 1:
  67.                         offset += file->;f_pos;
  68.         }
  69.         retval = -EINVAL;
  70.         if (offset>;=0 && offset<=file->;f_dentry->;d_inode->;i_sb->;s_maxbytes) {
  71.                 if (offset != file->;f_pos) {
  72.                         file->;f_pos = offset;
  73.                         file->;f_reada = 0;
  74.                 }
  75.                 retval = offset;
  76.         }
  77.         return retval;
  78. }

  79. static struct file_operations hello_file_operations = {
  80.         llseek:                hello_file_lseek,
  81.         read:                hello_file_read,
  82.         write:                hello_file_write,
  83. };

  84. static int hello_register(struct hello_dir_entry * dir, struct hello_dir_entry * dp)
  85. {
  86. printk("hello_register\n");
  87.         dp->;low_ino = 2;
  88.         dp->;next = dir->;subdir;
  89.         dp->;parent = dir;
  90.         dir->;subdir = dp;
  91.         if (S_ISDIR(dp->;mode)) {
  92.                 if (dp->;hello_iops == NULL) {
  93.                         dp->;hello_fops = NULL;
  94.                         dp->;hello_iops = &hello_dir_inode_operations;
  95.                 }
  96.                 dir->;nlink++;
  97.         } else if (S_ISREG(dp->;mode)) {
  98.                 if (dp->;hello_fops == NULL)
  99.                         dp->;hello_fops = &hello_file_operations;
  100.         }

  101.         return 0;
  102. }

  103. static struct hello_dir_entry *hello_create(struct hello_dir_entry **parent,
  104.                                           const char *name,
  105.                                           mode_t mode,
  106.                                           nlink_t nlink)
  107. {
  108. printk("hello_create\n");
  109.         struct hello_dir_entry *ent = NULL;
  110.         const char *fn = name;
  111.         int len;

  112.         len = strlen(name);
  113.         *parent = &hello_root;

  114.         ent = kmalloc(sizeof(struct hello_dir_entry) + len + 1, GFP_KERNEL);
  115.         if (!ent) goto out;

  116.         memset(ent, 0, sizeof(struct hello_dir_entry));
  117.         memcpy(((char *) ent) + sizeof(struct hello_dir_entry), fn, len + 1);
  118.         ent->;name = ((char *) ent) + sizeof(*ent);
  119.         ent->;namelen = len;
  120.         ent->;mode = mode;
  121.         ent->;nlink = nlink;
  122. out:
  123.         return ent;
  124. }


  125. struct hello_dir_entry *create_hello_entry(const char *name, mode_t mode,
  126.                                          struct hello_dir_entry *parent)
  127. {
  128. printk("create_hello_entry\n");
  129.         struct hello_dir_entry *ent;
  130.         nlink_t nlink;

  131.         if (S_ISDIR(mode)) {
  132.                 if ((mode & S_IALLUGO) == 0)
  133.                         mode |= S_IRUGO | S_IXUGO;
  134.                 nlink = 2;
  135.         } else {
  136.                 if ((mode & S_IFMT) == 0)
  137.                         mode |= S_IFREG;
  138.                 if ((mode & S_IALLUGO) == 0)
  139.                         mode |= S_IRUGO;
  140.                 nlink = 1;
  141.         }

  142.         ent = hello_create(&parent,name,mode,nlink);
  143.         if (ent) {
  144.                 if (hello_register(parent, ent) < 0) {
  145.                         kfree(ent);
  146.                         ent = NULL;
  147.                 }
  148.         }
  149.         return ent;
  150. }

  151. static inline struct hello_dir_entry *hello_read_entry(const char *name,
  152.         mode_t mode, struct hello_dir_entry *base,
  153.         read_hello_t *read_hello, void * data)
  154. {
  155. printk("hello_dir_entry\n");
  156.         struct hello_dir_entry *res=create_hello_entry(name,mode,base);
  157.         if (res) {
  158.                 res->;read_hello=read_hello;
  159.                 res->;write_hello = NULL;
  160.                 res->;data=data;
  161.         }
  162.         return res;
  163. }

  164. /************************************************************************************************************/
  165. int read_hello(char *page, char **start, off_t off, int count, int *eof, void *data)
  166. {
  167.         strcpy(page, "hello world!");
  168.         return 13;
  169. }

  170. int hello_misc_init(void)
  171. {
  172. printk("hello_misc_init\n");
  173.         struct hello_dir_entry *err;
  174.         err = hello_read_entry("zhang", 0, NULL, read_hello, NULL);
  175.         return !err;
  176. }               

复制代码


mount.c

  1. #include "hello.h"
  2. /*加载模块并安装文件系统*/

  3. static DECLARE_FSTYPE(hello_fs_type, "hello", hello_read_super, FS_SINGLE);
  4. struct vfsmount *mnt;

  5. int hello_root_init(void)
  6. {
  7.         struct nameidata nd;
  8.         int err;
  9.         err = register_filesystem(&hello_fs_type);
  10. printk("register_filesystem\n");
  11.         if (err)
  12.                 return err;
  13.         mnt = kern_mount(&hello_fs_type);/*安装文件系统*/
  14. printk("kern_mount\n");
  15.         err = PTR_ERR(mnt);
  16.         if (IS_ERR(mnt))
  17.                 goto out;
  18.         hello_misc_init();

  19. MOD_DEC_USE_COUNT;
  20.         char *name, *type;
  21.         name = kmalloc(10, GFP_KERNEL);
  22.         type = kmalloc(10, GFP_KERNEL);
  23.         strcpy(name, "/hello");
  24.         strcpy(type, "hello");
  25.         long (*do_mount)(char *, char *, char *, unsigned long, void *) = (void*)0xc01603f0;/*0xc0166ad0;*/
  26.         do_mount(NULL, name, type, 0, NULL);
  27.         kfree(name);
  28.         kfree(type);
  29.         /*if (err)
  30.                 goto out;
  31.         */

  32.         return 0;
  33. out:
  34.         mntput(mnt);
  35.         unregister_filesystem(&hello_fs_type);
  36.         return err;
  37. }


  38. int init_module(void)
  39. {
  40. printk("init_module\n");
  41.         hello_root_init();
  42.         return 0;
  43. }

  44. void cleanup_module()
  45. {
  46. printk("cleanup_module\n");
  47.         mntput(mnt);
  48.         unregister_filesystem(&hello_fs_type);
  49. }

复制代码


Makefile

  1. CC = gcc
  2. CFLAGS = -O -Wall -D__KERNEL__ -DMODULE
  3. #INCLUDEDIR =  /usr/local/linux-2.4.22/include

  4. INCLUDEDIR =  /usr/src/linux-2.4.20-8/include
  5. CFLAGS += -I$(INCLUDEDIR)

  6. myfs.o:                mount.o hello_entry.o hello.o
  7.         $(LD) -m elf_i386 -r -o myfs.o mount.o hello_entry.o hello.o

  8. mount.o:        mount.c hello.h /usr/include/linux/version.h
  9.         $(CC) $(CFLAGS) -c mount.c
  10.        
  11. hello_entry.o:        hello_entry.c hello.h /usr/include/linux/version.h
  12.         $(CC) $(CFLAGS) -c hello_entry.c
  13.        
  14. hello.o:        hello.c hello.h /usr/include/linux/version.h
  15.         $(CC) $(CFLAGS) -c hello.c

复制代码


测试程序read.c

  1. #include <sys/ioctl.h>;
  2. #include <sys/types.h>;
  3. #include <sys/stat.h>;
  4. #include <fcntl.h>;


  5. int main()
  6. {
  7.         int fp;
  8.         char buf[11];
  9.         buf[10] = 0;
  10.         int i;
  11.        
  12.         if ((fp = open("/hello/zhang", O_RDWR)) == 0) {
  13.                 printf("Could not opened!\n");
  14.                 return -1;
  15.         }
  16.         else
  17.                 printf("File open ok!\n");
  18.         read(fp, buf, 13);
  19.         printf("%s\n", buf);
  20.         close(fp);
  21. }

复制代码

论坛徽章:
0
2 [报告]
发表于 2004-05-26 08:23 |只看该作者

我的虚拟文件系统(linux)

成功了吗?

论坛徽章:
0
3 [报告]
发表于 2004-05-26 12:27 |只看该作者

我的虚拟文件系统(linux)

呵呵,当然成功了,不过我只建了一个文件,本来想把我的管道和共享内存都放上去,只是懒得动了

论坛徽章:
0
4 [报告]
发表于 2004-05-26 12:34 |只看该作者

我的虚拟文件系统(linux)

你要试的话,需要在Sysmap文件找到 do_mount的地址,就像我这样的long (*do_mount)(char *, char *, char *, unsigned long, void *) = (void*)0xc01603f0;
是不是有点可笑呀,呵呵
还有为了简单没有实现搜索目录,只能在hello目录下建文件

JohnBull版主要是感兴趣,我可以把我实现的共享内存给你看看,一起交流交流,很少能遇到个对内核感趣的

论坛徽章:
0
5 [报告]
发表于 2004-05-26 13:05 |只看该作者

我的虚拟文件系统(linux)

加精!坚决加精!

论坛徽章:
0
6 [报告]
发表于 2004-05-26 14:45 |只看该作者

我的虚拟文件系统(linux)

[quote]原帖由 "JohnBull"]加精!坚决加精![/quote 发表:

谢谢版主

论坛徽章:
0
7 [报告]
发表于 2004-05-26 15:02 |只看该作者

我的虚拟文件系统(linux)

对了还有得在根目录下建一个hello目录

论坛徽章:
0
8 [报告]
发表于 2004-05-26 16:59 |只看该作者

我的虚拟文件系统(linux)

感觉晕
看不懂

论坛徽章:
0
9 [报告]
发表于 2004-05-26 18:31 |只看该作者

我的虚拟文件系统(linux)

我也晕,但很佩服楼主,支持下!

论坛徽章:
0
10 [报告]
发表于 2004-05-26 20:09 |只看该作者

我的虚拟文件系统(linux)

[quote]原帖由 "xhl"]我也晕,但很佩服楼主,支持下![/quote 发表:


谢谢支持,小弟一定会继续努力,希望多几个能和我一起讨论内核编程的兄弟
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP