http://www.ibm.com/developerworks/cn/linux/l-initrd.html

一、从哪里到哪里

本文旨在描述linux中内核如何调用启动,然后如何从img的文件系统切换到硬盘的过程。

描述起于:linux-2.6.11/init/main.c中函数 static int init(void * unused)

描述止于:/etc/rc.d/rc.sysinit文件的被调用

二、描写流程

在linux代码linux-2.6.11/init/main.c中init这个函数被调用时,初始启动的文件

系统镜像:/boot/initrd-2.6.11.12.img(以2.6.11.12内核为例)已被grub加载到

内存中,并已挂载到根目录上("/")。

1、我们先来看看initrd-2.6.11.12.img到底是个什么东西:

[root@wj-server1 tmp]# cd /tmp

[root@wj-server1 tmp]# cp /boot/initrd-2.6.11.12.img /tmp/initrd-2.6.11.12.gz

[root@wj-server1 tmp]# gunzip initrd-2.6.11.12.gz

解压缩后的文件为:

[root@wj-server1 tmp]# ls -l initrd-2.6.11.12

-rw-r--r-- 1 root root 846848 7月 31 17:01 initrd-2.6.11.12

是一个CPIO格式的文件,该文件格式是种文件镜像让我们将它解开到一个目录中看看

其中的具体内容:

[root@wj-server1 tmp]# mkdir initrd

[root@wj-server1 tmp]# cd initrd

[root@wj-server1 initrd]# cpio -i < ../initrd-2.6.11.12

1654 blocks

[root@wj-server1 initrd]# ls

bin bootsplash dev etc init lib loopfs proc sbin sys sysroot

[root@wj-server1 initrd]# find .

.

./lib

./bin

./bin/nash

./bin/insmod

./bin/modprobe

./bin/hotplug

./etc

./dev

./dev/console

./dev/null

./dev/ram

./dev/systty

./dev/tty1

./dev/tty2

./dev/tty3

./dev/tty4

./loopfs

./proc

./sys

./sysroot

./sbin

./init

./bootsplash

可见该镜像文件目录中包括:

/bin 目录下的四个用于启动和切换到硬盘上的程序:

nash(用于处理根目录下的/init脚本)、insmod和modprobe来加载内核驱动、hotplug用

于外设的拔插处理。

/dev 目录下的八个设备文件

/init 是个nash的启动脚本文件

/bootsplash 是内核打了bootsplash补丁后,会在对该文件进行读取操作,然后将该文件

中包含的图片文件在启动时显示。

[root@wj-server1 initrd]# dmesg | grep -i bootsplash

bootsplash 3.1.6-2004/03/31: looking for picture... silentjpeg size 36270 bytes,

...found (1024x768, 19600 bytes, v3).

内核的这个装载信息就是在处理该文件。(具体的bootsplash的使用和创建这里不细说)。

附:CPIO文件的打包

[root@wj-server1 initrd]# cd /tmp/initrd

[root@wj-server1 initrd]# rm ../initrd-2.6.11.12

[root@wj-server1 initrd]# find . | cpio -c -o > ../initrd-2.6.11.12

1654 blocks

[root@wj-server1 initrd]# gzip ../initrd-2.6.11.12

[root@wj-server1 initrd]# mv ../initrd-2.6.11.12.gz ../initrd-2.6.11.12.img

2、回到内核init函数中,看看如何调用/boot/initrd-2.6.11.12.img中/init脚本的

....

// 这里判断在grub装载的/boot/initrd-2.6.11.12.img中是否有"/init"这个文件?

if (sys_access((const char __user *) "/init", 0) == 0)

execute_command = "/init"

else

....

// 如果有"/init"这个文件就先运行它。

if (execute_command)

run_init_process(execute_command);

run_init_process("/sbin/init");

run_init_process("/etc/init");

run_init_process("/bin/init");

run_init_process("/bin/sh");

panic("No init found. Try passing init= option to kernel");

