case SYS_SOCKET: err = sys_socket(a0, a1, a[2]);
|
进入sys_socket()函数
asmlinkage long sys_socket(int family, int type, int protocol) { 。。。。。。
retval = sock_create(family, type, protocol, &sock); 。。。。。。 }
|
再进入sock_create()最后进入__sock_create(),然后在那里执行
err = pf->create(net, sock, protocol);
|
这个过程我们在socket的实践到内核开始都追踪过了,不再细说了,我们这里直接从ipv4的socket的创建开始说起,我们回忆一下在有关的重要记忆点首先是net_families这个管理所有的网络协议的数组,我们说过在__sock_create()会在支持动态安装模块的前提下首先调用
if (net_families[family] == NULL) request_module("net-pf-%d", family);
|
也就是检查相应的协议有没有安装,我们在实践练习中曾经在创建socket用过这句
server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
由些传递下来的family参数则是AF_INET,这个值是2,也就是说我们要在net_families[2]处安装这里的tcp协议,那么在我们这里要谈到的网络协议是何时安装到数组中的呢?我是无名小卒,本文是原创如果转载请注明出处,我们在以前没提到过这里简要介绍一下,首先是内核在初始时会执行到init/main.c,而执行到内核的初始化函数kernel_init()在其内部调用了do_basic_setup()函数,再调用do_initcalls()函数,这里会看到有一个
for (call = __initcall_start; call < __initcall_end; call++) do_one_initcall(*call);
|
这就是称作为initcall机制,可以在socket.c中看到有一句,
core_initcall(sock_init); /* early initcall */
|
#define core_initcall(fn) __define_initcall("1",fn,1)
|
在2.6内核中已经把很多初始化函数都放在initcall中实现了。初始化中会执行socket.c中的sock_init()函数,同样我们在net/ipv4/af_inet.c中看到
#define fs_initcall(fn) __define_initcall("5",fn,5)
|
所以初始化中会执行inet_init()函数,这是我们要说的登记的重点,我们在这个inet_init()函数中看到有一句关键的
static int __init inet_init(void) { 。。。。。。 (void)sock_register(&inet_family_ops);
。。。。。。 }
|
会在sock_register中完成注册
int sock_register(const struct net_proto_family *ops) { 。。。。。。 if (net_families[ops->family]) err = -EEXIST; else { net_families[ops->family] = ops; err = 0; } 。。。。。。 }
|
这里会把
static struct net_proto_family inet_family_ops = { .family = PF_INET, .create = inet_create, .owner = THIS_MODULE, };
|
注册到
net_families数组中,而PF_INET就是上面我们说的AF_INET
所以这里我们的练习中会进经过
pf->create(net, sock, protocol)到inet_create()中,下一篇待续
阅读(10376) | 评论(0) | 转发(2) |