Android开发环境搭建和编译系统

1 工具使用
1.1 将dos格式的文件转换为unix格式文件
直接执行 dos2unix file
例如: dos2unix InotifyMon/AndroidManifest.xml

1.2 Linux Shell FTP使用
ftp <IP addr>
输入ID和password
prompt off
// 下载文件到本地
mget *

1.3 Linux sed
1.3.1 Linux命令之sed(Stream Editor)批量替换字符串操作
使用的格式如下:

sed -i "s/<oldstring>/<newstring>/g" `grep <oldstring> -rl <path>`

其中,oldstring是待被替换的字符串,newstring是待替换oldstring的新字符串,grep操作主要是按照所给的目录查找oldstring,path表示要查找的目录,譬如./
-i选项是直接在文件中替换,不在终端输出;
-r选项是所给的path中的目录递归查找;
-l选项是输出所有匹配到oldstring的文件;

1.3.2 sepolicy CIL
Android 8.0 adb root user sepolicy /system/etc/selinux/plat_sepolicy.cil
CIL: Selinux Common Intermediate Language
sed -i "s#\(abcd zcb (.*\) xxx#\1 su xxx#" 1.txt
I. \(和\)是用来标记一个表达式,这样就可以在后面被\1来引用原文。
II. abcd zcb (是要匹配的部分,.*是正则表达式匹配所有字符。
III. 第一个xxx表示要被替换的部分,替换为su xxx。
IV. 这里是用# 来分隔源和目标的,可能很多例子会用/来分隔源和目标。
V. 最后的1.txt表示在这个文件中做替换。

1.4 git
repo start --all <branch>
git clean -dfx
git reset --hard
repo sync -c -d .

git fetch -p
git branch --set-upstream-to=origin/<BRANCH> <BRANCH>

git format-patch -1 "${commit_id}"
git format-patch HEAD~3

cherry-pick的SHA1值在下面(Base - Patchset2 - SHA1)。

在~/.netrc中添加用户名和密码可以实现git pull自动输入密码。
machine <URL> login <username> password <xxx>

github PR,Pull Request:原作者大神,我改了点东西,你快把我的修改拉回去吧。

1.5 Java Configuration
sudo update-alternatives --config java
sudo update-alternatives --config javac
sudo update-alternatives --config javah
sudo update-alternatives --config jar
sudo update-alternatives --config javap
sudo update-alternatives --config javadoc

Or add the following states to /etc/profile

export JAVA_HOME=\
/usr/lib/jvm/java-6-openjdk-amd64
export JRE_HOME=\
${JAVA_HOME}/jre
export CLASSPATH=.:\
${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=\
$PATH:${JAVA_HOME}/bin:${JRE_HOME}/bin

1.6 Linux Lindent
apt install indent
scripts/Lindent /path/to/my.c
scripts/checkpatch.pl \
--no-tree -f /path/to/my.c

1.7 python3.8
无法修改python版本的情况下,如何使用python3.8
定义一个文件~/bin/python3,添加如下的内容,并修改权限为可执行。
/usr/bin/python3.8 $@
修改.bashrc,添加PATH=~/bin:$PATH,然后source .bashrc
此后任何需要python3的脚本都会优先使用~/bin/python3

2 Android toolchain
2.1 覆盖Android源代码中的cpp或者Java文件
1) device/<oem>/<soc_platform>/<project>/vendorsetup.sh
#!/bin/sh

MY_PATH=${PWD}
PROJ_PATH="device/<oem>/<soc_platform>/<project>"

if [ -f ${MY_PATH}/${PROJ_PATH}/overlay_setup.sh ]; then
    chmod a+x ${MY_PATH}/${PROJ_PATH}/overlay_setup.sh
fi

2) device/<oem>/<soc_platform>/<project>/overlay_setup.sh
#!/bin/sh

MY_PATH=${PWD}
OVL_PATH="device/<oem>/<soc_platform>/<project>/path/to/overlay"

# add shell commands here

3) device/<oem>/<soc_platform>/<project>/device.mk
$(shell $(LOCAL_PATH)/overlay_setup.sh)

2.2 Android添加自定义的产品类型
- 参考其它项目生成文件夹:device/<OEM>/<product>
- 将产品添加到lunch编译系统中:device/<OEM>/common/vendorsetup.sh

2.3 make过程
2.3.1 跟踪编译命令
boot.img: function build-recoveryimage-target
system.img: function build-systemimage-target

