linux img 内核启动,linux的启动流程(initrd.img)
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)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 信用卡逾期一天扣多少?会影响信用吗?
- 下一篇: 徽商银行信用卡怎么还款?还款渠道不同还款