Android系统从头开始移植


Android 系统开发编译环境配置 主机系统:Ubuntu9.04 (1)安装如下软件包 sudo apt-get install git-core sudo apt-get install gnupg sudo apt-get install sun-java5-jdk sudo apt-get install flex sudo apt-get install bison sudo apt-get install gperf sudo apt-get install libsdl-dev sudo apt-get install libesd0-dev sudo apt-get install build-essential sudo apt-get install zip sudo apt-get install curl sudo apt-get install libncurses5-dev sudo apt-get install zlib1g-dev android 编译对 java 的需求只支持 jdk5.0 低版本,jdk5.0 update 12 版本和 java 6 不支持。 (2)下载 repo 工具 curl http://android.git.kernel.org/repo >/bin/repo chmod a+x /bin/repo (3)创建源代码下载目录: mkdir /work/android-froyo-r2 (4)用 repo 工具初始化一个版本(以 android2.2r2 为例) cd /work/android-froyo-r2 repo init -u git://android.git.kernel.org/platform/manifest.git -b froyo 初始化过程中会显示相关的版本的 TAG 信息,同时会提示你输入用户名和邮箱地址,以上面的方式初始 化的是 android2.2 froyo 的最新版本, android2.2 本身也会有很多个版本,这可以从 TAG 信息中看出来,当前 froyo 的所有版本如下: * [new tag] android-2.2.1_r1 -> android-2.2.1_r1 * [new tag] android-2.2_r1 -> android-2.2_r1 * [new tag] android-2.2_r1.1 -> android-2.2_r1.1 * [new tag] android-2.2_r1.2 -> android-2.2_r1.2 * [new tag] android-2.2_r1.3 -> android-2.2_r1.3 * [new tag] android-cts-2.2_r1 -> android-cts-2.2_r1 * [new tag] android-cts-2.2_r2 -> android-cts-2.2_r2 * [new tag] android-cts-2.2_r3 -> android-cts-2.2_r3 这样每次下载的都是最新的版本,当然我们也可以根据 TAG 信息下载某一特定的版本如下: repo init -u git://android.git.kernel.org/platform/manifest.git -b android-cts-2.2_r3 (5)下载代码 repo sync froyo 版本的代码大小超过 2G,漫长的下载过程。 (6)编译代码 cd /work/android-froyo-r2 make Ubuntu 下使用 Simba 服务实现局域网内文件共 享 Ubuntu 下安装 Simba 服务器将 linux 电脑上的内容共享,同一局域网内的另外一台 Windows PC 即可访问 其共享内容, 从而实现 Windows 电脑向访问本地文件一样访问 Linux 文件系统的内容。 (1)安装 Simaba 服务器 sudo apt-get install samba (2)安装 samba 图形化配置软件 sudo apt-get install system-config-samba (3)创建一个 Simba 专用用户 “ ”—“ ”—“ ” “ ” “ ”从 系统 系统管理 用户和组 ,来创建。如图,先点击 解锁 ,然后 添加新用户 然后输入新用户名字(如 Simba)和密码(如 111111) “”“”,然后在 高级 里面,选择 主组 为 sambashare 后点 击"确定"即可 一句话来概括,就是创建一个主组为 sambashare 的用户 (4)配置 samba 共享 “ ”—“ —”从 系统 系统管理 samba“,运行配置界面 ” “—” “ ” “ 然后 首选项 服务器设置 。点击:安全性,在最后的 来宾帐号 里面, 选择我们新建立的那个用户 simba 后点击确定 (5)修改 samba 配置文件 打开/etc/samba/smb.conf,修改 valid users = XXXX 为 valid users = simba (6)重启 samba 服务 sudo /etc/init.d/samba restart (7)添加共享文件 “ ”—“ —”从 系统 系统管理 samba“,运行配置界面 点击"添加"来添加共享文件夹,点击"浏览"来选择需要共享的文件夹,选择"可擦写"和"显示",点击"访 问"可以设置访问权限,最好设置成"允许所有用户访问" 本文来自 CSDN 博客,转载请标明出处:http://blog.csdn.net/jiajie961/archive/2010/11/04/5987821.aspx Ubuntu 下 tftp 服务器的创建 实验平台:Ubuntu9.04 (1)安装 tftp 服务 sudo apt-get install tftp tftpd openbsd-inetd (2) 在根目录下创建文件夹 tftpboot 文件夹并修改权限 cd / sudo mkdir tftpboot sudo chmod 777 tftpboot (3)修改/etc/inetd.conf 文件如下: tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /tftpboot (4)开启 tftp 服务 sudo /etc/init.d/openbsd-inetd reload sudo in.tftpd -l /tftpboot (5)重启电脑,然后将测试文件放入/tftpboot 目录下即可开始测试,出现问题可能一般都是权限问题 /tftpboot 目录下的文件访问权限改成 0777 本文来自 CSDN 博客,转载请标明出处:http://blog.csdn.net/jiajie961/archive/2010/11/05/5989328.aspx 创建一个新的 Android 产品项目 从 google 网站上下载的 android 源代码编译时默认是编译 google 设定的产品,如果要开发自己的产品, 则需要重新定义一个产品项目,过程如下: 首先我们定义产品的规格,举例如下: 公司名称 ardent 产品名称 MTP 主板名称 merlin 然后安装下面的步骤新建产品项目: (1)在源代码目录下创建一个用户目录 mkdir vendor (2)在用户目录下创建一个公司目录 mkdir vendor/merlin (3)在公司目录下创建一个 products 目录 mkdir vendor/merlin/products (4)在上面创建的 products 下创建一个产品 makefile 文件 MTP.mk,内容如下: PRODUCT_PACKAGES := \ AlarmClock \ Email \ Fallback \ Launcher2 \ Music \ Camera \ Settings \ LatinIME \ NotePad \ SoundRecorder \ Bluetooth \ CertInstaller \ DeskClock $(call inherit-product, $(SRC_TARGET_DIR)/product/core.mk) # # Overrides PRODUCT_MANUFACTURER := ardent PRODUCT_BRAND := ardent PRODUCT_NAME := MTP PRODUCT_MODEL := MultiMedia Touch Phone PRODUCT_DEVICE := merlin PRODUCT_LOCALES := zh_CN 产品 makefile 文件的编写有一套规则,详细情况见此文后面的补充内容。 (5)在 vendor/merlin/products 目录下创建一个 AndroidProducts.mk 文件,定义 Android 产品配置文件的路径, 具体如下: PRODUCT_MAKEFILES := \ $(LOCAL_DIR)/MTP.mk (6)在公司目录下创建一个主板目录 mkdir vendor/ardent/merlin (7)在主板目录下新建一个主板配置文件 BoardConfig.mk,内容如下: TARGET_NO_BOOTLOADER := true TARGET_NO_KERNEL := true TARGET_CPU_ABI := armeabi BOARD_USES_GENERIC_AUDIO := true USE_CAMERA_STUB := true (8)如果你希望修改系统属性,则可以在主板目录下新建一个 system.prop 文件,该文件中可以修改系统属 性,举例如下: # system.prop for # This overrides settings in the products/generic/system.prop file # # rild.libpath=/system/lib/libreference-ril.so # rild.libargs=-d /dev/ttyS0 (9)在主板目录下建议一个 Android 的主板配置文件 AndroidBoard.mk,此文件是编译系统接口文件,内容 如下: # make file for new hardware from # LOCAL_PATH := $(call my-dir) # # this is here to use the pre-built kernel ifeq ($(TARGET_PREBUILT_KERNEL),) TARGET_PREBUILT_KERNEL := $(LOCAL_PATH)/kernel endif file := $(INSTALLED_KERNEL_TARGET) ALL_PREBUILT += $(file) $(file): $(TARGET_PREBUILT_KERNEL) | $(ACP) $(transform-prebuilt-to-target) # # no boot loader, so we don't need any of that stuff.. # LOCAL_PATH := vendor/ardent/merlin include $(CLEAR_VARS) # # include more board specific stuff here? Such as Audio parameters. # (10)编译新的项目 . build/envsetup.sh make PRODUCT-MTP-user 补充内容: (1) 上面的新建的几个文件的编写可以参考 build/target/board/generic 目 录 下 的 AndroidBoard.mk,BoardConfig.mk 和 system.prop (2)产品 makefile 的编写规则,变量定义解释如下: PRODUCT_NAME “终端用户可见的产品名称,对应到 Settings“ “中的 About the phone” 信息 PRODUCT_MODEL End-user-visible name for the end product PRODUCT_LOCALES 1 个 以空格分 隔开 的两个 字母的语 言码 加 上 2 字节的国 家码 的列 表,影 响 到"Settings"中的语言,时间,日期和货币格式设置, 举例:en_GB de_DE es_ES fr_CA PRODUCT_PACKAGES 需要安装的 APK 应用程序列表 PRODUCT_DEVICE 工作设计名称,即主板名称 PRODUCT_MANUFACTURER 生产厂家 PRODUCT_BRAND 软件设计针对的客户品牌 PRODUCT_PROPERTY_OVERRIDES 以"key=value"为格式的属性列表 PRODUCT_COPY_FILES “”文件复制列表,格式为 原文件路径:目的文件路径 ,编译过程中会按照此规 则复制文件 PRODUCT_OTA_PUBLIC_KEYS 产品的 OTA 公共密匙列表 PRODUCT_POLICY 声明此产品使用的政策 PRODUCT_PACKAGE_OVERLAYS 指 示 是 否使 用 默 认资 源或 添 加 任 何 产 品 特 定 的资 源 , 例 如 : vendor/acme/overlay PRODUCT_CONTRIBUTORS_FILE HTML 文件中包含项目的贡献者 PRODUCT_TAGS 以空格分隔开的指定产品关键词列表 本文来自 CSDN 博客,转载请标明出处:ttp://blog.csdn.net/jiajie961/archive/2010/11/07/5993126.aspx 制作 ubifs 文件系统 1,安装相关的软件包 apt-get install liblzo2-dev 2,获取相关的工具 mkfs.ubifs 和 ubinize 这两个工具是制作 ubifs 文件系统的时候用到,它们是 mtd-utils 工具包中的内容,mtd-utils 工具包你可以 从下面的网站下载和编译出来: 官方网站:http://www.linux-mtd.infradead.org/index.html 资源下载网站:http://git.infradead.org/ 3,创建一个 create-ubifs.sh 脚本,主要是调用 mkfs.ubifs 和 ubinize 工具和相关参数来制作 ubifs 文件系统, 内容如下: #!/bin/bash ########################################################## # Script to generate ubifs filesystem image. # ########################################################## ##### ubinize configuration file config_file=rootfs_ubinize.cfg ##### Function to check result of the command check_result() { if [ $? -ne 0 ] then echo "FAILED" else echo "SUCCESSFUL" fi } ###### Function to check whether an application exists check_program() { for cmd in "$@" do which ${cmd} > /dev/null 2>&1 if [ $? -ne 0 ] then echo echo "Cannot find command \"${cmd}\"" echo exit 1 fi done } if [ $# -ne 5 ] then echo echo 'Usage: create-ubifs.sh [page_size_in_bytes] [pages_per_block] [partition_size_in_bytes] [blocks_per_device] [path_to_rootfs]' echo exit fi page_size_in_bytes=$1 echo "Page size [$page_size_in_bytes]bytes." pages_per_block=$2 echo "Pages per block [$pages_per_block]" partition_size_in_bytes=$3 echo "File-system partition size [$partition_size_in_bytes]bytes." blocks_per_device=$4 echo "Blocks per device [$blocks_per_device]" path_to_rootfs=$5 # wear_level_reserved_blocks is 1% of total blcoks per device wear_level_reserved_blocks=`expr $blocks_per_device / 100` echo "Reserved blocks for wear level [$wear_level_reserved_blocks]" #logical_erase_block_size is physical erase block size minus 2 pages for UBI logical_pages_per_block=`expr $pages_per_block - 2` logical_erase_block_size=`expr $page_size_in_bytes \* $logical_pages_per_block` echo "Logical erase block size [$logical_erase_block_size]bytes." #Block size = page_size * pages_per_block block_size=`expr $page_size_in_bytes \* $pages_per_block` echo "Block size [$block_size]bytes." #physical blocks on a partition = partition size / block size partition_physical_blocks=`expr $partition_size_in_bytes / $block_size` echo "Physical blocks in a partition [$partition_physical_blocks]" #Logical blocks on a partition = physical blocks on a partitiion - reserved for wear level patition_logical_blocks=`expr $partition_physical_blocks - $wear_level_reserved_blocks` echo "Logical blocks in a partition [$patition_logical_blocks]" #File-system volume = Logical blocks in a partition * Logical erase block size fs_vol_size=`expr $patition_logical_blocks \* $logical_erase_block_size` echo "File-system volume [$fs_vol_size]bytes." echo echo "Generating configuration file..." echo "[rootfs-volume]" > $config_file echo "mode=ubi" >> $config_file echo "image=rootfs_ubifs.img" >> $config_file echo "vol_id=0" >> $config_file echo "vol_size=$fs_vol_size" >> $config_file echo "vol_type=dynamic" >> $config_file echo "vol_name=system" >> $config_file echo # Note: Check necessary program for installation #echo -n "Checking necessary program for installation......" #check_program mkfs.ubifs ubinize #echo "Done" #Generate ubifs image echo -n "Generating ubifs..." ./mkfs.ubifs -x lzo -m $page_size_in_bytes -e $logical_erase_block_size -c $patition_logical_blocks -o rootfs_ubifs.img -d $path_to_rootfs check_result echo -n "Generating ubi image out of the ubifs..." ./ubinize -o ubi.img -m $page_size_in_bytes -p $block_size -s $page_size_in_bytes $config_file -v check_result rm -f rootfs_ubifs.img rm -f $config_file (4)将 mkfs.ubifs 和 ubinize 以及 create-ubifs.sh 放置在同一目录下,然后调用 create-ubifs.sh 即可创建 ubifs 文件系统,create-ubifs.sh 用法如下: create-ubifs.sh page_size_in_bytes(页大小) pages_per_block(每个扇区的页数量) partition_size_in_bytes(分区 大小) blocks_per_device(扇区数量) path_to_rootfs(文件系统路径) 举例如下: ./create-ubifs.sh 2048 64 83886080 4096 ./rootfs 上面命令的意思是调用 create-ubifs.sh 将当前目录下的 rootfs 文件夹的内容制作成 ubifs 文件系统,nand flash 的页大小为 2k,每个扇区有 64 页, 总共有 4096 个扇区,要制作的文件系统的大小为 83886080 字节。 本文来自 CSDN 博客,转载请标明出处:http://blog.csdn.net/jiajie961/archive/2010/11/08/5994713.aspx android 编译系统 makefile(Android.mk)写法 android 编译系统的 makefile 文件 Android.mk 写法如下 (1)Android.mk 文件首先需要指定 LOCAL_PATH 变量,用于查找源文件。由于一般情况下 Android.mk 和需要编译的源文件在同一目录下,所以定义成如下形式: LOCAL_PATH:=$(call my-dir) 上面的语句的意思是将 LOCAL_PATH 变量定义成本文件所在目录路径。 (2)Android.mk 中可以定义多个编译模块,每个编译模块都是以 include $(CLEAR_VARS)开始 以 include $(BUILD_XXX)结束。 include $(CLEAR_VARS) CLEAR_VARS 由 编 译 系 统 提 供 , 指 定 让 GNU MAKEFILE 为 你 清 除 除 LOCAL_PATH 以 外 的 所 有 LOCAL_XXX 变量, 如 LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_SHARED_LIBRARIES,LOCAL_STATIC_LIBRARIE S 等。 include $(BUILD_STATIC_LIBRARY)表示编译成静态库 include $(BUILD_SHARED_LIBRARY)表示编译成动态库。 include $(BUILD_EXECUTABLE)表示编译成可执行程序 (3)举例如下(frameworks/base/libs/audioflinger/Android.mk): LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) 模块一 ifeq ($(AUDIO_POLICY_TEST),true) ENABLE_AUDIO_DUMP := true endif LOCAL_SRC_FILES:= \ AudioHardwareGeneric.cpp \ AudioHardwareStub.cpp \ AudioHardwareInterface.cpp ifeq ($(ENABLE_AUDIO_DUMP),true) LOCAL_SRC_FILES += AudioDumpInterface.cpp LOCAL_CFLAGS += -DENABLE_AUDIO_DUMP endif LOCAL_SHARED_LIBRARIES := \ libcutils \ libutils \ libbinder \ libmedia \ libhardware_legacy ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true) LOCAL_CFLAGS += -DGENERIC_AUDIO endif LOCAL_MODULE:= libaudiointerface ifeq ($(BOARD_HAVE_BLUETOOTH),true) LOCAL_SRC_FILES += A2dpAudioInterface.cpp LOCAL_SHARED_LIBRARIES += liba2dp LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP LOCAL_C_INCLUDES += $(call include-path-for, bluez) endif include $(BUILD_STATIC_LIBRARY) 模块一编译成静态库 include $(CLEAR_VARS) 模块二 LOCAL_SRC_FILES:= \ AudioPolicyManagerBase.cpp LOCAL_SHARED_LIBRARIES := \ libcutils \ libutils \ libmedia ifeq ($(TARGET_SIMULATOR),true) LOCAL_LDLIBS += -ldl else LOCAL_SHARED_LIBRARIES += libdl endif LOCAL_MODULE:= libaudiopolicybase ifeq ($(BOARD_HAVE_BLUETOOTH),true) LOCAL_CFLAGS += -DWITH_A2DP endif ifeq ($(AUDIO_POLICY_TEST),true) LOCAL_CFLAGS += -DAUDIO_POLICY_TEST endif include $(BUILD_STATIC_LIBRARY) 模块二编译成静态库 include $(CLEAR_VARS) 模块三 LOCAL_SRC_FILES:= \ AudioFlinger.cpp \ AudioMixer.cpp.arm \ AudioResampler.cpp.arm \ AudioResamplerSinc.cpp.arm \ AudioResamplerCubic.cpp.arm \ AudioPolicyService.cpp LOCAL_SHARED_LIBRARIES := \ libcutils \ libutils \ libbinder \ libmedia \ libhardware_legacy ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true) LOCAL_STATIC_LIBRARIES += libaudiointerface libaudiopolicybase LOCAL_CFLAGS += -DGENERIC_AUDIO else LOCAL_SHARED_LIBRARIES += libaudio libaudiopolicy endif ifeq ($(TARGET_SIMULATOR),true) LOCAL_LDLIBS += -ldl else LOCAL_SHARED_LIBRARIES += libdl endif LOCAL_MODULE:= libaudioflinger ifeq ($(BOARD_HAVE_BLUETOOTH),true) LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP LOCAL_SHARED_LIBRARIES += liba2dp endif ifeq ($(AUDIO_POLICY_TEST),true) LOCAL_CFLAGS += -DAUDIO_POLICY_TEST endif ifeq ($(TARGET_SIMULATOR),true) ifeq ($(HOST_OS),linux) LOCAL_LDLIBS += -lrt -lpthread endif endif ifeq ($(BOARD_USE_LVMX),true) LOCAL_CFLAGS += -DLVMX LOCAL_C_INCLUDES += vendor/nxp LOCAL_STATIC_LIBRARIES += liblifevibes LOCAL_SHARED_LIBRARIES += liblvmxservice # LOCAL_SHARED_LIBRARIES += liblvmxipc endif include $(BUILD_SHARED_LIBRARY) 模块三编译成动态库 (4)编译一个应用程序(APK) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # Build all java files in the java subdirectory LOCAL_SRC_FILES := $(call all-subdir-java-files) # Name of the APK to build LOCAL_PACKAGE_NAME := LocalPackage # Tell it to build an APK include $(BUILD_PACKAGE) (5)编译一个依赖于静态 Java 库(static.jar)的应用程序 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # List of static libraries to include in the package LOCAL_STATIC_JAVA_LIBRARIES := static-library # Build all java files in the java subdirectory LOCAL_SRC_FILES := $(call all-subdir-java-files) # Name of the APK to build LOCAL_PACKAGE_NAME := LocalPackage # Tell it to build an APK include $(BUILD_PACKAGE) (6)编译一个需要用平台的 key 签名的应用程序 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # Build all java files in the java subdirectory LOCAL_SRC_FILES := $(call all-subdir-java-files) # Name of the APK to build LOCAL_PACKAGE_NAME := LocalPackage LOCAL_CERTIFICATE := platform # Tell it to build an APK include $(BUILD_PACKAGE) (7)编译一个需要用特定 key 前面的应用程序 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # Build all java files in the java subdirectory LOCAL_SRC_FILES := $(call all-subdir-java-files) # Name of the APK to build LOCAL_PACKAGE_NAME := LocalPackage LOCAL_CERTIFICATE := vendor/example/certs/app # Tell it to build an APK include $(BUILD_PACKAGE) (8)添加一个预编译应用程序 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # Module name should match apk name to be installed. LOCAL_MODULE := LocalModuleName LOCAL_SRC_FILES := $(LOCAL_MODULE).apk LOCAL_MODULE_CLASS := APPS LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX) include $(BUILD_PREBUILT) (9)添加一个静态 JAVA 库 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # Build all java files in the java subdirectory LOCAL_SRC_FILES := $(call all-subdir-java-files) # Any libraries that this library depends on LOCAL_JAVA_LIBRARIES := android.test.runner # The name of the jar file to create LOCAL_MODULE := sample # Build a static jar file. include $(BUILD_STATIC_JAVA_LIBRARY) (10)Android.mk 的编译模块中间可以定义相关的编译内容,也就是指定相关的变量如下: LOCAL_AAPT_FLAGS LOCAL_ACP_UNAVAILABLE LOCAL_ADDITIONAL_JAVA_DIR LOCAL_AIDL_INCLUDES LOCAL_ALLOW_UNDEFINED_SYMBOLS LOCAL_ARM_MODE LOCAL_ASFLAGS LOCAL_ASSET_DIR LOCAL_ASSET_FILES 在 Android.mk 文件中编译应用程序(BUILD_PACKAGE)时设置此变量,表示资源 文件, 通常会定义成 LOCAL_ASSET_FILES += $(call find-subdir-assets) LOCAL_BUILT_MODULE_STEM LOCAL_C_INCLUDES 额外的 C/C++编译头文件路径,用 LOCAL_PATH 表示本文件所在目录 举例如下: LOCAL_C_INCLUDES += extlibs/zlib-1.2.3 LOCAL_C_INCLUDES += $(LOCAL_PATH)/src LOCAL_CC 指定 C 编译器 LOCAL_CERTIFICATE 签名认证 LOCAL_CFLAGS 为 C/C++ 编 译 器 定 义 额 外 的 标 志 ( 如 宏 定 义 ) , 举 例 : LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1 LOCAL_CLASSPATH LOCAL_COMPRESS_MODULE_SYMBOLS LOCAL_COPY_HEADERS install 应 用 程 序 时 需 要 复 制 的 头 文 件 , 必 须 同 时 定 义 LOCAL_COPY_HEADERS_TO LOCAL_COPY_HEADERS_TO install 应用程序时复制头文件的目的路径 LOCAL_CPP_EXTENSION 如 果 你 的 C++ 文 件 不 是 以 cpp 为 文 件 后 缀 , 你 可 以 通 过 LOCAL_CPP_EXTENSION 指定 C++ 文件后缀名 如:LOCAL_CPP_EXTENSION := .cc 注意统一模块中 C++文件后缀必须保持一致。 LOCAL_CPPFLAGS 传递额外的标志给 C++编译器,如:LOCAL_CPPFLAGS += -ffriend-injection LOCAL_CXX 指定 C++编译器 LOCAL_DX_FLAGS LOCAL_EXPORT_PACKAGE_RESOURCES LOCAL_FORCE_STATIC_EXECUTABLE 如果编译的可执行程序要进行静态链接(执行时不依赖于任何动 态库),则设置 LOCAL_FORCE_STATIC_EXECUTABLE:=true 目前只有 libc 有静态库形式,这个只有文件系统中/sbin 目录下的应用程序会用到, 这个目录下的应用程序在运行时通常 文件系统的其它部分还没有加载,所以必须进行静态链接。 LOCAL_GENERATED_SOURCES LOCAL_INSTRUMENTATION_FOR LOCAL_INSTRUMENTATION_FOR_PACKAGE_NAME LOCAL_INTERMEDIATE_SOURCES LOCAL_INTERMEDIATE_TARGETS LOCAL_IS_HOST_MODULE LOCAL_JAR_MANIFEST LOCAL_JARJAR_RULES LOCAL_JAVA_LIBRARIES 编译 java 应用程序和库的时候指定包含的 java 类库,目前有 core 和 framework 两种 多数情况下定义成:LOCAL_JAVA_LIBRARIES := core framework 注意 LOCAL_JAVA_LIBRARIES 不是必须的,而且编译 APK 时不允许定义(系统会自动添 加) LOCAL_JAVA_RESOURCE_DIRS LOCAL_JAVA_RESOURCE_FILES LOCAL_JNI_SHARED_LIBRARIES LOCAL_LDFLAGS 传递额外的参数给连接器(务必注意参数的顺序) LOCAL_LDLIBS 为可执行程序或者库的编译指定额外的库,指定库以"-lxxx"格式,举例: LOCAL_LDLIBS += -lcurses -lpthread LOCAL_LDLIBS += -Wl,-z,origin LOCAL_MODULE 生 成 的 模 块 的 名 称 ( 注 意 应 用 程 序 名 称 用 LOCAL_PACKAGE_NAME 而 不 是 LOCAL_MODULE) LOCAL_MODULE_PATH 生成模块的路径 LOCAL_MODULE_STEM LOCAL_MODULE_TAGS 生成模块的标记 LOCAL_NO_DEFAULT_COMPILER_FLAGS LOCAL_NO_EMMA_COMPILE LOCAL_NO_EMMA_INSTRUMENT LOCAL_NO_STANDARD_LIBRARIES LOCAL_OVERRIDES_PACKAGES LOCAL_PACKAGE_NAME APK 应用程序的名称 LOCAL_POST_PROCESS_COMMAND LOCAL_PREBUILT_EXECUTABLES 预 编 译 including $(BUILD_PREBUILT) 或 者 $ (BUILD_HOST_PREBUILT)时所用, 指定需要复制的可执行文件 LOCAL_PREBUILT_JAVA_LIBRARIES LOCAL_PREBUILT_LIBS 预编译 including $(BUILD_PREBUILT)或者$(BUILD_HOST_PREBUILT)时所用, 指定需要复制的库. LOCAL_PREBUILT_OBJ_FILES LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES LOCAL_PRELINK_MODULE 是否需要预连接处理(默认需要,用来做动态库优化) LOCAL_REQUIRED_MODULES 指定模块运行所依赖的模块(模块安装时将会同步安装它所依赖的模块) LOCAL_RESOURCE_DIR LOCAL_SDK_VERSION LOCAL_SHARED_LIBRARIES 可链接动态库 LOCAL_SRC_FILES 编译源文件 LOCAL_STATIC_JAVA_LIBRARIES LOCAL_STATIC_LIBRARIES 可链接静态库 LOCAL_UNINSTALLABLE_MODULE LOCAL_UNSTRIPPED_PATH LOCAL_WHOLE_STATIC_LIBRARIES 指定模块所需要载入的完整静态库(这些精通库在链接是不允许链 接器删除其中无用的代码) LOCAL_YACCFLAGS OVERRIDE_BUILT_MODULE_PATH 本文来自 CSDN 博客,转载请标明出处:http://blog.csdn.net/jiajie961/archive/2010/11/09/5997147.aspx Android 系统移植(一)-让 android 系统在目标平 台上运行起来 Android 系统由于用的是 linux 内核,因此内核移植和嵌入式 linux 内核移植差异不大,过程如下: (1)移植 boot-loader 和 linux2.6 内核到目标平台上,让 linux 内核可以启动起来,基本的驱动允许正 常。 此过程完全是嵌入式 linux 的开发,这里直接跳过。需要注意的是,由于 android 已经被 linux 官方开除, 因此从 网站上(如 http://www.kernel.org/)下载的最新 linux 内核源代码已经不包含 android 的专有驱动,因 此建议 从 google 网上下下载 Linux 内核,android 源代码浏览网站如下: http://android.git.kernel.org/ 从该网站上发现内核相关的包如下: kernel/common.git 通用 android 内核项目 kernel/experimental.git 实验性内核项目 kernel/linux-2.6.git 这个是标准的 Linux 内核,没有 android 的驱动 kernel/lk.git 微内核项目 kernel/msm.git 这个是高通 msm7xxx 系列芯片所用内核 kernel/omap.git kernel/tegra.git NVIDIA Tegra 系列芯片所用内核 下载内核代码的方法如下: git clone git://android.git.kernel.org/kernel/common.git 下载完后用 git branch -a 查看所有 git 分支,结果如下: android-2.6.27 origin/HEAD origin/android-2.6.25 origin/android-2.6.27 origin/android-2.6.29 origin/android-2.6.32 origin/android-2.6.35 origin/android-2.6.36 origin/android-goldfish-2.6.27 origin/android-goldfish-2.6.29 然后切换到最新分支 git checkout origin/android-2.6.36 (2)修改内核配置文件,打开 Android 必须的驱动(日志和 BINDER)如下: CONFIG_ANDROID=y CONFIG_ANDROID_BINDER_IPC=y CONFIG_ANDROID_LOGGER=y 此部分的代码在内核 drivers/staging/android 目录下。 (3)为了提高启动速度,采用 ramdisk,将 android 文件系统的部分内容压缩到内核中。 首先打开内核驱动: CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="root" CONFIG_INITRAMFS_ROOT_UID=0 CONFIG_INITRAMFS_ROOT_GID=0 然后在 android 源代码编译出来的 out/target/product/merlin/root 目录复制到内核目录下。 (4)根据 android 文件系统的要求对 nand flash 进行重新分区,举例如下: 将 nand flash 分区以下 8 个分区 NTIM OBM U-boot Kernel System UserData Mass Storage BBT (5)根据分区表修改内核启动参数如下: CONFIG_CMDLINE="ubi.mtd=4 ubi.mtd=5 ubi.mtd=6 root=ubi0_0 rootfstype=ubifs console=ttyS1,115200 uart_dma init=/init" 参数的意思是:载入的文件系统部分有 3 个分区,分别为 nand flash 的第 4,5,6 分区(从 0 编号),文件 系统采用 ubifs 格式,控制台设备为 ttyS1,波特率为 115200 启动的第一个应用程序是/init (6)确保控制台的设置和硬件保持一致,如:硬件上串口用的是 UART1,则内核启动参数中设置有 console=ttyS1,而且 android 的启动过程中设要设置正确,修改 部分位于 android 源代码 system/core/init/init.c 文件中,将 static char *console_name = "/dev/console"; 修改成 static char *console_name = "/dev/ttyS1"; (7)修 改 android 源 代码 system/core/rootdir 目 录下 的 init.rc 文件 ,作如下 修改 (android 默认 yaffs2 文件系统): 首先将 android 文件系统修改成可读写,将 mount rootfs rootfs / ro remount 修改成 mount rootfs rootfs / rw remount 然后修改挂载 system 和 userdata 部分的代码,将 # Mount /system rw first to give the filesystem a chance to save a checkpoint mount yaffs2 mtd@system /system mount yaffs2 mtd@system /system ro remount # We chown/chmod /data again so because mount is run as root + defaults mount yaffs2 mtd@userdata /data nosuid nodev chown system system /data chmod 0771 /data 改成 # Mount /system rw first to give the filesystem a chance to save a checkpoint mount ubifs ubi0_0 /system ro # We chown/chmod /data again so because mount is run as root + defaults mount ubifs ubi1_0 /data nosuid nodev chown system system /data chmod 0771 /data (8)完成后编译内核,可以启动文件系统,控制台可用,但是没有显示启动 log,而且不停的重启。 (9)系统不停的重启,因此控制台已经可用了,自然而然的想到看到 logcat 日志,一看,发现 logcat 设 备居然没起来,配置文件里面都定义了 居然没起来,查看了下内核 drivers/staging/android 目录,没有.o 文件,证明是没编译到,在看内核 目录下的.config 文件,发现居然没有了 logcat 和 binder 的宏定义,配置文件里面有定义而.config 文件中无定义,肯定是相关 Kconfig 文件的 问题,通过分析 drivers/staging 目录下的 Kconfig 文件发现是因为 STAGING_EXCLUDE_BUILD 宏默认是 y,在配置文件中否定此宏即可,在配 置文件中 CONFIG_STAGING 定义后加上即可,如下: CONFIG_STAGING=y # CONFIG_STAGING_EXCLUDE_BUILD is not set 修改后重新编译发现系统完成正常启动,启动过程中启动 log 也显示正常。 至此,android 初步移植工作已经完成,当然,系统还有很多问题,需要下一步继续修改。 总结:android 的移植按如下流程: (1)android linux 内核的普通驱动移植,让内核可以在目标平台上运行起来。 (2)正确挂载文件系统,确保内核启动参数和 android 源代码 system/core/rootdir 目录下的 init.rc 中 的文件系统挂载正确。 (3)调试控制台,让内核启动参数中的 console 参数以及 android 源代码 system/core/init/init.c 中的 console_name 设置和硬件保持一致 (4)打开 android 相关的驱动(logger,binder 等),串口输入 logcat 看 logger 驱动起来,没有的话调试 logger 驱动。 说明:ARM 的内核配置文件定义在内核 arch/arm/configs 目录下 Android 系统移植(二)-按键移植 这一部分主要是移植 android 的键盘和按键 (1)Android 使 用 标 准 的 linux 输 入 事 件 设 备 (/dev/input 目 录 下 ) 和 驱 动 , 按 键 定 义 在 内 核 include/linux/input.h 文件中, 按键定义形式如下: #define KEY_ESC 1 #define KEY_1 2 #define KEY_2 3 (2)内核中(我的平台是 arch/arm/mach-mmp/merlin.c 文件)中按键的定义如下形式: static struct gpio_keys_button btn_button_table[] = { [0] = { .code = KEY_F1, .gpio = MFP_PIN_GPIO2, .active_low = 1, /* 0 for down 0, up 1; 1 for down 1, up 0 */ .desc = "H_BTN button", .type = EV_KEY, /* .wakeup = */ .debounce_interval = 10, /* 10 msec jitter elimination */ }, [1] = { .code = KEY_F2, .gpio = MFP_PIN_GPIO3, .active_low = 1, /* 0 for down 0, up 1; 1 for down 1, up 0 */ .desc = "O_BTN button", .type = EV_KEY, /* .wakeup = */ .debounce_interval = 10, /* 10 msec jitter elimination */ }, [2] = { .code = KEY_F4, .gpio = MFP_PIN_GPIO1, .active_low = 1, /* 0 for down 0, up 1; 1 for down 1, up 0 */ .desc = "S_BTN button", .type = EV_KEY, /* .wakeup = */ .debounce_interval = 10, /* 10 msec jitter elimination */ }, }; static struct gpio_keys_platform_data gpio_keys_data = { .buttons = btn_button_table, .nbuttons = ARRAY_SIZE(btn_button_table), }; static struct platform_device gpio_keys = { .name = "gpio-keys", .dev = { .platform_data = &gpio_keys_data, }, .id = -1, }; 上 面 定 义 是 将 MFP_PIN_GPIO2 这 个 GPIO 口 的 按 键 映 射 到 Linux 的 KEY_F1 按 键 , MPF_PIN_GPIO3 映射到 KEY_F2,MFP_PIN_GPIO1 映射到 KEY_F4 (3)上面(2)步实现了从硬件 GPIO 口到内核标准按键的映射,但是 android 并没有直接使用映射后的键值, 而且对其再进行了一次映射,从内核标准键值 到 android 所用键值的映射表定义在 android 文件系统的/system/usr/keylayout 目录下。标准的映射 文件为 qwerty.kl,定义如下: key 399 GRAVE key 2 1 key 3 2 key 4 3 key 5 4 key 6 5 key 7 6 key 8 7 key 9 8 key 10 9 key 11 0 key 158 BACK WAKE_DROPPED key 230 SOFT_RIGHT WAKE key 60 SOFT_RIGHT WAKE key 107 ENDCALL WAKE_DROPPED key 62 ENDCALL WAKE_DROPPED key 229 MENU WAKE_DROPPED key 139 MENU WAKE_DROPPED key 59 MENU WAKE_DROPPED key 127 SEARCH WAKE_DROPPED key 217 SEARCH WAKE_DROPPED key 228 POUND key 227 STAR key 231 CALL WAKE_DROPPED key 61 CALL WAKE_DROPPED key 232 DPAD_CENTER WAKE_DROPPED key 108 DPAD_DOWN WAKE_DROPPED key 103 DPAD_UP WAKE_DROPPED key 102 HOME WAKE key 105 DPAD_LEFT WAKE_DROPPED key 106 DPAD_RIGHT WAKE_DROPPED key 115 VOLUME_UP key 114 VOLUME_DOWN key 116 POWER WAKE key 212 CAMERA key 16 Q key 17 W key 18 E key 19 R key 20 T key 21 Y key 22 U key 23 I key 24 O key 25 P key 26 LEFT_BRACKET key 27 RIGHT_BRACKET key 43 BACKSLASH key 30 A key 31 S key 32 D key 33 F key 34 G key 35 H key 36 J key 37 K key 38 L key 39 SEMICOLON key 40 APOSTROPHE key 14 DEL key 44 Z key 45 X key 46 C key 47 V key 48 B key 49 N key 50 M key 51 COMMA key 52 PERIOD key 53 SLASH key 28 ENTER key 56 ALT_LEFT key 100 ALT_RIGHT key 42 SHIFT_LEFT key 54 SHIFT_RIGHT key 15 TAB key 57 SPACE key 150 EXPLORER key 155 ENVELOPE key 12 MINUS key 13 EQUALS key 215 AT (4)android 对底层按键的处理方法 android 按 键 的 处 理 是 Window Manager 负 责 , 主 要 的 映 射 转 换 实 现 在 android 源 代 码 frameworks/base/libs/ui/EventHub.cpp 此文件处理来自底层的所有输入事件,并根据来源对事件进行分类处理,对于按键事件,处理过程如下 (a)记录驱动名称为 (b) 获 取 环 境 变 量 ANDROID_ROOT 为 系 统 路 径 ( 默 认 是 /system , 定 义 在 android 源 代 码/system/core/rootdir/init.rc 文件中) (c)查找路径为"系统路径/usr/keylayout/驱动名称.kl"的按键映射文件,如果不存在则默认用路径为"系 统路径/usr/keylayout/qwerty.kl" 这个默认的按键映射文件,映射完成后再把经映射得到的 android 按键码值发给上层应用程序。 所以我们可以在内核中定义多个按键设备,然后为每个设备设定不同的按键映射文件,不定义则会默认 用 qwerty.kl (5)举例 上 面 (2) 步 我 们 在 内 核 中 声 明 了 一 个 名 为 "gpio-keys" 的 按 键 设 备 , 此 设 备 定 义 在 内 核 drivers/input/keyboard/gpio_keys.c 文件中 然后我们在内核启动过程中注册此设备: platform_device_register(&gpio_keys); 然后我们可以自己定义一个名为 gpio-keys.kl 的 android 按键映射文件,此文件的定义可以参考 querty.kl 的内容,比如说我们想将 MPF_PIN_GPIO3 对应的按键作 android 中的 MENU 键用,首先我们在内核中将 MPF_PIN_GPIO3 映射到 KEY_F2,在 内核 include/linux/input.h 中查找 KEY_F2 发现 #define KEY_F2 60 参照 KEY_F2 的值我们在 gpio-keys.kl 中加入如下映射即可 key 60 MENU WAKE 其它按键也照此添加,完成后将按键表放置到/system/usr/keylayout 目录下即可。 补充: (1)android 按键设备的映射关系可以在 logcat 开机日志中找的到(查找 EventHub 即可) (2)android 按键设备由 Window Manager 负责,Window Manager 从按键驱动读取内核按键码,然 后将内核按键码转换成 android 按键码,转换完成 后 Window Manager 会将内核按键码和 android 按键码一起发给应用程序来使用,这一点一定要注意。 Android 系统开发小知识-在 android 产品开发中添加新的编译模块 Android 开 发 中 用 户 内 容 定 义 在 vendor 目录下,而用户产品的内容都定义在 vendor//目录下 如果需要添加新的内容,可以在该目录下新建子目录,同时修改 AndroidBoard.mk 文件即可。比如说要 添加一个按键映射文件: (1)在 vendor//目录下建立一个 keymaps 子目录 (2)将我们需要的按键映射文件 gpio-keys.kl 和 power-button.kl 复制到 keymaps 目录下 (3)在 keymaps 目录下新建一个 Mdroid.mk 文件,内容如下: LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) file := $(TARGET_OUT_KEYLAYOUT)/gpio-keys.kl ALL_PREBUILT += $(file) $(file): $(LOCAL_PATH)/gpio-keys.kl | $(ACP) $(transform-prebuilt-to-target) file := $(TARGET_OUT_KEYLAYOUT)/power-button.kl ALL_PREBUILT += $(file) $(file): $(LOCAL_PATH)/power-button.kl | $(ACP) $(transform-prebuilt-to-target) (4)在 vendor//目录下的 AndroidBoard.mk 添加如下内容: include $(LOCAL_PATH)/keymaps/Mdroid.mk Android 系统移植(三)-按键字符表 上节讲 android 的 Window Manager 将内核按键码通过按键映射表转换成 android 按键码, 这节讲的是 android 按键码向 android 字符的转换,转换也是通过 Window Manager 来完成的 (1)原始按键字符表,我们知道一个按键是可以显示多个字符的,决定显示字符的是 CAPS(大小 写),FN,NUNMBER 等按键 举例如下: [type=QWERTY] # keycode display number base caps fn caps_fn A 'A' '2' 'a' 'A' '#' 0x00 B 'B' '2' 'b' 'B' '<' 0x00 C 'C' '2' 'c' 'C' '9' 0x00E7 D 'D' '3' 'd' 'D' '5' 0x00 E 'E' '3' 'e' 'E' '2' 0x0301 F 'F' '3' 'f' 'F' '6' 0x00A5 G 'G' '4' 'g' 'G' '-' '_' H 'H' '4' 'h' 'H' '[' '{' I 'I' '4' 'i' 'I' '$' 0x0302 J 'J' '5' 'j' 'J' ']' '}' K 'K' '5' 'k' 'K' '"' '~' L 'L' '5' 'l' 'L' ''' '`' M 'M' '6' 'm' 'M' '!' 0x00 N 'N' '6' 'n' 'N' '>' 0x0303 O 'O' '6' 'o' 'O' '(' 0x00 P 'P' '7' 'p' 'P' ')' 0x00 Q 'Q' '7' 'q' 'Q' '*' 0x0300 R 'R' '7' 'r' 'R' '3' 0x20AC S 'S' '7' 's' 'S' '4' 0x00DF T 'T' '8' 't' 'T' '+' 0x00A3 U 'U' '8' 'u' 'U' '&' 0x0308 V 'V' '8' 'v' 'V' '=' '^' W 'W' '9' 'w' 'W' '1' 0x00 X 'X' '9' 'x' 'X' '8' 0xEF00 Y 'Y' '9' 'y' 'Y' '%' 0x00A1 Z 'Z' '9' 'z' 'Z' '7' 0x00 # on pc keyboards COMMA ',' ',' ',' ';' ';' '|' PERIOD '.' '.' '.' ':' ':' 0x2026 AT '@' '0' '@' '0' '0' 0x2022 SLASH '/' '/' '/' '?' '?' '\' SPACE 0x20 0x20 0x20 0x20 0xEF01 0xEF01 ENTER 0xa 0xa 0xa 0xa 0xa 0xa TAB 0x9 0x9 0x9 0x9 0x9 0x9 0 '0' '0' '0' ')' ')' ')' 1 '1' '1' '1' '!' '!' '!' 2 '2' '2' '2' '@' '@' '@' 3 '3' '3' '3' '#' '#' '#' 4 '4' '4' '4' '$' '$' '$' 5 '5' '5' '5' '%' '%' '%' 6 '6' '6' '6' '^' '^' '^' 7 '7' '7' '7' '&' '&' '&' 8 '8' '8' '8' '*' '*' '*' 9 '9' '9' '9' '(' '(' '(' GRAVE '`' '`' '`' '~' '`' '~' MINUS '-' '-' '-' '_' '-' '_' EQUALS '=' '=' '=' '+' '=' '+' LEFT_BRACKET '[' '[' '[' '{' '[' '{' RIGHT_BRACKET ']' ']' ']' '}' ']' '}' BACKSLASH '\' '\' '\' '|' '\' '|' SEMICOLON ';' ';' ';' ':' ';' ':' APOSTROPHE ''' ''' ''' '"' ''' '"' STAR '*' '*' '*' '*' '*' '*' POUND '#' '#' '#' '#' '#' '#' PLUS '+' '+' '+' '+' '+' '+' (2)android 为了减少载入时间,并没有使用原始按键表文件,而是将其转换成二进制文件 转换的工具源代码在 android 源代码 build/tools/kcm 目录下,android 在编译过程中会 首先编译转换工具,然后利用转换工具将 android 源代码 sdk/emulator/keymaps 目录下 的 qwerty.kcm 和 qwerty2.kcm 文件分别转换成 qwerty.kcm.bin 和 qwerty2.kcm.bin 转换后的二进制文件复制到 out/target/product//system/usr/keychars 目录下,也就是目标平台的/system/usr/keychars 目录中。 (3)Window Manager 对按键的处理在 android 源代码 frameworks/base/libs/ui/EventHub.cpp 文 件中 Window Manager 从内核接收到一个按键输入事件后会首先调用按键映射表将内核按键码映射成 android 按键码(这部分上节已讲),然后会 将 android 按键码转换成字符,具体过程如下: (a)设置系统系统属性 hw.keyboards.设备号.devname 的值为设备名 以上节的 gpio-keys 设备为例,会设置系统属性 hw.keyboards.65539.devname 的值为 gpio-keys (b)载入按键字符表,首先载入/system/usr/keychars 目录下的设备名.kcm.bin 文件(此例即 gpio- keys.kcm.bin 文件),如果载入失败 则载入该目录下的 querty.kcm.bin. (c)利用载入的按键字符表将 android 按键转换成按键字符发给上层应用程序。 (4)一般情况下一个控制按键是不需要作按键字符表的,系统会调用默认的去处理,但是如果要开发一个 全功能键盘(包含了字母和数字),那可能就需要 自己作一个专用的按键字符表了。 android 系统开发小问题-启动过程中 android 字符没有显示出来 android 目标平台可以正常启动,但是启动过程中的 android 字符没有显示出来,这个是 linux 内核配 置的问题 打开内核 framebuffer 控制台即可。 (1)make menuconifg 后 选 择 Device Drivers->Graphics support->Console display driver support->Framebuffer Console support 然后打开相关的几个配置选项即可。 (2)直接修改内核配置文件,如下: CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_FONTS=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y CONFIG_FONT_6x11=y # CONFIG_FONT_7x14 is not set # CONFIG_FONT_PEARL_8x8 is not set # CONFIG_FONT_ACORN_8x8 is not set # CONFIG_FONT_MINI_4x6 is not set # CONFIG_FONT_SUN8x16 is not set # CONFIG_FONT_SUN12x22 is not set # CONFIG_FONT_10x18 is not set (3)android 启动过程中的 android 字符显示在源代码的 system/core/init.c 中,如下: if( load_565rle_image(INIT_IMAGE_FILE) ) { fd = open("/dev/tty0", O_WRONLY); if (fd >= 0) { const char *msg; msg = "\n" "\n" "\n" "\n" "\n" "\n" "\n" // console is 40 cols x 30 lines "\n" "\n" "\n" "\n" "\n" "\n" "\n" " A N D R O I D "; write(fd, msg, strlen(msg)); close(fd); } } android 启动过程配置文件的解析与语法 (1)android 启动文件系统后调用的第一个应用程序是/init,此文件的很重要的内容是解析了 init.rc 和 init.xxx.rc 两个配置文件,然后执行解析出来的任务。相关代码在 android 源代码/system/core/init/init.c 文件中, 如下: parse_config_file("/init.rc"); /* pull the kernel commandline and ramdisk properties file in */ qemu_init(); import_kernel_cmdline(0); get_hardware_name(); snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware); parse_config_file(tmp); (2)从上面代码可以看到,第一个配置文件名称固定为 init.rc,而第二个配置文件格式为 init.xxx.rc,其 中 xxx 部分的内容 是 从 内核 读 取的 , 具 体 是读 取文 件 /proc/cpuinfo 中 的 Hardware 部 分, 然 后截 取其部 分内 容 。 Hardware 部分是定义在内核的 主板定义文件中,我的平台是定义在内核 arch/arm/mach-mmp/merlin.c 中,我的平台定义如下: MACHINE_START(ARDENT_MERLIN, "PXA168-based Merlin Platform") .phys_io = APB_PHYS_BASE, .boot_params = 0x00000100, .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc, .map_io = pxa_map_io, .init_irq = pxa168_init_irq, .timer = &pxa168_timer, .init_machine = merlin_init, MACHINE_END 这样截取到的 hardware 部分的内容就为 pxa168-based,也就是说我的平台的第二个配置文件应该命 名为 init.pxa168-based.rc (3)从上面看 init.xxx.rc 中的 xxx 内容是取决是内核中主板的定义的,如果觉得麻烦,可以将其在代码 中写死,例如: parse_config_file(“init.merlin.rc”); (4)配置文件的语法如下: (a)配置文件的内容包含有 4 种: 动作(Action) 命令(Commands) 服务(Services) 选项(Options) (b)动作和命令一起使用,形式如下: on 其中 trigger 是触发条件,也就是说在满足触发条件的情况下执行 1 个或多个相应的命令,举例如下: on property:persist.service.adb.enable=1 start adbd (c)服务和选项一起使用,形式如下: service [ ]*
还剩73页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 11 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

zeorro

贡献于2012-08-25

下载需要 11 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf