blob: 9bf373c11ac9831da77a262a3eb9a707a12a312e [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 Wang065521b2010-08-23 11:34:40 -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 efault 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 Wang065521b2010-08-23 11:34:40 -070055class UserImageOptions(object): pass
56USERIMAGE_OPTIONS = UserImageOptions()
57USERIMAGE_OPTIONS.fs_type = None
Doug Zongkereef39442009-04-02 12:14:19 -070058
59def AddUserdata(output_zip):
60 """Create an empty userdata image and store it in output_zip."""
61
62 print "creating userdata.img..."
63
64 # The name of the directory it is making an image out of matters to
65 # mkyaffs2image. So we create a temp dir, and within it we create an
66 # empty dir named "data", and build the image from that.
67 temp_dir = tempfile.mkdtemp()
68 user_dir = os.path.join(temp_dir, "data")
69 os.mkdir(user_dir)
70 img = tempfile.NamedTemporaryFile()
71
Ying Wang065521b2010-08-23 11:34:40 -070072 build_command = []
73 if USERIMAGE_OPTIONS.fs_type is not None and USERIMAGE_OPTIONS.fs_type.startswith("ext"):
74 build_command = ["mkuserimg.sh",
75 user_dir, img.name, USERIMAGE_OPTIONS.fs_type, "userdata"]
76 if "userdata.img" in OPTIONS.max_image_size:
77 build_command.append(str(OPTIONS.max_image_size["userdata.img"]))
78 else:
Ying Wangd421f572010-08-25 20:39:41 -070079 build_command = ["mkyaffs2image", "-f"]
80 if OPTIONS.mkyaffs2_extra_flags is not None:
81 build_command.append(OPTIONS.mkyaffs2_extra_flags);
82 build_command.append(user_dir)
83 build_command.append(img.name)
Ying Wang065521b2010-08-23 11:34:40 -070084
85 p = common.Run(build_command)
Doug Zongkereef39442009-04-02 12:14:19 -070086 p.communicate()
Ying Wang065521b2010-08-23 11:34:40 -070087 assert p.returncode == 0, "build userdata.img image failed"
Doug Zongkereef39442009-04-02 12:14:19 -070088
Ying Wangee4bad52010-08-24 11:18:07 -070089 if USERIMAGE_OPTIONS.fs_type is None or not USERIMAGE_OPTIONS.fs_type.startswith("ext"):
90 common.CheckSize(img.name, "userdata.img")
Doug Zongkereef39442009-04-02 12:14:19 -070091 output_zip.write(img.name, "userdata.img")
92 img.close()
93 os.rmdir(user_dir)
94 os.rmdir(temp_dir)
95
96
97def AddSystem(output_zip):
98 """Turn the contents of SYSTEM into a system image and store it in
99 output_zip."""
100
101 print "creating system.img..."
102
103 img = tempfile.NamedTemporaryFile()
104
105 # The name of the directory it is making an image out of matters to
106 # mkyaffs2image. It wants "system" but we have a directory named
107 # "SYSTEM", so create a symlink.
Mike Rittere44fade2009-09-15 11:18:31 -0700108 try:
109 os.symlink(os.path.join(OPTIONS.input_tmp, "SYSTEM"),
110 os.path.join(OPTIONS.input_tmp, "system"))
111 except OSError, e:
112 # bogus error on my mac version?
113 # File "./build/tools/releasetools/img_from_target_files", line 86, in AddSystem
114 # os.path.join(OPTIONS.input_tmp, "system"))
115 # OSError: [Errno 17] File exists
116 if (e.errno == errno.EEXIST):
117 pass
Doug Zongkereef39442009-04-02 12:14:19 -0700118
Ying Wang065521b2010-08-23 11:34:40 -0700119 build_command = []
120 if USERIMAGE_OPTIONS.fs_type is not None and USERIMAGE_OPTIONS.fs_type.startswith("ext"):
121 build_command = ["mkuserimg.sh",
122 os.path.join(OPTIONS.input_tmp, "system"), img.name,
123 USERIMAGE_OPTIONS.fs_type, "system"]
124 if "system.img" in OPTIONS.max_image_size:
125 build_command.append(str(OPTIONS.max_image_size["system.img"]))
126 else:
Ying Wangd421f572010-08-25 20:39:41 -0700127 build_command = ["mkyaffs2image", "-f"]
128 if OPTIONS.mkyaffs2_extra_flags is not None:
129 build_command.append(OPTIONS.mkyaffs2_extra_flags);
130 build_command.append(os.path.join(OPTIONS.input_tmp, "system"))
131 build_command.append(img.name)
Ying Wang065521b2010-08-23 11:34:40 -0700132
Ying Wangaa6dbe22010-08-26 14:01:50 -0700133 # p = common.Run(build_command)
134 # p.communicate()
135 # assert p.returncode == 0, "build system.img image failed"
136
137 # TODO: Why the above common.Run() generate different system.img for crespo?
Ying Wangae553142010-08-26 16:04:09 -0700138 str_command = " ".join(build_command)
Ying Wangaa6dbe22010-08-26 14:01:50 -0700139 print "running " + str_command
140 exit_code = os.system(str_command)
141 assert exit_code == 0, "build system.img image failed"
Doug Zongkereef39442009-04-02 12:14:19 -0700142
143 img.seek(os.SEEK_SET, 0)
144 data = img.read()
145 img.close()
146
Ying Wangee4bad52010-08-24 11:18:07 -0700147 if USERIMAGE_OPTIONS.fs_type is None or not USERIMAGE_OPTIONS.fs_type.startswith("ext"):
148 common.CheckSize(data, "system.img")
Doug Zongker048e7ca2009-06-15 14:31:53 -0700149 common.ZipWriteStr(output_zip, "system.img", data)
Doug Zongkereef39442009-04-02 12:14:19 -0700150
151
152def CopyInfo(output_zip):
153 """Copy the android-info.txt file from the input to the output."""
154 output_zip.write(os.path.join(OPTIONS.input_tmp, "OTA", "android-info.txt"),
155 "android-info.txt")
156
157
158def main(argv):
159
160 def option_handler(o, a):
161 if o in ("-b", "--board_config"):
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700162 pass # deprecated
Ying Wang065521b2010-08-23 11:34:40 -0700163 elif o in ("-f", "--fs_type"):
164 USERIMAGE_OPTIONS.fs_type = a
Doug Zongkereef39442009-04-02 12:14:19 -0700165 else:
166 return False
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700167 return True
Doug Zongkereef39442009-04-02 12:14:19 -0700168
169 args = common.ParseOptions(argv, __doc__,
Ying Wang065521b2010-08-23 11:34:40 -0700170 extra_opts="b:f:",
171 extra_long_opts=["board_config=", "fs_type="],
Doug Zongkereef39442009-04-02 12:14:19 -0700172 extra_option_handler=option_handler)
173
174 if len(args) != 2:
175 common.Usage(__doc__)
176 sys.exit(1)
177
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700178 OPTIONS.input_tmp = common.UnzipTemp(args[0])
179
180 common.LoadMaxSizes()
Doug Zongkereef39442009-04-02 12:14:19 -0700181 if not OPTIONS.max_image_size:
182 print
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700183 print " WARNING: Failed to load max image sizes; will not enforce"
184 print " image size limits."
Doug Zongkereef39442009-04-02 12:14:19 -0700185 print
186
Ying Wangd421f572010-08-25 20:39:41 -0700187 common.LoadMkyaffs2ExtraFlags()
188
Doug Zongkereef39442009-04-02 12:14:19 -0700189 output_zip = zipfile.ZipFile(args[1], "w", compression=zipfile.ZIP_DEFLATED)
190
191 common.AddBoot(output_zip)
192 common.AddRecovery(output_zip)
193 AddSystem(output_zip)
194 AddUserdata(output_zip)
195 CopyInfo(output_zip)
196
197 print "cleaning up..."
198 output_zip.close()
199 shutil.rmtree(OPTIONS.input_tmp)
200
201 print "done."
202
203
204if __name__ == '__main__':
205 try:
206 main(sys.argv[1:])
207 except common.ExternalError, e:
208 print
209 print " ERROR: %s" % (e,)
210 print
211 sys.exit(1)