﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Thinking in XiaoQiang-文章分类-google-android</title><link>http://www.blogjava.net/uiiang/category/31928.html</link><description>世人皆有悲哀，只有你不明白</description><language>zh-cn</language><lastBuildDate>Wed, 04 Jun 2008 00:12:14 GMT</lastBuildDate><pubDate>Wed, 04 Jun 2008 00:12:14 GMT</pubDate><ttl>60</ttl><item><title>对Android启动过程的进一步研究(转载)</title><link>http://www.blogjava.net/uiiang/articles/205606.html</link><dc:creator>小强</dc:creator><author>小强</author><pubDate>Tue, 03 Jun 2008 09:32:00 GMT</pubDate><guid>http://www.blogjava.net/uiiang/articles/205606.html</guid><wfw:comment>http://www.blogjava.net/uiiang/comments/205606.html</wfw:comment><comments>http://www.blogjava.net/uiiang/articles/205606.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/uiiang/comments/commentRss/205606.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/uiiang/services/trackbacks/205606.html</trackback:ping><description><![CDATA[<p>转载:http://www.forwind.cn/category/linux/android/<br />
<span style="font-size: 14pt"><br />
对于关注Android底层的朋友来说，其具体的启动过程应该是比较吸引我们的。但是很多启动文件什么的，都得adb push到host上来看，挺不方便的，都怪Android自带的Toolbox太简略了。所以在深入了解Android的启动流程之前，我们来把Busybox安装到Android上去，这样，就有很多工具供我们使用了。</span></p>
<p><span style="font-size: 14pt">首先去</span><a id="c0bg" title="busybox主页" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.busybox.net');" href="http://www.busybox.net/"><span style="font-size: 14pt">busybox主页</span></a><span style="font-size: 14pt"> 下载最新版本的源代码，然后用arm的交叉编译器编译出busybox的可执行程序，编译的时候需要注意一些设置选项，例如</span></p>
<p><span style="font-size: 14pt">Build Options —&gt;<br />
[*] Build BusyBox as a static binary (no shared libs) 这个要选上，因上这样子编译出来的busyBox才是可以独立运行的。<br />
│[*] Do you want to build BusyBox with a Cross Compiler? │ │<br />
│ │(/HOME/toolchains/gcc-4.0.2-glibc-2.3.5/arm-9tdmi-linux-gnu/bin/arm-9tdmi-linux-gnu│ 这是交叉编译器的路径，要根据具体的情况来设置。<br />
Installation Options —&gt;<br />
[*] Don&#8217;t use /usr<br />
这样子编译出来的busybox才不会安装到你主机的/usr目录下。一定要选上。</span></p>
<p><span style="font-size: 14pt">busybox的功能选项根据需要自选,但是不要太贪心.</span></p>
<p><span style="font-size: 14pt">OK，这里就不纠缠于编译busybox的东西了，网上资料无数。接下来，我们把busybox安装到模拟器上去。先在模拟器上随便建一个busybox的文件夹，然后进入busybox可执行文件目录，使用命令</span></p>
<blockquote>
<p><span style="font-size: 14pt">adb push busybox.asc /data/busybox/busybox</span></p>
</blockquote>
<p><span style="font-size: 14pt">然后进入adb shell，chmod 777 ./busybox，就可以直接使用了。但现在还是不方便，总不能每用一个命令就输一次busybox吧？所以，我们可以先用<code>./busybox --install将程序都安装到当前目录下，然后把当前目录添加到PATH变量中即可。暂时使用export来添加吧，如果想永久添加，往下看。</code></span></p>
<p><span style="font-size: 14pt">好了，准备工作完成，开始研究的工作了。既然是研究启动过程，那当然是先看看init.rc文件。去etc目录打开它，分析一下内容，首先是对env的定义，也就是全局环境变量的定义，接下来的建立和初始化里面的内容目前还不清楚什么意思，紧接着就是系统启动时运行的初始进程信息，这个比较有意思，包括了usbd-config和qemu，qemu自不用说，而usbd-config作为初始启动的进程，应该就是和上一篇文章猜的一样，用来调试或者usb通信的。往下看，是在初始启动进程完成之后开始启动的服务进程，这些进程如果因故退出，会自动重启。这里面包括了console控制台，adbd监护进程，usbd监护进程，debuggerd监护进程等.除去这些守护进程，能引起我们注意的，是runtime和zygote。这两个进程似乎掌管着其他进程以及应用程序的启动。</span></p>
<p><span style="font-size: 14pt">现在，来让我们做一个实验吧，将自动调用的启动过程变成手动，看看启动流程具体是什么样的。想达到这个目的，首先就是要修改init.rc文件，当然不是在模拟器的console中改，一是不能改，二是你改了也没用，下次加载就会给你覆盖了。所以，我们要从原始镜像<code>ramdisk.img入手了。从</code>2.6标准Linux内核开始，initrd.img都采用cpio压缩，猜测ramdisk.img也一样，需要使用gunzip解压缩，然后再使用cpio解包。好，</span><code><span style="font-size: 14pt">进入tools/lib/images目录下，先用file命令看看ramdisk.img的类型，没错，系统提示<br />
</span></code></p>
<blockquote>
<p><code><span style="font-size: 14pt">ramdisk.img: gzip compressed data, from Unix</span></code></p>
</blockquote>
<p><code><span style="font-size: 14pt">很好，然后将ramdisk.img复制一份到任何其他目录下，将其名称改为ramdisk.img.gz，并使用命令<br />
</span></code></p>
<blockquote>
<p><code><span style="font-size: 14pt">gunzip ramdisk.img.gz</span></code></p>
</blockquote>
<p><code><span style="font-size: 14pt">然后新建一个文件夹，叫ramdisk吧，进入，输入命令<br />
</span></code></p>
<blockquote>
<p><code><span style="font-size: 14pt">cpio -i -F ../ramdisk.img</span></code></p>
</blockquote>
<p><span style="font-size: 14pt">这下，你就能看见并操作ramdisk里面的内容了。当然你也可以直接在外面进行操作，但是还是建议把cpio解压缩出来的内容全部集中在一个文件夹里面，因为一会我们还要将其压缩成新的ramdisk.img。</span></p>
<p><span style="font-size: 14pt">OK，现在开始修改步骤吧。用任何一款编辑器打开init.rc，首先在PATH那里加上你的Busybox安装路径，然后注释内容，我们要手工启动他们。</span></p>
<blockquote>
<p><span style="font-size: 14pt"># zygote {<br />
# exec /system/bin/app_process<br />
# args {<br />
# 0 -Xzygote<br />
# 1 /system/bin<br />
# 2 &#8211;zygote<br />
# }<br />
# autostart 1<br />
# }# runtime {<br />
# exec /system/bin/runtime<br />
# autostart 1<br />
# }</span></p>
</blockquote>
<p><span style="font-size: 14pt">在这里需要注意，不要同时把两者都注释了，注释某一个，再试验手工启动它，如果两者同时注释我这里有问题，无法启动。</span></p>
<p><span style="font-size: 14pt">好，接下来，使用下列命令重新打包成镜像</span></p>
<blockquote>
<p><span style="font-size: 14pt">cpio -i -t -F ../ramdisk.img &gt; list<br />
cpio -o -H newc -O lk.img &lt; list</span></p>
</blockquote>
<p><span style="font-size: 14pt">当前目录下生成的lk.img就是我们的新镜像了。使用自己的镜像启动emulator；</span></p>
<blockquote>
<p><span style="font-size: 14pt">emulator -console -ramdisk lk.img</span></p>
</blockquote>
<p><span style="font-size: 14pt">如果我们注释的是zygote，那么在#后输入</span></p>
<blockquote>
<p><span style="font-size: 14pt">app_process -Xzygote /system/bin &#8211;zygote</span></p>
</blockquote>
<p><span style="font-size: 14pt">手工启动，命令行中输出的信息是</span></p>
<blockquote>
<p><span style="font-size: 14pt">Prepping: /system/app/AlarmProvider.apk:/system/app/Browser.apk:/system/app/Calendar.apk:/system/app/Camera.apk:/system/app/Contacts.apk:<br />
/system/app/Development.apk:/system/app/GDataFeedsProvider.apk:/system/app/Gmail.apk:/system/app/GmailProvider.apk:/system/app/GoogleApps.apk:<br />
/system/app/GoogleAppsProvider.apk:/system/app/Home.apk:/system/app/ImProvider.apk:/system/app/Maps.apk:/system/app/MediaPickerActivity.apk:<br />
/system/app/MediaProvider.apk:/system/app/Phone.apk:/system/app/PimProvider.apk:/system/app/ApiDemos.apk:/system/app/SettingsProvider.apk:<br />
/system/app/Sms.apk:/system/app/SyncProvider.apk:/system/app/TelephonyProvider.apk:/system/app/XmppService.apk:/system/app/YouTube.apk<br />
File not found: /system/app/AlarmProvider.apk<br />
File not found: /system/app/Calendar.apk<br />
File not found: /system/app/Camera.apk<br />
File not found: /system/app/GDataFeedsProvider.apk<br />
File not found: /system/app/Gmail.apk<br />
File not found: /system/app/GmailProvider.apk<br />
File not found: /system/app/MediaPickerActivity.apk<br />
File not found: /system/app/PimProvider.apk<br />
File not found: /system/app/ApiDemos.apk<br />
File not found: /system/app/Sms.apk<br />
File not found: /system/app/SyncProvider.apk<br />
File not found: /system/app/YouTube.apk<br />
Prep complete</span></p>
</blockquote>
<p><span style="font-size: 14pt">嘿嘿，从File not found的信息中可以看到一些Google可能会即将推出的应用，比如Gmail什么的。当然，这些都是Java框架的启动信息，我们以后还要借助其他工具来进行进一步探索。</span></p>
<p><span style="font-size: 14pt">如果我们注释的是runtime，那么输出信息是：</span></p>
<blockquote>
<p><span style="font-size: 14pt">+++ post-zygote</span></p>
</blockquote>
<p><span style="font-size: 14pt">看起来似乎zygote像是一个进程管理者，runtime通过与其沟通来启动新的进程，特别是那些系统服务进程。老实说，没有确切明白是啥意思，呵呵，吃饭时间到了，懒得看了。</span></p>
<p><span style="font-size: 14pt">好了，今天就说到这，基本的方法就是这样，有兴趣的朋友可以进一步深入研究。我们下一篇文章见。</span></p>
<img src ="http://www.blogjava.net/uiiang/aggbug/205606.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/uiiang/" target="_blank">小强</a> 2008-06-03 17:32 <a href="http://www.blogjava.net/uiiang/articles/205606.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>