zcat out/verbose.log.gz
当verbose.log.gz中出现/bin/bash -c "..."时,表示下面将要执行的命令。

2.3.2 extract cmd
import io
import re
import sys,os
import shutil

arg0_proc_name = ''
def print_usage():
    print('\nUsage: python ' +
        arg0_proc_name +
        ' <src_file>' +
        ' <dst_file>')

def write_file_string(
    file, string):
    h = open(file, 'a+')
    idx = string.find(']')
    if (idx >= 0):
        string = string[(idx + 1):]
    h.writelines(string)
    h.close()

def write_cmd_string_to_log(
    src_file, dst_file, match_string):
    fp = io.open(src_file,
        'r',
        encoding = 'utf-8',
        errors = 'ignore')
    try:
        for line_string in fp:
            if re.findall(match_string,
                line_string.lower()):
                write_file_string(
                    dst_file, line_string)
    except KeyboardInterrupt:
        print('Got ^C exit signal')
    fp.close()

def main():
    global arg0_proc_name
    arg0_proc_name = \
        sys.argv[0]
    if sys.argv[0].rfind(
        os.path.sep) > 0 :
        index = sys.argv[0].rfind(
            os.path.sep)
        arg0_proc_name = \
            sys.argv[0][index+1:]

    if len(sys.argv) < 3:
        print_usage()
        sys.exit(0)

    if (os.path.isfile(
        sys.argv[2])) :
        os.unlink(sys.argv[2])

    write_cmd_string_to_log(
        sys.argv[1],
        sys.argv[2],
        "/bin/bash -c")

if __name__ == '__main__':
    main()

3 Linux aarch64-linux-gnu-gcc
3.1 aarch64-linux-gnu-gcc
https://releases.linaro.org/components/toolchain/binaries
gcc-linaro-*.tar.xz: compiler
sysroot-linaro-*.tar.xz: root fs

xz -d xxx.tar.xz
tar xvf xxx.tar

Support legacy arm-linux-gcc binary:
Userspace binary formats ---> Kernel support for 32-bit EL0

3.2 Linux libtool静态链接
libtool在link-mode时,可以使用参数:-all-static
且这个参数要放在ld之后,如下:
/bin/sh ../libtool --tag=CC \
--mode=link \
aarch64-linux-gnu-gcc -all-static 

在这里是放在aarch64-linux-gnu-gcc之后,不然提示找不到-all-static。
生成的链接命令会自动加上:-static,并且自动寻找lib*.a的静态库。

3.3 showcase
# CROSS_COMPILE = \
# /path/to/bin/aarch64-linux-gnu-

# CC means C Compiler
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld
.PHONY: clean

OBJS = src/main.o
CFLAGS = \
    -I./include
LDFLAGS =

# compile every c file to object
%.o: %.c
        $(CC) $(CFLAGS) -c $^ -o $@
# link all of the objects to uevent_mon
uevent_mon: $(OBJS)
        $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) \
            -o $@
clean:
        rm -rf $(OBJS)
        rm -rf uevent_mon

4 modem image
4.1 contents.xml
该文件在私有代码的根目录下,主要定义了升级包中镜像的名字、路径以及相关的打包工具。在common/config目录下,有不同后缀的contents.xml,根据项目需要把对应的xml复制到根目录下,并改名为contents.xml。

QFIL - Tools - Flat Meta Build
读取contents.xml文件,提取所有img并将之打包成Flat或者Meta格式的文件夹。所有img在同一个文件夹下的格式称为Flat,img在独立文件夹中的格式称为Meta。

4.2 sparse image
file system.img
sparse ext2 image,sparse的另外一个意思是稀疏矩阵,for fastboot

file system_1.img
raw ext2 image, for QFIL

QFIL rawprogramX.xml中的physical_partition_number表示UFS的LUN。

4.3 python
Windows Notepad - Save as - Encoding (ANSI)
Windows Notepad - Edit - Replace... - replaces ? with blank

# python pyimg.py 6155_la
import sys,os
from xml.dom.minidom import parse

