上接《修改设备树文件》一文
现在每次开机都能看到/dev/rtc1了,那么我们还需要一个应用程序来把时间从RTC读取出来更新到系统中,然而通过linux系统自带的一个程序hwclock,我们就可以把RTC的时间更新到系统中来,不需要自己动手省了很多麻烦。当然这个程序需要附带几个参数,其功能如下:
查看rtc1的时间
hwclock -r -f /dev/rtc1
将系统的时间更新到rtc1
hwclock -w -f /dev/rtc1
将rtc1的时间更新到系统
hwclock -s -f /dev/rtc1
到现在我们的目的还没有完全达成,虽然开机后系统能自动把驱动硬件的接口(/devrtc1)外露出来,但是我们总不能每次开机后手动运行hwclock -s -f /dev/rtc1来更新系统时间吧,所以需要学会开机让程序自动运行。第一步,先写一个脚本用来更新时间。
#!/bin/sh ### BEGIN INIT INFO # Provides: RTC.sh # Required-Start: $local_fs $remote_fs $network $syslog # Required-Stop: $local_fs $remote_fs $network $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: date # Description: get correct date information ### END INIT INFO #/etc/init.d/RTC.sh #The following part always gets executed. echo "zy" #The following part carries out specific functions depending on arguments. case "$1" in start) echo "Reading date from /dev/rtc1......" hwclock -s -f /dev/rtc1 echo "Done!" ;; stop) echo "Stopping RTC" ;; *) echo "Usage: /etc/init.d/RTC.sh {start|stop}" exit 1 ;; esac exit 0
01:每一个脚本的第一句特别注释,用于向系统指定运行本脚本的shell
02-10:这是一段专门格式用于给insserv程序识别的LSB信息,通过这些信息insserv可以知道应该把你的脚本安排在一系启动脚本中哪个顺序开始运行。留待后面细说。
12:注解本脚本将要存放的绝对位置
14-15:这个地方不管任何情况此处的语句都会被执行,按需要写自己想要做的事情即可。
17-31:一个case结构,分成了三种情况,如果$1为start,那么做A事,然后跳出case结构;如果$1为stop,那么做B事,然后跳出case结构;如果$1为其他,那么做C事,然后以exit 1退出脚本。此处A事中的hwclock -s -f /dev/rtc1就我是最想做的事情,把RTC1的时间再开机之后更新到系统中。B事就随便写写意思意思。C事是属于报错情况,脚本会以exit 1 退出。此处$1表示运行脚本时跟在后面的第一个参数。留待后面细说。
现在启动脚本写好了,关键是如何让他开机自动运行?
将此脚本复制到/etc/init.d目录下,然后赋予可执行权限755.
通过insserv -v -d/etc/init.d/RTC.sh,搞定!
如果想去掉这个开机自动运行效果,运行insserv -r /etc/init.d/RTC.sh即可。
解释!
linux系统有7个运行级别,每个级别代表了系统不同的运行状态,如下
0 停机
1 单用户模式
2 多用户,没有NFS
3 完全多用户模式
4 保留
5 图形界面
6 重新启动
并非所有的linux系统都是上面这种标准,每个系统也可能随着版本而变化,事实上还可以定义更多的运行级别。在BBB的debian系统上2-5都是多用户运行状态,这个情况可以通过查看/etc/inittab来查看,并且还可以知道开机之后BBB会进入默认的运行级别2。
当我们开机后,系统进入默认运行级别中,如果默认级别设置为2,那么开机之后自动进入字符界面,如果设置为5,开机之后进入图形界面,注意默认级别不能设置为0和6,否则无法启动系统!进入默认级别后我们可以通过init N手动切换到其他的级别,比如想要关机了,可以直接运行init 0,想重启了可以直接运行init 6。但是不建议这种操作,最好还是使用reboot和shutdown来达到目的,因为调用reboot和shutdown后会把一些关机之前的善后工作完成,然后再自动切换到其它运行级别。而我们直接手动切换到0和6,则相当于我们平时直接强制按restart按钮或者直接断电关机。
对于每一个运行级别,/etc/rcN.d/目录下都有一些对应的链接文件,这些链接都指向了/etc/init.d目录中的脚本或者可执行文件。也许这种组织方式更方便些吧。而这些链接文件都有一个特定的顺序,因为系统进入一个特定的运行级别后都要按照特定顺序来完成一系列事情。顺序由这些链接文件名字的第二个和第三个数字(两位数字的范围是01-99)来决定,而做什么事情由/etv/init.d下的脚本和可执行文件决定。在/etc/rcN.d/目录下文件以K开头的表示kill,运行这个链接文件指向的脚本时后面会跟上一个stop参数,于是$1就成了stop;以S开头的文件表示start,运行这个链接文件指向的脚本时后面会跟上一个start参数,于是$1就成了start.
内核初始化完成后,会有一个初始进程init,这个进程会根据/etc/inittab中的设置进入默认运行级别2,然后根据/etc/rc2.d中的链接文件顺序来执行链接指向的脚本,而我们已经把前面写好的脚本放在了/etc/init.d目录下,并且赋予了可执行权限,那么现在还需要/etc/rcN.d目录下的一个链接文件来指向我们写好的脚本,而这个链接文件的顺序则是一个问题,因为我们无法手动安排这个顺序,想要在进入运行级别2的时候就运行这个脚本不是简简单单的在rc2.d下加一个链接文件就可以搞定的事情,这就需要用到insserv这个工具。
insserv是debian中专门用于管理不同运行级别中启动脚本运行顺序的一个工具,查看工具的帮助信息运行insserv -h。
insserv在对你的链接文件进行排序的时候,正是根据你的LSB信息来决定的。
# Required-Start:表示在本服务启动之前需要已经启动的服务
# Required-Stop:表示本服务必须可以在列出的服务关闭之前关闭
这个逻辑关系向insserv表明了自己希望放在哪个顺序,注意Required-Start和Required-Stop后面的变量必须来自
于/etc/insserv.conf文件中,不能自己随便定义变量。
Default-Start和Default-Stop表示你希望在哪些级别中以参数start运行,在哪些级别中以参数stop运行,比如你想在进入级别2-5之后都打开某个服务,但是关机之前又记得把这个服务关闭,那么insserv会先根据你的Required-Start和Required-Stop决定出你的顺序,然后再rc2.d-rc5.d这几个文件夹中放置同样以S开头的链接文件指向你的脚本,同时在rc0.d中放置一个以K开头的链接文件指向你的脚本,如此一来,只要你的启动脚本中的case结构针对start参数做出开启服务的动作,针对stop参数做出关闭服务的动作,就可以实现你的目的了。
insserv -v -d /etc/init.d/RTC.sh
加上-v,那么运行这个命令后,程序会告诉你他在哪些rcN.d目录下放置了以S开头的链接文件,在哪些rcN.d目
录下放置了以K开头的链接文件。
加上-d表示在运行级别上依据LSB中的默认信息Default-Start和Default-Stop来决定。
root@beaglebone:/etc/init.d# insserv -v -d RTC.sh insserv: enable service ../init.d/RTC.sh -> /etc/init.d/../rc0.d/K01RTC.sh insserv: enable service ../init.d/RTC.sh -> /etc/init.d/../rc1.d/K01RTC.sh insserv: enable service ../init.d/RTC.sh -> /etc/init.d/../rc2.d/S18RTC.sh insserv: enable service ../init.d/RTC.sh -> /etc/init.d/../rc3.d/S18RTC.sh insserv: enable service ../init.d/RTC.sh -> /etc/init.d/../rc4.d/S18RTC.sh insserv: enable service ../init.d/RTC.sh -> /etc/init.d/../rc5.d/S18RTC.sh insserv: enable service ../init.d/RTC.sh -> /etc/init.d/../rc6.d/K01RTC.sh insserv: creating .depend.boot insserv: creating .depend.start insserv: creating .depend.stop
事实上还尝试过update-rc.d这个工具,但是在BBB的debian中这个工具并不好用,乱七八糟无法管理好,貌似这个工
具好像也是在调用insserv做事的。