initrd的全名是 init ramdisk,是一个启动时存在于内存的文件系统。

kernal 到 initrd的流程

GRUB加载kernel时,kernel会先在内存中制造一个rootfs当做临时的空间供系统使用,接下来,kernel便会将initrd当做是一个系统,将其mount到rootfs上启动。

引入initrd的目的是为了把kernel的启动分成两个阶段:在kernel中保留最少最基本的启动代码,然后把对各种各样硬件设备的支持以模块的方式放在initrd中,这样就在启动过程中可以从initrd所mount的根文件系统中装载需要的模块。这样的一个好处就是在保持kernel不变的情况下,通过修改initrd中的内容就可以灵活的支持不同的硬件。在启动完成的最后阶段,根文件系统可以重新mount到其他设备上。

initrd文件结构

initrd文件在/boot目录中很容易找到,可以通过以下命令将期解压

## 将文件移至对应目录

cp initrd.img-xxxx-generic  ~/initrd/initrd.img.gz

## 老版本

gunzip initrd.img.gz
cpio -idmv < ../initrd.img ## 新版本 lsinitramfs /boot/initrd.img-xxx-generic (可以通过些命令查询其文件)
binwalk -y gzip initrd.img.gz (定位压缩文件的开始偏移量) ## 6938624 即是通过binwalk定位出来的值
dd if=initrd.img.gz bs=6938624 skip=1 | zcat | cpio -id --no-absolute-filenames -v ## 使用ls查看目录
bin conf etc init lib lib64 run sbin scripts usr var

经解压发现initrd就是最简单的一个文件系统,唯一不同的是存在一个init脚本。

export PATH=/sbin:/usr/sbin:/bin:/usr/bin
[ -d /dev ] || mkdir -m 0755 /dev
[ -d /root ] || mkdir -m 0700 /root
[ -d /sys ] || mkdir /sys
[ -d /proc ] || mkdir /proc
[ -d /tmp ] || mkdir /tmp
mkdir -p /var/lock
mount -t sysfs -o nodev,noexec,nosuid sysfs /sys
mount -t proc -o nodev,noexec,nosuid proc /proc

在init文件中要执行的第一件事情,就是创建几个重要的目录。其中/sys,/proc作为kernel使用的主要目录,init必须将其挂载。

  • /proc 这目录其实是加载kernel后,在内存里面建立的一个虚拟目录,主要提供系统运行的实时信息

  • /proc/PID 这目录表示,系统一进程运行时信息

  • /proc/paritions 表示系统检测到的硬盘分区情况,其使用major和mintor 两字段来标识唯一

  • /sys/block

  • /sys/bus

在收集完设备信息后,就要开始玩设备文件了

mount -t devtmpfs -o nosuid,mode=0755 udev /dev
mkdir /dev/pts
mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts || true
  • /dev  是以tmpfs的文件系统存放的devfs系统架构的文件
  • tmpfs 内存中的文件系统
  • devfs 将所有的设备信息以文件的方式存储
  • udev 补充devfs的问题,udev 会自动从/sys目录找到所需要的硬盘信息装置。
  • /dev/pts 主机虚拟终端,当ssh连接进来后,就出来一文件

在initrd建立好相关的文件系统配置后,就要开始转移到实体操作系统

  1. 建立默认使用的设备文件
  2. 加载moule
  3. 建立系统使用目录 并 /proc, /sys /dev 转移过去

initrd最后工作就是要通过init脚本文件,将所有一切交给存在硬盘中的实体操作系统。

exec run-init ${drop_caps} ${rootmnt} ${init} "$@" ${recovery:+--startup-event=recovery} <${rootmnt}/dev/console >${rootmnt}/dev/console 2>&1

重新调用/sbin/init来开始后续的正常启动流程.当然也可以 内核启动参数 init={所要执行的程序}来替换

init启动流程

说白init进程就是内核自动启动第一个用户级程序,所以其进程编号始终为1。

1. 以initdefault值判断系统以那level运行

0 - 停机(千万不能把initdefault 设置为0 )

       1 - 单用户模式

       2 - 多用户,没有 NFS

       3 - 完全多用户模式(标准的运行级)

4 - 没有用到

       5 - X11 (xwindow)

       6 - 重新启动 (千万不要把initdefault 设置为6 )

2. 执行/etc/rc.d/rc.sysinit

其过程相当很杂,大部份和系统环境相关

3. 执行/etc/rc.d/rcX.d

X 表示其运行级别,我们以3为例

  1. 里面有好多文件都以"S" 或 “K” 开头,"S" 为可会执行的脚本,“K”是死的。
  2. “SK”后面跟着数字,即脚本执行的顺序
  3. 通过改名字就可以调整服务
  4. 其中S99local连接到/etc/rc.d/rc.local专门给用户使用

4. 通过登录程序进入shell

initab的最后阶段扫运行minttyt程序,让用户输入密码登录,进行shell

