Linux网络技术学习(五)—— 网络设备初始化(I)
文章目录
- 什么时候进行的设备初始化?
- 设备注册和初始化
- NIC(网卡 Network Interface Card)初始化的基本目标
- 设备与内核之间的交互
- 硬件中断
- 中断类型
- 传送节流方式为了改善效率
- 中断共享
- IRQ处理函数映射的组织
- irqaction结构体存储方式
什么时候进行的设备初始化?
内核初始化图

1、当内核引导时,会执行start_kernel对一些子系统做初始化
2、start_kernel终止前会调用init内核线程,由其负责初始化的后续工作。
初始化任务中有三个部分:
1、引导期间选项
调用两次parse_args(一次是直接调用,而另一次是通过parse_early_param间接调用)以处理引导加载程序(bootloaser)在引导期间传给内核的配置参数。
2、中断和定时器
硬中断和软中断分别由init_IRQ和softirq_init做初始化。
3、初始化函数
内核子系统及内建的设备驱动程序由do_initcalls初始化。free_init_mem会释放一块被无用程序所持有的内容。
run_init_process确定在系统上运行的第一进程,也就是其他进程的父进程(PID为1)一直运行直到系统做完工作。
通常运行程序是Init,管理员可以通过init=引导期间选项指定另一个不同程序。
不提供选项,内核会从一组众所周知的位置去执行init命令,如果找不到init,就会发生内核panic
设备注册和初始化
一个网络设备可以用,就必须被内核认可,并且关联正确的驱动程序。
驱动程序把驱动设备所需的所有信息存储在私有数据结构中,然后与其他需要此设备的内核组件交互。
1、注册和初始化任务的一部分由内核负责
2、其他部分由设备驱动程序负责
初始化分为:硬件初始化、软件初始化、功能初始化
1、硬件初始化
由设备驱动程序和通用总线层(例,PCI或USB)合作完成。驱动有时会通过用户提供的参数协调,把每个设别的这类功能配置成IRQ和I/O地址,使其能与内核交互。
2、软件初始化
在设备能使用之前,需要依赖开启和配置的网络协议(用户需要提供IP地址等配置信息)等。
3、功能初始化
针对每个网络设备的配置。例:流量控制,可以决定封包加入及退出设备出口队列的方式。
NIC(网卡 Network Interface Card)初始化的基本目标
Linux内核中,每个设备都有一个net_device数据结构表示。net_device的分配以及内部字段的初始化,部分的是由设备驱动程序完成,部分是由内核函数完成。
设备驱动程序如何分配建立设备/内核通信所需的资源?
1、IRQ线
NIC必须被分配一个IRQ,用于设备与内核之间的交互。虚拟设备不需要分配一个IRQ:例如内环设备,因其活动都在内部进行。
/proc/interrupts文件可用于观察当前分派状态
2、I/O端口和内存注册
驱动程序将其设备的一个内存区域(配置寄存器)映射到系统内存,使得驱动程序的读/写操作可以通过系统内存地址直接进行,简化代码。I/O端口和内存分别使用request_region和release_region注册和释放

