针对内核3.9

系统开启时,会使用init/main.c,然后再里面调用kernel_init(),在里面会再调用do_basic_setup(),调用do_initcalls(),调用do_one_initcall(),这个函数会去把注册了所有需要初始化的系统调用一一初始化。而网络模块由于全部都是基于socket在进行,所以,相关网络模块,在do_one_initcall()中会通过core_init()调用sock_init()来把网络文件系统登记在整个linux的文件系统中。其中core_init()非常重要,负责在内核初始化阶段把这些需要初始化的函数集中放在一个section里然后之后一个一个的进行处理。代码为:

286 #define core_initcall(fn)               module_init(fn)

297 #define module_init(initfn)

298         static inline initcall_t __inittest(void)

299         { return initfn; }

300         int init_module(void) __attribute__((alias(#initfn)));

Sock_init的过程在2.6和3.9的内核中变化较大,代码如下:

static int __init sock_init(void)

2602 {

2603         int err;

2604         /*

2605          *      Initialize the network sysctl infrastructure.

2606          */

2607         err = net_sysctl_init();

2608         if (err)

2609                 goto out;

2610

2611         /*

2612          *      Initialize skbuff SLAB cache

2613          */

2614         skb_init();

2615

2616         /*

2617          *      Initialize the protocols module.

2618          */

2619

2620         init_inodecache();

2621

2622         err = register_filesystem(&sock_fs_type);

2623         if (err)

2624                 goto out_fs;

2625         sock_mnt = kern_mount(&sock_fs_type);

2626         if (IS_ERR(sock_mnt)) {

2627                 err = PTR_ERR(sock_mnt);

2628                 goto out_mount;

2629         }

然后一句一句地进行分析,我们知道sysctl设置和显示在/proc/sys目录中的内核参数.能用sysctl来设置或重新设置连网功能,如IP转发、IP碎片去除及源路由检查等。而2607行调用net_sysctl_init()来对其进行初始化,我们来看怎么初始化的。

83 static struct ctl_table_header *net_header;

84 __init int net_sysctl_init(void)

85 {

86         static struct ctl_table empty[1];

87         int ret = -ENOMEM;

92         net_header = register_sysctl("net", empty);

93         if (!net_header)

94                 goto out;

95         ret = register_pernet_subsys(&sysctl_pernet_ops);

96         if (ret)

97                 goto out;

98         register_sysctl_root(&net_sysctl_root);

99 out:

100         return ret;

101 }

首先调用register_sysctl()进行把新的sysctl注册到ctl表中去,然后调用register_pernet_subsys()利用超级块操作表注册块设备表(此处由于我还没有学习过文件系统所以没懂),最后调用register_sysctl_root(),这个函数实际上什么都没有,官方给的注释是为了避免局限性把这个系统所在位置注册为空,说实话,没怎么懂,还望指教。

回到sock_init(void)中,skb_init()是为了初始化slab,不关心。然后是init_inodecache(),这个函数负责对inode进行处理,大概是要创建一块用于socket相关的inode的调整缓存,以方便之后对inode进行创建和释放。

然后是 register_filesystem(struct file_system_type * fs),负责将socket文件系统注册到内核中。代码如下:

69 int register_filesystem(struct file_system_type * fs)

70 {

71         int res = 0;

72         struct file_system_type ** p;

73

74         BUG_ON(strchr(fs->name, '.'));

75         if (fs->next)

76                 return -EBUSY;

77         write_lock(&file_systems_lock);

78         p = find_filesystem(fs->name, strlen(fs->name));

79         if (*p)

80                 res = -EBUSY;

81         else

82                 *p = fs;

83         write_unlock(&file_systems_lock);

84         return res;

85 }

可以看到这里实际上是把一个新的文件系统注册到file_system_type这个全局变量的链表里,这里涉及到file_system_type这个数据结构,其中核心部分如下:

1802 struct file_system_type {

1803         const char *name;

1804         int fs_flags;

1811         struct dentry *(*mount) (struct file_system_type *, int,

1812                        const char *, void *);

1813         void (*kill_sb) (struct super_block *);

1814         struct module *owner;

1815         struct file_system_type * next;

1826 };

其中struct dentry *(*mount) (struct file_system_type *, int,const char *, void *);是一个函数指针(也可以理解成钩子函数),负责指明哪个函数来处理,比如此处需要用到的sock_fs_type,就通过mount来规定使用sockfs_mount来进行注册。

326 static struct file_system_type sock_fs_type = {

327         .name =         "sockfs",

328         .mount =        sockfs_mount,

329         .kill_sb =      kill_anon_super,

330 };

再回到sock_init(void),最后使用sock_mnt = kern_mount(&sock_fs_type);来把网络文件系统安装上。实际上是调用vfs_kern_mount(),大概是在虚拟文件系统下进行内存分配之类的工作,没看懂。

这里有一个非常优美的地方,在最后调用kern_mount(&sock_fs_type)时,会利用到sock_fs_type数据结构里的钩子函数sockfs_mount,然后继续调用mount_pseudo()执行实际上的安装,该函数是与文件系统相关的,是后面能执行socket等函数的先决条件。其中涉及文件系统,暂不讨论。

以上便是socket的初始化过程

socket相关的开机初始化分析的更多相关文章

  1. Linux学习-Linux 的开机流程分析

    开机流程一览 系统开机的经过可以汇整成底下的流程的: 加载 BIOS 的硬件信息与进行自我测试,并依据设定取得第一个可开机的装置; 读取并执行第一个开机装置内 MBR 的 boot Loader (亦 ...

  2. Linux内核启动代码分析二之开发板相关驱动程序加载分析

    Linux内核启动代码分析二之开发板相关驱动程序加载分析 1 从linux开始启动的函数start_kernel开始分析,该函数位于linux-2.6.22/init/main.c  start_ke ...

  3. TCP/IP协议栈源码图解分析系列10:linux内核协议栈中对于socket相关API的实现

    题记:本系列文章的目的是抛开书本从Linux内核源代码的角度详细分析TCP/IP协议栈内核相关技术 轻松搞定TCP/IP协议栈,原创文章欢迎交流, byhankswang@gmail.com linu ...

  4. socket相关系统调用的调用流程

    最近一直在读内核网络协议栈源码,这里以ipv4/tcp为例对socket相关系统调用的流程做一个简要整理,这些相关系统调用的内部细节虽然各有不同,但其调用流程则基本一致: 调用流程: (1)系统调用 ...

  5. sparkContext之一:sparkContext的初始化分析

    Spark源码学习:sparkContext的初始化分析 spark可以运行在本地模式local下,可以运行在yarn和standalone模式下,但是本地程序是通过什么渠道和这些集群交互的呢?那就是 ...

  6. 一只简单的网络爬虫(基于linux C/C++)————socket相关及HTTP

    socket相关 建立连接 网络通信中少不了socket,该爬虫没有使用现成的一些库,而是自己封装了socket的相关操作,因为爬虫属于客户端,建立套接字和发起连接都封装在build_connect中 ...

  7. libevent (一) socket属性设置与初始化操作

    socket属性设置与初始化操作 libevent是一个事件触发的网络库,适用于windows.linux.bsd等多种平台,内部使用select.epoll.kqueue等系统调用管理事件机制.著名 ...

  8. List 接口以及实现类和相关类源码分析

    List 接口以及实现类和相关类源码分析 List接口分析 接口描述 用户可以对列表进行随机的读取(get),插入(add),删除(remove),修改(set),也可批量增加(addAll),删除( ...

  9. JobTracker等相关功能模块初始化

    [Hadoop代码笔记]Hadoop作业提交之JobTracker等相关功能模块初始化 一.概要描述 本文重点描述在JobTracker一端接收作业.调度作业等几个模块的初始化工作.想过模块的介绍会在 ...

随机推荐

  1. The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the associated filter.

    The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the assoc ...

  2. Spring_Spring与IoC_基于XML的DI

    一.注入分类 bean实例在调用无参构造器创建空值对象后,就要对Bean对象的属性进行初始化.初始化时由容器自动完成的,称为注入.根据注入方式的不同,常用的有2类:设值注入.构造注入.(还有一种,实现 ...

  3. 移动web开发ajax缓存操作

    移动web开发过程中网速是必须考虑的一个因素,所以一般是尽可能的在本地存储数据,避免弱网环境下请求数据失败导致页面没有内容的情况. 前后端分离是web开发的必然趋势,在PC端我们有时甚至为了避免aja ...

  4. RN记录

    react-native run-android 出现 java.lang.nullpointerexception(no error message) 错误 删除 工程目录\android.grad ...

  5. Ubuntu 18 使用docker安装rancher/server:stable并运行kubernetes

    1.安装docker sudo apt-get install docker.io docker的版本:Docker version 17.12.1-ce 2.安装virtualbox-qt,因为vi ...

  6. 学习笔记---Javascript事件Event、IE浏览器下的拖拽效果

    学习笔记---Javascript事件Event.IE浏览器下的拖拽效果     1. 关于event常用属性有returnValue(是否允许事件处理继续进行, false为停止继续操作).srcE ...

  7. .net 面向对象程序设计深入](2)UML

    1.用例图简介 定义:用例图主要用来描述“用户.需求.系统功能单元”之间的关系.它展示了一个外部用户能够观察到的系统功能模型图. 类型:动态图 应用:需求分析阶段 2.用例图元素 2.1 参与者(Ac ...

  8. QT组件与std性能

    https://blog.csdn.net/zy19940906/article/details/53694909

  9. Memory Leak Detection in C++

    原文链接:http://www.linuxjournal.com/article/6556?page=0,0 An earlier article [“Memory Leak Detection in ...

  10. DFS BFS代码

    #define maxnum 30 #include<bits_stdc++.h> int visited[maxnum]={0}; using namespace std; typede ...