rhel6 启动过程分析

rhel6 启动过程分析
rhel6 启动过程分析

开机——很多人觉得很简单的事情,只要按下电源开关,然后系统就会自然启动,没有什么需要学习的。其实不然,如果系统没有什么问题,可以正常登陆的时候,当然开机很简单。但更多的时候,我们需要知道当机子不能正常开机的如何解决,这才是我们学习的目的。

那么我们就来分析一下Linux的开机流程

简单来说,系统开机的过程可以汇整成下面的流程:

1.加载BIOS的硬件信息、进行自我测试,并依据设定获得第一个可开机的设备;

2.读取并执行第一个开机设备内MBR的boot Loader(grub等程序);

3.依据boot loader的设置加载Kernel,Kernel会开始检测硬件与加载驱动程序;

4.内核启动init

5.系统初始化:(/etc/init/rcS.conf exec /etc/rc.d/rc.sysinit)

6.init找到/etc/inittab文件,确定默认的运行级别(X) (/etc/init/rcS.conf exec telinit $runlevel)

7.触发相应的runlevel事件(/etc/init/rc.conf exec /etc/rc.d/rc $RUNLEVEL)

8.开始运行/etc/rc.d/rc,传入参数X

9./etc/rc.d/rc脚本进行一系列设置,最后运行相应的/etc/rcX.d/中的脚本

10./etc/rcX.d/中的脚本按事先设定的优先级依次启动

11.最后执行/etc/rc.d/rc.local

12.加载终端或X-Window接口

BIOS, boot loader与kernel加载

BIOS, 开机自检与MBR

在个人计算机架构下,你想要启动整部系统首先就得要让系统去加载BIOS(Basic Input Output System),并通过BIOS程序去加载CMOS的信息,并且藉由CMOS内的设定值取得主机的各

项硬件配置信息(如CPU与接口设备的沟通频率、开机设备的搜寻顺序、硬盘的大小与类型、系统时间、各周边总线的是否启动Plug and Play (PnP, 即插即用设备)、各接口设备的I/O地址、以及与CPU沟通的IRQ(Interrupt ReQuest)中断等等)。

在取得这些信息后,BIOS还会进行开机自检(Power-on Self Test, POST)。然后开始执行硬件检测的初始化,并设定PnP设备,之后再定义出可开机的设备顺序,接下来就会开始进行开机设备的数据读取了(MBR相关的任务开始)。

由于不同的操作系统的文件系统格式不相同,因此我们必须要以一个开机管理程序来处理内核文件的加载问题,因此这个开机管理程序就被称为Boot Loader。这个Boot Loader程序安装在开机设备的第一个扇区(sector)内,也就是我们一直谈到的MBR (Master Boot Record,主要启动记录区)。下图就是MBR的组成图

Boot Loader 的功能

Boot Loader最主要功能是认识操作系统的文件格式并加载内核到主存储器中去执行。由于不同操作系统的文件格式不一致,因此每种操作系统都有自己的boot loader,用自己的loader 才有办法载入内核文件。

问题就来了:如果在一部主机上面安装多种不同的操作系统。既然必须要使用自己的loader 才能够加载属于自己的操作系统内核,而系统的MBR只有一个,那怎么会有办法同时在一部主机上面安装多系统呢?下面就来看看如何实现的。

每个文件系统(filesystem, 或者是partition) 都会保留一块启动扇区(boot sector) 提供操作系统安装boot loader,而通常操作系统默认都会安装一份loader 到他根目录所在的文件系统的boot sector 上。如果我们在一部主机上面安装Windows 与Linux 后,该boot sector, boot loader 与MBR 的相关性会有点像下图:

如上图所示,每个操作系统默认是会安装一套boot loader 到他自己的文件系统中(就是每个filesystem左下角的方框),而在Linux 统安装时,你可以选择将boot loader 安装到MBR 中,也可以选择不安装。如果选择安装到MBR的话,那理论上在MBR与boot sector都会保有一份boot loader程序。至于Windows安装时,他预设会主动的将MBR与boot sector都装上一份boot loader。所以,你会发现安装多操作系统时,你的MBR常常会被不同的操作系统的boot loader所覆盖。

现在还是没有解决我们上面的问题。虽然各个操作系统都可以安装一份boot loader 到他们的

boot sector中,这样操作系统可以通过自己的boot loader 来加载内核了。问题是系统的MBR 只有一个,要怎么执行boot sector里面的loader呢?

下面就来看看boot loader主要的功能

提供选项:用户可以选择不同的开机项目,这是多重引导的重要功能。

载入内核文件:直接指向可开机的程序区段来开始操作系统;

转交其他loader:将开机管理功能转交给其他loader负责。

由于具有选项功能,因此我们可以选择不同的内核来开机。而由于具有控制权转交的功能,因此我们可以加载其他boot sector内的loader。不过Windows的loader 预设不具有控制权转交的功能,因此你不能使用Windows 的loader 来加载Linux 的loader。这也是特别强调先装Windows再装Linux的缘故。

如上图所示,MBR使用Linux的grub 这个开机管理程序,并且里面已经有了三个选项,第一个选项可以直接指向Linux 的内核文件并且直接加载内核来开机;第二个选项可以将开机管理程控权交给Windows 来管理,此时Windows 的loader 会接管开机流程,这个时候他就能够启动windows 了。第三个选项则是使用Linux 在boot sector 内的开机管理程序,此时就会跳出另一个grub的选项。

重点就是要知道“boot loader的功能就是加载kernel文件”

加载内核检测硬件与initrd的功能

由boot loader的管理而开始读取内核文件后,接下来,Linux 就会将内核解压缩到主存储器当中,并且利用内核的功能,开始测试与驱动各个周边设备,包括储存设备、CPU、网卡、声卡等等。此时Linux 内核会以自己的功能重新检测一次硬件,而不一定会使用BIOS 检测到的硬件信息。也就是说,内核此时才开始接管BIOS 后的工作。内核档案一般来说,他会被放置到/boot 里面,并且取名为/boot/vmlinuz。

[root@yufei ~]# ls –format=single-column /boot

config-2.6.32-71.el6.i686 <===系统kernel的配置文件,内核编译完成后保存的就是这个配置文件

efi <===Extensible Firmware Interface(EFI,可扩展固件接口)是Intel 为全新类型的PC 固件的体系结构、接口和服务提出的建议标准。

grub <===开机管理程序grub相关数据目录

initramfs-2.6.32-71.el6.i686.img<===虚拟文件系统文件(RHEL6用initramfs代替了initrd,他们的目的是一样的,只是本身处理的方式有点不同)

