芯灵思开发板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()函数所做的事情了