blob: 7acc1fd6ce4bf76fdc7b64930cdaa5499da96043 [file] [log] [blame]
Doug Zongkereef39442009-04-02 12:14:19 -07001#!/usr/bin/env python
2#
3# Copyright (C) 2008 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17"""
18Given a target-files zipfile, produces an image zipfile suitable for
19use with 'fastboot update'.
20
21Usage: img_from_target_files [flags] input_target_files output_image_zip
22
23 -b (--board_config) <file>
Doug Zongkerfdd8e692009-08-03 17:27:48 -070024 Deprecated.
Doug Zongkereef39442009-04-02 12:14:19 -070025
Ying Wang933abf12010-06-16 14:31:34 -070026 -f (--fs_type) <value>
27 The file system type of the user image files to be created.
28 It can be ext fs variants, such as ext2, ext3, ext4, etc.
29 Default is yaffs.
30
Doug Zongkereef39442009-04-02 12:14:19 -070031"""
32
33import sys
34
35if sys.hexversion < 0x02040000:
36 print >> sys.stderr, "Python 2.4 or newer is required."
37 sys.exit(1)
38
Mike Rittere44fade2009-09-15 11:18:31 -070039import errno
Doug Zongkereef39442009-04-02 12:14:19 -070040import os
41import re
42import shutil
43import subprocess
44import tempfile
45import zipfile
46
47# missing in Python 2.4 and before
48if not hasattr(os, "SEEK_SET"):
49 os.SEEK_SET = 0
50
51import common
52
53OPTIONS = common.OPTIONS
54
Ying Wang933abf12010-06-16 14:31:34 -070055class UserImageOptions(object): pass
56USERIMAGE_OPTIONS = UserImageOptions()
57USERIMAGE_OPTIONS.fs_type = None
58
Doug Zongkereef39442009-04-02 12:14:19 -070059
60def AddUserdata(output_zip):
61 """Create an empty userdata image and store it in output_zip."""
62
63 print "creating userdata.img..."
64
65 # The name of the directory it is making an image out of matters to
66 # mkyaffs2image. So we create a temp dir, and within it we create an
67 # empty dir named "data", and build the image from that.
68 temp_dir = tempfile.mkdtemp()
69 user_dir = os.path.join(temp_dir, "data")
70 os.mkdir(user_dir)
71 img = tempfile.NamedTemporaryFile()
72
Ying Wang933abf12010-06-16 14:31:34 -070073 build_command = []
74 if USERIMAGE_OPTIONS.fs_type is not None and USERIMAGE_OPTIONS.fs_type.startswith("ext"):
75 build_command = ["mkuserimg.sh",
76 user_dir, img.name, USERIMAGE_OPTIONS.fs_type, "userdata"]
Ying Wangee81cd92010-08-03 18:05:25 -070077 if "userdata.img" in OPTIONS.max_image_size:
78 build_command.append(str(OPTIONS.max_image_size["userdata.img"]))
Ying Wang933abf12010-06-16 14:31:34 -070079 else:
Ying Wangd421f572010-08-25 20:39:41 -070080 build_command = ["mkyaffs2image", "-f"]
81 if OPTIONS.mkyaffs2_extra_flags is not None:
82 build_command.append(OPTIONS.mkyaffs2_extra_flags);
83 build_command.append(user_dir)
84 build_command.append(img.name)
Ying Wang933abf12010-06-16 14:31:34 -070085
86 p = common.Run(build_command);
Doug Zongkereef39442009-04-02 12:14:19 -070087 p.communicate()
Ying Wang933abf12010-06-16 14:31:34 -070088 assert p.returncode == 0, "build userdata.img image failed"
Doug Zongkereef39442009-04-02 12:14:19 -070089
Colin Cross48642602010-08-03 22:51:49 -070090 if USERIMAGE_OPTIONS.fs_type is None or not USERIMAGE_OPTIONS.fs_type.startswith("ext"):
91 common.CheckSize(img.name, "userdata.img")
Doug Zongkereef39442009-04-02 12:14:19 -070092 output_zip.write(img.name, "userdata.img")
93 img.close()
94 os.rmdir(user_dir)
95 os.rmdir(temp_dir)
96
97
98def AddSystem(output_zip):
99 """Turn the contents of SYSTEM into a system image and store it in
100 output_zip."""
101
102 print "creating system.img..."
103
104 img = tempfile.NamedTemporaryFile()
105
106 # The name of the directory it is making an image out of matters to
107 # mkyaffs2image. It wants "system" but we have a directory named
108 # "SYSTEM", so create a symlink.
Mike Rittere44fade2009-09-15 11:18:31 -0700109 try:
110 os.symlink(os.path.join(OPTIONS.input_tmp, "SYSTEM"),
111 os.path.join(OPTIONS.input_tmp, "system"))
112 except OSError, e:
113 # bogus error on my mac version?
114 # File "./build/tools/releasetools/img_from_target_files", line 86, in AddSystem
115 # os.path.join(OPTIONS.input_tmp, "system"))
116 # OSError: [Errno 17] File exists
117 if (e.errno == errno.EEXIST):
118 pass
Doug Zongkereef39442009-04-02 12:14:19 -0700119
Ying Wang933abf12010-06-16 14:31:34 -0700120 build_command = []
121 if USERIMAGE_OPTIONS.fs_type is not None and USERIMAGE_OPTIONS.fs_type.startswith("ext"):
122 build_command = ["mkuserimg.sh",
123 os.path.join(OPTIONS.input_tmp, "system"), img.name,
124 USERIMAGE_OPTIONS.fs_type, "system"]
Ying Wangee81cd92010-08-03 18:05:25 -0700125 if "system.img" in OPTIONS.max_image_size:
126 build_command.append(str(OPTIONS.max_image_size["system.img"]))
Ying Wang933abf12010-06-16 14:31:34 -0700127 else:
Ying Wangd421f572010-08-25 20:39:41 -0700128 build_command = ["mkyaffs2image", "-f"]
129 if OPTIONS.mkyaffs2_extra_flags is not None:
130 build_command.append(OPTIONS.mkyaffs2_extra_flags);
131 build_command.append(os.path.join(OPTIONS.input_tmp, "system"))
132 build_command.append(img.name)
Ying Wang933abf12010-06-16 14:31:34 -0700133
Ying Wangaa6dbe22010-08-26 14:01:50 -0700134 # p = common.Run(build_command)
135 # p.communicate()
136 # assert p.returncode == 0, "build system.img image failed"
137
138 # TODO: Why the above common.Run() generate different system.img for crespo?
Ying Wangae553142010-08-26 16:04:09 -0700139 str_command = " ".join(build_command)
Ying Wangaa6dbe22010-08-26 14:01:50 -0700140 print "running " + str_command
141 exit_code = os.system(str_command)
142 assert exit_code == 0, "build system.img image failed"
Doug Zongkereef39442009-04-02 12:14:19 -0700143
144 img.seek(os.SEEK_SET, 0)
145 data = img.read()
146 img.close()
147
Colin Cross48642602010-08-03 22:51:49 -0700148 if USERIMAGE_OPTIONS.fs_type is None or not USERIMAGE_OPTIONS.fs_type.startswith("ext"):
149 common.CheckSize(data, "system.img")
Doug Zongker048e7ca2009-06-15 14:31:53 -0700150 common.ZipWriteStr(output_zip, "system.img", data)
Doug Zongkereef39442009-04-02 12:14:19 -0700151
152
153def CopyInfo(output_zip):
154 """Copy the android-info.txt file from the input to the output."""
155 output_zip.write(os.path.join(OPTIONS.input_tmp, "OTA", "android-info.txt"),
156 "android-info.txt")
157
158
159def main(argv):
160
161 def option_handler(o, a):
162 if o in ("-b", "--board_config"):
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700163 pass # deprecated
Ying Wang933abf12010-06-16 14:31:34 -0700164 elif o in ("-f", "--fs_type"):
165 USERIMAGE_OPTIONS.fs_type = a
Doug Zongkereef39442009-04-02 12:14:19 -0700166 else:
167 return False
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700168 return True
Doug Zongkereef39442009-04-02 12:14:19 -0700169
170 args = common.ParseOptions(argv, __doc__,
Ying Wang933abf12010-06-16 14:31:34 -0700171 extra_opts="b:f:",
172 extra_long_opts=["board_config=", "fs_type="],
Doug Zongkereef39442009-04-02 12:14:19 -0700173 extra_option_handler=option_handler)
174
175 if len(args) != 2:
176 common.Usage(__doc__)
177 sys.exit(1)
178
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700179 OPTIONS.input_tmp = common.UnzipTemp(args[0])
180
Doug Zongkerb4c7d322010-07-01 15:30:11 -0700181 info = common.LoadInfoDict()
182 common.LoadMaxSizes(info)
Doug Zongkereef39442009-04-02 12:14:19 -0700183 if not OPTIONS.max_image_size:
184 print
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700185 print " WARNING: Failed to load max image sizes; will not enforce"
186 print " image size limits."
Doug Zongkereef39442009-04-02 12:14:19 -0700187 print
188
Ying Wangd421f572010-08-25 20:39:41 -0700189 common.LoadMkyaffs2ExtraFlags()
190
Doug Zongkereef39442009-04-02 12:14:19 -0700191 output_zip = zipfile.ZipFile(args[1], "w", compression=zipfile.ZIP_DEFLATED)
192
193 common.AddBoot(output_zip)
194 common.AddRecovery(output_zip)
195 AddSystem(output_zip)
196 AddUserdata(output_zip)
197 CopyInfo(output_zip)
198
199 print "cleaning up..."
200 output_zip.close()
201 shutil.rmtree(OPTIONS.input_tmp)
202
203 print "done."
204
205
206if __name__ == '__main__':
207 try:
208 main(sys.argv[1:])
209 except common.ExternalError, e:
210 print
211 print " ERROR: %s" % (e,)
212 print
213 sys.exit(1)