由代码我们看到kernel会先判断并运行/boot/initrd-2.6.11.12.img中的/init文件,我们

来看看该/boot/initrd-2.6.11.12.img/init文件的内容,我们上面已将该文件展开到目录

/tmp/initrd中:

[root@wj-server1 initrd]# cat ./init

#!/bin/nash # 该文件是个nash的脚本文件

# 挂接proc文件系统

mount -t proc /proc /proc

# 不输出nash调试信息,由/proc/cmdline决定,cat /proc/cmdline我的启动参数

# 输出ro root=/dev/hda3 vga=791 splash=silent,如果该命令行中带了quiet参

# 数,则不输出nash提示信息。

setquiet

# 提示信息(这里提示因该放到上面去,mkinitrd-4.2.17-2mgc.rpm包中原来如是,

# 笔误?为什么这里牵涉到mkinitrd这个包类?因为:/boot/initrd-2.6.11.12.img

# 文件由下面命令生成:mkinitrd /boot/initrd-2.6.11.12.img 2.6.11.12)

echo Mounted /proc filesystem

# 挂接sys文件系统

echo Mounting sysfs

mount -t sysfs /sys /sys

# 创建/dev临时目录

echo Creating /dev

mount -o mode=0755 -t tmpfs /dev /dev

# 创建设备文件(这些设备文件在切换到硬盘后,由/etc/rc.sysinit中start_udev

# 重新创建)

mknod /dev/console c 5 1

mknod /dev/null c 1 3

mknod /dev/zero c 1 5

# 新建伪终端目录

mkdir /dev/pts

# 新建共享内存目录

mkdir /dev/shm

# 这里是调用的nash中的makedevs指令装载硬盘等块设备,不装载其他设备只装载

# 硬盘等块设备

echo Starting udev

# 告诉内核当发现新拔插设备时用"/sbin/hotplug"程序来处理

echo -n "/sbin/hotplug" > /proc/sys/kernel/hotplug

makedevs

makedevs # 这里多搞一次没必要

echo Creating root device

# 由grub启动命令行root=/dev/hda3来联接设备/dev/root到root变量所指定的启动

# 设备,见下面我的grub启动参数:

# kernel /boot/vmlinuz-2.6.11.12 ro root=/dev/hda3 vga=791 splash=silent

mkrootdev /dev/root

# 挂接/dev/root目录

echo Mounting root filesystem

mount -o defaults --ro -t ext3 /dev/root /sysroot

echo Switching to new root

# 切换根目录到设备/dev/root目录,运行完该命令根目录"/"->"/dev/hda3"

switchroot --movedev /sysroot

由上面的注释我们大概能够明白./init脚本的基本运行流程:

a、装载基本的内核系统文件和设备文件

b、根据grub的启动命令行参数,判断root根文件设备,参看/boot/grub/grub.conf文件中制定

的参数,该参数在内核启动后可有cat /proc/cmdline显示出来,nash和其他的一些程序也是通

过读该系统文件来去内核启动参数的。

c、在将从grub启动参数中获得根设备并将其与/dev/root设备联接以后,通过nash的switchroot

指令将/dev/root设备挂接到根目录上("/")

看看这样操作后,留下的痕迹:

[root@wj-server1 initrd]# ls -l /dev/root

lrwxrwxrwx 1 root root 9 7月 31 12:06 /dev/root -> /dev/hda3

[root@wj-server1 initrd]# mount

/dev/hda3 on / type ext3 (rw)

到此为止,已将硬盘设备装载到根目录下了,从而取代了原来有initrd.img文件的根位置。

3、再回头看看内核中main.c中init函数,看看如何调用/sbin/init处理/etc/inittab文件

....

// 如果有"/init"这个文件就先运行它。

if (execute_command)

run_init_process(execute_command);

run_init_process("/sbin/init");

run_init_process("/etc/init");

run_init_process("/bin/init");

run_init_process("/bin/sh");

panic("No init found. Try passing init= option to kernel");

我们已经运行完run_init_process(execute_command);这里了,然后继续运行:

run_init_process("/sbin/init");

run_init_process("/etc/init");

run_init_process("/bin/init");

run_init_process("/bin/sh");

/sbin/init这个文件在SysVinit-2.85-34mgc.rpm这个包中,该程序的主要处理代码在文件:

sysvinit-2.85/src/init.c中,该文件主要查找和处理/etc/inittab文件,按照该文件的内容

依次做处理。

[root@wj-server1 initrd]# cat /etc/inittab

#

# inittab This file describes how the INIT process should set up

# the system in a certain run-level.

#

# Author: Miquel van Smoorenburg, # Modified for RHS Linux by Marc Ewing and Donnie Barnes

#

# Default runlevel. The runlevels used by RHS are:

# 0 - halt (Do NOT set initdefault to this)

# 1 - Single user mode

# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)

# 3 - Full multiuser mode

# 4 - unused

# 5 - X11

# 6 - reboot (Do NOT set initdefault to this)

#

id:5:initdefault: # /sbin/init 根据这里判断启动的级别

# System initialization.

si::sysinit:/etc/rc.d/rc.sysinit # /sbin/init 会最先运行这个系统配置文件

l0:0:wait:/etc/rc.d/rc 0 # /sbin/init 根据上面取得的级别运行相应

l1:1:wait:/etc/rc.d/rc 1 # 目录下的启动脚本

l2:2:wait:/etc/rc.d/rc 2

l3:3:wait:/etc/rc.d/rc 3

l4:4:wait:/etc/rc.d/rc 4

l5:5:wait:/etc/rc.d/rc 5

l6:6:wait:/etc/rc.d/rc 6

# Trap CTRL-ALT-DELETE

ca::ctrlaltdel:/sbin/shutdown -t3 -r now # 设置关机热键

# When our UPS tells us power has failed, assume we have a few minutes

# of power left. Schedule a shutdown for 2 minutes from now.

# This does, of course, assume you have powerd installed and your

# UPS connected and working correctly.

pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"

# If power was restored before the shutdown kicked in, cancel it.

pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"

# Run gettys in standard runlevels

1:2345:respawn:/sbin/mingetty tty1 # 建立6个登陆控制终端可以通过CTRL-ALT-F?

2:2345:respawn:/sbin/mingetty tty2 # 切换,'?'表示第几个登陆控制台,比如第1

3:2345:respawn:/sbin/mingetty tty3 # 个为F1,第2个为F2依次类推。F7为X11控制

4:2345:respawn:/sbin/mingetty tty4 # 台,后面就没有了,所以在X下可以很灵活

5:2345:respawn:/sbin/mingetty tty5 # 的切换到控制台下面操作。

6:2345:respawn:/sbin/mingetty tty6

# Run xdm in runlevel 5

x:5:once:/etc/X11/prefdm -nodaemon

通过内核中对/sbin/init的调用现在已经执行/etc/rc.d/rc.sysinit操作了。

阅读(897) | 评论(0) | 转发(0) |

