Chinaunix首页 | 论坛 | 博客
  • 博客访问: 775270
  • 博文数量: 239
  • 博客积分: 60
  • 博客等级: 民兵
  • 技术积分: 1045
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-22 18:25
文章分类

全部博文(239)

文章存档

2019年(9)

2018年(64)

2017年(2)

2016年(26)

2015年(30)

2014年(41)

2013年(65)

2012年(2)

分类: LINUX

2013-10-23 14:24:30

在我的博客中的- 如何从实践引领进入linux内核类别日志中我详细分析了Unix的socket的创建、发送、接收、关闭的过程,这节开始进入探讨IPV4的TCP的socket的创建,我们在linux/unix的socket从实践到内核分析部分 http://blog.chinaunix.net/u2/64681/showart.php?id=1287300中看到了关于socket的系统调用的总入口函数sys_socketcall()然后根据

    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中看到

fs_initcall(inet_init);

#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

#define PF_INET        AF_INET

所以这里我们的练习中会进经过pf->create(net, sock, protocol)到inet_create()中,下一篇待续
阅读(875) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~