设备与内核之间的交互
几乎所有设备(包括NIC)都采用两种与内核的交互方式:
1、轮询
由内核端的驱动定期检查设备状态,查看是否发生了什么事情
2、中断
由设备端驱动。当设备需要内核注意时,会向内核发送出一个硬件信号(产生中断事件)
硬件中断
每个中断事件都会运行一个函数,被称为中断处理函数,而中断处理函数必须按照设备的所需进行裁剪,因此由设备驱动程序安装。当设备驱动程序注册一个NIC时,会请求并分派一个IRQ。
static inline int __must_check
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,const char *name, void *dev)
void free_irq(unsigned int irq, void *dev_id)
request_irq函数会注册一个处理函数。首先确保所请求的中断是一个有效的中断,而且还没分配给另一个设备,除非这两个设备能够共享IRQ
free_irq函数会删除处理函数,给定的设备由dev_id标识。如果没有其他设备注册在该IRQ线,就关闭IRQ
在内核接收到中断通知时,会使用IRQ编号找出该驱动程序的中断处理函数并执行。为了找到处理函数,内核会把IRQ编号和函数处理函数之间的相连接关系存储在一张全局表中。相连关系可以是一对一或一对多。
中断类型
通过中断,NIC能够告知其驱动程序几种不同的事件:
1、接收一帧
这是常见标准的情况
2、传输失败
这种事件只有当被为二进制指数后退功能失败时,才由Ethernet设备产生(由NIC在硬件层实现)。驱动程序不会把这种通知信息转送到那些较高层的网络层,这些网络层会通过其他方式获取到传输失败。
3、DMA传输已成功完成
使用同步传输时(无DMA),当该帧已上传至NIC,驱动程序会立刻知道
使用DMA时,使用异步传输,设备驱动程序必须等待NIC发出明确的中断事件。
4、设备有足够内存处理新传输
当出口队列没有足够空间保存一个最大尺寸的帧时,NIC设备驱动程序会停止出口队列而关闭传输。
当内存可用时,该队列又会再次开启
传送节流方式为了改善效率
在系统中,设备驱动程序会在队列空间缺乏时关闭传输,同时要求NIC当可用内存大于给定量时(设备的MTU)发出一个中断,然后当中断到来时重启传输。
例:
// 平台: RK3568
// drivers/net/ethernet/3com/3c509.c
static netdev_tx_t
el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
{netif_stop_queue (dev);......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);......
}
驱动程序可以用netif_stop_queue停止设备队列,以此能禁止内核提交后续的传输请求。
驱动程序会检查该设备的内存是否足够的内存容纳一个1536个字节的包。
如果有,驱动程序会启动队列,允许内核再次提交传输请求。
否则,就会指示设备(配置寄存器),当条件满足时产生一个中断。中断处理函数将使用netif_start_queue重启设备队列。
中断共享
IRQ线是有限的资源。添加系统能容纳设备数目的简单方式,就是允许几台设备共享同一个IRQ。
每个设备会针对该IRQ将其自己的处理函数注册给内核,再由内核启用这些同一个共享IRQ的设备的所有函数。而不是由中断通知,寻找正确的设备,再启用其处理函数。
一组设备共享一条IRQ线时,所有这些设备的设备驱动程序都必须能力处理共享的IRQ(换言之,每当一个设备注册要使用一条IRQ线时,就必须明确说明其是否支持中断共享。)
当另一设备试图注册同一个IRQ编号时,如果此设备或者该IRQ当前所分派的设备无法共享IRQ,就会被拒绝。
IRQ处理函数映射的组织
IRQ处理函数的映射存储在一个向量表中,每一个IRQ都对应一个处理函数列表。
只有当多台设备共享同一个IRQ时,一个列表才会有一个以上的元素。向量的尺寸取决于具体的体系结构,可以从15变化到200以上。
// 定义在include/linux/interrupt.h
struct irqaction// 定义在include/linux/irqdesc.h
struct irq_desc// kernel/irq/manage.c
static int
__setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
在之前介绍的硬件中断函数request_irq函数就是包含__setup_irq的包裹函数,用一个irqaction结构体输入,然后将其插入至一个全局变量irq_desc。
handle_IRQ_event 处理中断并将其传给驱动程序的内核函数是依赖irq_desc结构体的。
irqaction结构体存储方式

