1#!/usr/bin/env python3
2# -*- coding:utf-8 -*-
3#
4# Copyright (C) 2021 Alibaba Group Holding Limited
5
6"""
7Generate the bin files including ota bin and the final bin files for chip rtl872xd.
8"""
9
10import sys
11import os
12import shutil
13import subprocess
14import platform
15
16
17home_path = os.path.expanduser("~")
18toolchain_path = os.path.join(home_path, ".aliot", "arm-ali-aoseabi", "main", "bin")
19objcopy = os.path.join(toolchain_path, "arm-ali-aoseabi-objcopy")
20nm = os.path.join(toolchain_path, "arm-ali-aoseabi-nm")
21strip = os.path.join(toolchain_path, "arm-ali-aoseabi-strip")
22cc_size = os.path.join(toolchain_path, "arm-ali-aoseabi-size")
23objdump = os.path.join(toolchain_path, "arm-ali-aoseabi-objdump")
24
25output_dir = os.getcwd()
26amebaz_dir = os.path.join(output_dir, "..", "..", "hardware", "chip", "rtl872xd")
27bin_dir = os.path.join(amebaz_dir, "bin")
28
29all_bin_output_file = os.path.join(output_dir, "binary", "all.bin")
30bin_output_file = os.path.join(output_dir, "binary", "burn.bin")
31
32km0_boot_file = os.path.join(bin_dir, "km0_boot_all.bin")
33km02_boot_file = os.path.join(bin_dir, "km0_boot_all_2nd.bin")
34km4_boot_file = os.path.join(bin_dir, "km4_boot_all.bin")
35ate_file = os.path.join(bin_dir, "ate.bin")
36KM0_BOOT_OFFSET = "0x0"
37KM4_BOOT_OFFSET = "0x4000"
38ATE_OFFSET = "0x188000"
39OTA_OFFSET = "0x6000"
40
41build_bin_py = os.path.join(amebaz_dir, "release", "auto_build_tool", "build_bin.py")
42release_dir = os.path.join(amebaz_dir, "release")
43
44
45def concatenate_bin_file(file_lists, output_file_path):
46    """Concatenate multiple binary files.
47
48    Concatenate binary files in file_lists array into the output_file_path.
49
50    Args:
51        file_lists: The input files tuple.
52        output_file_path: The output file containing all input files.
53
54    Returns: None
55    """
56    output_file = open(output_file_path, "ab")
57    for i in file_lists:
58        tmpFile = open(i, "rb")
59        fileContent = tmpFile.read()
60        output_file.write(fileContent)
61        tmpFile.close()
62    output_file.close()
63
64
65def gen_km0_km4_bin(raw_bin_file):
66    """Generate the final bin files.
67
68    Generate the bin files including ota bin and the final km0_km4_image2.bin files.
69
70    Args:
71        raw_bin_file: The compiled raw bin file, e.g. /usr/xxxx/alios/solutions/helloworld_demo/out/
72                      helloworld_demo@haas200.bin
73
74    Returns: None
75    """
76
77    raw_bin_file_array = raw_bin_file.split(".bin")
78    raw_elf_file = raw_bin_file_array[0] + ".elf"
79
80    print("========= linker img2_ns start =========")
81    image_target_folder = os.path.join(output_dir, "binary")
82    if os.path.exists(image_target_folder):
83        shutil.rmtree(image_target_folder, True)
84    os.makedirs(image_target_folder, 0o755)
85    target_img2_axf = os.path.join(image_target_folder, "target_img2.axf")
86    shutil.copyfile(raw_elf_file, target_img2_axf)
87
88    target_img2_map = os.path.join(image_target_folder, "target_img2.map")
89    subprocess.call(nm + " " + target_img2_axf + " | " + "sort " + "> " + target_img2_map,
90                    shell=True)
91    target_img2_asm = os.path.join(image_target_folder, "target_img2.asm")
92    subprocess.call(objdump + " -d " + target_img2_axf + " > " + target_img2_asm,
93                    shell=True)
94
95    target_pure_img2_axf = os.path.join(image_target_folder, "target_pure_img2.axf")
96    shutil.copyfile(target_img2_axf, target_pure_img2_axf)
97    subprocess.call([strip, target_pure_img2_axf])
98    target_pure_img2_map = os.path.join(image_target_folder, "target_pure_img2.map")
99    subprocess.call(nm + " " + target_pure_img2_axf + " | sort > " + target_pure_img2_map,
100                    shell=True)
101
102    ram2_bin = os.path.join(image_target_folder, "ram_2.bin")
103    subprocess.call([objcopy, "-j", ".ram_image2.entry", "-j", ".ram_image2.text", "-j",
104                    ".ram_image2.data", "-Obinary", target_pure_img2_axf, ram2_bin])
105
106    xip_image2_bin = os.path.join(image_target_folder, "xip_image2.bin")
107    subprocess.call([objcopy, "-j", ".xip_image2.text", "-Obinary", target_pure_img2_axf,
108                    xip_image2_bin])
109
110    psram2_bin = os.path.join(image_target_folder, "psram_2.bin")
111    subprocess.call([objcopy, "-j", ".psram_image2.text", "-j", ".psram_image2.data", "-Obinary",
112                    target_pure_img2_axf, psram2_bin])
113
114    print("========== Image Info HEX ==========")
115    subprocess.call([cc_size, "-A", "--radix=16", target_img2_axf])
116    subprocess.call([cc_size, "-t", "--radix=16", target_img2_axf])
117    print("========== Image Info HEX ==========")
118
119    print("========== Image Info DEC ==========")
120    subprocess.call([cc_size, "-A", "--radix=10", target_img2_axf])
121    subprocess.call([cc_size, "-t", "--radix=10", target_img2_axf])
122    print("========== Image Info DEC ==========")
123
124    print("========== linker img2_ns end ==========")
125
126    print("========== Image manipulating start ==========")
127    prepend_header_py = os.path.join(amebaz_dir, "prepend_header.py")
128    subprocess.call(["python", prepend_header_py, ram2_bin, "__ram_image2_text_start__",
129                    target_img2_map])
130    subprocess.call(["python", prepend_header_py, xip_image2_bin, "__flash_text_start__",
131                    target_img2_map])
132    subprocess.call(["python", prepend_header_py, psram2_bin, "__psram_image2_text_start__",
133                    target_img2_map])
134
135    xip_image2_prepend_bin_path = os.path.join(image_target_folder, "xip_image2_prepend.bin")
136    ram2_prepend_bin_path = os.path.join(image_target_folder, "ram_2_prepend.bin")
137    psram2_prepend_bin_path = os.path.join(image_target_folder, "psram_2_prepend.bin")
138    km4_image2_all_bin_path = os.path.join(image_target_folder, "km4_image2_all.bin")
139
140    concatenate_bin_file([xip_image2_prepend_bin_path, ram2_prepend_bin_path, psram2_prepend_bin_path],
141                          km4_image2_all_bin_path)
142    padPy = os.path.join(amebaz_dir, "pad.py")
143    subprocess.call(["python", padPy, km4_image2_all_bin_path])
144
145    km0_image2_all_bin_path = os.path.join(bin_dir, "km0_image2_all.bin")
146    km0_km4_image2_bin_path = os.path.join(image_target_folder, "km0_km4_image2.bin")
147    concatenate_bin_file([km0_image2_all_bin_path, km4_image2_all_bin_path], km0_km4_image2_bin_path)
148    shutil.copyfile(km0_km4_image2_bin_path, bin_output_file)
149    print("========== Image manipulating end ==========")
150
151    print("========== Generate littlefs, ota, ymodem bins ==========")
152    shutil.copyfile(km02_boot_file, os.path.join(image_target_folder, "km0_boot_all_2nd.bin"))
153    if platform.system() == "Windows":
154        subprocess.call([os.path.join(amebaz_dir, "tools", "genfs.bat")])
155    else:
156        subprocess.call([os.path.join(amebaz_dir, "tools", "genfs.sh")])
157
158    shutil.copyfile(os.path.join(amebaz_dir, "prebuild", "littlefs.bin"),
159    os.path.join(image_target_folder, "littlefs.bin"))
160    subprocess.call(["python", build_bin_py, "--target=" + km0_km4_image2_bin_path])
161    ymodem_burn_all_bin = os.path.join(image_target_folder, "ymodem_burn_all.bin")
162    shutil.copyfile(km0_km4_image2_bin_path, ymodem_burn_all_bin)
163
164    stupid_bin_file = os.path.join(release_dir, "auto_build_tool", "stupid.bin")
165    ymodem_burn_all_bin_file_hdl = open(ymodem_burn_all_bin, "r+b")
166    stupid_bin_file_hdl = open(stupid_bin_file, "rb")
167    stupid_bin_file_content = stupid_bin_file_hdl.read()
168    stupid_bin_file_hdl.close()
169    ymodem_burn_all_bin_file_hdl.seek(0)
170    ymodem_burn_all_bin_file_hdl.write(stupid_bin_file_content)
171    ymodem_burn_all_bin_file_hdl.close()
172    shutil.copyfile(ymodem_burn_all_bin, os.path.join(release_dir, "write_flash_gui", "ota_bin",
173                    "ymodem_burn_all.bin"))
174
175    ota_bin_dir = os.path.join(release_dir, "write_flash_gui", "ota_bin")
176    shutil.copyfile(os.path.join(ota_bin_dir, "ota_rtos_ota_all.bin"),
177    os.path.join(image_target_folder, "ota_burn_all.bin"))
178    shutil.copyfile(os.path.join(ota_bin_dir, "ota_rtos_ota_xz.bin.xz"),
179    os.path.join(image_target_folder, "ota_burn_xz.bin"))
180    shutil.copyfile(os.path.join(ota_bin_dir, "ota_rtos_ota_xz.bin.xz"),
181    os.path.join(ota_bin_dir, "ymodem_burn_xz.bin"))
182    shutil.copyfile(os.path.join(ota_bin_dir, "ymodem_burn_xz.bin"),
183    os.path.join(image_target_folder, "ymodem_burn_xz.bin"))
184
185    print("========== Generate littlefs, ota, ymodem bins end ==========")
186
187
188if __name__ == "__main__":
189    # e.g. args: --target=
190    # "/usr/xxxx/alios/solutions/helloworld_demo/out/helloworld_demo@haas200.bin"
191    args = sys.argv[1].split("=")
192    gen_km0_km4_bin(args[1])
193