• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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