Linux内核-协议栈-初始化流程分析

本文分析了Linux-3.19.3内核协议栈的初始化过程,包括主要步骤和关键函数,如net_namespace、/proc和/proc/sys的初始化。重点介绍了纯初始化函数net_ns_init,接着是sock_init,涉及net_inuse_init、netpoll_init、proto_init、net_dev_init及sysctl_core_init等。虽然初始化过程简单,但完整的数据包处理流程将在后续分析中探讨。

本文主要针对Linux-3.19.3版本的内核简单分析内核协议栈初始化涉及到的主要步骤和关键函数,不针对协议的解析以及数据包的处理流程做具体分析,后续有机会再详细分析


1.准备

  • Linux内核协议栈本身构建在虚拟文件系统之上,所以对Linux VFS不太了解的可以参考内核源码根目录下Documentation/filesystems/vfs.txt,另外,socket接口层,协议层,设备层的许多数据结构涉及到内存管理,所以对基本虚拟内存管理,slab缓存,页高速缓存不太了解的也可以查阅相关文档。

  • 源码涉及的主要文件位于net/socket.c,net/core,include/linux/net*. 基本上整个初始化过程主要与net,net_namespace,/proc,/proc/sys相关结构的初始化和文件的建立,主要使用register_pernet_subsystem钩子注册和调用各种操作.init和.exit


2.开始

开始分析前,这里有些小技巧可以快速定位到主要的初始化函数,在分析其他子系统源码时也可以采用这个技巧

grep _initcall socket.c
find ./core/ -name "*.c" |xargs cat | grep _initcall
grep net_inuse_init tags

这里写图片描述
这里写图片描述

这里*__initcall宏是设置初始化函数位于内核代码段.initcall#id.init的位置其中id代表优先级level,小的一般初始化靠前,定义在include/linux/init.h,使用gcc的attribute扩展。而各个level的初始化函数的调用流程基本如下:

start_kernel -> rest_init -> kernel_init内核线程 -> kernel_init_freeable -> do_basic_setup -> do_initcalls -> do_initcall_level -> do_one_initcall -> *(initcall_t)

这里写图片描述


3.详细分析

  • 可以看到pure_initcall(net_ns_init)位于0的初始化level,基本不依赖其他的初始化子系统,所以从这个开始
//core/net_namespace.c
//基本上这个函数主要的作用是初始化net结构init_net的一些数据,比如namespace相关,并且调用注册的pernet operations的init钩子针对net进行各自需求的初始化
pure_initcall(net_ns_init);
static int __init net_ns_init(void)
{
    struct net_generic *ng;
    //net namespace相关
#ifdef CONFIG_NET_NS
    //分配slab缓存
    net_cachep = kmem_cache_create("net_namespace", sizeof(struct net),SMP_CACHE_BYTES,SLAB_PANIC, NULL);

    /* Create workqueue for cleanup */
    netns_wq = create_singlethread_workqueue("netns");
    if (!netns_wq)
        panic("Could not create netns workq");
#endif
    ng = net_alloc_generic();
    if (!ng)
        panic("Could not allocate generic netns");

    rcu_assign_pointer(init_net.gen, ng);
    mutex_lock(&net_mutex);
    //初始化net namespace相关的对象, 传入初始的namespace init_user_ns
    //设置net结构的初始namespace
    //对每个pernet_list中注册的pernet operation,调用其初始化net中的对应数据对象
    if (setup_net(&init_net, &init_user_ns))
       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值