initrd-2.6.32-71.el6.i686.img <===此文件是linux系统启动时的模块供应主要来源,initrd 的目的就是在kernel加载系统识别cpu和内存等内核信息之后,让系统进一步知道还有那些硬件是启动所必须使用的;

symvers-2.6.32-71.el6.i686.gz <===模块符号信息

System.map-2.6.32-71.el6.i686 <===是系统kernel中的变量对应表;(也可以理解为是索引文件)

vmlinuz-2.6.32-71.el6.i686 <===系统使用kernel,用于启动的压缩内核镜像, 它也就是

/arch//boot中的压缩镜像.

Linux内核是可以通过动态加载内核模块的(就请想成驱动程序即可),这些内核模块就放在

/lib/modules/目录内。由于模块放到磁盘根目录内(这就是为什么/lib不可以与/ 分别放在不同的分区原因),因此在开机的过程中内核必须要挂载根目录,这样才能够读取内核模块提供加载驱动程序的功能。而且为了担心影响到磁盘内的文件系统,开机过程中根目录是以只读的方式来挂载的。

了解/boot/initrd这个文件

虚拟文件系统(Initial RAM Disk) 一般使用的文件名为/boot/initrd ,这个文件的作用是,能够通过boot loader 来加载到内存中,然后这个文件会被解压缩并且在内存当中仿真

成一个根目录,且此仿真在内存当中的文件系统能够提供一支可执行的程序,通过该程序来加载开机过程中所最需要的内核模块,通常这些模块就是USB, RAID, LVM, SCSI 等文件系统与磁盘接口的驱动程序。等载入完成后,会帮助内核重新呼叫/sbin/init 来开始后续的正常开机流程。

下面让我们来看看initrd文件的具体内容,

[root@yufei ~]# mkdir tmp

[root@yufei ~]# cd tmp/

[root@yufei tmp]# cp /boot/initrd-2.6.32-71.el6.i686.img ./

[root@yufei tmp]# file initrd-2.6.32-71.el6.i686.img

initrd-2.6.32-71.el6.i686.img: gzip compressed data, from Unix, last modified: Thu Dec 16 00:29:07 2010, max compression

我们可以看到,这个文件是GZIP压缩的文件,我们把后缀改成gz,然后再进行解压[root@yufei tmp]# mv initrd-2.6.32-71.el6.i686.img initrd-2.6.32-71.el6.i686.gz [root@yufei tmp]# gunzip initrd-2.6.32-71.el6.i686.gz

解压后,我们再来看看这个文件是什么类型的

[root@yufei tmp]# file initrd-2.6.32-71.el6.i686

initrd-2.6.32-71.el6.i686: ASCII cpio archive (SVR4 with no CRC)

是cpio压缩成的文件

[root@yufei ~]# cpio -iv < initrd-2.6.32-71.el6.i686

[root@yufei tmp]# ls -l

总用量30084

drwxr-xr-x. 2 root root 4096 12月30 19:56 bin

drwxr-xr-x. 2 root root 4096 12月30 19:56 cmdline

drwxr-xr-x. 3 root root 4096 12月30 19:56 dev

-rw-r–r–. 1 root root 18 12月30 19:56 dracut-004-32.el6

drwxr-xr-x. 2 root root 4096 12月30 19:56 emergency

drwxr-xr-x. 7 root root 4096 12月30 19:56 etc

-rwxr-xr-x. 1 root root 8088 12月30 19:56 init

drwxr-xr-x. 2 root root 4096 12月30 19:56 initqueue

drwxr-xr-x. 2 root root 4096 12月30 19:56 initqueue-finished

drwxr-xr-x. 2 root root 4096 12月30 19:56 initqueue-settled

-rw-r–r–. 1 root root 30709760 12月30 19:54 initrd-2.6.32-71.el6.i686

drwxr-xr-x. 9 root root 4096 12月30 19:56 lib

drwxr-xr-x. 2 root root 4096 12月30 19:56 mount

drwxr-xr-x. 2 root root 4096 12月30 19:56 pre-pivot

drwxr-xr-x. 2 root root 4096 12月30 19:56 pre-trigger

drwxr-xr-x. 2 root root 4096 12月30 19:56 pre-udev

drwxr-xr-x. 2 root root 4096 12月30 19:56 proc

drwxr-xr-x. 2 root root 4096 12月30 19:56 sbin

drwxr-xr-x. 2 root root 4096 12月30 19:56 sys

drwxr-xr-x. 2 root root 4096 12月30 19:56 sysroot

drwxr-xr-x. 2 root root 4096 12月30 19:56 tmp

drwxr-xr-x. 6 root root 4096 12月30 19:56 usr

drwxr-xr-x. 3 root root 4096 12月30 19:56 var

看到结果了吧,和我们系统中的/是不是很类似。有兴趣的朋友,慢慢了解吧!哈哈……

init及配置文件/etc/inittab 与runlevel

在内核加载完毕、进行完硬件检测与驱动程序加载后,此时主机硬件已经准备就绪了,这时候内核会主动的呼叫第一支程序,那就是/sbin/init

/sbin/init 最主要的功能就是准备软件执行的环境,包括系统的主机名、网络设定、语言、文件系统格式及其他服务的启动等。而所有的动作都会通过init的配置文件/etc/inittab来规划,而inittab 内还有一个很重要的设定内容,那就是默认的runlevel (开机运行级别)。

先来看看运行级别Run level

Linux就是通过设定run level来规定系统使用不同的服务来启动,让Linux的使用环境不同。我们来看看这个inittab文件里面的支持级别(RHEL6系统里面的,和以前的其它版本有很大的

差别)

[root@yufei ~]# vim /etc/inittab

……

17 # Default runlevel. The runlevels used are:

18 # 0 –halt (Do NOT set initdefault to this)

19 # 1 –Single user mode

20 # 2 –Multiuser, without NFS (The same as 3, if you do not have netwo rking)

21 # 3 –Full multiuser mode

22 # 4 –unused

23 # 5 –X11

24 # 6 –reboot (Do NOT set initdefault to this)

……

0 –halt (系统直接关机)

1 –single user mode (单人维护模式,用在系统出问题时的维护)

2 –Multi-user, without NFS (类似底下的runlevel 3,但无NFS 服务)

3 –Full multi-user mode (完整含有网络功能的纯文本模式)

4 –unused (系统保留功能)

5 –X11 (与runlevel 3 类似,但加载使用X Window)

6 –reboot (重新启动)

