Android AOSP 编译vendor.img

AOSP源码中的vendor.img文件,并不是由我们自己编译出来的,而是Google已编译好了的vendor.img文件,在编译AOSP源码时,会将vendor.img文件复制到out/target/product/<product_name>/目录下。若我们有修改fingerprint等需求,那么需要解包后再重新编译vendor.img文件。

一、环境准备

(1) Android系统源码编译环境(Android 9.0 Pixel 3)
(2) 开发环境(SubLime Text3)

二、下载驱动文件

在前置的文章中已经说明了驱动文件的下载和使用,详情查看Android系统源码编译

下载的驱动文件如下:

./extract-google_devices-sailfish.sh
./extract-qcom-sailfish.sh

执行脚本后解包出来的文件如下:

jhan@ubuntu:~/aosp/vendor/google_devices$ tree
.
├── blueline
│   ├── android-info.txt
│   ├── BoardConfigPartial.mk
│   ├── device-partial.mk
│   └── proprietary
│       └── vendor.img
└── crosshatch
    └── proprietary
        ├── BoardConfigVendor.mk
        └── device-vendor.mk

这里面要关注的是/aosp/vendor/google_devices/blueline/proprietary/vendor.img文件,这个文件已经是Google已编译好了的文件,我们需要对其进行解包。

三、配置编译vendor.img

修改/aosp/vendor/google_devices/blueline/BoardConfigPartial.mk 文件

注释如下内容
#BOARD_PREBUILT_VENDORIMAGE := vendor/google_devices/blueline/proprietary/vendor.img
添加如下内容
ENABLE_VENDOR_IMAGE := true
BOARD_VENDORIMAGE_PARTITION_SIZE := 536870912
BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
TARGET_COPY_OUT_VENDOR := vendor

重新编译

make -j16

三、解包vendor.img

对vendor.img文件进行格式转换

使用simg2img工具对vendor.img进行格式转换。simg2img工具在/aosp/out/host/linux-x86/bin目录下

./simg2img  /aosp/vendor/google_devices/blueline/proprietary/vendor.img /aosp/vendor/google_devices/blueline/proprietary/vendor_ext.img

挂载vendor_ext.img文件

mkdir vendor/google_devices/blueline/proprietary/vendor_mount
sudo mount vendor/google_devices/blueline/proprietary/vendor_ext.img vendor/google_devices/blueline/proprietary/vendor_mount

复制出挂载文件到其它目录

sudo cp -rf vendor/google_devices/blueline/proprietary/vendor_mount vendor/google_devices/blueline/proprietary/vendor_blob

sudo umount vendor/google_devices/blueline/proprietary/vendor_mount

修改权限组

sudo chown jhan:jhan vendor/google_devices/blueline/proprietary/vendor_blob/ -R

四、编写脚本

