Submitted by admin on 2011, July 19, 11:39 AM
1. 说明
1) 下载编译最基本的android源码,无法在真机上使用(不能生成boot.img),只能在模拟器上使用。这是因为没有编译相关机型的内核和硬件驱动。以下介绍的是用android源码编译出对应HTC G1的版本,和烧写的过程。编译生成的版本除相机不能用之外,其它绝大部分功能都能正常使用,在G1上运行2.1版的速度也不错。
2) 本文主要参考日文文档G1/G2烧机指南,感谢原文作者,原文地址:
http://code.google.com/p/android-development-environment/wiki/EclaironADP1andADP2
同时加入中文系统的支持和JIT支持(提高速度),以及相关文字解释。
3) 以下步骤都经过验证(只验证G1手机,G2部分请参见日文文档),实验系统ubuntu8.04,实验日期2010年5月8日
4) 关键字: android 2.1 eclair g1 源码编译
2. 建立android源码编译目录
$ export ANDROID=/exports/android/android_2.1_cn/
$ mkdir -p $ANDROID
$ cd $ANDROID
3. 源码下载
$ repo init -u git://android.git.kernel.org/platform/manifest.git -b android-2.1_r2 #设定下载 2.1版代码
$ vi .repo/local_manifest.xml # 新建下载配置文件
编辑内容如下
<?xml version=”1.0″ encoding=”UTF-8″?>
<manifest>
<project path=”kernel” name=”kernel/msm” revision=”refs/heads/android-msm-2.6.29-donut”/>
<project path=”vendor/htc/common-open” name=”platform/vendor/htc/common-open” revision=”master”/>
<project path=”vendor/htc/dream-open” name=”platform/vendor/htc/dream-open” revision=”master”/>
<project path=”vendor/htc/prebuilt-open” name=”platform/vendor/htc/prebuilt-open” revision=”master”/>
<project path=”vendor/htc/sapphire-open” name=”platform/vendor/htc/sapphire-open” revision=”master”/>
<project path=”vendor/qcom/android-open” name=”platform/vendor/qcom/android-open” revision=”master”/>
<project path=”vendor/qcom/proprietary-open” name=”platform/vendor/qcom/proprietary-open” revision=”master”/>
<project path=”vendor/pv-open” name=”platform/vendor/pv-open” revision=”master”/>
<project path=”vendor/aosp” name=”platform/vendor/aosp” revision=”master”/>
<project path=”hardware/htc/dream” name=”platform/hardware/htc/dream” revision=”master”/>
</manifest>
注意:其中msm是高通芯片组,path指明下载到源码目录中的位置,name指明git上的项目名
$ repo sync # 开始下载代码,此时需要等待较长时间
4. 打补丁以支持动态壁纸(此为步骤为可选)
$ wget http://android-development-environment.googlecode.com/files/patch_devphone_eclair.tar.gz
$ tar zxvf patch_devphone_eclair.tar.gz
$ ./patch/eclair-build-patch.sh
5. 编译内核及无线网络驱动
$ cd $ANDROID/kernel
$ make ARCH=arm CROSS_COMPILE=../prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- msm_defconfig # 设定默认的msm配置
$ vi .config # 修改新生成的配置文件,以重新设置CPU最高频率,修改如下:
修改CONFIG_MSM_CPU_FREQ_ONDEMAND_MAX项为CONFIG_MSM_CPU_FREQ_ONDEMAND_MAX=528000
$ make ARCH=arm CROSS_COMPILE=../prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- #编译内核
$ cd $ANDROID/system/wlan/ti/sta_dk_4_0_4_32
$ make ARCH=arm CROSS_COMPILE=$ANDROID/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- KERNEL_DIR=$ANDROID/kerne l #编译无线网络驱动
$ cp $ANDROID/kernel/arch/arm/boot/zImage $ANDROID/vendor/htc/dream-open/kernel
$ cp $ANDROID/system/wlan/ti/sta_dk_4_0_4_32/wlan.ko $ANDROID/vendor/htc/dream-open/wlan.ko
6. 编译android源码
在HTC网站http://developer.htc.com/adp.html
下载名为signed-dream_devphone_userdebug-ota-14721.zip的包,并把它放在$ANDROID目录下
$ cd $ANDROID
$ source build/envsetup.sh
$ lunch aosp_dream_us-eng # 指明机型
$ cd vendor/htc/dream-open
$ ./unzip-files.sh # 解压htc相关驱动
$ cd $ANDROID
$ vi buildspec.mk # 新建配置文件
加入如下内容
CUSTOM_LOCALES:=zh_CN # 设置编译为中文系统
WITH_JIT:=true # 加入JIT支持,使得运算速度加快1-2倍
$ make -j2 # 编译android源码,需要等待较长时间
7. 把编译好的软件烧写到手机
用usb线连接手机到电脑,按home+power键将手机启动到工程模式,按back键准备烧写
$ export PATH=$PATH:$ANDROID/out/host/linux-x86/bin # 把烧写工具所在目录加上路径
$ cd out/target/product/dream-open/
$ fastboot flash system system.img
$ fastboot flash boot boot.img
$ fastboot reboot
烧写系统后第一次启动手机需要几分钟,请耐心等待
8. 参考
1) 刷写部分未详细描述,具体请参考文档
http://xy0811.spaces.live.com/blog/cns!F8AECD2A067A6B17!1452.entry
2) 源码编译部分未详细描述,具体请参考文档
http://xy0811.spaces.live.com/blog/cns!F8AECD2A067A6B17!1364.entry
linux | 评论:0
| Trackbacks:0
| 阅读:1021
Submitted by admin on 2011, July 19, 11:19 AM
共享UID
安装在设备中的每一个Android包文件(.apk)都会被分配到一个属于自己的统一的Linux用户ID,并且为它创建一个沙箱,以防止影响其他应用程序(或者其他应用程序影响它)。用户ID 在应用程序安装到设备中时被分配,并且在这个设备中保持它的永久性。
通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中.所以默认就是可以互相访问任意数据. 也可以配置成运行成不同的进程, 同时可以访问其他APK的数据目录下的数据库和文件.就像访问本程序的数据一样.
对于一个APK来说,如果要使用某个共享UID的话,必须做三步:
1、在Manifest节点中增加android:sharedUserId属性。
2、在Android.mk中增加LOCAL_CERTIFICATE的定义。
如果增加了上面的属性但没有定义与之对应的LOCAL_CERTIFICATE的话,APK是安装不上去的。提示错误是:Package com.test.MyTest has no signatures that match those in shared user android.uid.system; ignoring!也就是说,仅有相同签名和相同sharedUserID标签的两个应用程序签名都会被分配相同的用户ID。例如所有和media/download相关的APK都使用android.media作为sharedUserId的话,那么它们必须有相同的签名media。
3、把APK的源码放到packages/apps/目录下,用mm进行编译。
举例说明一下。
系统中所有使用android.uid.system作为共享UID的APK,都会首先在manifest节点中增加android:sharedUserId="android.uid.system",然后在Android.mk中增加LOCAL_CERTIFICATE := platform。可以参见Settings等
系统中所有使用android.uid.shared作为共享UID的APK,都会在manifest节点中增加android:sharedUserId="android.uid.shared",然后在Android.mk中增加LOCAL_CERTIFICATE := shared。可以参见Launcher等
系统中所有使用android.media作为共享UID的APK,都会在manifest节点中增加android:sharedUserId="android.media",然后在Android.mk中增加LOCAL_CERTIFICATE := media。可以参见Gallery等。
另外,应用创建的任何文件都会被赋予应用的用户标识,并且正常情况下不能被其他包访问。当通过getSharedPreferences(String,int)、openFileOutput(String、int)或者openOrCreate Database(String、int、SQLiteDatabase.CursorFactory)创建一个新文件时,开发者可以同时或分别使用MODE_WORLD_READABLE和MODE_WORLD_RITEABLE标志允许其他包读/写此文件。当设置了这些标志后,这个文件仍然属于自己的应用程序,但是它的全局读/写和读/写权限已经设置,所以其他任何应用程序可以看到它。
关于签名:
build/target/product/security目录中有四组默认签名供Android.mk在编译APK使用:
1、testkey:普通APK,默认情况下使用。
2、platform:该APK完成一些系统的核心功能。经过对系统中存在的文件夹的访问测试,这种方式编译出来的APK所在进程的UID为system。
3、shared:该APK需要和home/contacts进程共享数据。
4、media:该APK是media/download系统中的一环。
应用程序的Android.mk中有一个LOCAL_CERTIFICATE字段,由它指定用哪个key签名,未指定的默认用testkey.
参考文档:
Android中如何修改系统时间(应用程序获得系统权限)
http://blog.csdn.net/liujian885/archive/2010/03/22/5404834.aspx
Android-sharedUserId数据权限
http://wallage.blog.163.com/blog/static/17389624201011010539408/
Runtime.exec权限问题
http://blog.csdn.net/yihua0001/archive/2010/07/23/5758980.aspx
关于签名
http://blog.csdn.net/duandianGG/archive/2010/07/21/5752568.aspx
android | 评论:0
| Trackbacks:0
| 阅读:1023
Submitted by admin on 2011, July 19, 11:19 AM
在 android 的API中有提供 SystemClock.setCurrentTimeMillis()函数来修改系统时间,可惜无论你怎么调用这个函数都是没用的,无论模拟器还是真机,在logcat中总会得到"Unable to open alarm driver: Permission denied ".这个函数需要root权限或者运行与系统进程中才可以用。
本来以为就没有办法在应用程序这一层改系统时间了,后来在网上搜了好久,知道这个目的还是可以达到的。
第一个方法简单点,不过需要在Android系统源码的环境下用make来编译:
1. 在应用程序的AndroidManifest.xml中的manifest节点中加入android:sharedUserId="android.uid.system"这个属性。
2. 修改Android.mk文件,加入LOCAL_CERTIFICATE := platform这一行
3. 使用mm命令来编译,生成的apk就有修改系统时间的权限了。
第二个方法麻烦点,不过不用开虚拟机跑到源码环境下用make来编译:
1. 同上,加入android:sharedUserId="android.uid.system"这个属性。
2. 使用eclipse编译出apk文件,但是这个apk文件是不能用的。
3. 用压缩软件打开apk文件,删掉META-INF目录下的CERT.SF和CERT.RSA两个文件。
4. 使用目标系统的platform密钥来重新给apk文件签名。这步比较麻烦,首先找到密钥文件,在我的Android源码目录中的位置是"build/target/product/security",下面的platform.pk8和platform.x509.pem两个文件。然后用Android提供的Signapk工具来签名,signapk的源代码是在"build/tools/signapk"下,用法为"signapk platform.x509.pem platform.pk8 input.apk output.apk",文件名最好使用绝对路径防止找不到,也可以修改源代码直接使用。
这样最后得到的apk和第一个方法是一样的。
最后解释一下原理,首先加入android:sharedUserId="android.uid.system"这个属性。通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中。那么把程序的UID配成android.uid.system,也就是要让程序运行在系统进程中,这样就有权限来修改系统时间了。
只是加入UID还不够,如果这时候安装APK的话发现无法安装,提示签名不符,原因是程序想要运行在系统进程中还要有目标系统的platform key,就是上面第二个方法提到的platform.pk8和platform.x509.pem两个文件。用这两个key签名后apk才真正可以放入系统进程中。第一个方法中加入LOCAL_CERTIFICATE := platform其实就是用这两个key来签名。
这也有一个问题,就是这样生成的程序只有在原始的Android系统或者是自己编译的系统中才可以用,因为这样的系统才可以拿到platform.pk8和platform.x509.pem两个文件。要是别家公司做的Android上连安装都安装不了。试试原始的Android中的key来签名,程序在模拟器上运行OK,不过放到G3上安装直接提示"Package ... has no signatures that match those in shared user android.uid.system",这样也是保护了系统的安全。
最最后还说下,这个android:sharedUserId属性不只可以把apk放到系统进程中,也可以配置多个APK运行在一个进程中,这样可以共享数据,应该会很有用的。
android | 评论:0
| Trackbacks:0
| 阅读:921
Submitted by admin on 2011, July 19, 11:11 AM
adbd源码位于system/core/adb/目录下,可执行文件位于/sbin/adbd。通过adb执行ps命令,结果如下:
USER PID PPID VSIZE RSS WCHAN PC NAME
root 1 0 296 212 c00b0124 0000d9ec S /init
... ...
shell 2183 1 3372 184 ffffffff 0000eca4 S /sbin/adbd
root 2204 1859 832 336 00000000 afe0c7dc R ps
看一下倒数第二行,adbd所在进程的父进程是root,本身的user是shell。对于一个发布状态的产品,这个是最正常不过了。但现在开发中遇到这样一个需求,产品已经处在发布状态(编译模式已经改成user)的情况下,因为BSP需要处理一些内核上的东西,需要在PC上执行adb shell后具有root权限。也就是这种效果:
USER PID PPID VSIZE RSS WCHAN PC NAME
root 1 0 296 212 c00b0124 0000d9ec S /init
... ...
root 1911 1 3376 184 ffffffff 0000eca4 S /sbin/adbd
root 2198 2197 828 332 00000000 afe0c7dc R ps
要达到这个效果,就是要在启动adbd时,以root用户启动。那么,先看一下在Android中怎么启动adbd。
可以看一下Android系统根目录下的/init.rc的片段:
... ...
# adbd is controlled by the persist.service.adb.enable system property
service adbd /sbin/adbd
disabled
# adbd on at boot in emulator
on property:ro.kernel.qemu=1
start adbd
on property:persist.service.adb.enable=1
start adbd
on property:persist.service.adb.enable=0
stop adbd
... ...
这里定义了一个触发器,只要persist.service.adb.enable值被置为1,就会启动/sbin/adbd。
怎么样设置persist.service.adb.enable的值呢?这里涉及到一个属性服务/system/core/init/property_service.c。看下面的东西之前先看一下我之前翻译过来的这篇StevGuo的文档,他对属性服务描述得很仔细,也很有条理。
http://blog.csdn.net/a345017062/archive/2010/12/17/6083026.aspx
今天搜资料的时候才发现网上N多人翻译了这篇文章,有点儿晕晕的。。。
我们继续。。。
通过阅读上面的文档,我们知道了属性服务启动时加载了四个文件,这四个文件里面都可以设置系统属性,还可以通过APK设置系统属性。但我把这些方式都,结果都一样,adbd是启动起来了,用户都是shell,还是没有root权限的。看来差异应该在编译模式上,是改为user编译模式后,系统改变了adbd启动时的权限。在build目录下搜索一下,发现了main.mk中有这样的代码片段
## user/userdebug ##
user_variant := $(filter userdebug user,$(TARGET_BUILD_VARIANT))
enable_target_debugging := true
ifneq (,$(user_variant))
# Target is secure in user builds.
ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=1
tags_to_install := user
ifeq ($(user_variant),userdebug)
# Pick up some extra useful tools
tags_to_install += debug
else
# Disable debugging in plain user builds.
enable_target_debugging :=
endif
# TODO: Always set WITH_DEXPREOPT (for user builds) once it works on OSX.
# Also, remove the corresponding block in config/product_config.make.
ifeq ($(HOST_OS)-$(WITH_DEXPREOPT_buildbot),linux-true)
WITH_DEXPREOPT := true
endif
# Disallow mock locations by default for user builds
ADDITIONAL_DEFAULT_PROPERTIES += ro.allow.mock.location=0
else # !user_variant
# Turn on checkjni for non-user builds.
ADDITIONAL_BUILD_PROPERTIES += ro.kernel.android.checkjni=1
# Set device insecure for non-user builds.
ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=0
# Allow mock locations by default for non user builds
ADDITIONAL_DEFAULT_PROPERTIES += ro.allow.mock.location=1
endif # !user_variant
ifeq (true,$(strip $(enable_target_debugging)))
# Target is more debuggable and adbd is on by default
ADDITIONAL_DEFAULT_PROPERTIES += ro.debuggable=1 persist.service.adb.enable=1
# Include the debugging/testing OTA keys in this build.
INCLUDE_TEST_OTA_KEYS := true
else # !enable_target_debugging
# Target is less debuggable and adbd is off by default
ADDITIONAL_DEFAULT_PROPERTIES += ro.debuggable=0 persist.service.adb.enable=0
endif # !enable_target_debugging
这段代码我大致解释一下:
主要通过判断当前的编译模式来给几个属性赋予不同的值,然后把属性存储在ADDITIONAL_DEFAULT_PROPERTIES这个变量中,这个变量在后面是要写到根目录下的/default.prop中去,在系统启动时被属性服务加载的。也就是说我们在/default.prop中看到的几个属性的值是在这里设置的。
只看两个属性ro.secure,persist.service.adb.enable。当前是user模式的话,编译系统会把ro.secure置为1,把persist.service.adb.enable置为0.也就是说,用user模式编译出来的系统运行在安全模式下,adbd默认关闭。即使通过设置属性的方式打开,adbd进程的用户也是shell,不具有root权限。这样,普通用户或者开发者拿到一个机器后,通过PC运行adb shell时,是以shell用户登录机器的。
好了,现在把ro.secure置为0,再重新编译,只要设置属性persist.service.adb.enable的值为1,adbd进程就会以root用户的身份启动。
http://blog.csdn.net/a345017062/article/details/6254402
android | 评论:0
| Trackbacks:0
| 阅读:1910
Submitted by admin on 2011, July 19, 11:06 AM
bionic,整个系统的基础类库,Android系统就是基于这个类库开发的,
system,Android系统类库,基于bionic类库开发,包含工具类库(libcutils),LOG类库(liblog),压缩类库(libzipfile)类。
主要功能有:
一、完成Android初始化(init)。
解析init.rc并开启系统初始化时需要加载的程序(parser.c),初始化设备(devices.c),开启属性服务(property_service.c)等。
二、开启Android系统的一些基础服务。
1、系统的设备服务(vold)。比如完成SD卡挂载、卸载管理,从内核处接收事件建立设备结点等。
三、SHELL程序及相应的toolbox。
四、ADB程序。
五、logcat系统。
可以说,bionic和system两个文件里的东西完成了Android对Linux的封装,在这两个文件夹的基础上构建起了Android系统的两大核心模块:Dalvik和Framework。Dalvik是一个基础纯C的VM,这个网上有比较详细的说明。重点一层层地分析一下Framework。
最底层就是几大模块:
1、utils工具库(frameworks/base/libs/utils/目录下)
这个类库基于bionic编译写,提供了一些对bionic里面的基础C/C++类库中的高层次封装。Framework中的C++程序大量使用这里的类库来封装更高层的系统功能。
2、binder库(framewoks/base/libs/binder/目录下)
这个与OpenBinder开源项目相似,提供了一种进程通信机制。C++和Java层都大量使用了这种机制。它把通信双方分为服务提供者和使用者两种角色。提供者内部有注册的服务接口,使用者去查找调用。
3、ui库(frameworks/base/libs/ui/目录下)
这个库主要提供了UI绘制和视频输出两类接口,整个系统的输出框架都是以这个库为基础,通过它与FrameBuffer通信。
4、surfaceflinger库(frameworks/base/libs/surfaceflinger/目录下)
对ui库的更高层次的封装,通过binder机制对Android系统中的上层模块提供输出服务。
5、audioflinger库(frameworks/base/libs/audioflinger/目录下)
音频输出基础类库,上层模块通过这个库与驱动还有打交导输出声音。
6、大量开源库(external/目录下)
这几大模块构成了整个Framework的基础。围绕这几大模块,就可以构建一个真正的操作系统的上层模块,创建应用程序运行环境了。比较典型的有:
多媒休服务,提供给音视频播放和录制服务。
服务管理,维护和管理系统中存在的大量服务提供程序,应用程序通过binder机制通过服务管理中心的servicemanager来访问和使用这些服务,比如电源、蓝牙、Wifi等模块都以服务的形式存在于系统中供应用程序调用。
运行时环境,初始化应用程序的运行环境,并加载第一个应用程序,Launcher。
应用程序运行时环境创建完成后,系统就算正式启动起来了。当一个应用程序被加载到系统中时,它和系统打交导最多的就是系统提供的开发API了。主要集中在frameworks/base/core/目录下。
转
android | 评论:0
| Trackbacks:0
| 阅读:921
Submitted by admin on 2011, July 19, 11:00 AM
折腾了几天,被Android那点儿少得可怜的shell命令折磨的死去活来,终于下定了革命的决心。看一下怎么把渺小的toolbox替换成伟大的busybox吧。先大致描述一下Android系统中的shell程序部分。
shell实现分为两部分:
一、shell解释器和内置命令
源码位于system/core/sh目录下,主要完成shell命令的解释查找,对于builtins.c中包含的内置命令,直接执行,对于toolbox的扩展命令,间接调用toolbox程序完成。
二、toolbox扩展命令
主要完成扩展命令的执行,每一个扩展命令对应一个name_main函数,如ls命令,对应ls_main函数。同时,每一个扩展命令都由一个system/core/toolbox/目录下面的.c文件实现。toolbox.c会根据这个目录下面的.c文件生成tools.h头文件,并在system/core/toolbox/Android.mk文件中为每个命令生成指向toolbox的连接。toolbox的实现结构使它扩展一个命令很容易。
假设现在我们自己想手工添加一个shell命令mycommand,只要在system/core/toolbox/目录下面新建一个mycommand.c文件,并在里面实现一个mycommand_main函数,然后在system/core/toolbox/Android.mk中添加mycommand.c即可。Android.mk会自动把它编译进toolbox程序,并在编译生成的Android系统/system/bin目录下为这个命令生成一个指向toolbox的连接。
接下来翻译一下网上的一篇文章,借助它,可以把Android自带的toolbox替换成busybox。
Installing Busybox command line tools
英文原文地址:
https://gforge.ti.com/gf/project/omapandroid/wiki/?pagename=Installing+Busybox+command+line+tools
在Android系统中安装busybox命令行工具
本文简单地介绍了怎么把busybox安装到Android的文件系统中去。如果你想直接安装,可以从下面的地址下载我已经预编译好并在Android2.1系统上试验成功的busybox,然后直接跳过下面的安装步骤。
http://download.csdn.net/source/3093680
一、编译busybox
1、下载busybox的最新版本,本文写作时最新版本是1.13.3。
下载地址:http://www.busybox.net/
2、解压源码:
tar jxf busybox-1.13.3.tar.bz2
3、运行menuconfig对busybox进行配置
cd busybox-1.13.3/
make menuconfig
4、在menuconfig中设置以下选项
Busybox Settings --> Build Options --> Build Busybox as a static binary (no shared libs) - Enable this option by pressing "Y"
Busybox Settings --> Build Options --> Cross compiler prefix - Set this option equal to "arm-none-linux-gnueabi-"
Busybox Settings --> Installation Options --> Don't use /usr - Enable this option by pressing "Y"
5、把交叉编译器的地址导入到环境变量:
export PATH=/opt/arm/arm-2007q3/bin:$PATH
6、编译busybox
make
二、安装busybox
把busybox安装到Android系统中去,做这几步:
1、在Android系统根目录下创建一个/bin目录。
mkdir /<path-to-android-fs>/bin
2、把编译出来的busybox复制到/bin目录下
cp busybox /<path-to-android-fs>/bin
3、把busybox安装到Android机器中
cd /bin
./busybox --install
三、把busybox作为默认shell
需要像下面这样编辑一下init.rc
1、编辑console服务,让它默认运行busybox
service console /system/bin/sh -> service console /bin/sh
2、把busybox路径加入到环境变量中
export PATH /sbin:/system/sbin:/system/bin:/system/xbin --> export PATH /bin:/sbin:/system/sbin:/system/bin:/system/xbin
注:
我使用busybox时,只是想简单地增加一些命令,把toolbox一些功能不是很全的命令替换掉,所以操作上没有上面说的那么复杂。下面是我的替代方案,可以试一下:
1、把busybox复制到/system/bin目录下。
adb push busybox /system/bin
2、把要添加的命令通过ln建立到busybox的连接。
比如,Android自带的toolbox是没有test这个命令的。我们要添加test命令就可以:
cd /system/bin
ln -s busybox test
这样,用户通过机器上的shell执行test命令时,就会调用busybox中实现test功能的applet。
对于一些原有的命令,如ls、chown等,如果不想用toolbox,也可以把它们的连接目标指向toolbox,拿chown来举例。
cd /system/bin
rm chown
ln -s busybox chown
这样做,最大的好处就是保证对系统的改动最少,又可以最大限度的扩展shell功能。
参考文档:
为Android加入busybox工具
http://blog.csdn.net/liaoshengjiong/archive/2009/03/04/3957725.aspx
什么是交叉编译
http://www.linuxeden.com/doc/article.php/21264
加入 busybox source
http://cwhuang.info/2010/03/ad-busybox-source
转 http://blog.csdn.net/a345017062/article/details/6250619
android | 评论:0
| Trackbacks:0
| 阅读:937
Submitted by admin on 2011, July 19, 10:36 AM
1. 软盘上安装引导器(grub)
一般制作软盘上跑的Linux引导器都使用sysLinux这个工具(这个工具不支持ext2分区格式,只能支持fat分区格式),因为我对grub比较熟悉,并且我在软盘上安装grub只用了132KB空间,不是很耗磁盘空间。
具体操作如下:
# mke2fs /dev/fd0
创建了 ext2 文件系统后,需要安装该文件系统:
# mount /dev/fd0 /mnt/floppy
现在,需要创建一些目录,并将一些关键文件(原先安装 GRUB 时已安装了这些文件)复制到软盘:
# mkdir /mnt/floppy/boot
# mkdir /mnt/floppy/boot/grub
# cp /boot/grub/stage1 /mnt/floppy/boot/grub
# cp /boot/grub/stage2 /mnt/floppy/boot/grub
再有一个步骤,就能得到可用的引导盘。
在Linux bash中,从 root 用户运行“grub”,该程序非常有趣并值得注意,因为它实际上是 GRUB 引导装入器的半功能性版本。尽管 Linux 已经启动并正在运行,您仍可以运行 GRUB 并执行某些任务,而且其界面与使用 GRUB 引导盘或将 GRUB 安装到硬盘 MBR 时看到的界面(即GRUB控制台)完全相同。
在 grub> 提示符处,输入:
grub> root (fd0)
grub> setup (fd0)
grub> quit
现在,引导盘完成了。
2. 安装根文件系统
一套Linux系统要正常启动,根文件系统要包括下列文件夹:
/bin /etc /proc /tmp /var /dev /mnt
要包括下列基本的设备文件:
/dev/console /dev/fd0 /dev/null /dev/ram0 /dev/tty /dev/tty0
要包括下列配置文件:
/etc/rc.d/inittab /etc/rc.d/rc.sysinit /etc/fstab
要实现基本的功能,还要包括一些常用工具:如:sh,ls,cd,cat等。其中,前面三个部分不要多少空间的,但是常用工具会占用很多空间,要是用原来系统中的这些命令,就是全部用静态编译,不是用动态连接库,大概有2MB~3MB,放不进软盘。网络上解决的方案是使用BusyBox工具。具体可以到官方网站:www.busybox.net看看。下载BusyBox工具的源代码。
注意:
(1) 译的时候要静态编译,修改 Makefile 中的 DOSTATIC 参数,从false 改为 true,这样,编译出来的代码就不要依赖glibc了。
(2) 因为我们用的是 BusyBox 上的 init,与一般所使用的 init 不太一样,会先执行 /etc/init.d/rcS 而非 /etc/rc.d/rc.sysinit,为了做出来的 FloppyLinux 架构与 Redhat 的架构一样,所以修改了 BusyBox 中的 init.c底下是修到的部分内容∶
#ifndef INIT_SCRIPT
#define INIT_SRCIPT "/etc/rc.d/rc.sysinit"
#endif
具体操作如下:
(1) 官方网站上下载BusyBox的最新版本:busybox-0.60.5.tar.gz解开,按照上面的注意点修改源代码。
(2) 运行下列命令:
#make
#make install
(3) 译好的可势行文件放在 ./_install 文件夹里的。
#cp ./_install /tmp/floppy-Linux -r
(4) 动建立其它的文件或文件夹:
#cd /tmp/floppy-Linux
# mkdir dev etc etc/rc.d proc mnt tmp var
# chmod 755 dev etc etc/rc.d bin mnt tmp var
# chmod 555 proc
# cd dev
# mknod tty c 5 0
# mknod console c 5 1
# chmod 666 tty console
# mknod tty0 c 4 0
# chmod 666 tty0
# mknod ram0 b 1 0
# chmod 600 ram0
# mknod fd0 b 2 0
# chmod 600 fd0
# mknod null c 1 3
# chmod 666 null
(5) 建启动配置文件:(inittab,rc.sysinit,fstab)
initab:
::sysinit:/etc/rc.d/rc.sysinit
::askfirst:/bin/sh
rc.sysinit:
#!/bin/sh
[1] [2] 下一页
mount -a
# chmod 755 rc.sysinit
fstab:
proc /proc proc defaults 0 0
(6) 作Ramdisk的镜像文件:
# dd if=/dev/zero of=/tmp/initrd bs=1k count=4096
# losetup /dev/loop0 /tmp/initrd
# mke2fs -m 0 /dev/loop0>
# mount -t ext2 /dev/loop0 /mnt
# cp -r /tmp/floppy-Linux/* /mnt
# umount /mnt
# losetup -d /dev/loop0
# dd if=/tmp/initrd gzip -9 > /tmp/initrd.gz
# rm -f /tmp/initrd
# sync
3.编译内核:
这部分内容不详细讲述,主要是去掉了一些不需要的选项,减小内核,编译出来的内核是725920Byte。里面包含了必要的网卡驱动和网络协议栈。
4.整合启动盘
现在所用到了的东西全部搞好了,下面就是整合一下:
全部文件(文件夹)如下:
/lost+found/
/boot/
/boot/grub/
/boot/grub/stage1 =========èGrub启动时用到的两个文件
/boot/grub/stage2
/boot/grub/menu.lst =========èGrub的配置文件指向grub.conf
/boot/grub/grub.conf
/boot/kernel =============è内核
/initrd.gz ===============è内存镜像文件
这样这张软盘就能启动一套Linux系统了,占用1.213MB。
linux | 评论:0
| Trackbacks:0
| 阅读:913
Submitted by admin on 2011, July 18, 7:56 PM
安卓系统 浅谈,由此可以大概分析刷机变砖的形成
*****************系统的基本启动过程************************
本帖隐藏的内容需要回复才可以浏览(2周后自动解除隐藏)#1,整个系统的引导是从boot.bin开始的
#2,boot完成必要的初始化以后,通过pit信息找到sbl分区
#3,sbl在引导过程中,检测是否存在满足要求的按键组合,如果满足进入download模式(俗称挖煤)的条件,就进入download,如果是进入recovery模式的按键组合,就传递参数给kernel,也就是zImage分区,进入recovery模式,如果都没有,就传递参数给kernel,正常启动系统。
*****************变砖的基本成因***************************
本帖隐藏的内容需要回复才可以浏览
1、boot、pit、sbl直接决定了机器有没有变砖,如果这三个区有一个出了问题,机器将直接无法进入download模式,也就是彻底变砖了。
2、有的sbl版本不检测按键组合,这就是我们常说的锁三键,破解方法就是刷入检测按键组合的版本即可。(例如:I9000的锁三键)
3、boot和sbl具有对应关系,不是随便两个组合就能引导成功,如果单独刷入了这两个文件而彼此之间是不匹配的那就变砖了。
*****************Odin软件平台刷机详解**************************
1,pit和re-partion。这两个需要组合在一起使用,功能就是把pit文件写入到bml2分区,目前看到的pit文件内容基本一致,区别在于factoryfs和dbdatafs两个分区大小不同,也就是说不同的版本调整了factoty和dbdata分区的大小,以满足不同的要求。(建议不要乱刷)
#2,pda——Pda文件是整个rom的核心内容,一般是个tar包,完整的内容包括下面几个文件
boot.bin、sbl.bin、param.lfs、zImage、factoryfs.rfs、cache.rfs
看过上面的分区机构以后,就很容易理解了,odin刷机做的事情,就是解包后把各个文件克隆到各个对应的分区。具体哪个文件名对应哪个分区,则是根据pit文件里的信息来确定的,如果这次不刷pit文件,odin会去读机器内部的pit信息。
某些pda文件的后缀是md5,本质上还是一个tar包。(其实你不管用什么扩展名,刷机平台都会用一样的方式解压,只要确保文件是正常的就应该可以)
#3, Phone,也叫modem,原来wm系统的机器叫radio,都是一个概念,管理无线通讯的,对应分区表中的bml12
#4,Csc,一般也是一个tar包,里面包含dbdata.rfs和cache.rfs(这个在pda文件中也有,应该是会被csc覆盖的)。
#5,这里提到的文件每次刷机都不是必须的,比如我们往往单刷kernel,实际上就是只刷pda文件中的zImage。
#6,风险分析。通过前面讲的分区机构和系统引导过程,我们可以知道odin刷机主要的风险集中在pit分区和pda文件中的boot和sbl,如果这几个刷到一半出了问题,将直接导致机器变砖。
*****************Recovery模式刷机分析***************************
我们的机器还支持在recovery模式下刷机,由于官方的recovery程序功能有限,现在流行使用ClockworkMod Recovery,新版的Cognition 就是用这个刷的。
至于和官方的版本有什么功能增强,我没有查到相关资料,望高人补充。
这个方式下刷机使用的rom格式是一个zip包,在META-INF\com\google\android目录下有一个脚本update-script,recovery程序如何处理zip,是由这个脚本决定的。
现将Cog包里的脚本摘几句看看
format SYSTEM:
format CACHE:
format DATA:
//格式化三个分区
delete SDCARD:update.zip
copy_dir PACKAGE:sdcard SDCARD://sdcard目录下文件复制到sdcard
删除了sdcard上两个目录
delete_recursive SDCARD:Voodoo
delete_recursive SDCARD:Android
copy_dir PACKAGE:system SYSTEM://system目录下所有内容拷贝到system分区
copy_dir PACKAGE:updates TMP:/updates
format SYSTEM:
…….
…….
//设置文件权限
set_perm_recursive 0 0 0755 0555 SYSTEM:etc/ppp
set_perm_recursive 0 0 0755 0755 SYSTEM:etc/init.d
set_perm_recursive 1002 1002 0755 0440 SYSTEM:etc/bluetooth
set_perm 0 0 0755 SYSTEM:etc/bluetooth
set_perm 3002 3002 0444 SYSTEM:etc/bluetooth/blacklist.conf
set_perm 0 0 755 TMP:/updates/bmlwrite
run_program /system/bin/busybox --install -s /system/xbin
//用bmlwrite直接克隆分区,其实和odin刷机一个道理。
run_program /tmp/updates/bmlwrite /tmp/updates/modem.bin /dev/block/bml12
run_program /tmp/updates/bmlwrite /tmp/updates/Sbl.bin /dev/block/bml4
run_program /tmp/updates/bmlwrite /tmp/updates/zImage /dev/block/bml7
注意上面的那个Sbl.bin,很多人变砖就是因为这个!原因前面已经说了。
此文为网友发过来的WORD文档,我略做修改,具体来源不明,在此发表感谢作者
android | 评论:0
| Trackbacks:0
| 阅读:1049