0, 4, 6 不是关机、重新启动就是系统保留的,所以不能将预设的run level设定为这三个值。RHEL6系统上的这个文件和以前的版本有很大的差别,目前这个文件只能设置运行级别,其它的相关配置文件,在此文件中已经做了说明如:

System initialization is started by /etc/init/rcS.conf

Individual runlevels are started by /etc/init/rc.conf

Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf

Terminal gettys are handled by /etc/init/tty.conf and /etc/in it/serial.conf,with configuration in /etc/sysconfig/init.

更多的内容,大家可以到/etc/init/里面看看

从这个文件我们已经看出,红帽已经使用新的Upstart启动服务来替换以前的init,想了解更多,请参考https://www.360docs.net/doc/d06141681.html,/2010_12_1500.html

在RHEL6的版本中,我们可以把/etc/init/这个目录里面的内容,看成是以前/etc/inittab这个文件里的拆分。

下面是RHEL6上面Upstart大致的一个启动过程:

1.内核启动init

2.系统初始化:(/etc/init/rcS.conf exec /etc/rc.d/rc.sysinit)

3.init找到/etc/inittab文件,确定默认的运行级别(X) (/etc/init/rcS.conf exec telinit $runlevel)

4.触发相应的runlevel事件(/etc/init/rc.conf exec /etc/rc.d/rc $RUNLEVEL)

5.开始运行/etc/rc.d/rc,传入参数X

6./etc/rc.d/rc脚本进行一系列设置,最后运行相应的/etc/rcX.d/中的脚本

7./etc/rcX.d/中的脚本按事先设定的优先级依次启动

8.最后执行/etc/rc.d/rc.local

9.加载终端或X-Window接口

想要了解更多的内容,请大家打开/etc/init/这个目录里面的文件看看。

/etc/rc.sysinit 这个文件干了哪些工作?

vim /etc/rc.sysinit

1、获得网络环境

2、挂载设备

3、开机启动画面Plymouth(取替了过往的RHGB)

4、判断是否启用SELinux

5、显示于开机过程中的欢迎画面

6、初始化硬件

7、用户自定义模块的加载

8、配置内核的参数

9、设置主机名

10、同步存储器

11、设备映射器及相关的初始化

12、初始化软件磁盘阵列(RAID)

13、初始化LVM 的文件系统功能

14、检验磁盘文件系统(fsck)

15、磁盘配额(quota)

16、重新以可读写模式挂载系统磁盘

17、更新quota(非必要)

18、启动系统虚拟随机数生成器

19、配置机器(非必要)

20、清除开机过程当中的临时文件

21、创建ICE目录

22、启动交换分区(swap)

23、将开机信息写入/var/log/dmesg文件中

这个文件里面的许多预设配置文件在/etc/sysconfig/这个目录当中,要想更多的系统启动信息,大家可以到/var/log/dmesg文件中查看,也可以用dmesg命令来查看。

系统服务的启动

经过/etc/rc.sysinit 的系统模块与相关硬件信息的初始化后,我们的RHEL6系统应该已经能顺利工作了。但我们还需要启动一些为我们提供服务的服务。这个时候,依据在/etc/inittab里面run level的设定值,就可以来决定启动的服务项目了。

大家可以打开/etc/rc这个文件来研究

我们以运行级别3来说明

ls /etc/rc3.d/

在这个目录下的文件主要具有2个特点:

1、全部以Sxx或Kxx(xx为数字)开头

2、全部是连结文件,连结到/etc/init.d/

现在来说明一下这些的目的

S表示启动服务

K表示停止服务

后面的数字是启动的先后顺序

我们以S00microcode_ctl来举例

[root@yufei ~]# ls -l /etc/rc3.d/S00microcode_ctl

lrwxrwxrwx. 1 root root 23 12月15 22:40 /etc/rc3.d/S00microcode_ctl

-> ../init.d/microcode_ctl

他的意思就是

S00microcode_ctl=/etc/init.d/microcode_ctl start

而且是第一个启动的服务。这样我想大家应该明白了吧。

用户自定义开机启动脚本

上面讲到的都是一些系统服务,大家知道,我们的Linux系统容许安装其它的软件来提供服务,那我想要自己安装的服务也要在开机启动,那怎么办,没有关系,找/etc/rc.local 来完成。这就是我们要讲的用户自定义开机启动脚本。我们只要把想启动的脚本写到这个文件中,开机就能启动了,注意一点,写在这里面的脚本要使用绝对路径。

加载终端或X-Window接口

在完成了系统所有服务的启动后,接下来Linux就会启动终端或者是X Window来等待使用者登陆了!

在/etc/init/start-ttys.conf中我们可以看到有6个纯文本终端(tty[1-6])。我们可以用[Ctrl+Alt+F1~F6]来切换这些终端。如果要切换到X window终端我们可以用[Ctrl+Alt+F7] 注:虚拟机个与真实的环境还是有区别的,有很多快捷键是冲突的,所以这个需要自行实验获得。更详细的分析,请看ice360评论!感谢ice360的支持。

运行级别的切换

通过上面的学习,我们知道run level是在/etc/rc.sysinit 执行完毕之后,而run level 的不同之处仅是/etc/rc[0-6].d 里面启动的服务不同而已。如果我们切换run level只需要停止与启动一些服务就OK,那么要如何来实现,其它很简单,用init n(数字)来切换。

比如说,我们要把运行级别5换成3,我们就用init 3来实现,切换的时候系统做了哪些事,我们来看看

先对比/etc/rc3.d/ 及/etc/rc5.d 内的K 与S 开头的文件;

对比/etc/rc3.d/ 内有多余的K 开头文件则予以关闭;

对比/etc/rc3.d/ 内有多余的S 开头文件则予以启动;

两个run level 都存在的服务就不会被关闭;

是不是很简单,而且还不需要重新启动。如果说我想关机或重新启动系统,是不你已经想到了如何通过init来实现。哈哈……

如果本文有什么不妥的地方,请各位看官及时提出来,不至于误导其他的读者。也提醒一下转载的朋友,请确认没有问题后再转载。

本文关键字:一天一点,学习Linux,RHEL6,开机流程

android系统开机启动流程分析

