Ubuntu12.04 编译Android 7.1 mkimage.sh 失败

平台

rk3399 + Android 7.1

问题

在编译Android7.1过程中, 执行make 完成后, 开始打包img文件时调用:
./mkimage.sh
出现以下错误

in=/media/MyPassport/rk3399-7.1/out/target/product/rk3399_box/system.img out=/media/MyPassport/rk3399-7.1/out/target/product/rk3399_box/system.img.out align=1024
Total of 292968 4096-byte output blocks in 4834 input chunks.
Exception:unpack requires a string argument of length 12
Traceback (most recent call last):
  File "device/rockchip/common/sparse_tool.py", line 183, in <module>
    main()
  File "device/rockchip/common/sparse_tool.py", line 175, in main
    print("i=%u" % (i))
UnboundLocalError: local variable 'i' referenced before assignment

Exception:unpack requires a string argument of length 12 ???没写过python, 不明白这是什么样的错误

分析

查看出错部分代码:
|–device/rockchip/common/sparse_tool.py

#! /usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on Fri Jun  9 15:54:32 2017

@author: LY
"""
import os, struct, sys

def usage(argv0):
  print("""
Usage: %s sparse_image_file [align_unit_K]
""" % ( argv0 ))
  sys.exit(-1)

def main():
    me = os.path.basename(sys.argv[0])
    if len(sys.argv) < 2:
        print("Error: Not enough param")
        usage(me)
    in_file_path = sys.argv[1]
    out_file_path = in_file_path + ".out"
    if len(sys.argv) > 2:
        align_unit = int(sys.argv[2])
    else:
        align_unit = 1024
    print("in=%s out=%s align=%u" % (in_file_path, out_file_path, align_unit))
    try:
        fin = open(in_file_path, 'rb')
        fout = open(out_file_path, 'wb')
        head_bin = fin.read(28)
        head_struct = list(struct.unpack("<I4H4I", head_bin))

        magic = head_struct[0]
        major_version = head_struct[1]
        minor_version = head_struct[2]
        file_hdr_sz = head_struct[3]
        chunk_hdr_sz = head_struct[4]
        blk_sz = head_struct[5]
        total_blks = head_struct[6]
        total_chunks = head_struct[7]
        image_checksum = head_struct[8]
        
        if magic == 0xED26FF3A:
            print("Total of %u %u-byte output blocks in %u input chunks."
                  % (total_blks, blk_sz, total_chunks))
            out_total_chunks = 0
            out_head = bytearray(28)
            out_chunk = bytearray(12)
            chunk_struct = list(struct.unpack("<2H2I", out_chunk))
            buffer = bytearray(align_unit * 1024)
            offset = 0
            i = 0
            remain_count = align_unit * 1024
            fout.write(out_head)
            while i < total_chunks:
                in_chunk = fin.read(12)
                in_chunk_struct = struct.unpack("<2H2I", in_chunk)
                chunk_type = in_chunk_struct[0]
                reserved1 = in_chunk_struct[1]
                chunk_sz = in_chunk_struct[2]
                total_sz = in_chunk_struct[3]
                data_sz = total_sz - 12
                fill_value = 0
                fill_bin = bytearray(4)
                if chunk_type == 0xCAC1:#raw chunk
                    data_sz = chunk_sz * blk_sz
                elif chunk_type == 0xCAC2:#fill chunk
                    fill_bin = fin.read(4)
                    fill_value = struct.unpack("<I", fill_bin)
                    data_sz = chunk_sz * blk_sz
                elif chunk_type == 0xCAC3:#don't care chunk
                    data_sz = chunk_sz * blk_sz
                else:
                    print("Error: Unknown chunk %04X" % (chunk_type))
                    break
                if offset == 0:
                    chunk_struct[0] = chunk_type
                    chunk_struct[1] = 0
                    chunk_struct[2] = 0
                    chunk_struct[3] = 12
                    remain_count = align_unit * 1024
                if data_sz > remain_count:
                    if offset == 0:
                        fout.write(in_chunk)
                        if chunk_type == 0xCAC1:
                            fout.write(fin.read(data_sz))
                        elif chunk_type == 0xCAC2:
                            fout.write(fill_bin)
                    else:
                        if chunk_struct[0] != 0xCAC3:
                            fout.write(struct.pack("<2H2I",*chunk_struct))
                            fout.write(buffer[0:offset])
                        else:
                            chunk_struct[3] = 12
                            fout.write(struct.pack("<2H2I",*chunk_struct))
                        if chunk_type == 0xCAC2:
                            fin.seek(-16,os.SEEK_CUR)
                        else:
                            fin.seek(-12,os.SEEK_CUR)
                        i -= 1
                    out_total_chunks += 1
                    offset = 0
                elif data_sz == remain_count:
                    if offset == 0:
                        fout.write(in_chunk)
                        if chunk_type == 0xCAC1:
                            fout.write(fin.read(data_sz))
                        elif chunk_type == 0xCAC2:
                            fout.write(fill_bin)
                    else:
                        if chunk_type == 0xCAC1:#raw chunk
                            if chunk_struct[0] != 0xCAC1:
                                chunk_struct[0] = 0xCAC1
                            chunk_struct[2] += chunk_sz
                            chunk_struct[3] += data_sz
                            buffer[offset:] = fin.read(data_sz)
                        elif chunk_type == 0xCAC2:#fill chunk
                            if chunk_struct[0] != 0xCAC1:
                                chunk_struct[0] = 0xCAC1
                            chunk_struct[2] += chunk_sz
                            chunk_struct[3] += data_sz
                            buffer[offset:] = [(fill_value % 256) for j in range(data_sz)]
                        elif chunk_type == 0xCAC3:#don't care chunk
                            buffer[offset:] = [0 for j in range(data_sz)]
                            chunk_struct[2] += chunk_sz
                            chunk_struct[3] += data_sz
                        offset += data_sz
                        remain_count -= data_sz
                        if chunk_struct[0] == 0xCAC3:
                            chunk_struct[3] = 12
                        fout.write(struct.pack("<2H2I",*chunk_struct))
                        if chunk_struct[0] != 0xCAC3:
                            fout.write(buffer)
                    out_total_chunks += 1
                    offset = 0
                else:
                    if chunk_type == 0xCAC1:#raw chunk
                        if chunk_struct[0] != 0xCAC1:
                            chunk_struct[0] = 0xCAC1
                        chunk_struct[2] += chunk_sz
                        chunk_struct[3] += data_sz
                        buffer[offset:offset + data_sz] = fin.read(data_sz)
                    elif chunk_type == 0xCAC2:#fill chunk
                        if chunk_struct[0] != 0xCAC1:
                            chunk_struct[0] = 0xCAC1
                        chunk_struct[2] += chunk_sz
                        chunk_struct[3] += data_sz
                        buffer[offset:offset + data_sz] = [(fill_value % 256) for j in range(data_sz)]
                    elif chunk_type == 0xCAC3:#don't care chunk
                        buffer[offset:offset + data_sz] = [0 for j in range(data_sz)]
                        chunk_struct[2] += chunk_sz
                        chunk_struct[3] += data_sz
                    offset += data_sz
                    remain_count -= data_sz
                i += 1
            if offset > 0:
                if chunk_struct[0] == 0xCAC3:
                    chunk_struct[3] = 12
                fout.write(struct.pack("<2H2I",*chunk_struct))
                if chunk_struct[0] != 0xCAC3:
                    fout.write(buffer)
                out_total_chunks += 1
                offset = 0;    
            fout.seek(0, os.SEEK_SET)
            head_struct[7] = out_total_chunks
            fout.write(struct.pack("<I4H4I", *head_struct))
            fin.close()
            fout.close()
            print("Generating optimized sparse image done,total_chunk=%u." % (out_total_chunks))
        else:
            print("Error: %s: Magic should be 0xED26FF3A but is 0x%08X" % (in_file_path, magic))
    except Exception as e:
        print("Exception:" + str(e))
        print("i=%u" % (i))
        if fin:
            fin.close()
        if fout:
            fout.close()
    sys.exit(0)
        
if __name__ == "__main__":
  main()

上网搜索, 发现一般解决方案如下,
打开文件时,用了’r’模式而非‘rb’,将代码

f=open(filepath,'r')

修改为

f=open(filepath,'rb')

查看上面的源码发现, 并非此类问题, 所以, 这个问题不一样.

尝试加入打印信息进行调试, 这是一个很坑的过程, 因为不懂python, 所以, 用TAB进行缩进, 结果一加代码就出错,
后面想起曾经有人吐嘈过python缩进的语法问题, 改用空格缩进, 如愿输出打印信息.

最后定位问题在:

out_chunk = bytearray(12)
chunk_struct = list(struct.unpack("<2H2I", out_chunk))

尝试写一个测试脚本测试:
|-- test.py

import os, struct, sys
out_chunk = bytearray(12)
out_chunk_struct = struct.unpack("<2H2I", out_chunk)

尝试执行, 发现出错信息致.
在这里, 开始怀疑python版本的问题, 同样, 版本兼容也是被吐嘈过的.
#python --version
Python 2.7.3

扫描二维码关注公众号,回复: 4730545 查看本文章

RK源码中要求是python 2.6 - 2.7这没毛病, 但我还是想试试新版本是否可以解决问题,
于是装了python3的版本, python test.py, 对, 这次没错了
顺便记录下python版本切换方法:

 #sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.2 3
 #sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 2
#切换时执行:
sudo update-alternatives --config python

感谢:https://blog.csdn.net/weiwangchao_/article/details/80395941 对struct.unpack的讲解.

尝试修改test.py

import os, struct, sys
out_chunk = struct.pack("<2H2I", 0,0,0,0)
out_chunk_struct = struct.unpack("<2H2I", out_chunk)

再次执行python test.py 这次也OK了.

解决

|–device/rockchip/common/sparse_tool.py

out_chunk = bytearray(12)
//改为
out_chunk = struct.pack("<2H2I", 0,0,0,0)

再次调用./mkimage.sh
解决!

猜你喜欢

转载自blog.csdn.net/ansondroider/article/details/85520148