Chinaunix
标题:
Linux内核网络协议栈1-socket文件系统注册
[打印本页]
作者:
zhuyoong
时间:
2011-06-24 17:29
标题:
Linux内核网络协议栈1-socket文件系统注册
本帖最后由 zhuyoong 于 2011-06-24 17:36 编辑
一、注册时机
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宏定义如下:
#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文件系统类型
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主要逻辑
函数的主要代码如下:
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():在内核中安装文件系统,并建立安装点;
在安装的过程中,会初始化该安装点的超级块,此时会将该超级块的操作函数指针记录下来;如:
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结构变量如下:
static struct super_operations sockfs_ops = {
.alloc_inode = sock_alloc_inode,
.destroy_inode =sock_destroy_inode,
.statfs = simple_statfs,
};
复制代码
该操作函数结构体定义了如何分配inode,如何销毁inode等;
系列文章,请参考我在iteye的blog:
http://diecui1202.iteye.com
作者:
yingqy88
时间:
2011-08-12 14:10
回复
1#
zhuyoong
请问楼主那些书有详细介绍文件系统?很多书都是讲这部分的时候都是从它的数据结构讲起,如struct super_block, struct super_operations等,但是我觉得从实际应用出发来讲这些东西才会比较容易理解其中某些字段的意义。请楼主推荐一些来看看,谢谢!
作者:
zhuyoong
时间:
2011-08-12 17:50
回复
2#
yingqy88
文件系统,可以看《深入理解Linux内核》,这本书里关于文件系统,是从数据结构及相关的操作开始讲的。
但是我感觉,一开始看数据结构,很枯燥,因为数据结构字段太多,很多都不理解,看了效果也不好,从具体的场景出发,再回过来看数据结构印象可能会更深一些吧~~
作者:
yingqy88
时间:
2011-08-16 20:38
回复
3#
zhuyoong
是啊,内核的数据结构就像一张巨大复杂的网,搞的我晕头转向。我正是在看epoll的时候,看到它的实现很多都是基于文件系统的。我想比较透彻
的了解epoll,所以才会有此一问。
Thanks!
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2