initrd&init进程的更多相关文章

  1. 使用gdb跟踪Linux内核启动过程(从start_kernel到init进程启动)

    本次实验过程如下: 1. 运行MenuOS系统 在实验楼的虚拟机环境里,打击打开shell,使用下面的命令 cd LinuxKernel/ qemu -kernel linux-/arch/x86/b ...

  2. 实验三:gdb跟踪调试内核从start_kernel到init进程启动

    原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 如果我写的不好或者有误的地方请留言 ...

  3. Linux内核分析-使用gdb跟踪调试内核从start_kernel到init进程启动

    姓名:江军 ID:fuchen1994 实验日期:2016.3.13 实验指导 使用实验楼的虚拟机打开shell cd LinuxKernel/ qemu -kernel linux-3.18.6/a ...

  4. 构建一个简单的Linux系统 MenuOs —— start_kernel到init进程(20135304刘世鹏)

    构建一个简单的Linux系统 MenuOs —— start_kernel到init进程 作者:刘世鹏20135304 <Linux内核分析>MOOC课程http://mooc.study ...

  5. Linux---从start_kernel到init进程启动

    “平安的祝福 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” ini ...

  6. Linux init进程详解

    init模块 一般来说,Linux程序只能用另一个Linux程序启动.例如,登录Linux终端程序Mingetty. 但终端程序又由谁启动呢?在计算机上启动Linux时,内核装入并启动init程序. ...

  7. imx6 启动 init进程

    之前不知道imx6内核是怎么启动文件系统的init进程,查了下资料,记录于此,以后再来补充. kernel/init/main.c static noinline int init_post(void ...

  8. Android init进程概述

    init进程,其程序位于根文件系统中,在kernle自行启动后,其中的 start_kernel 函数把根文件系统挂载到/目录后,在 rest_init 函数中通过 kernel_thread(ker ...

  9. init进程解析rc文件的相关函数分析

    init进程的源码文件位于system/core/init,其中解析rc文件语法的代码放在五个函数中, init_parse_config_file (init_parser.c), read_fil ...

  10. init进程学习

    linux的init进程 一个在线编辑markdown文档的编辑器,是内核启动的第一个进程,init进程有很多重要的任务,它的pit 为1,在linux shell中使用pstree命令可以看到它为其 ...

随机推荐

  1. Windows系统解决VSCode终端无法输入问题

    最近重装了电脑系统(将原来的Win7装成Win10),重新安装了VSCode和git,也在VSCode里配置了git环境,但是在VSCode中的终端总是不显示.现记录下解决办法: 解决方法: 1.右键 ...

  2. android常用布局基础学习

    总结:可水平放置可垂直放置也可穿插使用,默认为水平 <!--我在第一次使用权重的时候忽视了本线性布局中的宽度与高度,如果要使用权重,请将线性布局的最初大小设置为match_parent,否则不会 ...

  3. 基于 SASL/SCRAM 让 Kafka 实现动态授权认证

    一.说明 在大数据处理和分析中 Apache Kafka 已经成为了一个核心组件.然而在生产环境中部署 Kafka 时,安全性是一个必须要考虑的重要因素.SASL(简单认证与安全层)和 SCRAM(基 ...

  4. RHCA rh442 001 调优本质 调优方法 监控

    调优是一种感知 调优按照成本和性能 一.架构及调优 二.代码及调优 三.配置类调优 从调优效果和成本成正比 设计电商,日访问百万级,未来可能千万级 数据库 系统 服务器多少台 缓存 appache,n ...

  5. 【Excel】VBA编程 01 入门

    视频地址: https://www.bilibili.com/video/BV1Q5411p71p 在Excel种需要打开[开发工具]和[启用所有宏]两点 打开开发工具选项 宏启用 菜单栏才会有开发工 ...

  6. 制约国产深度学习框架发展的根本原因 —— AI芯片的无法自主生产或量产

    秉着没事就胡言乱语的宗旨,这里在接着胡说八道一下. 国外的深度学习框架如TensorFlow.pytorch.Jax打的如火如荼,按照以往惯例我们是不应该去做自主研发软件系统的,毕竟硬件不在掌握之下, ...

  7. 【转载】 浅谈PyTorch的可重复性问题(如何使实验结果可复现)

    原文地址: https://www.zhangshengrong.com/p/9MNlDK09NJ/ ================================================ ...

  8. baselines算法库common/wrapper.py模块分析

    common/wrapper.py模块: import gym class TimeLimit(gym.Wrapper): def __init__(self, env, max_episode_st ...

  9. 神经网络之卷积篇:详解边缘检测示例(Edge detection example)

    详解边缘检测示例 卷积运算是卷积神经网络最基本的组成部分,使用边缘检测作为入门样例.在这个博客中,会看到卷积是如何进行运算的. 在之前的博客中,说过神经网络的前几层是如何检测边缘的,然后,后面的层有可 ...

  10. .NET 8 + Blazor 多租户、模块化、DDD框架、开箱即用

    前言 基于 .NET 8 的开源项目,主要使用 WebAPI + Blazor 支持多租户和模块化设计,DDD构建.可以帮助我们轻松地搭建起一个功能完善的Web应用程序.除了帮助你快速构建应用程序之外 ...