OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 2 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 '''A module to support automated testing of ChromeOS formware. | 6 '''A module to support automated testing of ChromeOS formware. |
7 | 7 |
8 Utilizes services provided by <board arch>/flashrom_util.py read/write the | 8 Utilizes services provided by <board arch>/flashrom_util.py read/write the |
9 flashrom chip and to parse the flash rom image. | 9 flashrom chip and to parse the flash rom image. |
10 | 10 |
(...skipping 21 matching lines...) Expand all Loading... |
32 '''An object to provide logical services for automated flashrom testing.''' | 32 '''An object to provide logical services for automated flashrom testing.''' |
33 | 33 |
34 DELTA = 1 # value to add to a byte to corrupt a section contents | 34 DELTA = 1 # value to add to a byte to corrupt a section contents |
35 | 35 |
36 # File in the state directory to store public root key. | 36 # File in the state directory to store public root key. |
37 PUB_KEY_FILE_NAME = 'root.pubkey' | 37 PUB_KEY_FILE_NAME = 'root.pubkey' |
38 | 38 |
39 def __init__(self): | 39 def __init__(self): |
40 # make sure it does not accidentally overwrite the image. | 40 # make sure it does not accidentally overwrite the image. |
41 self.fum = None | 41 self.fum = None |
42 self.bios_layout = None | |
43 self.chros_if = None | 42 self.chros_if = None |
44 self.image = '' | 43 self.image = '' |
45 self.pub_key_file = '' | 44 self.pub_key_file = '' |
46 self.fv_sections = { | 45 self.fv_sections = { |
47 'a': FvImage('VBOOTA', 'FVMAIN'), | 46 'a': FvImage('VBOOTA', 'FVMAIN'), |
48 'b': FvImage('VBOOTB', 'FVMAINB'), | 47 'b': FvImage('VBOOTB', 'FVMAINB'), |
49 } | 48 } |
50 | 49 |
51 def init(self, flashrom_util_module, chros_if, pub_key_file=None): | 50 def init(self, flashrom_util_module, chros_if, pub_key_file=None): |
52 '''Flashrom handler initializer. | 51 '''Flashrom handler initializer. |
(...skipping 17 matching lines...) Expand all Loading... |
70 flashrom is read and its contents are saved into a | 69 flashrom is read and its contents are saved into a |
71 temporary file which is used instead. | 70 temporary file which is used instead. |
72 | 71 |
73 The input file is parsed and the sections of importance (as defined in | 72 The input file is parsed and the sections of importance (as defined in |
74 self.fv_sections) are saved in separate files in the state directory | 73 self.fv_sections) are saved in separate files in the state directory |
75 as defined in the chros_if object. | 74 as defined in the chros_if object. |
76 ''' | 75 ''' |
77 | 76 |
78 if image_file: | 77 if image_file: |
79 self.image = open(image_file, 'rb').read() | 78 self.image = open(image_file, 'rb').read() |
| 79 self.fum.set_bios_layout(image_file) |
80 else: | 80 else: |
81 self.image = self.fum.read_whole() | 81 self.image = self.fum.read_whole() |
82 self.bios_layout = self.fum.detect_chromeos_layout('bios', | |
83 len(self.image)) | |
84 self.whole_flash_layout = self.fum.detect_layout('all', | |
85 len(self.image)) | |
86 | 82 |
87 for section in self.fv_sections.itervalues(): | 83 for section in self.fv_sections.itervalues(): |
88 for subsection_name in section.names(): | 84 for subsection_name in section.names(): |
89 f = open(self.chros_if.state_dir_file(subsection_name), 'wb') | 85 f = open(self.chros_if.state_dir_file(subsection_name), 'wb') |
90 f.write(self.fum.get_section(self.image, | 86 f.write(self.fum.get_section(self.image, subsection_name)) |
91 self.bios_layout, subsection_name)) | |
92 f.close() | 87 f.close() |
93 | 88 |
94 if not self.pub_key_file: | 89 if not self.pub_key_file: |
95 self._retrieve_pub_key() | 90 self._retrieve_pub_key() |
96 | 91 |
97 def _retrieve_pub_key(self): | 92 def _retrieve_pub_key(self): |
98 '''Retrieve root public key from the firmware GBB section.''' | 93 '''Retrieve root public key from the firmware GBB section.''' |
99 | 94 |
100 gbb_header_format = '<4s20s2I' | 95 gbb_header_format = '<4s20s2I' |
101 pubk_header_format = '<2Q' | 96 pubk_header_format = '<2Q' |
102 | 97 |
103 gbb_section = self.fum.get_section( | 98 gbb_section = self.fum.get_section(self.image, 'FV_GBB') |
104 self.image, self.bios_layout, 'FV_GBB') | |
105 | 99 |
106 # do some sanity checks | 100 # do some sanity checks |
107 try: | 101 try: |
108 sig, _, rootk_offs, rootk_size = struct.unpack_from( | 102 sig, _, rootk_offs, rootk_size = struct.unpack_from( |
109 gbb_header_format, gbb_section) | 103 gbb_header_format, gbb_section) |
110 except struct.error, e: | 104 except struct.error, e: |
111 raise FlashromHandlerError(e) | 105 raise FlashromHandlerError(e) |
112 | 106 |
113 if sig != '$GBB' or (rootk_offs + rootk_size) > len(gbb_section): | 107 if sig != '$GBB' or (rootk_offs + rootk_size) > len(gbb_section): |
114 raise FlashromHandlerError('Bad gbb header') | 108 raise FlashromHandlerError('Bad gbb header') |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 | 158 |
165 if not self.image: | 159 if not self.image: |
166 raise FlashromHandlerError( | 160 raise FlashromHandlerError( |
167 'Attempt at using an uninitialized object') | 161 'Attempt at using an uninitialized object') |
168 if section not in self.fv_sections: | 162 if section not in self.fv_sections: |
169 raise FlashromHandlerError('Unknown FW section %s' | 163 raise FlashromHandlerError('Unknown FW section %s' |
170 % section) | 164 % section) |
171 | 165 |
172 # Get the appropriate section of the image. | 166 # Get the appropriate section of the image. |
173 subsection_name = self.fv_sections[section].body_name | 167 subsection_name = self.fv_sections[section].body_name |
174 body = self.fum.get_section(self.image, self.bios_layout, | 168 body = self.fum.get_section(self.image, subsection_name) |
175 subsection_name) | |
176 | 169 |
177 # Modify the byte in it within 5% of the section body. | 170 # Modify the byte in it within 5% of the section body. |
178 index = len(body) / 20 | 171 index = len(body) / 20 |
179 body_list = list(body) | 172 body_list = list(body) |
180 body_list[index] = '%c' % ((ord(body[index]) + delta) % 0x100) | 173 body_list[index] = '%c' % ((ord(body[index]) + delta) % 0x100) |
181 self.image = self.fum.put_section(self.image, self.bios_layout, | 174 self.image = self.fum.put_section(self.image, |
182 subsection_name, ''.join(body_list)) | 175 subsection_name, ''.join(body_list)) |
183 return subsection_name | 176 return subsection_name |
184 | 177 |
185 def corrupt_section(self, section): | 178 def corrupt_section(self, section): |
186 '''Corrupt a section of the image''' | 179 '''Corrupt a section of the image''' |
187 | 180 |
188 return self._modify_section(section, self.DELTA) | 181 return self._modify_section(section, self.DELTA) |
189 | 182 |
190 def restore_section(self, section): | 183 def restore_section(self, section): |
191 '''Restore a previously corrupted section of the image.''' | 184 '''Restore a previously corrupted section of the image.''' |
192 | 185 |
193 return self._modify_section(section, -self.DELTA) | 186 return self._modify_section(section, -self.DELTA) |
194 | 187 |
195 def corrupt_firmware(self, section): | 188 def corrupt_firmware(self, section): |
196 '''Corrupt a section in the FLASHROM!!!''' | 189 '''Corrupt a section in the FLASHROM!!!''' |
197 | 190 |
198 subsection_name = self.corrupt_section(section) | 191 subsection_name = self.corrupt_section(section) |
199 self.fum.write_partial(self.image, self.bios_layout, | 192 self.fum.write_partial(self.image, (subsection_name, )) |
200 (subsection_name, )) | |
201 | 193 |
202 def restore_firmware(self, section): | 194 def restore_firmware(self, section): |
203 '''Restore the previously corrupted section in the FLASHROM!!!''' | 195 '''Restore the previously corrupted section in the FLASHROM!!!''' |
204 | 196 |
205 subsection_name = self.restore_section(section) | 197 subsection_name = self.restore_section(section) |
206 self.fum.write_partial(self.image, self.bios_layout, | 198 self.fum.write_partial(self.image, (subsection_name, )) |
207 (subsection_name, )) | |
208 | 199 |
209 def write_whole(self): | 200 def write_whole(self): |
210 '''Write the whole image into the flashrom.''' | 201 '''Write the whole image into the flashrom.''' |
211 | 202 |
212 if not self.image: | 203 if not self.image: |
213 raise FlashromHandlerError( | 204 raise FlashromHandlerError( |
214 'Attempt at using an uninitialized object') | 205 'Attempt at using an uninitialized object') |
215 self.fum.write_partial(self.image, self.whole_flash_layout, ('all', )) | 206 self.fum.write_whole(self.image) |
216 | 207 |
217 def dump_whole(self, filename): | 208 def dump_whole(self, filename): |
218 '''Write the whole image into a file.''' | 209 '''Write the whole image into a file.''' |
219 | 210 |
220 if not self.image: | 211 if not self.image: |
221 raise FlashromHandlerError( | 212 raise FlashromHandlerError( |
222 'Attempt at using an uninitialized object') | 213 'Attempt at using an uninitialized object') |
223 open(filename, 'w').write(self.image) | 214 open(filename, 'w').write(self.image) |
OLD | NEW |