概述

内核的初始化过程过程中,与网络相关的工作如下所示:

内核引导时执行start_kernel,start_kernel结束之前会调用rest_init,rest_init初始化内核线程init(在Linux3-12中为kernel_init)。

asmlinkage void __init start_kernel(void)

{

...

parse_early_param();//间接调用parse_args

parse_args(...); //处理内核引导程序(boot loader)在引导期间传给内核的参数,

...

init_IRQ(); //初始化硬件中断

tick_init();

init_timers(); //定时器用于支持后续初始化工作的运行。

hrtimers_init();

softirq_init(); //初始化软件中断

...

rest_init(); //这里会通过kernel_thread函数调用内核线程init(kernel_init).

}

static init __ref kernel_init(void *unused)

{

kernel_init_freeable(); //Linux-3.12 在这里调用do_basic_setup

free_initmem(); //用于释放已经不再需要的内存。

.....

run_init_process(execute_command)

...

}

static void __init do_basic_setup(void)

{

cpuset_init_smp();

usermodehelper_init();

shmem_init();

driver_init();

init_irq_proc();

do_ctors();

usermodehelper_enable();

do_initcalls(); //初始化内核子系统和内建的设备驱动

random_int_secret_init();

}

设备的注册和初始化

一个设备要能够正常工作,他就必须被内核所识别,并且与正确的驱动关联起来。设备驱动程序以私有结构体的形式保存了驱动本设备所需要的所有信息,并且与其他和本设备有交互的组件相互影响。

设备的注册和初始化一部分由内核完成,一部分由设备驱动程序完成。

设备的初始化包括了硬件初始化、软件初始化、功能初始化三部分:硬件初始化:由设备驱动程序和通用总线层完成,有时也需要用户提供一些参数。主要任务是将硬件功能配置成IRQ和I/O地址,以便能够跟内核相互作用。软件初始化:设备使用之前必须关注当前配置或启用的网络协议,

一般需要用户提供诸如ip地址之类的参数。功能初始化:Linux内核提供了一系列的网络选项,有些网络选项对每一个设备都需要进行单独配置(如实现Qos的子系统),这些配置决定了数据包进入队列和离开设备的出口队列的方式。

NIC初始化目标

网络设备在Linux中都是以net_device实例进行初始化的,本节先不讨论这个,本节主要介绍设备驱动程序如何分配/建立设备与内核通信所需要的资源。IRQ线:NIC必须分派一个IRQ,用于在必要时唤起内核的注意(虚拟设备不需要分配IRQ,因为它的工作都是在内部实现。)/proc/interrupts文件可用于观察当前中断线分派状态。I/O端口和内存注册:驱动程序会将设备的一块内存映射到系统内存,使得驱动程序的读写操作能够通过系统内存直接进行。注册和释放操作分别由request_region和

release_region进行。

设备与内核之间的交互

几乎所有设备与内核的交互都是通过以下两种方式:

内核的轮询:

内核定时检查设备的状态,判断设备是否有什么请求。

设备驱动的中断请求:

设备驱动发送硬件信号引起内核注意

内核轮询在其他文章会介绍,本文主要介绍硬件中断中与网络有关的概念。

硬件中断

每一个中断都会运行一个中断处理程序,这些中断响应程序都是设备驱动为设备量身定做的。一般而言,当设备注册一个NIC时,它首先会请求并分配一个IRQ,然后要为IRQ注册(如果设备被卸载了,则需要注销)一个IRQ响应程序。相应的内核代码在kernel/irq/manage.c和arch/XXX/kernel/irq.c。(其中XXX为处理器架构)

int request_threaded_irq(unsigned int irq, irq_handler_t handler,

irq_handler_t thread_fn, unsigned long irqflags,

const char *devname, void *dev_id)

void free_irq(unsigned int irq, void *dev_id)

注意:irq的注册和释放函数都带有参数dev_id。因为IRQ是可以共享的,因此需要IRQ number和dev_id共同来唯一表示中断。

另,在注册IRQ时,必须保证IRQ还未有设备请求,除非所有设备都支持IRQ共享。

内核接收到一个中断信号时,会通过IRQ number调用关联的中断响应程序。IRQ number与中断响应程序以表的形式保存。由于多个设备可能共享IRQ的关系,IRQ number与中断响应程序的关系可能是一对多的。

中断类型:接收到数据帧、帧传输失败、DMA传输已成功完成、设备已经有足够内存来创建新的传输会话(可用NIC可用内存达到一定数值时产生一个中断)

为了防止内核在设备内存不足时多次提交传输请求,设备驱动可以关闭内核出口队列,待到资源足够是才重启。下面是一个范例:

static netdev_tx_t

el3_start_xmit(struct sk_buff *skb, struct net_device *dev)

{

……

netif_stop_queue (dev);

……

dev->trans_start = jiffies;

if (inw(ioaddr + TX_FREE) > 1536)

netif_start_queue(dev);

else

/* Interrupt us when the FIFO has room for max-sized packet. */

outw(SetTxThreshold + 1536, ioaddr + EL3_CMD);

……

}

IRQ共享:IRQ线是很有限的资源,为了让一个系统能支持更多的设备,只能让多个设备共享IRQ线。IRQ共享的机制是这样的,内核收到中断请求,然后调用所有与该中断相关联的响应例程,然后有各个响应例程自行判断过滤是否对这个中断进行处理。(注意,IRQ与响应程序是一对多的,发生一个IRQ,哪些响应程序要处理,哪些不需要不是有内核去判断,而是各个中断响应程序自己判断,内核则是调用所有的响应程序。)

IRQ与IRQ响应程序的组织:用全局的vector:irq_desc来组织,irq_desc包含所有IRQ,每个IRQ对应自己的链表,链表中是该IRQ关联的所有响应程序。只有IRQ共享时,IRQ链表的节点才会超过一个。整个组织如下图:

初始化选项

所有的系统内建组件以及作为模块加载的设备都能通过用户的输入参数调整所实现的功能、重写其默认值,或者在引导前后有不同的值。

模块选项:(module_param系列的宏)

模块加载时可以定义。如果是内建的组件,由于在引导期间无法配置,可以通过sys/进行运行时配置。

引导期间内核选项:(__setup系列宏)

引导期间提供。用于可以内建到内核的模块。

设备处理层的初始化

网络代码初始化有以下重要的部分:流量控制,每个CPU输入队列初始化。这些初始化工作在引导期间由net_dev_init完成:

static int __init net_dev_init(void)

subsys_initcall(net_dev_init);

用户空间辅助程序

/sbin/modprobe 在内核需要加载某个模块时调用,判断内核传递的模块是不是/etc/modprobe.conf文件中定义的别名

/sbin/hotplug 在内核检测到一个新设备插入或拔出系统时调用,它的任务是根据设备标识加载正确的驱动

以模块方式加载

kmod模块加载器允许内核组件通过调用request_module请求加载某个模块

举个例子;如果系统管理员使用ifconfig配置某个网卡,但这个网卡驱动还没有加载,如eth0,内核就会给/sbin/modprobe发送一个请求,让它加载名称为

eth0的模块。如果/etc/modprobe.conf中包含“alias eth0 xxx”的字符,/sbin/modprobe就会尝试加载xxx.ko模块。

module_param 宏定义在引入sysfs后可以通过文件来访问得到模块参数

模块选项有三项 , 第一项参数名称,第二项参数类型,第三项表示参数作为文件在sys文件系统中所有的权限。

每个模块都会在sys/modules下生成对应的目录,通过目录下的文件可以获取模块参数。

pnp热插拔

hotplug允许内核检测热插拔设备的插入和拔出并通知用户进程(/sbin/hotplug),用户进程根据这些通知来加载相应的驱动

在编译内核时,会在kernel目录下生成modules.pcimap和modules.usbmap两个文件,这两个文件分别包含了内核所支持设备的pci id和usb id,文件中还包

含于每个设备的id相对应的内核模块名称,当用户进程收到内核关于pnp的通知后,会使用这个文件来查找正确的设备驱动

虚拟设备

虚拟设备一般也使用net_device结构体进行实例化(也有一些例外,如别名接口设备)。

虚拟设备一般会有用户空间配置工具来对其进行配置。尤其是无法使用ifconfig来进行配置的高级字段。

虚拟设备一般会有一个/proc接口目录,其内容详细程度取决于虚拟设备的设计。

虚拟设备与这是设备的对应关系不是一一对应的。这就导致了虚拟设备可能需要进行流量控制的配置。

虚拟设备的流量是简介从真实物理设备获得的,因而不需要分配IRQ、IO端口和IO内存。

虚拟设备与其他真实物理设备一样,能对特殊的事件通知做出相应的反应。

/proc调整

