职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 388|回复: 1

Linux内核网络协议栈1- socket文件系统注册

[复制链接]
江南枫 发表于 2011-8-23 10:08 | 显示全部楼层 |阅读模式
一、注册时机 1、在......
推荐链接 20-30......


  
一、注册时机
1、在内核初始化时完成;
2、内核初始化过程(init/main.c):kernel_init()->do_basic_setup()->do_initcalls()->do_one_initcall();
3、socket文件系统注册过程(net/socket.c):core_initcall(sock_init);
1) core_initcall宏定义如下:
C代码  
#define core_initcall(fn) __define_initcall("1",fn,1)   
  
#define __define_initcall(level,fn,id) \   
   static initcall_t __initcall_##fn##id __used \   
   __attribute__((__section__(".initcall" level ".init"))) = fn  

#define core_initcall(fn) __define_initcall("1",fn,1)

#define __define_initcall(level,fn,id) \
   static initcall_t __initcall_##fn##id __used \
   __attribute__((__section__(".initcall" level ".init"))) = fn宏定义__define_initcall(level,fn, id)对于内核的初始化很重要,他指示编译器在编译的时候,将一系列初始化函数的起始地址值按照一定的顺序放在一个section中。在内核初始化阶段,do_initcalls()将按顺序从该section中以函数指针的形式取出这些函数的起始地址,来依次完成相应的初始化。由于内核某些部分的初始化需要依赖于其他某些部分的初始化的完成,因此这个顺序排列常常很重要。该宏的作用分三部分:a) 申明一个函数指针initcall_t(即int *(void))变量__initcall_fn_id;b) 将该函数指针初始化为fn;c) 编译的时候需要把这个函数指针变量放置到名称为 ".initcall"level".init"的section中;
根据上面的解释,core_initcall(sock_init)的作用就是让编译器在编译时声明函数指针变量__initcallsock_init1,让其指向sock_init,并放到名为".initcall1.init"的section中;

二、socket文件系统注册
1、socket文件系统类型
C代码  
static struct file_system_type sock_fs_type = {   
   .name = "sockfs",   
   .get_sb = sockfs_get_sb,   
   .kill_sb = kill_anon_super,   
};  

static struct file_system_type sock_fs_type = {
   .name = "sockfs",
   .get_sb = sockfs_get_sb,
   .kill_sb = kill_anon_super,
};其中,get_sb函数指针定义了如何获取该文件系统的超级块,而kill_sb函数指针定义了如何删除该超级块;
2、sock_init主要逻辑
函数的主要代码如下:
C代码  
static int __init sock_init(void){   
   init_inodecache();   
   register_filesystem(&sock_fs_type);   
   sock_mnt = kern_mount(&sock_fs_type);   
   return 0;   
}  

static int __init sock_init(void){
   init_inodecache();
   register_filesystem(&sock_fs_type);
   sock_mnt = kern_mount(&sock_fs_type);
   return 0;
}1) init_inodecache():创建一块用于socket相关的inode的调整缓存;后面创建inode、释放inode会使用到;
2) register_filesystem():将socket文件系统注册到内核中;
在内核中,所有的文件系统保存在全局变量file_systems中,如下:
static struct file_system_type *file_systems;
不同的文件系统类型通过结构体的next字段形成一个单向链表;
这样,注册文件系统实质是将新的结构体插入到单向链表中的过程;
3) kern_mount():在内核中安装文件系统,并建立安装点;
在安装的过程中,会初始化该安装点的超级块,此时会将该超级块的操作函数指针记录下来;如:
C代码  
static int sockfs_get_sb(struct file_system_type *fs_type,   
             int flags, const char *dev_name, void *data,   
             struct vfsmount *mnt)   
{   
    return get_sb_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC,   
                 mnt);   
}  

static int sockfs_get_sb(struct file_system_type *fs_type,
                         int flags, const char *dev_name, void *data,
                         struct vfsmount *mnt)
{
        return get_sb_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC,
                             mnt);
}其中sockfs_ops结构变量如下:
C代码  
static struct super_operations sockfs_ops = {   
    .alloc_inode =  sock_alloc_inode,   
    .destroy_inode =sock_destroy_inode,   
    .statfs =   simple_statfs,   
};  

static struct super_operations sockfs_ops = {
        .alloc_inode =        sock_alloc_inode,
        .destroy_inode =sock_destroy_inode,
        .statfs =        simple_statfs,
};该操作函数结构体定义了如何分配inode,如何销毁inode等;


能文能武 发表于 2011-8-23 10:08 | 显示全部楼层
推荐链接
20-30万急聘多名天才Java/MTA软件工程师
见证又一个准百万富翁的诞生!
3G培训就业月薪平均7K+,不3K就业不花一分钱!


您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-4-29 14:32 , Processed in 0.108876 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表