linux img 内核启动,linux的启动流程(initrd.img)相关推荐

  1. linux 驱动 内核模式,Linux内核模块和驱动的编写

    Linux内核是一个整体是结构,因此向内核添加任何东西,或者删除某些功能,都十分困难.为了解决这个问题引入了内核机制.从而可以动态的想内核中添加或者删除模块. 模块不被编译在内核中,因而控制了内核的大 ...

  2. linux追加内核参数,Linux设置内核参数的方法

    1 内核参数的查看方法 使用"sysctl -a"命令可以查看所有正在使用的内核参数.内核参数比较多(一般多达500项),按照前缀主要分为以下几大类:net.ipv4.net.ip ...

  3. linux pae内核安装,Linux 安装PAE内核

    客户软件是部署在32位的CentOS5服务器当中,CentOS5目前只能识别4G内存,需要安装PAE内核,让系统支持PAE物理地址扩展. 1.安装PAE内核 yum -y install kernel ...

  4. linux升级内核ivh,Linux内核升级

    当前的系统版本为rhel7.2,内核版本为"Linux 3.10.0-327.el7.x86_64" [root@rhel7_2 ~]# hostnamectl Static ho ...

  5. linux禁止内核抢占,Linux内核态抢占机制分析

    [51CTO晃荡]8.26 带你深度懂得清华大年夜学.搜狗基于算法的IT运维实践与摸索 本文起首介绍非抢占式内核(Non-Preemptive Kernel)和可抢占式内核(Preemptive Ke ...

  6. linux的内核设计,Linux内核设计的艺术 清晰完整版PDF+配套源码

    <Linux内核设计的艺术:图解Linux操作系统架构设计与实现原理>内容提要: 关于Linux内核的书已经不计其数,但这本书却是独树一帜的,它的内容代表着Linux内核研究成果的世界顶尖 ...

  7. linux ipv6内核编译,linux ipv6内核设置

    linux ipv6内核设置,进入/proc/sys/net/ipv6: conf/all/forwarding Type: BOOLEAN 在两个接口之间进行global IPv6 forwardi ...

  8. Linux 进内核,arm linux 启动流程之 进入内核

    原标题:arm linux 启动流程之 进入内核 还是从编译链接生成vm 的过程来看吧,由一大堆.o文件链接而成,第一个就是 kernel/arch//kernel/head-armv.o ,而且我们 ...

  9. linux内核删不掉,linux 删除内核文件,未能启动,修复方法 CDROM与网络法

    当缺少 /boot 内核文件 vmlinuz-2-. initramfs-2- 此时只能借助 光盘 CDROM 来引导生成 进入  RESCUE 模式 1    chroot        /mnt/ ...

  10. linux中内核4c,Linux内核编译

    年纪大了,记性不好,这篇文档作为自学笔记,也算是积累,给自己一个交待. Linux内核编译的大致流程如下: 一.获取内核代码:编译内核代码之前一定要获取到内核代码,到http://www.kernel ...

最新文章

  1. Linear and Discrete Optimization - Week 1
  2. Windows 10 太难用,如何定制你的 Ubuntu?
  3. mysql 在存储过程出现的问题,记录一下
  4. Xamarin iOS教程之申请付费开发者账号下载证书
  5. Linux基本命令 -- grep参数说明及常用用法
  6. Flink – SlotSharingGroup
  7. Confluence 6 配置 workbox 通知
  8. php脚本语法格式,[PHP学习笔记][五]PHP基本语法规则
  9. Java虚拟机工作原理详解 (一)
  10. java1.6安装_JAVAjdk1.6安装方法
  11. AutoCAD 二次开发之 ObjectARX 环境搭建
  12. springboot+爱心捐赠小程序 毕业设计-附源码211711
  13. qiankun 出现[import-html-entry]: error occurs while executing normal script
  14. 多御浏览器安卓版有哪些地方值得下载使用?
  15. Adaboost 算法的公式推导与讲解
  16. AMD将推出7纳米GPU Vega,专为深度学习和机器学习打造
  17. matlab矩阵分块与把分块矩阵还原
  18. 服务器同步备份到本地文件,私有云服务器同步本地文件
  19. GIS的polygon和multipolygon
  20. MACD指标5种背离分析(图解)

热门文章

  1. 在c语言中卖水果的程序,非常难的C语言问题!!!(悬赏80)
  2. php 登陆 sql语句,PHP 连接MySQL数据库的SQL语句的简单示例
  3. mysql中的运算符的执行顺序_【MySQL】执行顺序
  4. html给span标签设置index,html – 绝对定位嵌套元素的z-index
  5. Master of GCD(差分数组||线段树)
  6. 1. 两数之和(Java)
  7. 【计算机组成原理】逻辑运算
  8. linux7启动某个服务器,如何在单用户模式下启动RHEL 7 CentOS 7服务器
  9. 汉字笔画数据_把所有汉字叠起来会怎样?
  10. CentOS 6.5 安装配置Tomcat7服务器