linux网口初始化_深入理解Linux网络技术内幕——网络设备初始化相关推荐

  1. linux aslr 关闭代码,Linux/ARM 禁用ASLR安全的代码[网络技术]

    赞助商链接 本文"Linux/ARM 禁用"ASLR安全"的代码[网络技术]"是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及 ...

  2. 《深入理解LINUX网络技术内幕》小记1

    1.函数指针是一种很方便的方式,使用函数指针的优点是可以根据不同准则以及该对象所扮演的角色进行初始化.函数指针在网络代码中 广为使用,举例说明: a.当入口数据封包或出口数据封包由路由器子系统处理时, ...

  3. 深入理解Linux网络技术内幕(十)——帧的接收

    文章目录 前言 与其他功能交互 设备的开启和关闭 队列 通知内核帧已接收:NAPI和netif_rx NAPI简介 NAPI所用之net_device字段 net_rx_action和NAPI 新旧驱 ...

  4. linux目录结构与功能_深入理解linux系统的目录结构(总结的非常详细)

    对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能,对于我们用好linux系统只管重要,下面 ...

  5. linux常用命令_干货:Linux常用命令全称及讲解

    从事IT行业的很多人都会使用Linux常用命令,但是知道这些常用命令全称的人并不多,让我们来看看这些常用命令对应的全称吧!小编精心整理了一下,毕竟常用命令比较多,如果没有你常用的还望海涵,可以评论区补 ...

  6. linux mysql怎么样_最强Linux和Mysql面试题套餐,让你的面试无懈可击!

    引言: 大家好,我是一菲,在软件测试当中linux 操作系统和Mysql数据库的内容是十分的知识同时也是十分重要的.所以一菲这两天通过查阅资料等其他方式为大家梳理了liunx和Mysql面试题大礼包, ...

  7. linux中流设备_[快速上手Linux设备驱动]之块设备驱动流程详解一

    [快速上手Linux设备驱动]之块设备驱动流程详解一 walfred已经在[快速上手Linux设备驱动]之我看字符设备驱动一 文中详细讲解了linux下字符设备驱动,并紧接着用四篇文章描述了Linux ...

  8. mysql和linux的题目_最强Linux和Mysql面试题套餐,让你的面试无懈可击!

    引言: 大家好,我是一菲,在软件测试当中linux 操作系统和Mysql数据库的内容是十分的知识同时也是十分重要的.所以一菲这两天通过查阅资料等其他方式为大家梳理了liunx和Mysql面试题大礼包, ...

  9. Linux/Centos7系统管理之深入理解Linux文件系统与日志分析

    前言:inode(文件节点)与block(数据块)硬链接与软连接恢复误删除的文件 (即rm-rf 的操作,可以先进行备份的操作,然后可以进行恢复ext4和xfs文件系统皆可)日志文件的分类用户日志与程 ...

最新文章

  1. ajax csv写文件内容,接收.csv文件作为ajax成功函数中的数据
  2. python requests.packages.urllib3问题记录
  3. Linux复习资料——MySQL-client-5.6.50-1.el7.x86_64与MySQL-server-5.6.50-1.el7.x86_64包安装MySQL全过程
  4. Spring Boot 静态资源处理,原来如此!
  5. koa --- 使用中间件多层级抛出错误
  6. CPU使用率的查看以及性能分析(perf top/record/report)
  7. @JsonProperty注解解析
  8. linux如何标识用户账号和组账号,linux管理用户和组
  9. 03Linux用户和组及权限
  10. (转)淘淘商城系列——中文分析器IK-Analyzer的使用
  11. 从零开始刷Leetcode——数组(532.561)
  12. 【CF Round #534 Div2】B:Game with string(水题,积累思路)
  13. 难道这个会是我的广角选择?
  14. IDEA怎么设置背景图片
  15. 电力电子课设日志(已完结)
  16. HTML页面基本结构
  17. Time-Series Representation Learning via Temporal and Contextual Contrasting
  18. 在MATLAB环境下使用深度学习网络DeepLabV3+进行语义分割(云图分割)
  19. (转)如何应用MTCNN和FaceNet模型实现人脸检测及识别
  20. 【微信小程序经验】各类图表相关组件+Demo源码(折线图,柱状图,K线,分时图)

热门文章

  1. 硕士发表SCI论文84篇遭质疑?!本人霸气回应:有无造假随便查!没有拼爹!...
  2. 关于石英晶体谐振器可靠性分析
  3. 《嵌入式 – GD32开发实战指南》第14章 内部温度传感器
  4. 服务器维护后必刷绿龙吗,魔兽世界怀旧服世界BOSS绿龙快速收割指南
  5. python合并单元格居中_Python基于xlrd模块处理合并单元格
  6. openlayers 计算绘制的矢量多边形的面积 (getArea方法)
  7. harmonyos开源,华为杨海松:鸿蒙系统支持第三方手机 “开源开放毫无保留”
  8. centos6.6 cobber 安装
  9. REPAIR TABLE导致死锁
  10. RTThread中falut定位方法