对一个可能的IRQ都有一个irq_desc实例,每个成功注册的IRQ处理函数都有一个irqaction实例。irq_desc尺寸是由结构体中NR_IRQS指定
当给定IRQ编号(也就是irq_desc向量的给定元素)有一个以上的irqaction实例时,就需要中断共享。
irqaction数据结构的字段中存储哪些与IRQ处理例程相关的信息:
// 平台RK3288
typedef irqreturn_t (*irq_handler_t)(int, void *);
irq_handler_t handler;
// handler成员为中断处理函数,由设备驱动程序所提供的函数,用于处理中断的通知信息
// 传入的参数: int irq(产生此通知信息的IRQ编号);void *dev_id(设备标识符。同一个驱动程序可能同时要负责不同的设备,需要设备ID来正确处理通知信息)unsigned int irq;
// 一组标识,取值为IRQF_* 定义在include/linux/interrupt.h
// IRQF_SHARED 当置位时,设备驱动程序可以处理共享的IRQ
// IRQF_IRQPOLL 中断用于轮询(出于性能考虑,只有首先在共享中断中注册的中断才被考虑)void *dev_id
// 与此设备相关联的net_device数据结构的指针。声明为void *的原因是,不仅仅只有NIC设备使用IRQ,各种设备类型使用的不同的数据结构struct irqaction *next;
// 所有共享同一个IRQ编号的设备会用此指针链接成一个列表const char *name;
// 设备名称。可以通过/proc/interrupts内容读取设备名称