编写脚本,使得文件参与编译生成新的vendor.img文件,这里涉及到编写的规则,规则如下:
解包出来的vendor目录:vendor/google_devices/blueline/proprietary/vendor_blob/ (简称vendor_blob
编译源码是产生的vendor目录:out/target/product/blueline/vendor (简称vendor_out

  1. 首先将vendor_out目录与vendor_blob目录进行对比,如果文件在vendor_blob中存在,vendor_out目录中不存在,则需要添加PRODUCT_COPY_FILES拷贝规则;
  2. 如果文件在vendor_blob中存在,out_vendor中也存在,则无论两个文件是否二进制相同,均不需要添加拷贝规则,并将其从vendor_blob删除;
  3. 如果文件是软链接,则需要使用$(shell ln -s xxx)规则创建软链接;
  4. APK文件不能直接拷贝,需要添加Android.mk定义编译规则。

使用python脚本对上述的规则进行编写。

import os
import shutil

vendor_blob = r'/home/jhan/aosp/vendor/google_devices/blueline/proprietary/vendor_blob'
vendor_out = r"/home/jhan/aosp/out/target/product/blueline/vendor"

#覆盖device-partial.mk文件
device_partial_file = r'/home/jhan/aosp/vendor/google_devices/blueline/device-partial.mk'
#添加Android.mk文件
android_mk_file= r'/home/jhan/aosp/vendor/google_devices/blueline/Android.mk'
f1=''
f2=''
#create file 
for root, dirs, files in os.walk(vendor_blob):
    for file in files:
        path = os.path.join(root, file)
        if os.path.exists(path):
            if path.endswith('.apk'):
                #生成Android.mk文件,用于拷贝apk文件到vendor指定目录下
                vendor_path=path.replace(vendor_blob,vendor_out)
                if os.path.exists(vendor_path):
                    #off 
                    pass
                else:
                    dirpath=os.path.dirname(path)
                    path=dirpath.replace(vendor_blob,'')
                    print("create Android.mk -> "+path)
                    apk_mk_file=open(dirpath+"/Android.mk",'w')
                    apk_mk_file.write('LOCAL_PATH := $(call my-dir)\n')
                    apk_mk_file.write('include $(CLEAR_VARS)\n')
                    apk_mk_file.write('LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)\n')
                    apk_mk_file.write('LOCAL_MODULE := '+file.replace('.apk','')+'\n')
                    apk_mk_file.write('LOCAL_MODULE_TAGS := optional\n')
                    apk_mk_file.write('LOCAL_MODULE_PATH := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_VENDOR)'+os.path.dirname(path)+"\n")
                    apk_mk_file.write('LOCAL_MODULE_CLASS := APPS\n')
                    apk_mk_file.write('LOCAL_SRC_FILES := $(LOCAL_MODULE).apk\n')
                    apk_mk_file.write('LOCAL_CERTIFICATE := platform\n')
                    apk_mk_file.write('include $(BUILD_PREBUILT)\n')
                    apk_mk_file.close()

                pass
            else:
                #create script file 
             #$(prebuilt_blob_dir)/media/ensemble_fd_model.emd:$(TARGET_COPY_OUT_VENDOR)/media/ensemble_fd_model.emd 
                if f1 != '':
                    path=path.replace(vendor_blob,vendor_out)
                    if os.path.exists(path):
                        #off
                        pass
                    else:
                        path=path.replace(vendor_out,'')
                        f1.write('$(prebuilt_blob_dir)'+path+":"+"$(TARGET_COPY_OUT_VENDOR)"+path+" \\\n")
                        print('$(prebuilt_blob_dir)'+path+":"+"$(TARGET_COPY_OUT_VENDOR)"+path)
                else:
                	#生成device_partial.mk文件,用于复制文件到vendor目录下
                    f1 = open(device_partial_file,'w')
                    f1.write('prebuilt_blob_dir := vendor/google_devices/blueline/proprietary/vendor_blob\n')
                    f1.write('PRODUCT_COPY_FILES += \\\n')
                    print("create device-partial.mk")
                pass
        else:
            # ln -s create script file
            if f2 != '':
                #$(shell ln -s /data/vendor/wifidump $(TARGET_OUT_VENDOR)/rfs/msm/mpss/ramdumps)
                shell_comm='ls -l '+root+' | grep "'+file+' ->"'
                #print(shell_comm)
                tt=os.popen(shell_comm)
                comm_result=tt.read()
                data_sp=comm_result.split(' ')
                lndata = data_sp[len(data_sp)-1].strip()
                #print(comm_result.strip()+"--"+lndata)   

                path=path.replace(vendor_blob,'')
                f2.write('$(shell mkdir -p $(TARGET_OUT_VENDOR)'+os.path.dirname(path)+')\n')
                f2.write('$(shell ln -s '+lndata+ ' $(TARGET_OUT_VENDOR)'+path+')\n\n')
                print('$(shell ln -s '+lndata+ ' $(TARGET_OUT_VENDOR)'+path+")")
                pass
            else:
            	#生成Android.mk文件,用于创建软连接
                f2 = open(android_mk_file,'w')
                f2.write('$(shell rm -rf $(TARGET_OUT_VENDOR)/rfs/)\n\n')
                

f1.close()
f2.close()

执行python脚本

python vendor_build.py

五、编译

source build/envsetup.sh 
lunch xx
make -j16

六、相关报错

报错信息主要为 parser error : XML declaration allowed only at the start of the document,如下:

[ 41% 799/1918] Copy xml: out/target/product/blueline/vendor/etc/data/dsi_config.xml
FAILED: out/target/product/blueline/vendor/etc/data/dsi_config.xml 
/bin/bash -c "(out/soong/host/linux-x86/bin/xmllint vendor/google_devices/blueline/proprietary/vendor_blob/etc/data/dsi_config.xml >/dev/null ) && (mkdir -p out/target/product/blueline/vendor/etc/data/ ) && (rm -f out/target/product/blueline/vendor/etc/data/dsi_config.xml ) && (cp \"vendor/google_devices/blueline/proprietary/vendor_blob/etc/data/dsi_config.xml\" \"out/target/product/blueline/vendor/etc/data/dsi_config.xml\" )"
vendor/google_devices/blueline/proprietary/vendor_blob/etc/data/dsi_config.xml:8: parser error : XML declaration allowed only at the start of the document
<?xml version="1.0" encoding="UTF-8"?>
     ^
[ 41% 800/1918] Copy xml: out/target/product/blueline/vendor/etc/data/netmgr_config.xml
FAILED: out/target/product/blueline/vendor/etc/data/netmgr_config.xml 
/bin/bash -c "(out/soong/host/linux-x86/bin/xmllint vendor/google_devices/blueline/proprietary/vendor_blob/etc/data/netmgr_config.xml >/dev/null ) && (mkdir -p out/target/product/blueline/vendor/etc/data/ ) && (rm -f out/target/product/blueline/vendor/etc/data/netmgr_config.xml ) && (cp \"vendor/google_devices/blueline/proprietary/vendor_blob/etc/data/netmgr_config.xml\" \"out/target/product/blueline/vendor/etc/data/netmgr_config.xml\" )"
vendor/google_devices/blueline/proprietary/vendor_blob/etc/data/netmgr_config.xml:8: parser error : XML declaration allowed only at the start of the document
<?xml version="1.0" encoding="UTF-8"?>

解决方法为:将<?xml version="1.0" encoding="UTF-8"?>放在第一行
相关文件如下:
vendor/google_devices/blueline/proprietary/vendor_blob/etc/data/dsi_config.xml
vendor/google_devices/blueline/proprietary/vendor_blob/etc/data/netmgr_config.xml

七、刷机

fastboot flashall -w

八 、参考

Ryan ZHENG - [Android] 基于AOSP源码为Pixel3编译vendor.img


asjhan for Android reverse

 
posted @ 2023-04-19 22:23  asjhan  阅读(631)  评论(0编辑  收藏  举报  来源