【Linux技术】Linux内核Initrd机制解析,内核更新步骤,grub配置说明

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:

什么是Initrd

   initrd的英文含义是 boot loader initialized RAM disk,就是由boot loader初始化的内存盘。在 linux内核启动前, boot loader 会将存储介质中的 initrd 文件加载到内存,内核启动时会在访问真正的根文件系统前先访问该内存中的 initrd 文件系统

   在 boot loader 配置了 initrd 的情况下,内核启动被分成了两个阶段,第一阶段先执行 initrd文件系统中的"某个文件",完成加载驱动模块等任务,第二阶段才会执行真正的根文件系统中的 /sbin/init 进程。

   这里提到的"某个文件",Linux2.6 内核会同以前版本内核的不同,所以这里暂时使用了"某个文件"这个称呼,后面会详细讲到。

   第一阶段启动的目的是为第二阶段的启动扫清一切障碍,最主要的是加载根文件系统存储介质的驱动模块。为了在内核启动之后能够判断哪些硬件驱动需要加载,哪些不需要,文件系统有没有问题等,最终使得根分区能顺利加载。我们知道根文件系统可以存储在包括IDE、SCSI、USB在内的多种介质上,如果将这些设备的驱动都编译进内核,可以想象内核会多么庞大、臃肿。



Initrd的用途

   1.linux 发行版的必备部件

   linux 发行版必须适应各种不同的硬件架构,将所有的驱动编译进内核是不现实的,initrd技术是解决该问题的关键技术,Linux发行版在内核中只编译了基本的硬件驱动,在安装过程中通过检测系统硬件,生成包含安装系统硬件驱动的initrd,无非是一种即可行又灵活的解决方案。

   2.livecd 的必备部件

   同linux发行版相比livecd可能会面对更加复杂的硬件环境,所以也必须使用initrd。

   3.制作 Linux usb 启动盘必须使用 initrd

   usb 设备是启动比较慢的设备,从驱动加载到设备真正可用大概需要几秒钟时间。如果将usb驱动编译进内核,内核通常不能成功访问usb设备中的文件系统。因为在内核访问usb设备时,usb设备通常没有初始化完毕。所以常规的做法是,在 initrd 中加载usb驱动,然后休眠几秒中,等待usb设备初始化完毕后再挂载usb设备中的文件系统。

   4.在linuxrc脚本中可以很方便地启用个性化bootsplash。



Linux2.4内核对Initrd的处理流程

   为了清晰的了解Linux2.6内核initrd机制的变化,在介绍Linux2.6内核initrd之前,先对linux2.4内核的initrd进行一个简单的介绍。Linux2.4内核的initrd的格式是文件系统镜像文件,本文将其称为image-initrd,以区别后面介绍的linux2.6内核的cpio格式的initrd。

linux2.4内核对initrd的处理流程如下:

   1.boot loader把内核以及/dev/initrd的内容加载到内存,/dev/initrd是由boot loader初始化的设备,存储着initrd。

   2.在内核初始化过程中,内核把/dev/initrd设备的内容解压缩并拷贝到/dev/ram0设备上。

   3.内核以可读写的方式把/dev/ram0设备挂载为原始的根文件系统。

   4.如果/dev/ram0被指定为真正的根文件系统,那么内核跳至最后一步正常启动。

   5.执行initrd上的/linuxrc文件,linuxrc通常是一个脚本文件,负责加载内核访问根文件系统必须的驱动,以及加载根文件系统。

   6./linuxrc执行完毕,真正的根文件系统被挂载。

   7.如果真正的根文件系统存在/initrd目录,那么/dev/ram0将从/ 移动到/initrd。否则如果/initrd目录不存在,/dev/ram0将被卸载。

   8.在真正的根文件系统上进行正常启动过程,执行/sbin/init。linux2.4内核的initrd的执行是作为内核启动的一个中间阶段,也就是说initrd的/linuxrc执行以后,内核会继续执行初始化代码,我们后面会看到这是linux2.4内核同2.6内核的initrd处理流程的一个显著区别。



Linux2.6内核对Initrd的处理流程

   linux2.6内核支持两种格式的initrd,一种是前面第3部分介绍的linux2.4内核那种传统格式的文件系统镜像-image-initrd,它的制作方法同Linux2.4内核的initrd一样,其核心文件就是/linuxrc。另外一种格式的initrd 是cpio格式的,这种格式的initrd从 linux2.5 起开始引入,使用cpio工具生成,其核心文件不再是/linuxrc,而是/init,本文将这种initrd称为cpio-initrd。

   尽管linux2.6内核对cpio-initrd和image-initrd这两种格式的initrd均支持,但对其处理流程有着显著的区别,下面分别介绍linux2.6内核对这两种initrd的处理流程。

   cpio-initrd 的处理流程

   1.boot loader把内核以及initrd文件加载到内存的特定位置。

   2.内核判断initrd的文件格式,如果是cpio格式。

   3.将initrd的内容释放到rootfs中。

   4.执行initrd中的/init文件,执行到这一点,内核的工作全部结束,完全交给/init文件处理。

   image-initrd的处理流程

   1.boot loader把内核以及initrd文件加载到内存的特定位置。

   2.内核判断initrd的文件格式,如果不是cpio格式,将其作为image-initrd处理。

   3.内核将initrd的内容保存在rootfs下的/initrd.image文件中。

   4.内核将/initrd.image的内容读入/dev/ram0设备中,也就是读入了一个内存盘中。

   5.接着内核以可读写的方式把/dev/ram0设备挂载为原始的根文件系统。

   6..如果/dev/ram0被指定为真正的根文件系统,那么内核跳至最后一步正常启动。

   7.执行initrd上的/linuxrc文件,linuxrc通常是一个脚本文件,负责加载内核访问根文件系统必须的驱动,以及加载根文件系统。

   8./linuxrc执行完毕,常规根文件系统被挂载

   9.如果常规根文件系统存在/initrd目录,那么/dev/ram0将从/移动到/initrd。否则如果/initrd目录不存在,/dev/ram0将被卸载。

   10.在常规根文件系统上进行正常启动过程 ,执行/sbin/init。

