Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(180)

Unified Diff: chromeos_interface.py

Issue 6881019: Fix SAFT to work on all x86 platforms using crossystem. (Closed) Base URL: ssh://gitrw.chromium.org:9222/saft.git@master
Patch Set: Fix another Mario recovery reason shortcoming. Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | saft_utility.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chromeos_interface.py
diff --git a/chromeos_interface.py b/chromeos_interface.py
index 0df860969df5b950d49b0a2f61d8237cb262519c..bf96fd15430c75ea1355845cf3074dc674ab3cb2 100755
--- a/chromeos_interface.py
+++ b/chromeos_interface.py
@@ -21,9 +21,117 @@ class ChromeOSInterfaceError(Exception):
class Crossystem(object):
'''A wrapper for the crossystem utility.'''
+ # Code dedicated for user triggering recovery mode through crossystem.
+ USER_RECOVERY_REQUEST_CODE = '193'
+
+ '''
+ The first three legacy boot vector digits are the boot vector base (the
+ entire vector consists of 5 digits). They used to be reported by the BIOS
+ through ACPI, but that scheme has been superseded by the 'crossystem'
+ interface.
+
+ The digits of the boot vector base have the following significance
+
+ - first digit -
+ 1 - normal boot
+ 2 - developer mode boot
+ 3 - recovery initialed by pressing the recovery button
+ 4 - recovery from developer mode warning screen
+ 5 - recovery caused by both firmware images being invalid
+ 6 - recovery caused by both kernel images being invalid
+ 8 - recovery initiated by user
+
+ - second digit -
+ 0 - recovery firmware
+ 1 - rewritable firmware A
+ 2 - rewritable firmware B
+
+ - third digit -
+ 0 - Read only (recovery) EC firmware
+ 1 - rewritable EC firmware
+
+
+ Below is a list of dictionaries to map current system state as reported by
+ 'crossystem' into the 'legacy' boot vector digits.
+
+ The three elements of the list represent the three digits of the boot
+ vector. Each list element is a dictionary where the key is the legacy boot
+ vector value in the appropriate position, and the value is in turn a
+ dictionary of name-value pairs.
+
+ If all name-value pairs of a dictionary element match those reported by
+ crossystem, the legacy representation number is considered the appropriate
+ vector digit.
+
+ Note that on some platforms (namely, Mario) same parameters returned by
+ crossystem are set to a wrong value. The class init() routine adjust the
+ list to support those platforms.
+ '''
+
+ VECTOR_MAPS = [
+ { # first vector position
+ '1': {
+ 'devsw_boot': '0',
+ 'mainfw_type': 'normal',
+ 'recoverysw_boot': '0',
+ },
+ '5': {
+ 'devsw_boot': '0',
+ 'recoverysw_boot': '0',
+ 'recovery_reason' : '3',
+ 'mainfw_type': 'recovery',
+ },
+ '6': {
+ 'devsw_boot': '0',
+ 'recoverysw_boot': '0',
+ 'recovery_reason' : '66',
+ 'mainfw_type': 'recovery',
+ },
+ '8': {
+ 'devsw_boot': '0',
+ 'recoverysw_boot': '0',
+ 'recovery_reason' : USER_RECOVERY_REQUEST_CODE,
+ 'mainfw_type': 'recovery',
+ },
+ },
+ { # second vector position
+ '0': {'mainfw_type': 'recovery',},
+ '1': {
+ 'mainfw_type': 'normal',
+ 'mainfw_act': 'A'
+ },
+ '2': {
+ 'mainfw_type': 'normal',
+ 'mainfw_act': 'B'
+ },
+ },
+ { # third vector position
+ '0': {'ecfw_act': 'RO',},
+ '1': {'ecfw_act': 'RW',},
+ },
+ ]
+
def init(self, cros_if):
+ '''Init the instance. If running on Mario - adjust the map.'''
+
self.cros_if = cros_if
+ # Hack Alert!!! Adjust vector map to work on Mario
+ fwid = self.__getattr__('fwid').lower()
+ if not 'mario' in fwid:
+ return
+ # Mario firmware is broken and always reports recovery switch as set
+ # at boot time when booting up in recovery mode. This is why we
+ # exclude recoverysw_boot from the map when running on mario.
+ for state in self.VECTOR_MAPS[0].itervalues():
+ if state['mainfw_type'] != 'recovery':
+ continue
+ if 'recoverysw_boot' in state:
+ del(state['recoverysw_boot'])
+ if state['recovery_reason'] == self.USER_RECOVERY_REQUEST_CODE:
+ # This is the only recovery reason Mario knows about
+ state['recovery_reason'] = '1'
+
def __getattr__(self, name):
'''
Retrieve a crosssystem attribute.
@@ -40,84 +148,27 @@ class Crossystem(object):
else:
self.cros_if.run_shell_command('crossystem "%s=%s"' % (name, value))
+ def request_recovery(self):
+ '''Request recovery mode next time the target reboots.'''
- def get_boot_vector_base(self):
- '''
- Convert system state into a legacy boot vector base.
-
- The first three legacy boot vector digits are the boot vector base
- (the entire vector consists of 5 digits). They used to be reported by
- the BIOS through ACPI, but that scheme has been superseded by the
- 'crossystem' interface.
+ self.__setattr__('recovery_request', self.USER_RECOVERY_REQUEST_CODE)
- The digits of the boot vector base have the following significance
-
- - first digit -
- 1 - normal boot
- 2 - developer mode boot
- 3 - recovery initialed by pressing the recovery button
- 4 - recovery from developer mode warning screen
- 5 - recovery caused by both firmware images being invalid
- 6 - recovery caused by both kernel images being invalid
-
- - second digit -
- 0 - recovery firmware
- 1 - rewritable firmware A
- 2 - rewritable firmware B
-
- - third digit -
- 0 - Read only (recovery) EC firmware
- 1 - rewritable EC firmware
-
-
- This function uses a three tuple of dictionaries to map current system
- state as reported by 'crossystem' into the 'legacy' boot vector
- digits.
-
- Each tuple element is a dictionary, where the key is the 'legacy'
- representation of the state, and the value is a yet another dictionary
- of name-value pairs.
-
- If all name-value pairs match those in the crossystem output, the
- legacy representation number is returned as the appropriate vector
- number.
+ def get_boot_vector_base(self):
+ '''Convert system state into a legacy boot vector base.
- The function returns a list of three digits in symbolic representation.
+ The function looks up the VECTOR_MAPS list above to find the digits
+ matching the current crossystem output, and returns a list of three
+ digits in symbolic representation, which become the base of the 5
+ digit boot state vector.
- Should it be impossible to interpret the state, the function returns a
- partially built list, which is an indication of a problem for the
+ Should it be impossible to interpret the state, the function returns
+ a partially built list, which is an indication of a problem for the
caller (list shorter than 3 elements).
'''
- vector_maps = (
- { # first vector position
- '1': {
- 'devsw_boot': '0',
- 'recoverysw_boot': '0',
- 'recovery_reason' : '0',
- 'tried_fwb' : '0',
- },
- },
- { # second vector position
- '0': {'mainfw_type': 'recovery',},
- '1': {
- 'mainfw_type': 'normal',
- 'mainfw_act': 'A'
- },
- '2': {
- 'mainfw_type': 'normal',
- 'mainfw_act': 'B'
- },
- },
- { # third vector position
- '0': {'ecfw_act': 'RO',},
- '1': {'ecfw_act': 'RW',},
- },
- )
-
boot_vector = []
- for vector_map in vector_maps:
+ for vector_map in self.VECTOR_MAPS:
for (digit, values) in vector_map.iteritems():
for (name, value) in values.iteritems():
if self.__getattr__(name) != value:
@@ -129,7 +180,8 @@ class Crossystem(object):
return boot_vector
def dump(self):
- '''Dump all values as multiline text.'''
+ '''Dump all crossystem values as multiline text.'''
+
return '\n'.join(self.cros_if.run_shell_command_get_output(
'crossystem'))
« no previous file with comments | « no previous file | saft_utility.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698