am57xx_env根文件加载过程
1. /etc/inittab
# The default runlevel.
id:5:initdefault: /*默认启动级别为5*/
si::sysinit:/etc/init.d/rcS
# What to do in single-user mode.
~~:S:wait:/sbin/sulogin
# /etc/init.d executes the S and K scripts upon change of runlevel.
# Runlevel 0 is halt;Runlevel 1 is single-user;Runlevels 2-5 are multi-user;Runlevel 6 is reboot.
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
# Normally not reached, but fallthrough in case of emergency.
z6:6:respawn:/sbin/sulogin
O2:12345:respawn:/sbin/getty -L 115200 ttyO2
1:12345:respawn:/sbin/getty 38400 tty1
总结:在etc目录中目录rc0.d、rc1.d、rc2.d、rc3.d、rc4.d、rc5.d、rc6.d、rcS.d表示不同运行等级,其中只是链接文件,实际指向目录/etc/init.d中文件;不同级别对应不同目录,运行了不同个数的脚本。
2. /etc/init.d/rcS
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
# Make sure proc is mounted
[ -d "/proc/1" ] || mount /proc /*确认proc并挂载*/
. /etc/default/rcS /*为/etc/rcS.d目录中启动脚本设置默认值*/
# Trap CTRL-C &c only in this shell so we can interrupt subprocesses.
trap ":" INT QUIT TSTP
# Call all parts in order.
exec /etc/init.d/rc S /*使用S等级启动服务*/
--- /etc/default/rcS
#Defaults for the boot scripts in /etc/rcS.d
# Time files in /tmp are kept in days.
TMPTIME=0
# Set to yes if you want sulogin to be spawned on bootup
SULOGIN=no
# Set to no if you want to be able to login over telnet/rlogin
# before system startup is complete (as soon as inetd is started)
DELAYLOGIN=no
# Assume that the BIOS clock is set to UTC time (recommended)
UTC=yes /*使用BIOS时钟设置UTC时间*/
# Set VERBOSE to "no" if you would like a more quiet bootup.
VERBOSE=no /*设置VERBOSE为no,可以更加简便的启动*/
# Set EDITMOTD to "no" if you don't want /etc/motd to be edited automatically
EDITMOTD=no
# Whether to fsck root on boot
ENABLE_ROOTFS_FSCK=no
# Set FSCKFIX to "yes" if you want to add "-y" to the fsck at startup.
FSCKFIX=yes
# Set TICKADJ to the correct tick value for this specific machine
#TICKADJ=10000
# Enable caching in populate-volatile.sh
VOLATILE_ENABLE_CACHE=yes
# Indicate whether the rootfs is intended to be read-only or not.
# Setting ROOTFS_READ_ONLY to yes and rebooting will give you a read-only rootfs.
# Normally you should not change this value.
ROOTFS_READ_ONLY=no
--- /etc/init.d/rc
#!/bin/sh
. /etc/default/rcS
export VERBOSE
{
step=$(($step + $step_change))
if [ "$num_steps" != "0" ]; then
progress=$((($step * $progress_size / $num_steps) + $first_step))
else
progress=$progress_size
fi
if [ -e /mnt/.psplash/psplash_fifo ]; then
echo "PROGRESS $progress" > /mnt/.psplash/psplash_fifo
fi
}
startup()
{
[ "$VERBOSE" = very ] && echo "INIT: Running $@..."
/*以.sh结尾的脚本是必须执行的脚本,不是以.sh结尾的脚本服务是可以开启或关闭的,通过start或stop参数*/
case "$1" in /*传入的第一个参数是要执行的文件名,第二个参数是start*/
*.sh)
(/*若文件名是以.sh结尾的则执行这个脚本*/
trap - INT QUIT TSTP
scriptname=$1
shift
. $scriptname
)
;;
*) /*若不是以.sh结尾的*/
/*实际上rc进程调用的脚本都称为初始化脚本。要启动、停止或者重启一个服务,应该用参数start、stop和restart。*/
"$@" /*执行这个脚本带参数,比如传入的是$@=“/etc/rcS.d/S02banner start”,即带start参数执行这个脚本,这样可以灵活的控制服务的start或者stop*/
;;
esac
startup_progress
}
#忽略这三个信号,防止脚本执行时使用ctrl-C就退出脚本.
trap ":" INT QUIT TSTP
#设置终端,将CR字符映射为NL字符,避免阶梯效应
stty onlcr 0>&1
# Limit stack size for startup scripts
[ "$STACK_SIZE" == "" ] || ulimit -S -s $STACK_SIZE
# Now find out what the current and what the previous runlevel are.
runlevel=$RUNLEVEL
# Get first argument. Set new runlevel to this argument.
[ "$1" != "" ] && runlevel=$1
if [ "$runlevel" = "" ]
then
echo "Usage: $0 <runlevel>" >&2
exit 1
fi
previous=$PREVLEVEL
[ "$previous" = "" ] && previous=N
/*传入参数是S的话,则runlevel=S、previous=N*/
export runlevel previous
/*检查该目录是否为空目录,执行里面的脚本等*/
if [ -d /etc/rc$runlevel.d ]
then
PROGRESS_STATE=0
progress_size=$(((100 - $PROGRESS_STATE) / 3))
case "$runlevel" in
0|6)
first_step=-100
progress_size=100
step_change=1
;;
S)
first_step=$PROGRESS_STATE
progress_size=$(($progress_size * 2))
step_change=1
;;
*)
first_step=$(($progress_size * 2 + $PROGRESS_STATE))
step_change=1
;;
esac
num_steps=0
for s in /etc/rc$runlevel.d/[SK]*; /*取/etc/rcS.d目录下以S或K开头的文件名*/
do
/*去掉变量s中所有的/etc/rcS.d/S?的部分,若s剩下的文件名中为这5个中则跳出for*/
case "${s##/etc/rc$runlevel.d/S??}" in
gdm|xdm|kdm|reboot|halt)
break
;;
esac
num_steps=$(($num_steps + 1))/*表示查找到目录/etc/rcS.d下有多少个脚本*/
done
step=0
/*第一步,运行KILL脚本*/
if [ $previous != N ]
then
for i in /etc/rc$runlevel.d/K[0-9][0-9]*
do
[ ! -f $i ] && continue
startup $i stop /*在本文件中startup()函数*/
done
fi
/*第二步,运行这个级别的START脚本*/
for i in /etc/rc$runlevel.d/S* /*取得S开头的脚本*/
do
[ ! -f $i ] && continue /*检查是否为常规文件,不是则进行下次循环*/
/*如果previous=N/S,则此if语句不执行*/
if [ $previous != N ] && [ $previous != S ]
then
suffix=${i#/etc/rc$runlevel.d/S[0-9][0-9]} /*获得i文件名的后缀*/
stop=/etc/rc$runlevel.d/K[0-9][0-9]$suffix /*获得stop文件名*/
previous_start=/etc/rc$previous.d/S[0-9][0-9]$suffix
/*如果有起始脚本并且灭有停止脚本,则不进行这项服务,continue继续下一次循环*/
[ -f $previous_start ] && [ ! -f $stop ] && continue
fi
case "$runlevel" in
0|6) /*运行级别0或者6*/
startup $i stop
;;
*) /*在本文件中startup()函数,运行名称$i的脚本*/
startup $i start
;;
esac
done
fi
if [ "x$runlevel" != "xS" ] && [ ! -x /etc/rc${runlevel}.d/S??xserver-nodm ]; then
if type psplash-write >/dev/null 2>&1; then
TMPDIR=/mnt/.psplash psplash-write "QUIT" || true
umount -l /mnt/.psplash
fi
fi
3. /etc/init.d/***
3.1 /etc/init.d/alignment.sh
#!/bin/sh
if [ -e /proc/cpu/alignment ]; then
echo "3" > /proc/cpu/alignment
fi
/* 设置Linux对出现字节对齐错误的处理方式:0(忽略),1(提醒警告),2(修复),3(修复+提醒警告),4(信号),5(信号+提醒警告)*/
3.2 /etc/init.d/alsa-state(声音系统)
安装了alsa的驱动,但是每一次开机的时候,声卡总是静音,要进行手工调解。
决定进行改造:
每次重启电脑后,音量设置都复位了,需重新调整音量。经研究,原来是我没有把ALSA声音系统的当前设置状态保存到 /var/lib/alsa/asound.state中。而每次重启电脑时,ALSA系统的初始化脚本(/etc/init.d/alsa)会用 /var/lib/alsa/asound.state这个默认的配置文件来设置ALSA系统的状态。所以就造成用户自已配置的状态失效,每次重启都还原到初始状态。有一个工具叫alsactl,它可自动把当前配置信息保存到/var/lib/alsa/asound.state中。alsactl包含在alsa-utils软件包中。用以下命令安装:
debian:~# apt-get install alsa-utils
把音量、音色等调整好后,保存到/var/lib/alsa/asound.state文件中:
debian:~# alsactl store
重启电脑,马上就可聆听到自由的声音了。
脚本内容:
#! /bin/sh
# source function library
. /etc/init.d/functions
asound_restore(){
echo "ALSA: Restoring mixer settings..."
if test -x /usr/sbin/alsactl -a -e /var/lib/alsa/asound.state
then
/usr/sbin/alsactl -f /var/lib/alsa/asound.state restore &
fi
}
asound_store(){
echo "ALSA: Storing mixer settings..."
if test -x /usr/sbin/alsactl
then
/usr/sbin/alsactl -f /var/lib/alsa/asound.state store
fi
}
case "$1" in
start)asound_restore ;;
stop)asound_store ;;
status)
status /usr/sbin/alsactl;
exit $?
;;
*)
echo "Usage: /etc/init.d/alsa-state {start|stop|status}"
exit 1
;;
esac
3.3 /etc/init.d/functions
该脚本是给/etc/init.d里边的文件使用的。提供了一些基础的功能,看看里边究竟有些什么。首先会设置umask,path,还有语言环境,然后会设置success,failure,warning,normal几种情况下的字体颜色。提供的重要方法:
checkpid:检查是否已存在pid,如果有一个存在,返回0(通过查看/proc目录)
daemon:启动某个服务。/etc/init.d目录部分脚本的start使用到这个
killproc:杀死某个进程。/etc/init.d目录部分脚本的stop使用到这个
pidfileofproc:寻找某个进程的pid
pidofproc:类似上面的,只是还查找了pidof命令
status:返回一个服务的状态
echo_success,echo_failure,echo_passed,echo_warning分别输出各类信息
success,failure,passed,warning分别记录日志并调用相应的方法
action:打印某个信息并执行给定的命令,它会根据命令执行的结果来调用success,failure方法
strstr:判断$1是否含有$2
confirm:显示"Start service $1(Y)es/(N)o/(C)ontinue?[Y]"的提示信息,并返回选择结果
# -*-Shell-script-*-
NORMAL="\\033[0;39m" # Standard console grey
SUCCESS="\\033[1;32m" # Success is green
WARNING="\\033[1;33m" # Warnings are yellow
FAILURE="\\033[1;31m" # Failures are red
INFO="\\033[1;36m" # Information is light cyan
BRACKET="\\033[1;34m" # Brackets are blue
pidofproc () {
# pidof output null when no program is running, so no "2>/dev/null".
pid=`pidof $1`
status=$?
case $status in
0)
echo $pid
return 0
;;
127)
echo "ERROR: command pidof not found" >&2
exit 127
;;
*)
return $status
;;
esac
}
machine_id() { # return the machine ID
awk 'BEGIN { FS=": " } /Hardware/ \
{ gsub(" ", "_", $2); print tolower($2) } ' </proc/cpuinfo
}
killproc() { # kill the named process(es)
pid=`pidofproc $1` && kill $pid
}
status() {