通过上面的流程介绍可知,Linux2.6内核对image-initrd的处理流程同linux2.4内核相比并没有显著的变化,cpio-initrd的处理流程相比于image-initrd的处理流程却有很大的区别,流程非常简单。



Linux发行版内核更新步骤

   (1)进入内核目录,执行清理工作:make distclean(对于全新的内核,此步可以省略)。

   (2)复制参考配置文件到内核目录下的.config。

   (3)使.config生效:make menuconfig。

   (4)编译内核镜像:make bzImage。

   (5)编译内核模块:make modules。

   (6)安装内核模块:make modules_install。

   (7)制作initrd:RHEL、fedoral等使用mkinitrd,Ubuntu、Debian等使用mkinitramfs。

   (8)复制initrd和内核镜像bzImage到/boot。

   (9)修改grub配置文档,添加新的启动项。

   (10)然后重启系统,进入grub选择从新的内核启动。



grub配置文件说明

   (1)default行,是指grub启动时默认菜单项。0表示第一项,如果是多系统可以修改此选项改变默认光标停留位置。

   (2)timeout行,是指在菜单到自动启动系统前的停留时间,单位时间为sec,可以按需分配。

   (3)splashimage行,指定启动菜单的背景图标,图片格式应该是xpm。

   (4)hiddenmenu行,用于启动时隐藏菜单,除非在 timeout 之前按下 Esc键才能看到菜单。

   (5)password行,用于定义进入 GRUB 命令模式的密码。你还可以为每个操作系统都定义一个密码,方法是把 password 命令放在 title行之后。

   第25~28行为linux类,其一般格式如下。

1
2
3
4
title (......)
root (hd[0-n],x)
kernel (......)
initrd (......)

   title行,指定一个启动操作系统名称。

   root行,指定相应内核镜像所在目录/boot所在的磁盘分区,hd[0-n]表示的是第几个硬盘,x则表示的是[第几个分区-1]。

   kernel行,指定Linux的内核镜像所在路径。

   initrd行,指定Linux的initial ramdisk所在路径。




本文转自infohacker 51CTO博客,原文链接:http://blog.51cto.com/liucw/1201947
相关文章
|
15天前
|
算法 Linux 调度
深入理解Linux内核调度器:从基础到优化####
本文旨在通过剖析Linux操作系统的心脏——内核调度器,为读者揭开其高效管理CPU资源的神秘面纱。不同于传统的摘要概述,本文将直接以一段精简代码片段作为引子,展示一个简化版的任务调度逻辑,随后逐步深入,详细探讨Linux内核调度器的工作原理、关键数据结构、调度算法演变以及性能调优策略,旨在为开发者与系统管理员提供一份实用的技术指南。 ####
54 4
|
15天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
45 2
|
4天前
|
缓存 网络协议 Linux
深入探索Linux操作系统的内核优化策略####
本文旨在探讨Linux操作系统内核的优化方法,通过分析当前主流的几种内核优化技术,结合具体案例,阐述如何有效提升系统性能与稳定性。文章首先概述了Linux内核的基本结构,随后详细解析了内核优化的必要性及常用手段,包括编译优化、内核参数调整、内存管理优化等,最后通过实例展示了这些优化技巧在实际场景中的应用效果,为读者提供了一套实用的Linux内核优化指南。 ####
16 1
|
9天前
|
算法 Linux 开发者
Linux内核中的锁机制:保障并发控制的艺术####
本文深入探讨了Linux操作系统内核中实现的多种锁机制,包括自旋锁、互斥锁、读写锁等,旨在揭示这些同步原语如何高效地解决资源竞争问题,保证系统的稳定性和性能。通过分析不同锁机制的工作原理及应用场景,本文为开发者提供了在高并发环境下进行有效并发控制的实用指南。 ####
|
16天前
|
缓存 负载均衡 Linux
深入理解Linux内核调度器
本文探讨了Linux操作系统核心组件之一——内核调度器的工作原理和设计哲学。不同于常规的技术文章,本摘要旨在提供一种全新的视角来审视Linux内核的调度机制,通过分析其对系统性能的影响以及在多核处理器环境下的表现,揭示调度器如何平衡公平性和效率。文章进一步讨论了完全公平调度器(CFS)的设计细节,包括它如何处理不同优先级的任务、如何进行负载均衡以及它是如何适应现代多核架构的挑战。此外,本文还简要概述了Linux调度器的未来发展方向,包括对实时任务支持的改进和对异构计算环境的适应性。
37 6
|
17天前
|
缓存 运维 网络协议
深入Linux内核架构:操作系统的核心奥秘
深入Linux内核架构:操作系统的核心奥秘
36 2
|
2月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
70 0
|
2月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
57 0
|
2月前
|
存储 Java C++
Collection-PriorityQueue源码解析
Collection-PriorityQueue源码解析
62 0
|
2月前
|
安全 Java 程序员
Collection-Stack&Queue源码解析
Collection-Stack&Queue源码解析
85 0