Linux中国 | Linux.cn - 我们的Linux中文社区

 找回密码
 加入

QQ登录

QQ登录

搜索

学习 initrd中的init(四)

热度 6已有 1070 次阅读2010-8-4 11:23 |关键词:initrd 学习 root sed label case escape

# Parse command line options
for x in $(cat /proc/cmdline); do
	case $x in
	init=*)
		init=${x#init=}
		;;
	root=*)
		ROOT=${x#root=}
		case $ROOT in
		LABEL=*)
			ROOT="${ROOT#LABEL=}"

			# support / in LABEL= paths (escape to \x2f)
			case "${ROOT}" in
			*[/]*)
			if [ -x "$(command -v sed)" ]; then
				ROOT="$(echo ${ROOT} | sed 's,/,\\x2f,g')"
			else
				if [ "${ROOT}" != "${ROOT#/}" ]; then
					ROOT="\x2f${ROOT#/}"
				fi
				if [ "${ROOT}" != "${ROOT%/}" ]; then
					ROOT="${ROOT%/}\x2f"
				fi
				IFS='/'
				newroot=
				for s in $ROOT; do
					if [ -z "${newroot}" ]; then
						newroot="${s}"
					else
						newroot="${newroot}\\x2f${s}"
					fi
				done
				unset IFS
				ROOT="${newroot}"
			fi
			esac
			ROOT="/dev/disk/by-label/${ROOT}"
			;;
		UUID=*)
			ROOT="/dev/disk/by-uuid/${ROOT#UUID=}"
			;;
		/dev/nfs)
			[ -z "${BOOT}" ] && BOOT=nfs
			;;
		esac
		;;
	rootflags=*)
		ROOTFLAGS="-o ${x#rootflags=}"
		;;
	rootfstype=*)
		ROOTFSTYPE="${x#rootfstype=}"
		;;
	rootdelay=*)
		ROOTDELAY="${x#rootdelay=}"
		case ${ROOTDELAY} in
		*[![:digit:].]*)
			ROOTDELAY=
			;;
		esac
		;;
	resumedelay=*)
		RESUMEDELAY="${x#resumedelay=}"
		;;
	loop=*)
		LOOP="${x#loop=}"
		;;
	loopflags=*)
		LOOPFLAGS="-o ${x#loopflags=}"
		;;
	loopfstype=*)
		LOOPFSTYPE="${x#loopfstype=}"
		;;
	cryptopts=*)
		cryptopts="${x#cryptopts=}"
		;;
	nfsroot=*)
		NFSROOT="${x#nfsroot=}"
		;;
	netboot=*)
		NETBOOT="${x#netboot=}"
		;;
	ip=*)
		IPOPTS="${x#ip=}"
		;;
	hwaddr=*)
		HWADDR="${x#hwaddr=}"
		;;
	boot=*)
		BOOT=${x#boot=}
		;;
	resume=*)
		RESUME="${x#resume=}"
		;;
	resume_offset=*)
		resume_offset="${x#resume_offset=}"
		;;
	noresume)
		noresume=y
		;;
	panic=*)
		panic="${x#panic=}"
		case ${panic} in
		*[![:digit:].]*)
			panic=
			;;
		esac
		;;
	quiet)
		quiet=y
		;;
	ro)
		readonly=y
		;;
	rw)
		readonly=n
		;;
	debug)
		debug=y
		quiet=n
		exec >/dev/.initramfs/initramfs.debug 2>&1
		set -x
		;;
	debug=*)
		debug=y
		quiet=n
		set -x
		;;
	break=*)
		break=${x#break=}
		;;
	break)
		break=premount
		;;
	blacklist=*)
		blacklist=${x#blacklist=}
		;;
	netconsole=*)
		netconsole=${x#netconsole=}
		;;
	esac
done
  

这段代码主要解析kernel后的参数。先从 /proc/cmdline 里面得到每一个内核参数,并在接下来的case当中进行处理。cat一下你现在的linux系统的 /proc /cmdline 文件,你就会看到当前系统启动时候的参数。

root@alice-desktop:~# cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-2.6.32-21-generic root=UUID=f14c5e87-e505-472d-ba0f-8879a2f705bf ro quiet splash
 init=*  决 定 init 变量的值。在第三篇中已经赋值为"/sbin/init"

root=* 是指定即将要进入的系统的根目录。在其下还有一个case判断,根据参数形式 的不同,对 ROOT 变量赋予不同的字符串。现在常用的 是 root=UUID=x...x-...-xxx 的形式,如 root=UUID=fa96108d-afa0-45a8-ba28- c80d1673d958。不建议使用 root=LABEL=* 的形式,我们可以看一下 /dev/disk/by-label 和 /dev/disk /by-uuid 下面的软链接就知道了,并不是所有的分区都有 label,但是所有的分区都有 uuid。

root@alice-desktop:~# ls /dev/disk
by-id by-label by-path by-uuid
root@alice-desktop:~# ls /dev/disk/by-label
b
root@alice-desktop:~# ls /dev/disk/by-uuid
b6f0bfc1-a2fa-4e45-b487-cd9fca32753b  f14c5e87-e505-472d-ba0f-8879a2f705bf

所 推荐使用 root=UUID=* 的形式。 

rootflags=* 指定将要进入的系统的根目录所在的分区挂载到 ${rootmnt} 目录时的参数,并将参数转化成 mount 命令可识别的形式(就是在前面加了"-o ",具体见 man mount赋予 ROOTFLAGS 变量。  rootfstype=* 指 定将要进入的系统的根目录所在的分区的文件系统的格式(如 vfat, ext3 等),赋予 ROOTFSTYPE 变量。

rootdelay=* 指 定将要进入的系统的根目录所在的分区必须在多少秒之内准备好,其值赋予 ROOTDELAY 变量。以 上 ROOT, ROOTFLAGS, ROOTFSTYPE, ROOTDELAY 以及上面提到的 rootmnt 变量将 在 mountroot 函数(/scripts/local 中定义)中使用,在下文介绍到挂载系统根目录所在分区的时候将详细介绍。  cryptopts=* 不太了解,如有人知道可以评论给我。谢谢

nfsroot=*nfs,ip=*  相关,可以查看nfs相关内容

boot=* 赋予 BOOT 变量相应的值,即在挂载将要进入的系统的根目录所在的分区之前要读取并执行的文件,  resume=*  指明存放 system snapshot image 的分区。

noresume  赋予 NORESUME 变量字符串"y"。若NORESUME 变量不为空,则禁止休眠后的唤醒。若在休眠之后的一次启动使用了 noresume 参数,则在再一次启动的时候,不会有恢复状态的过程,而是像普通的启动一样进入系统。这是因为正常启动系统 swap 分区被重新 activate 的缘故。

panic=*  赋予 panic 变量相应的值,具体见对此脚本第41行 break 变量的解释。

quiet赋予 quiet 变量相应的值,具体见对此脚本第43行 quiet 变量的解 释。

ro, rw不同选项赋予 readoly 变量相应的值,readonly 变量在 mountroot 函数中控制以只读或读写方式挂载分区。

debug   debug 模式。赋予 debug 变量值"y",有些文章说是通过 exec 把当 前 shell 的 stdout 和 stderr 都重定向到了文件 /dev/initramfs.debug,这样平常输出到终端的文字都被输出 到了那个文件。最后,set -x 相当于在 shell 被调用时添加了 -x 参数,每一条命令在执行之前都被输出到了 stderr,并且在前面添 加了一个'+',便于debug。  但是我并没有早到这个文件 /dev/initramfs.debug。不知道为什么。

发表评论 评论 (1 个评论)

回复 fuhualiang 2011-1-14 12:37

facelist

你需要登录后才可以评论 登录 | 加入

无觅相关文章插件