Android本质上就是一个基于Linux内核的操作系统方案.docx
《Android本质上就是一个基于Linux内核的操作系统方案.docx》由会员分享,可在线阅读,更多相关《Android本质上就是一个基于Linux内核的操作系统方案.docx(18页珍藏版)》请在冰豆网上搜索。
Android本质上就是一个基于Linux内核的操作系统方案
Android本质上就是一个基于Linux核的操作系统。
与UbuntuLinux、FedoraLinux类似。
只是Android在应用层专门为移动设备添加了一些特有的支持。
既然Android是Linux核的系统,那么基本的启动过程也应符合Linux的规则。
如果研究过其他Linux系统应该了解,一个完整的Linux系统首先会将一个Linux核装载到存,也就是编译Linux核源代码生成的bzImage文件,对于为Android优化的Linux核源代码会生成zImage文件。
该文件就是Linux核的二进制版本。
由于zImage在核空间运行,而我们平常使用的软件都是在应用空间运行(关于核空间和应用空间的详细描述,可以参考《Android深度探索(卷1):
HAL与驱动开发》一书的容,在后续的各卷中将会对Android的整体体系进行全方位的剖析)。
核空间和应用空间是不能直接通过存地址级别访问的,所以就需要建立某种通讯机制。
目前Linux有很多通讯机制可以在用户空间和核空间之间交互,例如设备驱动文件(位于/dev目录中)、存文件(/proc、/sys目录等)。
了解Linux的同学都应该知道Linux的重要特征之一就是一切都是以文件的形式存在的,例如,一个设备通常与一个或多个设备文件对应。
这些与核空间交互的文件都在用户空间,所以在Linux核装载完,需要首先建立这些文件所在的目录。
而完成这些工作的程序就是本文要介绍的init。
Init是一个命令行程序。
其主要工作之一就是建立这些与核空间交互的文件所在的目录。
当Linux核加载完后,要做的第一件事就是调用init程序,也就是说,init是用户空间执行的第一个程序。
在分析init的核心代码之前,还需要初步了解init除了建立一些目录外,还做了如下的工作
1.初始化属性
2.处理配置文件的命令(主要是init.rc文件),包括处理各种Action。
3.性能分析(使用bootchart工具)。
4.无限循环执行command(启动其他的进程)。
尽管init完成的工作不算很多,不过代码还是非常复杂的。
Init程序并不是由一个源代码文件组成的,而是由一组源代码文件的目标文件而成的。
这些文件位于如下的目录。
/system/core/init
其中init.c是init的主文件,现在打开该文件,看看其中的容。
由于init是命令行程序,所以分析init.c首先应从main函数开始,现在好到main函数,代码如下:
intmain(intargc,char**argv)
{
intfd_count=0;
structpollfdufds[4];
char*tmpdev;
char*debuggable;
chartmp[32];
intproperty_set_fd_init=0;
intsignal_fd_init=0;
intkeychord_fd_init=0;
boolis_charger=false;
if(!
strcmp(basename(argv[0]),"ueventd"))
returnueventd_main(argc,argv);
if(!
strcmp(basename(argv[0]),"watchdogd"))
returnwatchdogd_main(argc,argv);
/*cleartheumask*/
umask(0);
//下面的代码开始建立各种用户空间的目录,如/dev、/proc、/sys等
mkdir("/dev",0755);
mkdir("/proc",0755);
mkdir("/sys",0755);
mount("tmpfs","/dev","tmpfs",MS_NOSUID,"mode=0755");
mkdir("/dev/pts",0755);
mkdir("/dev/socket",0755);
mount("devpts","/dev/pts","devpts",0,NULL);
mount("proc","/proc","proc",0,NULL);
mount("sysfs","/sys","sysfs",0,NULL);
/*检测/dev/.booting文件是否可读写和创建*/
close(open("/dev/.booting",O_WRONLY|O_CREAT,0000));
open_devnull_stdio();
klog_init();
//初始化属性
property_init();
get_hardware_name(hardware,&revision);
//处理核命令行
process_kernel_cmdline();
……
is_charger=!
strcmp(bootmode,"charger");
INFO("propertyinit\n");
if(!
is_charger)
property_load_boot_defaults();
INFO("readingconfigfile\n");
//分析/init.rc文件的容
init_parse_config_file("/init.rc");
……//执行初始化文件中的动作
action_for_each_trigger("init",action_add_queue_tail);
//在charger模式下略过mount文件系统的工作
if(!
is_charger){
action_for_each_trigger("early-fs",action_add_queue_tail);
action_for_each_trigger("fs",action_add_queue_tail);
action_for_each_trigger("post-fs",action_add_queue_tail);
action_for_each_trigger("post-fs-data",action_add_queue_tail);
}
queue_builtin_action(property_service_init_action,"property_service_init");
queue_builtin_action(signal_init_action,"signal_init");
queue_builtin_action(check_startup_action,"check_startup");
if(is_charger){
action_for_each_trigger("charger",action_add_queue_tail);
}else{
action_for_each_trigger("early-boot",action_add_queue_tail);
action_for_each_trigger("boot",action_add_queue_tail);
}
/*runallpropertytriggersbasedoncurrentstateoftheproperties*/
queue_builtin_action(queue_property_triggers_action,"queue_property_triggers");
#ifBOOTCHART
queue_builtin_action(bootchart_init_action,"bootchart_init");
#endif
//进入无限循环,建立init的子进程(init是所有进程的父进程)
for(;;){
intnr,i,timeout=-1;
//执行命令(子进程对应的命令)
execute_one_command();
restart_processes();
if(!
property_set_fd_init&&get_property_set_fd()>0){
ufds[fd_count].fd=get_property_set_fd();
ufds[fd_count].events=POLLIN;
ufds[fd_count].revents=0;
fd_count++;
property_set_fd_init=1;
}
if(!
signal_fd_init&&get_signal_fd()>0){
ufds[fd_count].fd=get_signal_fd();
ufds[fd_count].events=POLLIN;
ufds[fd_count].revents=0;
fd_count++;
signal_fd_init=1;
}
if(!
keychord_fd_init&&get_keychord_fd()>0){
ufds[fd_count].fd=get_keychord_fd();
ufds[fd_count].events=POLLIN;
ufds[fd_count].revents=0;
fd_count++;
keychord_fd_init=1;
}
if(process_needs_restart){
timeout=(process_needs_restart-gettime())*1000;
if(timeout<0)
timeout=0;
}
if(!
action_queue_empty()||cur_action)
timeout=0;
//bootchart是一个性能统计工具,用于搜集硬件和系统的信息,并将其写入磁盘,以便其
//他程序使用
#ifBOOTCHART
if(bootchart_count>0){
if(timeout<0||timeout>BOOTCHART_POLLING_MS)
timeout=BOOTCHART_POLLING_MS;
if(bootchart_step()<0||--bootchart_count==0){
bootchart_finish();
bootchart_count=0;
}
}
#endif
//等待下一个命令的提交
nr=poll(ufds,fd_count,timeout);
if(nr<=0)
continue;
for(i=0;iif(ufds[i].revents==POLLIN){
if(ufds[i].fd==get_property_set_fd())
handle_property_set_fd();
elseif(ufds[i].fd==get_keychord_fd())
handle_keychord();
elseif(ufds[i].fd==get_signal_