blob: 07eb6487cc077cec9e4096835941a114b9fce4be [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:
Doug Zongker39a98452010-09-03 14:15:34 -0700129 build_command.extend(OPTIONS.mkyaffs2_extra_flags.split());
Ying Wangd421f572010-08-25 20:39:41 -0700130 build_command.append(os.path.join(OPTIONS.input_tmp, "system"))
131 build_command.append(img.name)
Ying Wang065521b2010-08-23 11:34:40 -0700132
Doug Zongker39a98452010-09-03 14:15:34 -0700133 p = common.Run(build_command)
134 p.communicate()
135 assert p.returncode == 0, "build system.img image failed"
Doug Zongkereef39442009-04-02 12:14:19 -0700136
137 img.seek(os.SEEK_SET, 0)
138 data = img.read()
139 img.close()
140
Ying Wangee4bad52010-08-24 11:18:07 -0700141 if USERIMAGE_OPTIONS.fs_type is None or not USERIMAGE_OPTIONS.fs_type.startswith("ext"):
142 common.CheckSize(data, "system.img")
Doug Zongker048e7ca2009-06-15 14:31:53 -0700143 common.ZipWriteStr(output_zip, "system.img", data)
Doug Zongkereef39442009-04-02 12:14:19 -0700144
145
146def CopyInfo(output_zip):
147 """Copy the android-info.txt file from the input to the output."""
148 output_zip.write(os.path.join(OPTIONS.input_tmp, "OTA", "android-info.txt"),
149 "android-info.txt")
150
151
152def main(argv):
153
154 def option_handler(o, a):
155 if o in ("-b", "--board_config"):
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700156 pass # deprecated
Ying Wang065521b2010-08-23 11:34:40 -0700157 elif o in ("-f", "--fs_type"):
158 USERIMAGE_OPTIONS.fs_type = a
Doug Zongkereef39442009-04-02 12:14:19 -0700159 else:
160 return False
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700161 return True
Doug Zongkereef39442009-04-02 12:14:19 -0700162
163 args = common.ParseOptions(argv, __doc__,
Ying Wang065521b2010-08-23 11:34:40 -0700164 extra_opts="b:f:",
165 extra_long_opts=["board_config=", "fs_type="],
Doug Zongkereef39442009-04-02 12:14:19 -0700166 extra_option_handler=option_handler)
167
168 if len(args) != 2:
169 common.Usage(__doc__)
170 sys.exit(1)
171
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700172 OPTIONS.input_tmp = common.UnzipTemp(args[0])
173
174 common.LoadMaxSizes()
Doug Zongkereef39442009-04-02 12:14:19 -0700175 if not OPTIONS.max_image_size:
176 print
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700177 print " WARNING: Failed to load max image sizes; will not enforce"
178 print " image size limits."
Doug Zongkereef39442009-04-02 12:14:19 -0700179 print
180
Ying Wangd421f572010-08-25 20:39:41 -0700181 common.LoadMkyaffs2ExtraFlags()
182
Doug Zongkereef39442009-04-02 12:14:19 -0700183 output_zip = zipfile.ZipFile(args[1], "w", compression=zipfile.ZIP_DEFLATED)
184
185 common.AddBoot(output_zip)
186 common.AddRecovery(output_zip)
187 AddSystem(output_zip)
188 AddUserdata(output_zip)
189 CopyInfo(output_zip)
190
191 print "cleaning up..."
192 output_zip.close()
193 shutil.rmtree(OPTIONS.input_tmp)
194
195 print "done."
196
197
198if __name__ == '__main__':
199 try:
200 main(sys.argv[1:])
201 except common.ExternalError, e:
202 print
203 print " ERROR: %s" % (e,)
204 print
205 sys.exit(1)