芯灵思开发板
INIT
守护进程
本章主要讲的是芯灵思开发板
init
守护进程,首先我们来看一下
init
进程源码的位置,他是放在:
system/core/init/init.c
,当我们编译完生成
init
应用程序后,他会放在:
/init
下,
init
是内核起来之后,所启动的第一个进程,我们先将开发板和我们的
pc
机用
USB
线连接在一起,然后我们切换到
cmd
命令下,使用
adb
命令查看电脑有没有连接到我们的设备
我们看到有一个设备,20140723
就是我们的开发板设备,然后用
adb shell
命令登录到我们的设备然后用
ls -l
来详细查看一下这些文件,我们会看到我们的
init
守护进程
然后用ps
看一下我们系统中跑的所有程序
我们可以看到这个PID
是
1
的程序就是我们的
init
进程,这个
init
进程就负责创建所有的服务,并且守护我们整个系统,那我们再来看一下
init
进程所做的主要工作
首先init
是我们系统启动的第一个应用程序,第二他会根据安卓的一些需求,来自己创建一些目录、挂载一些分区,第三就是解析我们的启动脚本,将我们的一些服务,变量等全部解析出来,解析完之后就会根据这些东西来启动服务,执行相关的命令,启动服务之后,他就会在这里守护这些服务,这就是
init
进程所做的主要事情。
下面我们来看一下我们的
init
进程的源代码,首先找到入口函数
在代码执行过程中,我们会首先清除
umask,
请、清
umask
主要就是为了解决我们在后边创建文件时的权限问题,第二步呢,就是在我们的根目录下创建一些临时的文件,但是当我们断电之后这些文件就会消失,创建完之后他会挂载一些分区,在创建完这些目录之后,他会尝试在我们的
dev
目录下创建一个
booting
文件,创建完之后就会关闭掉,就是为了尝试下在
dev
下有写权限
然后我们看一下
init
所做的主要工作
首先是klog_init()
,他呢就是将
log
重定向到我们的
/proc/kmsg
中
kmsg
其实就是我们内核
log
信息的一个输出目录,而我们的
klog_init
()将我们应用程序的
log
重定向到了我们的
kmsg
中,我们来看一下是如何实现的
首先呢他是创建了一个/dev/kmsg
的节点,创建之后打开,打开之后我们把文件描述符保存起来,
klog
是一个全局的,然后下面有一个
klog_write
()函数,这个函数是供给其他的一些函数调用的,这个函数呢会调用一个写函数,会写到我们的
klog_fd
中,下面我们通过
adb
来看一下
kmsg
,首先登陆设备
adb shell
然后
cat /proc/kmsg
看完之后我们
ctrl+c
退出来,
在登上去,再看一下,你会发现这个就会变成空的,因为我们这个只能看一次,所以说我们要是在想查看启动信息的话,就只能重启我们的设备了,
这就是
klog_init()
所做的事情,以及我们如何在
init.c
中添加打印调试信息
下面我们来看一下
property_init()
,他呢主要是初始化一些环境变量,我们暂时先不看他
我们第三个函数式
get_hardware_name()
这个函数主要是得到我们的硬件信息和硬件版本
这个函数主要是传了两个参数进去,一个
hardware
,另一个就是
revision
,他做的事情就是打开
cpuinfo
,得到我们的硬件版本,我们在
adb
下看一下我们的
CPUinfo
,看下他的
CPU
信息
我们可以看到我们的硬件信息、版本信息、串号、还有CPU
的一些信息,这就是
get_hardware_name()
所做的一些事情
我们再来看一下
process_kernel_cmdline()
函数,它主要是解析我们内核的启动参数,即
uboot
启动的时候所带的参数,我们来看一下他所做的事情
我们所传的的启动内核信息他是在/proc/cmdline
这个文件中,我们会把它读到
import_kernel_nv
中,然后我们会把传的一些参数给他设置到
boot_props
中,我们来看一下我们的
cmdline
的具体内容,我们切到
adb
下
这个就是启动的时候
uboot
给内核传的一个参数,我们所使用的串口、波特率的一些信息就会显示出来,还有首先启动的
init
进程等
下面我们再来
property_load_boot_defaults()
函数,它主要是导入我们的默认环境变量
我们在这里就会导入我们的PROP_PATH_RAMDISK_DEFAULT
而这个文件就是根目录下的
/default.prop
我们切到adb
下来看一下这个文件的主要内容
他在这里会有一些简单的环境变量的设置
最后我们来看一下get_kernel_cmdline_partitions()
函数,这个是为了得到系统的分区,并且创建相关的链接,我们来看一下这个函数
他首先会在/dev
目录下创建一个
block
,而且创建一个
block/by-name
目录,然后他会读取我们的
/proc/cmdline
,读取完之后他会根据
cmdline
所传的信息将我们的
partitions
给读出来,然后我们来看一下
cmdline
在里边会有一个partitions
的一个字符串,字符串后边会有一个
bootloader@mmcblk0p2.....0p1
一直到最后,我们来看一下他是如何来解析这个字符串的,他所解析的内容就是将我们前面的名字和我们
block
分区一一对应起来
在我们的/dev
目录下创建一个
block/by-name
,比如我们解析的是我们的
boot
,那么这个
boot
分区就会和他后面所对应的
mmcblk0p2
一一对应起来,然后创建了一个软连接,这样的话我们每一个分区和我们分区的名字就能够对应起来,我们来看一下我们的
block/by-name
在这个目录下呢,他就创建了这几个软连接,每个软连接都对应了我们的/dev/block/mmcblk
的一个分区给映射起来了,这样的话我们就知道,我们每一个分区所对应的名字是什么,这就是
get_kernel_cmdline_partitions()
函数所做的事情了