def readXML(flavor, dnl_file):
    domTree = parse("./contents.xml")
    rootNode = domTree.documentElement

    builds_flat = \
        rootNode.getElementsByTagName(
        "builds_flat")
    builds = \
        builds_flat[0].getElementsByTagName(
        "build")

    for build in builds:
        name = \
            build.getElementsByTagName(
            "name")
        download_files = \
            build.getElementsByTagName(
           dnl_file)
        for download_file in download_files:
            file_name = \
            download_file.getElementsByTagName(
            "file_name")
            file_paths = \
            download_file.getElementsByTagName(
            "file_path")

            show = 0
            if download_file.hasAttribute("flavor") \
                and \
                (download_file.getAttribute("flavor")
                == flavor):
                show = 1

            for file_path in file_paths:
                if file_path.hasAttribute("flavor") \
                    and \
                    (file_path.getAttribute("flavor")
                        == flavor) and \
                    (file_path.firstChild.data.find(
                        "emmc")  < 0):
                    show = 1
                    break

            if show == 1:
                print(name[0].firstChild.data +
                    "/" +
                    file_path.firstChild.data.rstrip("/") +
                    "/" +
                    file_name[0].firstChild.data)

if __name__ == '__main__':
    arg0_proc_name = sys.argv[0]
    if sys.argv[0].rfind(os.path.sep) > 0:
        index = sys.argv[0].rfind(os.path.sep)
        arg0_proc_name = sys.argv[0][index+1:]
    if len(sys.argv) < 2:
        print("\nUsage: python " +
            arg0_proc_name +
            " <flavor>\n")
        sys.exit(0)

    readXML(sys.argv[1], "download_file")
    readXML(sys.argv[1], "partition_file")
    readXML(sys.argv[1], "partition_patch_file")
    readXML(sys.argv[1], "device_programmer")

4.4 image
#!/bin/sh

amss_flavors="660_la"
PRODUCT="sdm660"
ANDROID_PATH="/path/to/android"
AMSS_PATH="/path/to"
AMSS_ANDROID="${AMSS_PATH}/LINUX"

cd ${AMSS_PATH}
rm -rf ${AMSS_ANDROID}
mkdir -p ${AMSS_ANDROID}
ln -s ${ANDROID_PATH}/ ${AMSS_ANDROID}

# Generate NON-HLOS.bin and spare image
# cd common/build && python update_common_info.py
cd common/build && python build.py --flavors=${amss_flavors} --variant=xxx
cd -

# Check if bin/ is generated
if [ -d "common/build/ufs/${amss_flavors}/bin" ]; then
    ls "common/build/ufs/${amss_flavors}/bin"
else
    echo "Error, no bin generated!"
    exit 0
fi

# Copy files, search keyword LINUX in contents.xml, need to be copied,
# QFIL - Tools - Flat Meta Build
cp_files="${AMSS_PATH}/common/build/ufs/${amss_flavors}/bin/NON-HLOS.bin
${AMSS_PATH}/common/build/ufs/${amss_flavors}/gpt_main0.bin
${AMSS_PATH}/common/build/ufs/${amss_flavors}/gpt_backup0.bin
${AMSS_PATH}/common/build/ufs/${amss_flavors}/patch0.xml
${AMSS_PATH}/common/build/ufs/${amss_flavors}/rawprogram0.xml
${AMSS_PATH}/xxx/boot_images/QcomPkg/SDMPkg/6150/Bin/AU/RELEASE/prog_firehose_ddr.elf
${AMSS_PATH}/xxx/trustzone_images/build/ms/bin/PAZAANAA/tz.mbn
${ANDROID_PATH}/out/target/product/${PRODUCT}/*.img"

for file in ${cp_files}; do
    echo ${file}
    cp $file ${AMSS_PATH}/common/build/ufs/${amss_flavors}/bin/sparse_images
done

# zip
GEN_TIME=$(date +%Y-%m-%d-%H%M%S)
GEN_FILE=FlashPackage_${PRODUCT}_${GEN_TIME}

cd common/build/ufs/${amss_flavors}/bin
zip -r ${GEN_FILE}.zip ./sparse_images
cd -
mv common/build/ufs/${amss_flavors}/bin/${GEN_FILE}.zip ./

echo "${AMSS_PATH}/${GEN_FILE}.zip has been created!"

5 Abbreviations
aop.mbn: always on processor, qcom RPM partition,使用CM4或者RISC-V
cmnlib.mbn: qcom trustzone commonlib, qseecom_sample_client
devcfg.mbn: qcom QUP访问权限控制,SPI片选和时钟线分别对应I2C的SDA和SCL
km41.mbn: qcom keymaster v4.1
lagvm: qcom Linux Android Guest Virtual Machine

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值