网站超链接怎么做/百度保障中心人工电话
系列文章目录
深度探索Linux操作系统 —— 编译过程分析
深度探索Linux操作系统 —— 构建工具链
深度探索Linux操作系统 —— 构建内核
深度探索Linux操作系统 —— 构建initramfs
文章目录
- 系列文章目录
- 前言
- 一、为什么需要 initramfs
- 二、initramfs原理探讨
- 三、构建基本的initramfs
- 四、将硬盘驱动编译为模块
- 1、配置devtmpfs
- 2、将硬盘控制器驱动配置为模块
- 3、自动加载硬盘控制器驱动
- (1)内核向用户空间发送事件
- (2)udev加载驱动和建立设备节点
前言
一般而言,桌面、服务器等通用系统都使用 initramfs。部分嵌入式系统中,也会使用 initramfs,甚至有的使用 initramfs 作为最终的根文件系统。那么什么是 initramfs 呢?很难用一句话将 initramfs 的作用描述清楚,或许可以将 initramfs 定位为内核通往根文件系统的桥梁。
一、为什么需要 initramfs
鸡和蛋的问题:内核要加载这些模块或者运行这些程序才能正确识别根文件系统所在的设备,但是保存这些模块或者程序的根文件系统又存储在这些设备上。
内核开发者们设计了 initramfs 机制。initramfs 是一个临时的文件系统,其中包含了必要的设备如硬盘、网卡、文件系统等的驱动以及加载驱动的工具及其运行环境,比如基本的 C 库,动态库的链接加载器等等。同时,那些处理根文件系统在 RAID 、网络设备上的程序也存放在 initramfs 中。由第三方程序(如 Bootloader )负责将 initramfs 从硬盘装载进内存。以驱动硬盘为例,内核就不必再从硬盘,而是从已经加载到内存的 initramfs 中获取硬盘控制器等相关驱动了,继而可以驱动硬盘,访问硬盘上的根文件系统,从而解决了前面提到的鸡和蛋的矛盾。
在初始化的最后,内核运行 initramfs 中的 init 程序,该程序将探测硬件设备、加载驱动,挂载真正的文件系统,执行文件系统上的 /sbin/init,进而切换到真正的用户空间。真正的文件系统挂载后,initramfs 即完成了使命,其占用的内存也会被释放。
二、initramfs原理探讨
在 2.4 以及更早版本的内核中,内核使用的是 initrd。initrd 是基于ramdisk技术的,而 ramdisk 就是一个基于内存的块设备,因此 initrd 也具有块设备的一切属性。比如 initrd 容量是固定的,一旦创建 initrd 时设定了一个大小,就不能再进行动态调整。
ramfs 与 ramdisk 有着本质的区别,ramdisk 本质上是基于内存的一个块设备,而 ramfs 是基于缓存的一个文件系统。因此,ramfs 去除了前述块设备的一些限制。比如,ramfs 根据其中包含的文件大小可自由伸缩;增加文件时,自动分配内存;删除文件时,自动释放内存。更重要的是,ramfs 是基于已有的缓存机制,因此不必再像 ramdisk 那样需要和缓存之间进行多余的复制一环。
从 2.6 开始,内核开发人员基于 ramfs 开发了 initramfs 替代 initrd 。
当 2.6 版本的内核引导时,在挂载真正的根文件系统之前,首先将挂载一个名为 rootfs 的文件系统,并将 rootfs 的根作为虚拟文件系统目录树的总根。那么为什么要使用 rootfs 这么一个中间过程呢?原因之一还是为了解决鸡和蛋的问题。内核需要根文件系统上的驱动以及程序来驱动和挂载根文件系统,但是这些驱动和程序有可能没有编译进内核,而在根文件系统上。如果不借助第三方,内核是没有办法挂载真正的根文件系统的。而 rootfs 虽然名称为 rootfs ,但是并不是什么新的文件系统,事实上,其就是一个 ramfs,只不过换了一个名称。换句话说,rootfs 是在内存中的,内核不需要特殊的驱动就可以挂载 rootfs,所以内核使用 rootfs 作为一个过渡的桥梁。
在挂载了 rootfs 后,内核将 Bootloader 加载到内存中的 initramfs 中打包的文件解压到 rootfs 中,而这些文件中包含了驱动以及挂载真正的根文件系统的工具,内核通过加载这些驱动、使用这些工具,实现了挂载真正的根文件系统。此后,rootfs 也完成了历史使命,被真正的根文件系统覆盖(overmount)。但是 rootfs 作为虚拟文件系统目录树的总根,并不能被卸载。但是这没有关系,前面我们已经谈到了,rootfs 基于 ramfs,删除其中的文件即可释放其占用的空间。
三、构建基本的initramfs
# 1
mkdir initramfs
cd initramfs# 2
# /vita/initramfs/init
#!/bin/bash
echo "Hello Linux!"
exec /bin/bash# 3
mkdir bin
cp ../sysroot/bin/bash bin/
bash 依赖
vita@baisheng:/vita/initramfs$ ldd bin/bashlibdl.so.2 => /vita/sysroot/lib/libdl.so.2libgcc_s.so.1 =>/vita/cross-tool/i686-none-linux-gnu/lib/libgcc_s.so.1libc.so.6 => /vita/sysroot/lib/libc.so.6vita@baisheng:/vita/initramfs$ ldd lib/libdl.so.2libc.so.6 => /vita/sysroot/lib/libc.so.6ld-linux.so.2 => /vita/sysroot/lib/ld-linux.so.2vita@baisheng:/vita/initramfs$ ldd lib/libc.so.6ld-linux.so.2 => /vita/sysroot/lib/ld-linux.so.2vita@baisheng:/vita/initramfs$ ldd lib/ld-linux.so.2vita@baisheng:/vita/initramfs$ ldd lib/libgcc_s.so.1libc.so.6 => /vita/sysroot/lib/libc.so.6
bash 依赖于libc、libdl 以及 libgcc_s.so.1,因此,我们需要在 initramfs 中安装这三个库,以及安装加载动态库的动态加载/链接器。
根据依赖关系可见,libdl 依赖 libc 和动态链接器,libgcc 只依赖 libc,libc 仅依赖动态链接器,而动态链接器不依赖其他任何库,因此,我们不再需要安装其他库到 initramfs 中。
四、将硬盘驱动编译为模块
1、配置devtmpfs
Linux 从 2.6.18 开始采用 udev,/dev 目录使用了基于内存的文件系统 tmpfs 管理设备文件。
2009 年初,开发人员又提出了 devtmpfs ,并在同年年底被 Linux 2.6.32 正式收录。内核引导时,devtmpfs 将所有注册的设备在 devtmpfs 中建立相应的设备文件,一旦进入用户空间,在启动 udev 前,就可以将 devtmpfs 挂载到 /dev 目录下。
也就是说,在启动 udev 前,devtmpfs 中已经建立了初步的设备文件,一般启动程序不必再等待 udev 建立设备节点,甚至在某些嵌入式系统上,不再需要 udev 创建设备节点,因为这个基本的 /dev 已经足够,从而缩短了系统的启动时间。同 rootfs 类似,devtmpfs 也不是新设计的文件系统,如果内核配置支持 tmpfs ,那么其就是 tmpfs;否则,devtmpfs 就是 ramfs,只不过换了一个名字而已。
2、将硬盘控制器驱动配置为模块
接下来重新编译内核和模块。内核和模块可以使用单独的命令分开编译,也可以使用一条 make 命令同时编译内核和模块。编译完成后,将模块暂时安装在 “/vita/sysroot/lib/modules” 目录下。
vita@baisheng:/vita/build/linux-3.7.4$ make bzImage
vita@baisheng:/vita/build/linux-3.7.4$ make modules
vita@baisheng:/vita/build/linux-3.7.4$ make \INSTALL_MOD_PATH=$SYSROOT modules_install
最终安装的硬盘控制器驱动模块包括:
vita@baisheng:/vita$ ls sysroot/lib/modules/3.7.4/kernel/drivers/ata/ahci.ko ata_piix.ko libahci.ko
我们将其复制到 initramfs 中。
3、自动加载硬盘控制器驱动
从 2.6 版内核开始,Linux 采用 udev 管理驱动模块的加载以及设备节点的管理。每当内核发现新的设备,便通过 NETLINK 向用户空间发送新设备事件,该事件中记录了设备的相关信息。用户空间的 udev 服务进程收到内核事件后,根据事件中携带的信息,首先判断该设备的驱动是否已经加载,如果没有,则加载驱动。驱动加载后,内核会再次向用户空间报告发现新设备事件,这时设备已经成功驱动了,并且主次设备号等信息也已经准备好了,udev 收到事件后,或者为设备建立节点,或者执行某些特定的操作。整个过程如图4-19所示。
(1)内核向用户空间发送事件
PC 机上的硬盘控制器,无论是 IDE 接口的,还是 SATA 接口的,一般都是通过 PCI 总线连接到计算机上的。内核在引导时,PCI 子系统将进行初始化,枚举总线上的设备,并尝试为设备匹配驱动;然后将收集到的设备相关信息组织为 uevent 事件;接着调用 kobject_uevent ,通过 NETLINK 将组织好的 uevent 发送到用户空间,通知 udev 有新设备了。简单地讲,内核的工作就是探测并收集设备信息,将其包装到 uevent 事件中,然后发送到用户空间。
事实上,无论是发现新的设备,还是有新的驱动载入,抑或是用户向 sysfs 中的 uevent 写入字符串,内核都将调用函数 kobject_uevent 向用户空间发送事件。
结构体 kobj_uevent_env 用来保存收集到的设备相关信息,所以在函数 kobject_uevent_env 中,首先为 kobj_uevent_env 申请了一块内存,即变量 env 指向的内存,用来临时存放准备发送到用户空间的设备相关信息。
然后向该内存中添加了三个默认的变量,包括 ACTION、DEVPATH 和 SUBSYSTEM 。 其中 ACTION 指的是热插拔的动作,如 “add”,“remove”,“change” 等。DEVPATH 指的是设备在 sysfs 文件系统中注册的设备路径,比如笔者的硬盘 sda 的 DEVPATH 是 “/devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0/block/sda” 。SUBSYSTEM 一般是指设备所在的总线,比如笔者的硬盘是挂在 PCI 总线上的,因此该变量的值是 “pci”。
pci_uevent 又向 uevent 中追加了 pci class 、 vendor id 、 device id 以及 MODALIAS 等变量,其中 MODALIAS 需要重点关注,其是由设备所在总线、vendor ID、device ID 等相关参数连接而成的一个字符串。在接下来的章节中,读者将看到,用户空间的 udev 恰恰就是根据这个变量为设备匹配驱动模块的。
除了总线外,如果硬盘控制器所属的 class 或者 type 也需要继续向 uevent 中追加变量,则继续调用硬盘控制器所属的 class 或者 type 中的相应的函数,这里不再继续分析了。最终,内核向用户空间发送的 uevent 事件包含的大致的内容如下,其中不同变量之间使用 “\0” 进行分隔。
(2)udev加载驱动和建立设备节点
udev 是用户空间动态管理设备的机制,包括加载驱动、管理设备节点等。udev 机制的核心是其服务进程 udevd。当启动过程进入用户空间阶段后,udevd 将被启动。udevd 启动后,首先读取并分析所有的规则文件,并将其缓存在内存中。一般情况下,系统默认的规则文件存在 /lib/udev/rules.d 目录下,用户自定义的规则存放在 /etc/udev/rules.d 目录下。每当动态地增加、删除或者改变某个规则文件时,udevd 将更新其缓存在内存中的规则。然后,udevd 通过 NETLINK 协议,监听并处理来自内核的 uevent 事件。每当 udevd 收到一个内核的 uevent ,udevd 均创建一个单独的子进程处理 uevent 。
对于每个内核报告的 uevent,udevd 根据 uevent 中的变量逐个匹配规则。规则文件通常以数字开头,数字小的先进行匹配。若每个规则文件中包含若干个规则,同一规则不允许断行,每个规则至少包含一个 key-value 对,每个 key-value 对之间使用逗号分隔。可以将规则理解为由匹配条件和赋值动作组成,当所有的匹配条件都满足后,赋值动作就会发生。规则中可以加载驱动模块;规定如何给设备接点命名、建立符号连接;设备连接和断开时分别执行指定的程序等。
前面我们看到内核在发现新设备时会将设备的一些信息通过 NETLINK 发送到用户空间,udev 接收到事件后,如果发现设备尚未被驱动,将尝试加载驱动模块。那么 udev 如何确定设备对应的驱动模块呢?一般而言,根据设备的 vender ID 和 device ID 就可以标识一类设备,当然有的也需要根据 subvendor ID 和 subdevice ID 进一步细分。而在驱动代码中,恰恰使用这些设备信息明确声明了其可以支持的设备。以驱动 AHCI 模式的 SATA 硬盘控制器驱动为例:
相关文章:

深度探索Linux操作系统 —— 构建initramfs
系列文章目录 深度探索Linux操作系统 —— 编译过程分析 深度探索Linux操作系统 —— 构建工具链 深度探索Linux操作系统 —— 构建内核 深度探索Linux操作系统 —— 构建initramfs 文章目录 系列文章目录前言一、为什么需要 initramfs二、initramfs原理探讨三、构建基本的init…...

使用cmake构建Qt6.6的qt quick项目,添加应用程序图标的方法
最近,在学习qt的过程中,遇到了一个难题,不知道如何给应用程序添加图标,按照网上的方法也没有成功,后来终于自己摸索出了一个方法。 1、准备一张图片作为图标,保存到工程目录下面,如logo.ico。 …...

VUE宝典之vue-dialog使用
文章目录 🍁vue-dialog概述🍁vue-dialog项目引入🍂安装Vue Dialog插件🍂引入Vue Dialog插件🍂引入 Vue Dialog 组件🍂在组件中使用Vue Dialog 🍁vue-dialog代码示例🍁vue-dialog父子…...

AWTK 串口屏开发(1) - Hello World
1. 功能 这个例子很简单,制作一个调节温度的界面。在这里例子中,模型(也就是数据)里只有一个温度变量: 变量名数据类型功能说明温度整数温度。范围 (0-100) 摄氏度 2. 创建项目 从模板创建项目,将 hmi/…...

鸿蒙Harmony开发初探
一、背景 9月25日华为秋季全场景新品发布会,余承东宣布鸿蒙HarmonyOS NEXT蓄势待发,不再支持安卓应用。网易有道、同程旅行、美团、国航、阿里等公司先后宣布启动鸿蒙原生应用开发工作。 二、鸿蒙Next介绍 HarmonyOS是一款面向万物互联,全…...

【MySQL语言汇总[DQL,DDL,DCL,DML]以及使用python连接数据库进行其他操作】
MySQL语言汇总[DQL,DDL,DCL,DML] SQL分类1.DDL:操作数据库,表创建 删除 查询 修改对数据库的操作对表的操作复制表(重点)!!!!! 2.DML:增删改表中数据3.DQL:查询表中的记录…...

解决方案:Mac 安装 pip
python3 --version 通过以下命令来下载pip: curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py curl命令允许您指定一个直接下载链接。使用-o选项来设置下载文件的名称。 通过运行以下命令安装下载的包: python3 get-pip.py...

【恋上数据结构】前缀树 Tire 学习笔记
Tire 需求分析 如何判断一堆不重复的字符串是否以某个前缀开头? 用 Set\Map 存储字符串(不重复)遍历所有字符串进行判断缺点:时间复杂度 O(n) 有没有更优的数据结构实现前缀搜索? Tire(和 Tree 同音&a…...

2023五岳杯量子计算挑战赛数学建模思路+模型+代码+论文
赛题思路:12月6日晚开赛后第一时间更新,获取见文末名片 “五岳杯”量子计算挑战赛,是国内专业的量子计算大赛,也是玻色量子首次联合移动云、南方科技大学共同发起的一场“企校联名”的国际竞赛,旨在深度融合“量子计算…...

Angular中的单向和双向数据绑定
1、单向数据绑定: 单向数据绑定是指数据从组件流向视图或从视图流向组件,但数据的流动是单向的。 在Angular中,主要有以下两种形式的单向数据绑定: 从组件到视图(插值表达式): 使用插值表达式…...

【Vue】vue整合element
上一篇: vue项目的创建 https://blog.csdn.net/m0_67930426/article/details/134816155 目录 整合过程 使用: 整合过程 项目创建完之后,使用编译器打开项目 在控制器里输入如下命令 npm install element-ui 如图表示安装完毕 然后在…...

HarmonyOS应用开发者高级认证考试答案
一、判断题 云函数打包完成后,需要到AppGallery Connect创建对应函数的触发器才可以在端侧中调用(错)在column和Row容器组件中,aligntems用于设置子组件在主轴方向上的对齐格式,justifycontent用于设置子组件在交叉轴…...

6、Broker消息处理流程(六)
前面分析完Broker启动会启动RemotingServer服务同时会注册Processor处理器,接着分析Producer进行消息的发送,当Producer发送完消息后就得到Broker去接收Producer发送的消息了。 Producer发送给Broker消息时候,发送的请求code为SEND_MESSAGE(这…...

Clean 架构下的现代 Android 架构指南
Clean 架构下的现代 Android 架构指南 Clean 架构是 Uncle Bob 提出的一种软件架构,Bob 大叔同时也是 SOLID 原则的命名者。 Clean 架构图如下: 这张图描述的是整个软件系统的架构,而不是单体软件,其中至少包括服务端以及客户端…...

代码随想录算法训练营第四十六天| 139 单词拆分
目录 139 单词拆分 139 单词拆分 class Solution { public:bool wordBreak(string s, vector<string>& wordDict) {vector<bool>dp(s.size() 1);//长度为i的字符串时能否成功拆分unordered_set<string>set(wordDict.begin(),wordDict.end());dp[0] t…...

IEEE期刊论文模板
一、模板下载 1、登陆IEEE作者中心Author Center 地址:Publish with IEEE Journals - IEEE Author Center Journals 2、点击“Download a template” 3、在弹出的模板下载页面点击IEEE模板选择器“IEEE Template Selector” 4、在弹出的模板选择器页面点击“Tran…...

上位机与PLC:ModbusTCP通讯之数据类型转换
前请提要: 从PLC读取的数值,不管是读正负整数还是正负浮点数,读取过来后都会变成UInt16,也就是Ushort类型 一、ushort(UInt16)转成 Int32 源代码方法: //ushort类型转Int32类型的方法private int ushortToInt32(ushort[] date, int start){//先进行判断,长度是否正确…...

界面控件DevExpress WPF导航组件,助力升级应用程序用户体验!(上)
DevExpress WPF的Side Navigation(侧边导航)、TreeView、导航面板组件能帮助开发者在WPF项目中添加Windows样式的资源管理器栏或Outlook NavBar(导航栏),DevExpress WPF NavBar和Accordion控件包含了许多开发人员友好的…...

联合基于信息论的安全和隐蔽通信的框架
这个标题很帅 abstractintroductionsystem modelPROPOSED JOINT OPTIMIZATION OF ITS AND COVERT TRANSMISSION RATE信息论安全 (ITS)隐蔽通信需要(CC)Joint Information-Theoretic Secrecy and Covert Communication in the Presence of an Untrusted User and Warden 202…...

行业地位失守,业绩持续失速,科沃斯的故事不好讲
特劳特曾在《定位》一书中提到,为了在容量有限的消费者心智中占据品类,品牌最好的差异化就是成为第一,做品类领导者或开创者,销量遥遥领先;其次分化品类,做到细分品类的唯一,即细分品类的第一。…...

蓝桥杯:货物摆放--因数存到数组里的技巧--减少运算量的方法
小蓝有一个超大的仓库,可以摆放很多货物。 现在,小蓝有 n 箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、宽、高。 小蓝希望所有的货物最终摆成一个大…...

我的创作纪念日——一年
机缘 初心始于对技术的热爱和分享知识的渴望。最初,我在一次练习中遇到了一些问题,通过解决这些问题并将解决方案记录下来,我意识到分享经验对自己和他人都非常有价值。于是,我开始在博客和社交平台上记录日常学习过程、撰写技术…...

Windows server 部署iSCSI共享磁盘搭建故障转移群集
在域环境下,在域控制器中配置iSCSI服务,配置共享网络磁盘,在节点服务器使用共享磁盘,并在节点服务器中搭建故障转移群集,实现故障转移 环境准备 准备3台服务器,配置都是8g2核,50g硬盘…...

2023年山东省职业院校技能大赛信息安全管理与评估二三阶段样题
2023年山东省职业院校技能大赛信息安全管理与评估二三阶段 样题 第二阶段 模块二 网络安全事件响应、数字取证调查、应用程序安全 一、竞赛内容 Geek极安云科专注技能竞赛技术提升,基于各大赛项提供全面的系统性培训,拥有完整的培训体系。团队拥有曾…...

数据结构——栈与栈排序
栈的特性 栈是一种遵循后进先出(LIFO)原则的数据结构。其基本操作包括: push:将元素添加到栈顶。pop:移除栈顶元素。peek:查看栈顶元素,但不移除。 栈排序的原理 栈排序的核心是使用两个栈&…...

Java Web应用小案例 - 实现用户登录功能
文章目录 一、使用纯JSP方式实现用户登录功能(一)项目概述(二)实现步骤1、创建Web项目2、创建登录页面 二、使用JSPServlet方式实现用户登录功能三、使用JSPServletDB方式实现用户登录功能 一、使用纯JSP方式实现用户登录功能 &a…...

Excel——多列合并成一列的4种方法
Excel怎么将多列内容合并成一列? 怎么将多个单元格的内容连接起来放在一个单元格里? 比如下图,要将B、C、D列的内容,合并成E列那样,该怎么做呢? △图1 本文中,高潜老师将给大家介绍 4种 将多…...

Vue笔记(四)路由
路由(Vue Router) 用Vue Vue Router创建单页面应用非常简单。当加入Vue Router时,需要将组件映射到路由上,让Vue知道在哪里渲染它们。 路由基本例子 <!-- 引入Vue 和 router --><script src"https://unpkg.com/vu…...

Redis部署-哨兵模式
目录 redis sentinel相关名词 redis sentinel架构 故障转移流程 基于docker搭建redis哨兵 准备工作 搭建过程 模拟主节点宕机,观察哨兵节点的工作流程 哨兵重新选取主节点的流程 1.主观下线 2.客观下线 3.哨兵节点推举出一个leader节点 4.leader选举完毕,leader挑选…...

滑动窗口练习(三)— 加油站问题
题目 测试链接 在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。 给定两个整数数组…...