相关文章:
Linux网络技术学习(五)—— 网络设备初始化(I)
文章目录什么时候进行的设备初始化?设备注册和初始化NIC(网卡 Network Interface Card)初始化的基本目标设备与内核之间的交互硬件中断中断类型传送节流方式为了改善效率中断共享IRQ处理函数映射的组织irqaction结构体存储方式什么时候进行的…...
[技术选型] ClickHouse和StarRocks的介绍
文章目录1.ClickHouse介绍2.StarRocks介绍1.ClickHouse介绍 ClickHouse是面向联机分析处理(OLAP)的开源分析引擎。最初由俄罗斯第一搜索引擎Yandex开发,于2016年开源,开发语言为C。由于其优良的查询性能,PB级的数据规…...
算法刷题打卡第90天:表现良好的最长时间段
表现良好的最长时间段 难度:中等 给你一份工作时间表 hours,上面记录着某一位员工每天的工作小时数。 我们认为当员工一天中的工作小时数大于 8 小时的时候,那么这一天就是「劳累的一天」。 所谓「表现良好的时间段」,意味在这…...
Python语言零基础入门教程(十七)
Python 文件I/O 本章只讲述所有基本的 I/O 函数,更多函数请参考Python标准文档。 #### 打印到屏幕 最简单的输出方法是用print语句,你可以给它传递零个或多个用逗号隔开的表达式。此函数把你传递的表达式转换成一个字符串表达式,并将结果写…...
C语言中大小端问题
目录 一、什么是大小端 二、 举个例子 三、大小端演示 四、解释"二"中举例的问题 五、怎么判断是大端还是小端 六、一个题目 一、什么是大小端 大端模式(大端字节序存储):就是高位字节数据存放在内存的低地址端ÿ…...
vue2+微前端qiankun从搭建到部署的实践(主子应用切换;集成vue3+vite3子应用)
一、最终效果 二、微前端(qiankun)介绍及为什么选择用微前端,可以看官网 三、目录结构如下 四、具体配置 一、主应用配置 1、主应用技术栈 Vue-cli4搭建项目Vue2Element-Uiqiankun;Vue2Element-Uiqiankun 2、搭建好主项目&…...
怎么代理微信小程序创业?
随着微信的兴起,小程序已经成为了人们生活中不可或缺的一部分。如果你想要创业的话,那么代理微信小程序是一个不错的选择。本文将为大家介绍怎么代理微信小程序创业。 一、什么是微信小程序 微信小程序是一款专为移动设备使用者而设计的应用。它通过扫…...
今天是情人节呐,我利用Python制作了好多表白的东西,快来吧~
今天是情人节那,有没有现在没有对象的宝子,评论里扣个111哈哈 目录 玫瑰 爱心树 丘比特 多彩气球 阿玥的小课堂 一、情人节的由来 二、情人节的来历和意义 玫瑰 局部代码实现如下: # 花瓣1 turtle.left(150) turtle.circle(-90, 70) …...
【Linux】-- 进程信号(处理、内核)
上篇:【Linux】-- 进程信号(认识、应用)_川入的博客-CSDN博客 目录 信号其他相关常见概念 pending handler block 信号处理的过程 sigset_t sigset_t使用 系统接口 sigpending sigprocmask 捕捉方法 sigaction struct sigactio …...
C/【静态通讯录】
🌱博客主页:大寄一场. 🌱系列专栏:C语言学习笔记 😘博客制作不易欢迎各位👍点赞⭐收藏➕关注 前言 往期回顾: C/扫雷 C/N子棋 通讯录作为通讯录地址的书本,当今的通讯录可以涵盖多项…...
万卷书 - 让孩子对自己负责 [The Self-Driven Child]
让孩子对自己负责 The Self-Driven Child - 让你的孩子更加科学合理的掌控自己的生活 简介 《The Self-Driven Child》(2018)解释了我们对孩子的习惯性控制欲,它导致了孩子压力过大、难以合作,以及主观能动性差。本书不提倡这种做法,而是认为我们应该帮助孩子自己做出合适…...
Postman中cookie的操作
在接口测试中,某些接口的调用,需要带入已有Cookie,比如有些接口需要登陆后才能访问。 Postman接口请求使用Cookie有如下两种方式: 1、直接在头域中添加Cookie头域,适用于已经知道请求所用Cookie数据的情况。 2、使用…...
torch.grid_sample
参考: 双线性插值的理论Pytorch grid_sample解析PyTorch中grid_sample的使用方法pytorch中的grid_sample()使用 查阅官方文档,TORCH.NN.FUNCTIONAL.GRID_SAMPLE grid_sample的函数签名如下所示,torch.nn.functional.grid_sample(input, gr…...
前端基于 Docker 的 SSR 持续开发集成环境实践
项目收益 整体开发效率提升20%。加快首屏渲染速度,减少白屏时间,弱网环境下页面打开速度提升40%。 权衡 在选择使用SSR之前,需要考虑以下事项! SSR需要可以运行Node.js的服务器,学习成本相对较高。对于服务器而言&a…...
ARM交叉编译入门及交叉编译第三方库常见问题解析
1. 交叉编译是什么? 交叉编译简单说来,就是编译成果物的地儿不是你运行这个成果物的地儿。最常见的场景,就是我们要编译一个 ARM版本 的可执行程序,但我们编译这个 ARM版本 可执行程序的地方,是在一个 x86_x64 的平台…...
Ruby Web Service 应用 - SOAP4R
什么是 SOAP? 简单对象访问协议(SOAP,全写为Simple Object Access Protocol)是交换数据的一种协议规范。 SOAP 是一种简单的基于 XML 的协议,它使应用程序通过 HTTP 来交换信息。 简单对象访问协议是交换数据的一种协议规范,是一种轻量的、…...
HashMap底层实现原理概述
原文https://blog.csdn.net/fedorafrog/article/details/115478407 hashMap结构 常见问题 在理解了HashMap的整体架构的基础上,我们可以试着回答一下下面的几个问题,如果对其中的某几个问题还有疑惑,那就说明我们还需要深入代码,…...
Linux驱动学习环境搭建
背景常识 一、程序分类 程序按其运行环境分为: 1. 裸机程序:直接运行在对应硬件上的程序 2. 应用程序:只能运行在对应操作系统上的程序 二、计算机系统的层次结构 所有智能设备其实都是计算机,机顶盒、路由器、冰箱、洗衣机、汽…...
Java基础之异常
目录1 异常1.1 异常的概述1.2 常见异常类型1.3 JVM的默认处理方案1.4 编译时异常的处理方式1.4.1 异常处理之 try ... catch ... [ktʃ](捕获异常)1.4.2 异常处理之 throws(抛出异常)1.5 Throwable 的成员方法1.6 编译时异常和运行…...
感慨:大三了,未来该何去何从呢
笔者曾在十一月份通过了字节跳动的三次面试, 但是最终因为疫情原因不能满足公司的入职时间要求, 没有拿到offer。近期也是投递了大量大厂的实习岗, 但是要么已读不回, 要么明确告诉我学历至少要985硕士(天天被阿里cpu)。 说实话一…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
