1#!/usr/bin/env python 2# coding: utf-8 3# Copyright (c) 2021 Huawei Device Co., Ltd. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15import configparser 16import os 17import shutil 18import sys 19import argparse 20import subprocess 21 22DTC_419 = "dtc_419_path" 23DTC_510 = "dtc_510_path" 24FSTAB_REQUIRED = "fstab_required_path" 25NEED_CLEAR_RESOURCE_SECTION = \ 26 [DTC_419, DTC_510, FSTAB_REQUIRED, "mkimage_path"] 27 28 29def args_parse(args): 30 parser = argparse.ArgumentParser(description='mkcpioimage.py') 31 32 parser.add_argument("src_dir", help="The source file for sload.") 33 parser.add_argument("device", help="The deivce for mkfs.") 34 parser.add_argument("resource_config", 35 help="The ramdisk resource config file.") 36 37 args = parser.parse_known_args(args)[0] 38 return args 39 40 41def run_cmd(cmd, dir_list=None): 42 res = subprocess.Popen(cmd, stdout=subprocess.PIPE, 43 stdin=subprocess.PIPE, 44 stderr=subprocess.PIPE) 45 if dir_list is not None: 46 for each_path in dir_list: 47 print("mkcpio image, cpio stdin: ", each_path) 48 res.stdin.write(("%s\n" % each_path).encode('utf-8')) 49 sout, serr = res.communicate() 50 res.wait() 51 return res.pid, res.returncode, sout, serr 52 53 54def get_dir_list(input_path, dir_list): 55 if os.path.isdir(input_path): 56 dir_list.append(input_path) 57 tem_list = os.listdir(input_path) 58 for each in tem_list: 59 each_path = os.path.join(input_path, each) 60 get_dir_list(each_path, dir_list) 61 else: 62 dir_list.append(input_path) 63 64 65def build_run_fitimage(args): 66 src_dir = args.src_dir 67 index = src_dir.rfind('/') 68 root_dir = src_dir[:index] 69 70 if BOOT_TYPE == "two_stages": 71 fit_cmd = \ 72 [os.path.join(root_dir, "make-boot.sh"), 73 os.path.join(root_dir, "../../..")] 74 else: 75 if not os.path.exists("./ohos.its"): 76 print("error there is no configuration file") 77 return -1 78 if not os.path.exists(os.path.join(root_dir, "images", "zImage-dtb")): 79 print("error there is no kernel image") 80 return -1 81 82 fit_cmd = \ 83 ["mkimage", '-f', "./ohos.its", 84 os.path.join(root_dir, "images", "boot.img")] 85 86 res = run_cmd(fit_cmd) 87 if res[1] != 0: 88 print(" ".join(["pid ", str(res[0]), " ret ", str(res[1]), "\n", 89 res[2].decode(), res[3].decode()])) 90 91 return res[1] 92 93 94def build_run_cpio(args): 95 work_dir = os.getcwd() 96 os.chdir(args.src_dir) 97 98 output_path = os.path.join(work_dir, args.device) 99 ramdisk_cmd = ['cpio', '-o', '-H', 'newc', '-O', output_path] 100 dir_list = [] 101 get_dir_list("./", dir_list) 102 res = run_cmd(ramdisk_cmd, dir_list) 103 if res[1] != 0: 104 print(" ".join(["pid ", str(res[0]), " ret ", str(res[1]), "\n", 105 res[2].decode(), res[3].decode()])) 106 os.chdir(work_dir) 107 return res[1] 108 109 110def build_run_chmod(args): 111 src_dir = args.src_dir 112 src_index = src_dir.rfind('/') 113 root_dir = src_dir[:src_index] 114 115 if BOOT_TYPE == "two_stages": 116 return 0 117 118 chmod_cmd = ['chmod', '664', os.path.join(root_dir, "images", "boot.img")] 119 res = run_cmd(chmod_cmd) 120 if res[1] != 0: 121 print(" ".join(["pid ", str(res[0]), " ret ", str(res[1]), "\n", 122 res[2].decode(), res[3].decode()])) 123 return res[1] 124 125 126def parse_resource_config(resource_config_file_path): 127 """ 128 parse ramdisk_resource_config.ini 129 :param resource_config_file_path: ramdisk_resource_config.ini path 130 :return: 131 """ 132 dtc_419_source_path = "" 133 dtc_510_source_path = "" 134 global BOOT_TYPE 135 BOOT_TYPE = "" 136 need_clear_section_target_path_list = [] 137 if os.path.exists(resource_config_file_path): 138 ramdisk_config = configparser.ConfigParser() 139 ramdisk_config.read(resource_config_file_path) 140 for each_section in ramdisk_config.items(): 141 if each_section[0] == "DEFAULT": 142 continue 143 section_options = dict(ramdisk_config.items(each_section[0])) 144 source_path = section_options.get("source_path", None) 145 target_path = section_options.get("target_path", None) 146 if each_section[0] in NEED_CLEAR_RESOURCE_SECTION: 147 if each_section[0] == FSTAB_REQUIRED: 148 need_clear_section_target_path_list.append(source_path) 149 else: 150 need_clear_section_target_path_list.append(target_path) 151 if each_section[0] == DTC_419: 152 dtc_419_source_path = source_path 153 if each_section[0] == "board": 154 BOOT_TYPE = section_options.get("boot_type", None) 155 if each_section[0] == DTC_510: 156 dtc_510_source_path = source_path 157 if os.path.exists(source_path): 158 shutil.copy(source_path, target_path) 159 else: 160 if each_section[0] not in [DTC_419, DTC_510]: 161 print("Error: source file does not exist! path: %s" % 162 source_path) 163 sys.exit(1) 164 if not os.path.exists(dtc_419_source_path) and \ 165 not os.path.exists(dtc_510_source_path): 166 print("Warning: dtc tool does not exists, ") 167 else: 168 print("Error: ramdisk_resource_config.ini file does not exist!") 169 sys.exit(1) 170 return need_clear_section_target_path_list 171 172 173def clear_resource_file(input_file_path_list): 174 """ 175 clear resource file 176 :param input_file_path_list: List of files to clean up 177 :return: 178 """ 179 for each_path in input_file_path_list: 180 if os.path.exists(each_path): 181 os.remove(each_path) 182 183 184def main(args): 185 args = args_parse(args) 186 print("Make cpio image!") 187 188 need_clear_section_target_path_list = \ 189 parse_resource_config(args.resource_config) 190 191 res = build_run_cpio(args) 192 if res != 0: 193 print("error run cpio ramdisk errno: %s" % str(res)) 194 clear_resource_file(need_clear_section_target_path_list) 195 sys.exit(1) 196 res = build_run_fitimage(args) 197 if res != 0: 198 print("error run fit image errno: %s" % str(res)) 199 clear_resource_file(need_clear_section_target_path_list) 200 sys.exit(2) 201 res = build_run_chmod(args) 202 if res != 0: 203 print("error run chmod errno: %s" % str(res)) 204 clear_resource_file(need_clear_section_target_path_list) 205 sys.exit(3) 206 clear_resource_file(need_clear_section_target_path_list) 207 208 209if __name__ == '__main__': 210 main(sys.argv[1:]) 211