#111
#112 if (qemu[0])
#113 import_kernel_cmdline(1);
这段代码是用来判断是否使用模拟器运行,如果时,就加载内核命令行参数。
#114
#115 if (!strcmp(bootmode,"factory"))
#116 property_set("ro.factorytest", "1");
#117 else if (!strcmp(bootmode,"factory2"))
#118 property_set("ro.factorytest", "2");
#119 else
#120 property_set("ro.factorytest", "0");
这段代码是根据内核命令行参数来设置工厂模式测试,比如在工厂生产手机过程里需要自动化演示功能,就可以根据这个标志来进行特别处理。
#121
#122 property_set("ro.serialno", serialno[0] ? serialno : "");
这段代码是设置手机序列号到属性里保存,以便上层应用程序可以识别这台手机。
#123 property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown");
这段代码是保存启动模式到属性里。
#124 property_set("ro.baseband", baseband[0] ? baseband : "unknown");
这段代码是保存手机基带频率到属性里。
#125 property_set("ro.carrier", carrier[0] ? carrier : "unknown");
这段代码是保存手机硬件载波的方式到属性里。
#126 property_set("ro.bootloader", bootloader[0] ? bootloader : "unknown");
这里是保存引导程序的版本号到属性里,以便系统知道引导程序有什么特性。
#127
#128 property_set("ro.hardware", hardware);
这里是保存硬件信息到属性里,其实就是获取CPU的信息。
#129 snprintf(tmp, PROP_VALUE_MAX, "%d", revision);
#130 property_set("ro.revision", tmp);
这里是保存硬件修订的版本号到属性里,这样可以方便应用程序区分不同的硬件版本。
#131
#132 /* execute all the boot actions to get us started */
#133 action_for_each_trigger("init", action_add_queue_tail);
#134 drain_action_queue();
这段代码是先把所有init命令添加队列,然后再执行。
#135
#136 /* read any property files on system or data and
#137 * fire up the property service. This must happen
#138 * after the ro.foo properties are set above so
#139 * that /data/local.prop cannot interfere with them.
#140 */
#141 property_set_fd = start_property_service();
这段代码是加载system和data目录下的属性,并启动属性监听服务。
#142
#143 /* create a signalling mechanism for the sigchld handler */
#144 if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0) {
#145 signal_fd = s[0];
#146 signal_recv_fd = s[1];
#147 fcntl(s[0], F_SETFD, FD_CLOEXEC);
#148 fcntl(s[0], F_SETFL, O_NONBLOCK);
#149 fcntl(s[1], F_SETFD, FD_CLOEXEC);
#150 fcntl(s[1], F_SETFL, O_NONBLOCK);
#151 }
这段代码是创建一个全双工的通讯机制的两个SOCKET,信号可以在signal_fd和signal_recv_fd双向通讯,从而建立起沟通的管道。其实这个信号管理,就是用来让init进程与它的子进程进行沟通的,子进程从signal_fd写入信息,init进程从signal_recv_fd收到信息,然后再做处理。
#152
#153 /* make sure we actually have all the pieces we need */
#154 if ((device_fd < 0) ||
#155 (property_set_fd < 0) ||
#156 (signal_recv_fd < 0)) {
#157 ERROR("init startup failure\n");
#158 return 1;
#159 }
这段代码是判断关键的几个组件是否成功初始化,主要就是设备文件系统是否成功初始化,属性服务是否成功初始化,信号通讯机制是否成功初始化。
#160
#161 /* execute all the boot actions to get us started */
#162 action_for_each_trigger("early-boot", action_add_queue_tail);
#163 action_for_each_trigger("boot", action_add_queue_tail);
#164 drain_action_queue();
这段代码是执行early-boot和boot属性的命令。
#165
#166 /* run all property triggers based on current state of the properties */
#167 queue_all_property_triggers();
#168 drain_action_queue();
这段代码是根据当前属性,运行属性命令。
#169
#170 /* enable property triggers */
#171 property_triggers_enabled = 1;
这段代码是标明属性触发器已经初始化完成。
#172
#173 ufds[0].fd = device_fd;
#174 ufds[0].events = POLLIN;
#175 ufds[1].fd = property_set_fd;
#176 ufds[1].events = POLLIN;
#177 ufds[2].fd = signal_recv_fd;
#178 ufds[2].events = POLLIN;
#179 fd_count = 3;
这段代码是保存三个重要的服务socket,以便后面轮询使用。
#180
#181 if (keychord_fd > 0) {
#182 ufds[3].fd = keychord_fd;
#183 ufds[3].events = POLLIN;
#184 fd_count++;
#185 } else {
#186 ufds[3].events = 0;
#187 ufds[3].revents = 0;
#188 }
这段代码是判断是否处理组合键轮询。
#189
#190 #if BOOTCHART
#191 bootchart_count = bootchart_init();
#192 if (bootchart_count < 0) {
#193 ERROR("bootcharting init failure\n");
#194 } else if (bootchart_count > 0) {
#195 NOTICE("bootcharting started (period=%d ms)\n", bootchart_count*BOOTCHART_POLLING_MS);
#196 } else {
#197 NOTICE("bootcharting ignored\n");
#198 }
#199 #endif
这段代码是初始化linux程序启动速度的性能分析工具,这个工具有一个好处,就是图形化显示每个进程启动顺序和占用时间,如果想优化系统的启动速度,记得启用这个工具。