zoukankan      html  css  js  c++  java
  • Android源码、内核编译

    Android源码和内核的编译就是一场马拉松,每一个节点都耗时漫长,下载源码、编译源码、下载内核、编译内核,下载中途会断掉,编译中间会失败,求解再重来,又是一轮马拉松,于是每一步都要做好备份和记录,可是30G的源码(编译后已经达到70G)备份一次都需要好久。好在春节伊始我放弃了其他的学习,全力搞这个过程,终于算是拿下了。不过,漫漫长路,这只是一个开头。

    我编译的是Android最新稳定版本android-6.0.1_r11,内核是android-goldfish-3.4,平台是Mac OS 10.11。

    • 一、Android源码下载和编译

    source.android.com官网对Mac OSX下的编译说的挺详细的了,不过因为你懂的原因,去到官网很不方便,我还是把自己的心路历程记录下来,以便以后再做的时候查找方便。

    • 1、前期准备

    这是为后面下载和编译做好环境设置和工具的准备。

    • (1)创建大小写敏感的磁盘镜像文件

    Launchpad - 其它 - 磁盘工具,点击菜单 文件 - 新建映像 - 空白映像

    如下,在格式中必须选择“OS X 扩展(区分大小写,日志式)”,我在映像格式中选择了“稀疏磁盘映像”,以便未来比较容易地扩展:

    不过我发现mac的磁盘工具貌似有bug:点击存储之后,实际生成的磁盘映像文件还是“OS X 扩展(日志式)”的,而不是大小写区分,需要点击该分区文件 - 分区,此时你会发现在“格式”中选择的是“OS X 扩展(日志式)”,把它改为“OS X 扩展(区分大小写,日志式)”,再点应用。

    • (2)确认JDK、XCode版本、make版本

    在命令行下输入java -version,确认已经是最新的Java 8了:

    输入make -v,确认是3.8.1,据说最新的3.8.2有bug,如果装的是3.8.2,需要退到3.8.1:

    我的XCode版本是7.2.1

    • (3)安装所需要的packages

    到http://www.macports.org/install.php下载和安装macports,再利用macports下载几个packages:

    $ POSIXLY_CORRECT=1 sudo port install gmake libsdl git gnupg
    • (4)调高文件描述符的限制

    编辑~/.bash_profile文件,加入如下内容,把单个进程可打开的文件描述符上限改为1024:

    # set the number of open files to be 1024
    ulimit -S -n 1024

    然后执行source ~/.bash_profile

    • 2、优化编译环境

    编辑~/.bashrc文件,添加如下内容,有助于加速编译过程:

    export USE_CCACHE=1

    然后执行source ~/.bashrc

    • 3、安装repo

    编辑 ~/.bash_profile文件,添加:

    export PATH=~/bin:$PATH

    然后执行source ~/.bash_profile。

    下载repo工具,并设为可执行:

    $ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
    $ chmod a+x ~/bin/repo
    • 4、初始化repo

    挂载1-(1)中创建的大小写敏感磁盘映像文件,并在里面创建目录android-6.0.1_r11,假设它的全目录名为WORKING_DIRECTORY,

    执行如下命令初始化repo客户端:

    cd WORKING_DIRECTORY
    repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-6.0.1_r11

    我把源指向的清华的镜像服务器,它将下载分支android-6.0.1_r11,点击此处查看Android分支的名称列表

    如果要下载最新主干代码,则执行:

    repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest
    • 5、下载Android代码树

    注意,接下来我们将进入长夜漫漫的下载过程,执行:

    repo sync

    我下过几次,每次都要花上四五个小时,而且常常中途会断掉,建议晚上睡觉前走起,运气好的话,第二天早上搞定。如果失败了,还是执行这个命令,会接着上文继续下载。

    • 6、编译Android源码

    Android源码的编译步骤仅如下三步:

    • (1)设置环境变量

    $ source build/envsetup.sh
    • (2)选择编译目标

    $ lunch aosp_arm-eng

    官网说这个参数将为模拟器打开所有的调试开关。不带参数直接调用lunch会列出所有的目标选项,但是我没找到每个选项的具体描述。

    • (3)编译

    $ make -j4

    又是一个漫漫长夜的过程,我的编译大概花了三四个小时,但我没有使用-j4参数,打开这个参数将开启多线程编译。后来缀上这个参数再重新编译,果然效果明显,只用了2个小时12分钟,建议打开。

    • (4)编译问题

    build/core/combo/mac_version.mk:38: *****************************************************
    build/core/combo/mac_version.mk:39: * Can not find SDK 10.9 at /Developer/SDKs/MacOSX10.9.sdk
    build/core/combo/mac_version.mk:40: *****************************************************
    build/core/combo/mac_version.mk:41: *** Stop..  Stop.

    原因是本机的XCode SDK已经升级到10.11,打开目录:

    /Applications/XCode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs,

    检查其下的MacOSXxx.xx.sdk即可确认本机的SDK版本,然后修改WORKING_DIRECTORY/build/core/combo/mac_version.mk,将

    mac_sdk_versions_supported :=  10.6 10.7 10.8

    改为

    mac_sdk_versions_supported :=  10.9 10.10 10.11

    然后重新启动lunch aosp_arm-eng即可。

     

    fatal error: linux/netfilter/xt_DSCP.h: No such file or directory

    我在WORKING_DIRECTORY/external/iptables/extensions/../include/linux/netfilter下面能找到该文件,只不过是xt_dscp.h,我把它改名为xt_DSCP.h即可。我不知道为什么会出这样的问题,我的文件系统已经是大小写敏感的了,而且我是直接repo到该文件系统的,如果真的有错误,应该是可重现的。

    • 7、运行emulator

    经过两个多小时的编译,终于看到如下结果:

     

    在命令行下直接运行

    $emulator

    即可启动模拟器。启动过程很慢,需要耐心等待:

    编译过程做好了各种环境变量的设置:

    内核使用的是WORKING_DIRECTORY/prebuilts/qemu-kernel/arm64/kernel-qemu

    sysdir默认是WORKING_DIRECTORY/out/target/product/generic/

    系统镜像文件分别是sysdir下的system.img、ramdisk.img和userdata.img

    赶紧把磁盘卸载掉,备份磁盘映像文件!未来就可以在它的基础上做更多尝试,万一踩到屎了,还可以拿这个备份直接来用,不需要再编译一次了。

    以后再挂载该磁盘映像文件以后,需要先执行

    $cd WORKING_DIERCTORY
    $source build/envsetup.sh

    再执行$emulator即可。

    • 二、编译内核

    Android源码默认不包含他所使用的Linux内核源码,因此需要额外下载和独立编译。

    1、确认自己的内核版本号

    在刚刚的模拟器中查看手机信息,如下:

    确认内核版本是3.4

    • 2、下载内核源码

    在WORKDING_DIRECTORY目录下

    $cd WORKING_DIRECTORY 
    $mkdir kernel
    $cd kernel
    $git clone https://android.googlesource.com/kernel/goldfish.git

    这个仓库有970M,我下了三四个小时,悲催的是我没有找到它在国内的镜像服务器,而且这东西不能续传,我中途VPN断掉了,连上之后,git就不认之前下载了一半的文件了,需要从头再来,T T

    下完之后,可以看一下该内核仓库包含的分支:

    $ git branch -a
    * (头指针分离于 origin/android-goldfish-3.4)
      master
      remotes/origin/HEAD -> origin/master
      remotes/origin/android-3.10
      remotes/origin/android-3.18
      remotes/origin/android-3.4
      remotes/origin/android-goldfish-2.6.29
      remotes/origin/android-goldfish-3.10
      remotes/origin/android-goldfish-3.10-l-mr1-dev
      remotes/origin/android-goldfish-3.10-m-dev
      remotes/origin/android-goldfish-3.18-dev
      remotes/origin/android-goldfish-3.4
      remotes/origin/android-goldfish-3.4-l-mr1-dev
      remotes/origin/linux-goldfish-3.0-wip
      remotes/origin/master

    checkout3.4的分支代码:

    $git checkout remotes/origin/android-goldfish-3.4

    在kernel下创建子目录goldfish,并把刚刚检出的代码都放到goldfish下面。

    • 3、编译内核源码

    依次执行如下命令:

    $ export ARCH=arm
    $ export SUBARCH=arm
    $ export CROSS_COMPILE=arm-eabi-
    $ export PATH=WORKING_DIRECTORY/prebuilts/gcc/darwin-x86/arm/arm-eabi-4.8/bin:$PATH
    $ make goldfish_armv7_defconfig
    $ make -j4
    • 4、编译问题

    'elf.h' file not found

    我把http://www.rockbox.org/tracker/9006?getfile=16683另存为elf.h拷贝到WORKDING_DIRECTORY/kernel/goldfish/scripts/mod下。

    注意尽管在WORKING_DIRECTORY/kernel/goldfish/include/linux/elf.h下也有一个elf.h,但不能使用这个文件。

    然后将WORKING_DIRECTORY/kernel/goldfish/scripts/mod下的mk_elfconfig.c和modpost.h两个文件里的

    #include <elf.h>

    改为

    #include "elf.h"

    file2alias.c中的ADD宏发生语法错误

    把发生错误的那行做如下修改:

    sprintf(str+strlen(str), 
        sizeof(field) == 1 ? "%2X" : 
        sizeof(field) == 2 ? "%4X" : 
        sizeof(field) == 4 ? "%8X" : ""  // 最后的""改为"%8X"
        ……
    • 5、运行新编内核

    内核的编译很快,几分钟就会看到如下结果:

    产生的Linux内核文件放在了arch/arm/boot/zImage

    运行

    $ emulator -kernel WORKING_DIRECTORY/kernel/goldfish/arch/arm/boot/zImage

    启动模拟器,找到关于手机的内核版本,可以看到编译机器的信息:

    几天的探索终于开花结果,万里探索路终于可以迈出第一步了,内心小激动~~

    • 三、编译内核驱动模块

    激动之后是艰难的撸码行军。

    编译内核驱动模块需要在kernel/goldfish下面首先敲make menuconfig命令,来配置编译方式。今天发现在Mac OSX下面该命令是有问题的:

    palancedeMacBook-Pro:goldfish palance$ make menuconfig
      HOSTLD  scripts/kconfig/mconf
    Undefined symbols for architecture x86_64:
      "_COLS", referenced from:
          _dialog_checklist in checklist.o
          _dialog_clear in util.o
          _dialog_inputbox in inputbox.o
          _dialog_textbox in textbox.o
          _dialog_yesno in yesno.o
          _dialog_menu in menubox.o
    
          ……………………
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    make[1]: *** [scripts/kconfig/mconf] Error 1
    make: *** [menuconfig] Error 2
    
    e[0;31m#### make failed to build some targets (1 seconds) ####e[00m

    解决方案是找到WORKING_DIRECTORY/kernel/goldfish/scripts/kconfig/lxdialog/check-lxdialog.sh文件,如下加入粗体的部分:

    ldflags()         
    {                 
        for extin so a dylib;do
            for libi n ncursesw ncurses curses ;do
                $cc-print-file-name=lib${lib}.${ext} | grep-q /
                if [$?-eq0];then
                    echo"-l${lib}"
                    exit
                fi  
            done       
    
            for lib in ncursesw ncurses curses ; do
                if [ -f /usr/lib/lib${lib}.${ext} ];then
                    echo "-l${lib}"
                    exit                                                                                  
                fi  
            done                          
        done           
        exit1         
    
    }

    再执行make menuconfig,搞定:

  • 相关阅读:
    LeetCode15 3Sum
    LeetCode10 Regular Expression Matching
    LeetCode20 Valid Parentheses
    LeetCode21 Merge Two Sorted Lists
    LeetCode13 Roman to Integer
    LeetCode12 Integer to Roman
    LeetCode11 Container With Most Water
    LeetCode19 Remove Nth Node From End of List
    LeetCode14 Longest Common Prefix
    LeetCode9 Palindrome Number
  • 原文地址:https://www.cnblogs.com/palance/p/5187103.html
Copyright © 2011-2022 走看看