一,系统引导bootloader 加电,cpu执行bootloader程序,正常启动系统,加载boot.img【其中包含内核。还有ramdisk】 二,内核kernel bootloader加载kernel,kernel自解压,初始化,载入built-in驱动程序,完成启动。 内核启动后会创建若干内核线程,在后装入并执行程序/sbin/init/,载入init process,切换至用户空间(user-space) 内核zImage解压缩 head.S【这是ARM-Linux运行的第一个文件,这些代码是一个比较独立的代码包裹器。其作用就是解压Linux内核,并将PC指针跳到内核(vmlinux)的第一条指令】首先初始化自解压相关环境(内存等),调用decompress_kernel进行解压,解压后调用start_kernel启动内核【start_kernel是任何版本linux内核的通用初始化函数,它会初始化很多东西,输出linux版本信息,设置体系结构相关的环境,页表结构初始化,设置系 统自陷入口,初始化系统IRQ,初始化核心调度器等等】,最后调用rest_init【rest_init 会调用kernel_init启动init进程(缺省是/init)。然后执行schedule开始任务调度。这个init是由android的./system/core/init下的代码编译出来的,由此进入了android的代码】。 三,Init进程启动 【init是kernel启动的第一个进程,init启动以后,整个android系统就起来了】 init进程启动后,根据init.rc 和init. .rc脚本文件建立几个基本 服务(servicemanager zygote),然后担当property service 的功能 打开.rc文件,解析文件内容。【system/core/init/init.c】将service信息放置到service.list中【system/core/init/init_parser.c】。 建立service进程。【service_start(…) execve(…)】 在init.c中,完成以下工作 1、初始化log系统【解析/init.rc和init.%hardware%.rc文件,在两个 文件解析步骤2时执行“early-init”行动】 2、初始化设备【在/dev下创建所有设备节点,下载firmwares】 3、初始化属性服务器【在两个文件解析步骤2时执行“init”行动】

详解bootloader的执行流程与ARM Linux启动过程分析

详解bootloader的执行流程与ARM Linux启动过程分析 ARM Linux启动过程分析是本文要介绍的内容,嵌入式Linux 的可移植性使得我们可以在各种电子产品上看到它的身影。对于不同体系结构的处理器来说Linux的启动过程也有所不同。 本文以S3C2410 ARM处理器为例,详细分析了系统上电后bootloader的执行流程及ARM Linux的启动过程。 1、引言 Linux 最初是由瑞典赫尔辛基大学的学生Linus Torvalds在1991 年开发出来的,之后在GNU的支持下,Linux 获得了巨大的发展。虽然Linux 在桌面PC 机上的普及程度远不及微软的Windows 操作系统,但它的发展速度之快、用户数量的日益增多,也是微软所不能轻视的。而近些年来Linux 在嵌入式领域的迅猛发展,更是给Linux 注入了新的活力。 一个嵌入式Linux 系统从软件角度看可以分为四个部分:引导加载程序(bootloader),Linux 内核,文件系统,应用程序。 其中bootloader是系统启动或复位以后执行的第一段代码,它主要用来初始化处理器及外设,然后调用Linux 内核。 Linux 内核在完成系统的初始化之后需要挂载某个文件系统做为根文件系统(Root Filesystem)。 根文件系统是Linux 系统的核心组成部分,它可以做为Linux 系统中文件和数据的存储区域,通常它还包括系统配置文件和运行应用软件所需要的库。 应用程序可以说是嵌入式系统的“灵魂”,它所实现的功能通常就是设计该嵌入式系统所要达到的目标。如果没有应用程序的支持,任何硬件上设计精良的嵌入式系统都没有实用意义。 从以上分析我们可以看出bootloader 和Linux 内核在嵌入式系统中的关系和作用。Bootloader在运行过程中虽然具有初始化系统和执行用户输入的命令等作用,但它最根本

linux启动过程

Linux系统启动过程分析 by 王斌斌 binbinwang118@https://www.360docs.net/doc/d06141681.html, Linux系统启动过程分析 操作系统的启动过程,实际上是控制权移交的过程。Linux 系统启动包含四个主要的阶段:BIOS initialization, boot loader, kernel initialization, and init startup.见下图: 阶段一、BIOS initialization,主要功能如下: 1.Peripherals detected 2.Boot device selected 3.First sector of boot device read and executed 系统上电开机后,主板BIOS(Basic Input / Output System)运行POST(Power on self test)代码,检测系统外围关键设备(如:CPU、内存、显卡、I/O、键盘鼠标等)。硬件配置信息及一些用户配置参数存储在主板的CMOS( Complementary Metal Oxide Semiconductor)上(一般64字节),实际上就是主板上一块可读写的RAM芯片,由主板上的电池供电,系统掉电后,信息不会丢失。 执行POST代码对系统外围关键设备检测通过后,系统启动自举程序,根据我们在BIOS中设置的启动顺序搜索启动驱动器(比如的硬盘、光驱、网络服务器等)。选择合适的启动器,比如通常情况下的硬盘设备,BIOS会读取硬盘设备的第一个扇区(MBR,512字节),并执行其中的代码。实际上这里BIOS并不关心启动设备第一个扇区中是什么内容,它只是负责读取该扇区内容、并执行,BIOS的任务就完成了。此后将系统启动的控制权移交到MBR部分的代码。 注:在我们的现行系统中,大多关键设备都是连在主板上的。因此主板BIOS提供了一个操作系统(软件)和系统外围关键设备(硬件)最底级别的接口,在这个阶段,检测系统外围关键设备是否准备好,以供操作系 “” 统使用。 阶段二、Boot Loader 关于Boot Loader,简单的说就是启动操作系统的程序,如grub,lilo,也可以将boot loader本身看成一个小系统。 The BIOS invokes the boot loader in one of two ways: 1.It pass control to an initial program loader (IPL) installed within a driver's Master Boot Record (MBR) 2.It passes control to another boot loader, which passes control to an IPL installed within a partition's boot sector. In either case, the IPL must exist within a very small space, no larger than 446 bytes. Therefore, the IPL for GRUB is merely a first stage, whose sole task is to locate and load a second stage boot loader, which does most of the work to boot the system. There are two possible ways to configure boot loaders: Primary boot loader: Install the first stage of your Linux boot loader into the MBR. The boot loader must be configure to pass control to any other desired operating systems. Secondary boot loader: Install the first stage of your Linux boot loader into the boot sector of some partition. Another boot loader must be installed into the MBR, and configured to pass control to your Linux boot loader. 假设Boot Loader 为grub (grub-0.97),其引导系统的过程如下: grub 分为stage1 (stage1_5) stage2两个阶段。stage1 可以看成是initial program loaderI(IPL),而stage2则实现了grub 的主要功能,包括对特定文件系统的支持(如ext2,ext3,reiserfs等),grub自己的shell,以及内部程序(如:kernrl,initrd,root )等。

Android 开机启动流程

Android的开机流程 1. 系统引导bootloader 1) 源码:bootable/bootloader/* 2) 说明:加电后,CPU将先执行bootloader程序,此处有三种选择 a) 开机按Camera+Power启动到fastboot,即命令或SD卡烧写模式,不加载内核及文件系统,此处可以进行工厂模式的烧写 b) 开机按Home+Power启动到recovery模式,加载recovery.img,recovery.i mg包含内核,基本的文件系统,用于工程模式的烧写 c) 开机按Power,正常启动系统,加载boot.img,boot.img包含内核,基本文件系统,用于正常启动手机(以下只分析正常启动的情况) 2. 内核kernel 1) 源码:kernel/* 2) 说明:kernel由bootloader加载 3. 文件系统及应用init 1) 源码:system/core/init/* 2) 配置文件:system/rootdir/init.rc, 3) 说明:init是一个由内核启动的用户级进程,它按照init.rc中的设置执行:启动服务(这里的服务指linux底层服务,如adbd提供adb支持,vold提供SD卡挂载等),执行命令和按其中的配置语句执行相应功能 4. 重要的后台程序zygote 1)源码:frameworks/base/cmds/app_main.cpp等 2) 说明:zygote是一个在init.rc中被指定启动的服务,该服务对应的命令是/system/bin/app_process a)建立Java Runtime,建立虚拟机 b) 建立Socket接收ActivityManangerService的请求,用于Fork应用程序 c) 启动System Server 5. 系统服务system server 1)源码:frameworks/base/services/java/com/android/server/SystemServer.jav a 2) 说明:被zygote启动,通过SystemManager管理android的服务(这里的服务指frameworks/base/services下的服务,如卫星定位服务,剪切板服务等) 6. 桌面launcher 1)源码:ActivityManagerService.java为入口,packages/apps/launcher*实现 2) 说明:系统启动成功后SystemServer使用xxx.systemReady()通知各个服务,系统已经就绪,桌面程序Home就是在ActivityManagerService.systemReady()通知的过程中建立的,最终调用()启launcher 7. 解锁 1) 源码: frameworks/policies/base/phone/com/android/internal/policy/impl/*lock* 2) 说明:系统启动成功后SystemServer调用wm.systemReady()通知WindowManagerService,进而调用PhoneWindowManager,最终通过LockPatternKeyguardView显示解锁界面,跟踪代码可以看到解锁界面并不是一个Activity,这是只是向特定层上绘图,其代码了存放在特殊的位置

linux内核启动 Android系统启动过程详解

linux内核启动+Android系统启动过程详解 第一部分:汇编部分 Linux启动之 linux-rk3288-tchip/kernel/arch/arm/boot/compressed/ head.S分析这段代码是linux boot后执行的第一个程序,完成的主要工作是解压内核,然后跳转到相关执行地址。这部分代码在做驱动开发时不需要改动,但分析其执行流程对是理解android的第一步 开头有一段宏定义这是gnu arm汇编的宏定义。关于GUN 的汇编和其他编译器,在指令语法上有很大差别,具体可查询相关GUN汇编语法了解 另外此段代码必须不能包括重定位部分。因为这时一开始必须要立即运行的。所谓重定位,比如当编译时某个文件用到外部符号是用动态链接库的方式,那么该文件生成的目标文件将包含重定位信息,在加载时需要重定位该符号,否则执行时将因找不到地址而出错 #ifdef DEBUG//开始是调试用,主要是一些打印输出函数,不用关心 #if defined(CONFIG_DEBUG_ICEDCC)

……具体代码略 #endif 宏定义结束之后定义了一个段, .section ".start", #alloc, #execinstr 这个段的段名是 .start,#alloc表示Section contains allocated data, #execinstr表示Section contains executable instructions. 生成最终映像时,这段代码会放在最开头 .align start: .type start,#function /*.type指定start这个符号是函数类型*/ .rept 8 mov r0, r0 //将此命令重复8次,相当于nop,这里是为中断向量保存空间 .endr b 1f .word 0x016f2818 @ Magic numbers to help the loader

分析Android 开机启动慢的原因

开机启动花了40多秒,正常开机只需要28秒就能开机起来。 内核的启动我没有去分析,另一个同事分析的。我主要是分析从SystemServer启来到开机动画结束显示解锁界面的这段时间,也就是开机动画的第三个动画开始到结束这段时间,这是个比较耗时阶段,一般都在17秒左右(见过牛B的手机,只需5秒)。 SystemServer分两步执行:init1和init2。init1主要是初始化native的服务,代码在sy stem_init.cpp的system_init,初始化了SurfaceFlinger和SensorService这两个native的服务。init2启动的是java的服务,比如ActivityManagerService、WindowManagerService、PackageManagerService等,在这个过程中PackageManagerService用的时间最长,因为PackageManagerService会去扫描特定目录下的jar包和apk文件。 在开机时间需要40多秒的时,从Log上可以看到,从SurfaceFlinger初始化到动画结束,要27秒左右的时间,即从SurfaceFlinger::init的LOGI("SurfaceFlinger is starting")这句Log到void SurfaceFlinger::bootFinished()的LOGI("Boot is finished (%ld ms)", long(ns 2ms(duration)) ),需要27秒左右的时间,这显然是太长了,但到底是慢在哪了呢?应该在个中间的点,二分一下,于是想到了以启动服务前后作为分隔:是服务启动慢了,还是在服务启动后的这段时间慢?以ActivityManagerService的Slog.i(TAG, "System now ready")的这句Log为分割点,对比了一下,在从SurfaceFlinger is starting到System now read y多了7秒左右的时间,这说明SystemServer在init1和init2过程中启动慢了,通过排查,发现在init1启动的时候,花了7秒多的时间,也就是system_init的LOGI("Entered system _init()")到LOGI("System server: starting Android runtime.\n")这段时间用了7秒多,而正常情况是400毫秒便可以初始化完,通过添加Log看到,在SensorService启动时,用了比较长的时间。 不断的添加Log发现,在启动SensorService时候,关闭设备文件变慢了,每次关闭一个/dev/input/下的设备文件需要100ms左右,而SensorService有60~70次的关闭文件,大概有7s左右的时间。 调用流程是: frameworks/base/cmds/system_server/library/system_init.cpp: system_init->SensorServi ce::instantiate frameworks/native/services/sensorservice/SensorService.cpp: void SensorService::onFi rstRef()->SensorDevice& dev(SensorDevice::getInstance()) hardware/libsensors/SensorDevice.cpp: SensorDevice::SensorDevice()->sensors_open hardware/libsensors/sensors.cpp: open_sensors->sensors_poll_context_t sensors_poll_context_t执行打开每个传感器设备时,遍历/dev/input/目录下的设备文件,以匹配当前需要打开的设备,遍历文件是在 hardware/libsensors/SensorBase.cpp的openInput下实现,如果打开的设备文件不是正在打开的设备文件,会执行下面语句的else部分: if (!strcmp(name, inputName)) { strcpy(input_name, filename); break;

基于MT6752的 android 系统启动流程分析报告

基于MT6752的Android系统启动流程分析报告 1、Bootloader引导 (2) 2、Linux内核启动 (23) 3、Android系统启动 (23) 报告人: 日期:2016.09.03

对于Android整个启动过程来说,基本可以划分成三个阶段:Bootloader引导、Linux kernel启动、Android启动。但根据芯片架构和平台的不同,在启动的Bootloader阶段会有所差异。 本文以MTK的MT6752平台为例,分析一下基于该平台的Android系统启动流程。 1、Bootloader引导 1.1、Bootloader基本介绍 BootLoader是在操作系统运行之前运行的一段程序,它可以将系统的软硬件环境带到一个合适状态,为运行操作系统做好准备,目的就是引导linux操作系统及Android框架(framework)。 它的主要功能包括设置处理器和内存的频率、调试信息端口、可引导的存储设备等等。在可执行环境创建好之后,接下来把software装载到内存并执行。除了装载software,一个外部工具也能和bootloader握手(handshake),可指示设备进入不同的操作模式,比如USB下载模式和META模式。就算没有外部工具的握手,通过外部任何组合或是客户自定义按键,bootloader也能够进入这些模式。 由于不同处理器芯片厂商对arm core的封装差异比较大,所以不同的arm处理器,对于上电引导都是由特定处理器芯片厂商自己开发的程序,这个上电引导程序通常比较简单,会初始化硬件,提供下载模式等,然后才会加载通常的bootloader。 下面是几个arm平台的bootloader方案: marvell(pxa935) : bootROM + OBM + BLOB informax(im9815) : bootROM + barbox + U-boot mediatek(mt6517) : bootROM + pre-loader + U-boot broadcom(bcm2157) : bootROM + boot1/boot2 + U-boot 而对MT6752平台,MTK对bootloader引导方案又进行了调整,它将bootloader分为以下两个部分: (1) 第1部分bootloader,是MTK内部(in-house)的pre-loader,这部分依赖平台。 (2) 第2部分bootloader,是LK(little kernel的缩写,作用同常见的u-boot差不多),这部分依赖操作系统,负责引导linux操作系统和Android框架。 1.2、bootloader的工作流程 1.2.1 bootloader正常的启动流程 先来看启动流程图:

linux grub 引导启动过程详解

linux grub 引导启动过程详解 2008-01-08 17:18 这几天看了很多文档,算是对linux的启动过程有了比较细致的了解. 网上有很多文章谈到这方面的内容,但总觉得没有一篇完全的解析linux启动的 细节,下面是我小弟在学习的过程中总结出来的一些东东.这个是完整的linux启动过程, 不涉及内核,但是我觉得比较详细哦. (由于本人比较懒,这一段是从网上抄的) 机器加电启动后,BIOS开始检测系统参数,如内存的大小,日期和时间,磁盘 设备以及这些磁盘设备用来引导的顺序,通常情况下,BIOS都是被配置成首先检查 软驱或者光驱(或两者都检查),然后再尝试从硬盘引导。如果在这些可移动的设 备中,没有找到可引导的介质,那么BIOS通常是转向第一块硬盘最初的几个扇区, 寻找用于装载操作系统的指令。装载操作系统的这个程序就是boot loader. linux里面的boot loader通常是lilo或者grub,从Red Hat Linux 7.2起,GRUB( GRand Unified Bootloader)取代LILO成为了默认的启动装载程序。那么启动的时候grub是如何被载入的呢 grub有几个重要的文件,stage1,stage2,有的时候需要stage1.5.这些文件一般都 在/boot/grub文件夹下面.grub被载入通常包括以下几个步骤: 1. 装载基本的引导装载程序(stage1),stage1很小,网上说是512字节,但是在我的系统上用du -b /boot/grub/stage1 显示的是1024个字节,不知道是不是grub版本不同的缘故还是我理解有误.stage1通常位于主引导扇区里面,对于硬盘就是MBR了,stage1的主要功能就是装载第二引导程序(stage2).这主要是归结于在主引导扇区中没有足够的空间用于其他东西了,我用的是grub 0.93,stage2文件的大小是107520 bit. 2. 装载第二引导装载程序(stage2),这第二引导装载程序实际上是引出更高级的功能, 以允许用户装载入一个特定的操作系统。在GRUB中,这步是让用户显示一个菜单或是输入命令。由于stage2很大,所以它一般位于文件系统之中(通常是boot所在的根 分区). 上面还提到了stage1.5这个文件,它的作用是什么呢你到/boot/grub目录下看看, fat_stage_1.5 e2fs_stage_1.5 xfs_stage_1.5等等,很容易猜想stage1.5和文件系统 有关系.有时候基本引导装载程序(stage1)不能识别stage2所在的文件系统分区,那么这 时候就需要stage1.5来连接stage1和stage2了.因此对于不同的文件系统就会有不同的stage1.5.但是对于grub 0.93好像stage1.5并不是很重要,因为我试过了,在没有stage1.5 的情况下, 我把stage1安装在软盘的引导扇区内,然后把stage2放在格式化成ext2或者fat格式的软盘内,启动的时候照常引导,并不需要e2fs_stage_1.5或者fat_stage_1.5. 下面是我的试验: #mkfs.ext2 /dev/fd0 #mount -t ext2 /dev/fd0 /mnt/floppy #cd /mnt/floppy #mkdir boot #cd boot #mkdir grub (以上三步可用mkdir -p boot/grub命令完成) #cd grub #cp /boot/grub/{stage1,stage2,grub.conf} ./ #cd; umount /mnt/floppy

Android开机启动流程样本

Android的开机流程 1. 系统引导bootloader 1) 源码: bootable/bootloader/* 2) 说明: 加电后, CPU将先执行bootloader程序, 此处有三种选择 a) 开机按Camera+Power启动到fastboot, 即命令或SD卡烧写模式, 不加载内核及文件系统, 此处能够进行工厂模式的烧写 b) 开机按Home+Power启动到recovery模式, 加载recovery.img, recovery.img包含内核, 基本的文件系统, 用于工程模式的烧写 c) 开机按Power, 正常启动系统, 加载boot.img, boot.img包含内核, 基本文件系统, 用于正常启动手机( 以下只分析正常启动的情况) 2. 内核kernel 1) 源码: kernel/* 2) 说明: kernel由bootloader加载 3. 文件系统及应用init 1) 源码: system/core/init/* 2) 配置文件: system/rootdir/init.rc, 3) 说明: init是一个由内核启动的用户级进程, 它按照init.rc中的设置执行: 启动服务( 这里的服务指linux底层服务, 如adbd提供adb支持, vold提供SD卡挂载等) , 执行命令和按其中的配置语句执行相应功能 4. 重要的后台程序zygote 1) 源码: frameworks/base/cmds/app_main.cpp等 2) 说明: zygote是一个在init.rc中被指定启动的服务, 该服务对应的命令是/system/bin/app_process

Linux启动过程详解

深入浅出:Linux的启动流程刨析 Linux的启动过程,是一个Linuxer必须要熟练掌握的。通过系统的启动过程,可以更深入的理解Linux,假如Linux系统出问题的话,可以通过启动过程来分析原因,解决问题。而且,在掌握了Linux的启动流程后,还可以借助宿主机来打造自己的Linux。 下面是我画的一张简单的Linux启动流程图 在了解启动流程之前,我们应该先知道系统的几个重要脚本和配置文件,他们对应的路径为: 1、/sbin/init 2、/etc/inittab 3、/etc/rc.d/rc.sysinit 4、/etc/rc.d/rcN.d //这是几个文件夹N代表数字1,2,3,4.. 5、/etc/fstab 1、关于/sbin/init与/etc/inittab 关于/sbin/init ,它是一个二进制可执行文件,为系统的初始化程序,而/etc/inittab是它的配置文件,我们可以通过/etc/inittab来一睹它的功能,里面的内容是一种固定的文本格式,id:runlevels:action:process 我们来通过它的内容来学习它之前,先了解写运行级别的分类(0-6): 0:关机half

1:单用户模式singel user 2:多用户模式multi user ,不提供nfs服务without nfs 3:完全多用户字符模式full multiuser text mod 4:系统预留officially undefined 5:图形登录界面graphical login 6:重启reboot id:3:initdefault: //这里定义linux的启动时的运行级别,可以看到我的主机的启动级别是3 # System initialization. si::sysinit:/etc/rc.d/rc.sysinit //紧接着,运行系统第一个脚本/etc/rc.d/rc/sysinit //它的action:sysyinit指的是定义系统初始化过程 l0:0:wait:/etc/rc.d/rc 0 l1:1:wait:/etc/rc.d/rc 1 l2:2:wait:/etc/rc.d/rc 2 //然后就是加载服务了,他们被定义在/etc/rc.d/rcN.d l3:3:wait:/etc/rc.d/rc 3 //action:waite 这个进程在在对应级别启动一次,知道它结束为止,我的系统启动级别为3,所有执行rc 3对应的服务 l4:4:wait:/etc/rc.d/rc 4 l5:5:wait:/etc/rc.d/rc 5 l6:6:wait:/etc/rc.d/rc 6 ca::ctrlaltdel:/sbin/shutdown -t3 -r now //这里定义了一个组合快捷键,熟悉吧,没错就是重启,你可以把它注释掉不用 pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"//这里定义了ups电源,powerfail 指的是如果突然断电,它对应的process命令是,提示用户系统电源失效,将要关机,提醒用户把数据都存储好 pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"//这里的action,powerokwaite,指的是系统恢复供电,关机取消...

 1:2345:respawn:/sbin/mingetty tty1 //开启终端,在系统准备工作做好后,就会启动出6个终端,tty1~6 mingetyy就是终端的执行命令 2:2345:respawn:/sbin/mingetty tty2 //可以看到他们对应的级别是2345,你也可以注释

Android系统启动过程详解

Android系统启动过程详解 Android系统启动过程 首先Android框架架构图:(来自网上,我觉得这张图看起来很清晰) Linux内核启动之后就到Android Init进程,进而启动Android相关的服务和应用。 启动的过程如下图所示:(图片来自网上,后面有地址)

下面将从Android4.0源码中,和网络达人对此的总结中,对此过程加以学习了解和总结, 以下学习过程中代码片段中均有省略不完整,请参照源码。

一Init进程的启动 init进程,它是一个由内核启动的用户级进程。内核自行启动(已经被载入内存,开始运行, 并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程。init始终是第一个进程。 启动过程就是代码init.c中main函数执行过程:system\core\init\init. c 在函数中执行了:文件夹建立,挂载,rc文件解析,属性设置,启动服务,执行动作,socket监听…… 下面看两个重要的过程:rc文件解析和服务启动。 1 rc文件解析 .rc文件是Android使用的初始化脚本文件(System/Core/Init/readm e.txt中有描述: four broad classes of statements which are Actions, Commands, Services, and Options.) 其中Command 就是系统支持的一系列命令,如:export,hostname,mkdir,mount,等等,其中一部分是linux 命令, 还有一些是android 添加的,如:class_start :启动服务,class_stop :关闭服务,等等。 其中Options是针对Service 的选项的。 系统初始化要触发的动作和要启动的服务及其各自属性都在rc脚本文件中定义。具体看一下启动脚本:\system\core\rootdir\init.rc 在解析rc脚本文件时,将相应的类型放入各自的List中: \system\core\init\Init_parser.c :init_parse_config_file( )存入到 action_queue、action_list、service_list中,解析过程可以看一下parse_config函数,类似状态机形式挺有意思。 这其中包含了服务:adbd、servicemanager、vold、ril-daemon、deb uggerd、surfaceflinger、zygote、media…… 2 服务启动 文件解析完成之后将service放入到service_list中。 文件解析完成之后将service放入到service_list中。 \system\core\init\builtins.c

Android SystemBar启动流程分析

Android SystemBar启动流程分析 SystemBars的服务被start时,最终会调用该类的onNoService()方法。 @Override public void start() { if (DEBUG) Log.d(TAG, "start"); ServiceMonitor mServiceMonitor = new ServiceMonitor(TAG, DEBUG, mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this); mServiceMonitor.start(); // will call onNoService if no remote service is found } @Override public void onNoService() { if (DEBUG) Log.d(TAG, "onNoService"); createStatusBarFromConfig(); // fallback to using an in-process implementation } private void createStatusBarFromConfig() { … mStatusBar = (BaseStatusBar) cls.newInstance(); … mStatusBar.start(); } BaseStatusBar是一个抽象类,故调用其子类的PhoneStatusBar的start 函数。 @Override public void start() { … super.start(); … } 子类的start又调用了父类的start public void start() { … createAndAddWindows(); … }

Linux启动全过程-由bootloader到fs

Linux启动过程 许多人对Linux的启动过程感到很神秘,因为所有的启动信息都在屏幕上一闪而过。其实Linux的启动过程并不象启动信息所显示的那样复杂,它主要分成两个阶段: 1.启动内核。在这个阶段,内核装入内存并在初始化每个设备驱动器时打印信息。 2.执行程序init。装入内核并初始化设备后,运行init程序。init程序处理所有程序的启动, 包括重要系统精灵程序和其它指定在启动时装入的软件。 下面以Red Hat为例简单介绍一下Linux的启动过程。 一、启动内核 首先介绍启动内核部分。电脑启动时,BIOS装载MBR,然后从当前活动分区启动,LILO获得引导过程的控制权后,会显示LILO提示符。此时如果用户不进行任何操作,LILO将在等待制定时间后自动引导默认的操作系统,而如果在此期间按下TAB键,则可以看到一个可引导的操作系统列表,选择相应的操作系统名称就能进入相应的操作系统。当用户选择启动LINUX操作系统时,LILO就会根据事先设置好的信息从ROOT文件系统所在的分区读取LINUX映象,然后装入内核映象并将控制权交给LINUX内核。LINUX内核获得控制权后,以如下步骤继续引导系统: 1. LINUX内核一般是压缩保存的,因此,它首先要进行自身的解压缩。内核映象前面的一些代码完成解压缩。 2. 如果系统中安装有可支持特殊文本模式的、且LINUX可识别的SVGA卡,LINUX会提示用户选择适当的文本显示模式。但如果在内核的编译过程中预先设置了文本模式,则不会提示选择显示模式。该显示模式可通过LILO或RDEV工具程序设置。 3. 内核接下来检测其他的硬件设备,例如硬盘、软盘和网卡等,并对相应的设备驱动程序进行配置。这时,显示器上出现内核运行输出的一些硬件信息。 4. 接下来,内核装载ROOT文件系统。ROOT文件系统的位置可在编译内核时指定,也可通过LILO 或RDEV指定。文件系统的类型可自动检测。如果由于某些原因装载失败,则内核启动失败,最终会终止系统。 二、执行init程序 其次介绍init程序,利用init程序可以方便地定制启动其间装入哪些程序。init的任务是启动新进程和退出时重新启动其它进程。例如,在大多数Linux系统中,启动时最初装入六个虚拟的控制台进程,退出控制台窗口时,进程死亡,然后init启动新的虚拟登录控制台,因而总是提供六个虚拟登陆控控制台进程。控制init程序操作的规则存放在文件/etc/inittab中。Red Hat Linux缺省的inittab文件如下:# #inittab This file describes how the INIT process should set up the system in a certain #run-level. # # #Default runlevel.The runlevels used by RHS are: #0-halt(Do NOT set initdefault to this) #1-Single user mode #2-Multiuser,without NFS(the same as 3,if you do not have networking) #3-Full multiuser mode #4-unused #5-X11 #6-reboot(Do NOT set initdefault to this)

AndroidL系统启动及加载流程分析

Android L系统启动及加载流程分析 1、概述 Android L的启动可以分为几个步骤:Linux内核启动、init进程启动、native系统服务及java系统服务启动、Home启动,主要过程如下图: 图1 整个启动流程跟4.4及之前的版本相差不多,只是有个别不同之处,本文我们主要分析Linux内核启动之后的过程。

2、启动过程分析 2.1 init进程启动 当系统内核加载完成之后,会启动init守护进程,它是内核启动的第一个用户级进程,是Android的一个进程,进程号为1,init进程启动后执行入口函数main(),主要操作为: 图2 AndroidL上将selinux的安全等级提高了,设为了enforcing模式,4.4上是permissive模式。 解析rc脚本文件,即init.rc脚本,该文件是Android初始化脚本,定义了一系列的动作和执行这些动作的时间阶段e aryl-init、init、early-boot、boot、post-fs等阶段。init进程main 函数中会根据这些阶段进行解析执行。AndroidL上为了流程更清晰,增加了charger(充电开机)、ffbm(工厂模式)、以及late-init阶段,实际上这些阶段是对其他阶段的组合执行,比如late-init:

2.2 ServiceManager的启动 servicemanager的启动就是init进程通过init.rc脚本启动的: 源码在frameworks/native/cmds/servicemanager/service_manager.c中,servicemanager是服务管理器,它本身也是一个服务(handle=0),通过binder调用,为native和Java系统服务提供注册和查询服务的,即某个服务启动后,需要将自己注册到servicemanager中,供其他服务或者应用查询使用。AndroidL上servicemanger中在处理注册和查询动作之前添加了selinux安全检测相关的处理。 2.3 SurfaceFinger、MediaServer进程启动 Android4.4以前,surfacefinger的启动根据属性system_init.startsurfaceflinger,决定是通过init.rc启动还是systemserver进程启动,之后的版本包括AndoridL都是通过init.rc启动的: 启动后会向servicemanager进程注册服务中,该服务启动时主要功能是初始化整个显

android开机启动流程简单分析

android开机启动流程简单分析 android启动 当引导程序启动Linux内核后,会加载各种驱动和数据结构,当有了驱动以后,开始启动Android系统同时会加载用户级别的第一个进程init(system\core\init\init.cpp)代码如下: int main(int argc, char** argv) { ..... //创建文件夹,挂载 // Get the basic filesystem setup we need put together in the initramdisk // on / and then we'll let the rc file figure out the rest. if (is_first_stage) { mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); mkdir("/dev/pts", 0755); mkdir("/dev/socket", 0755); mount("devpts", "/dev/pts", "devpts", 0, NULL); #define MAKE_STR(x) __STRING(x) mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC)); mount("sysfs", "/sys", "sysfs", 0, NULL); } ..... //打印日志,设置log的级别 klog_init(); klog_set_level(KLOG_NOTICE_LEVEL); ..... Parser& parser = Parser::GetInstance(); parser.AddSectionParser("service",std::make_unique()); parser.AddSectionParser("on", std::make_unique()); parser.AddSectionParser("import", std::make_unique()); // 加载init.rc配置文件 parser.ParseConfig("/init.rc"); } 加载init.rc文件,会启动一个Zygote进程,此进程是Android系统的一个母进程,用来启动Android的其他服务进程,代码: 从Android L开始,在/system/core/rootdir 目录中有4 个zygote 相关的启动脚本如下图:

相关文档
最新文档