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

Unified Diff: src/platform/utils/reboot_mode.py

Issue 2320003: A script for accessing reboot info in CMOS. (Closed) Base URL: ssh://git@chromiumos-git/chromeos
Patch Set: Changes based on review comments. Created 10 years, 7 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 | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/platform/utils/reboot_mode.py
diff --git a/src/platform/utils/reboot_mode.py b/src/platform/utils/reboot_mode.py
new file mode 100755
index 0000000000000000000000000000000000000000..18f336fd565a9a047f3d7b0456cc7826ef2754fd
--- /dev/null
+++ b/src/platform/utils/reboot_mode.py
@@ -0,0 +1,171 @@
+#!/usr/bin/python
+
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""A script to manipulate ChromeOS CMOS reboot Field.
+
+A few bits in a byte in CMOS (called RDB, short for 'Reboot Data Byte'
+hereafter) are dedicated to information exchange between Linux and BIOS.
+
+The CMOS contents are available through /dev/nvrom. The location of RDB is
+reported by BIOS through ACPI. The few bits in RDB operated on by this script
+are defined in the all_mode_fields dictionary below along with their
+functions.
+
+When invoked without parameters this script prints values of the fields. When
+invoked with any of the bit field names as parameter(s), the script sets the
+bit(s) as required.
+
+Additional parameters allow to specify alternative ACPI and NVRAM files for
+testing.
+"""
+
+__author__ = 'The Chromium OS Authors'
+
+import optparse
+import sys
+
+class RebootModeError(Exception):
+ pass
+
+# global variables
+parser = optparse.OptionParser()
+acpi_file = '/sys/devices/platform/chromeos_acpi/CHNV'
+nvram_file = '/dev/nvram'
+
+# Offset of RDB in NVRAM
+rdb_offset = 0
+
+# NVRAM contents read on startup
+rdb_value = ''
+
+# All bitfields in RDB this script provides access to. Field names prepended
+# by `--' become this script's command line options
+all_mode_fields = {
+ 'recovery' : 0x80,
+ 'debug_reset' : 0x40,
+ 'try_firmware_b': 0x20
+ }
+
+# A dictionary of fields to be updated as requested by the command line
+# parameters
+fields_to_set = {}
+
+
+def OptionHandler(option, opt_str, value, p):
+ """Process bit field name command line parameter.
+
+ Verifies that the value is in range (0 or 1) and adds the appropriate
+ element to fields_to_set dictionary. Should the same field specified in the
+ command line more than once, only the last value will be used.
+
+ Raises:
+ RebootModeError in case the parameter value is out of range.
+ """
+
+ global fields_to_set
+ key = opt_str[2:]
+ if value < 0 or value > 1:
+ raise RebootModeError('--%s should be either 0 or 1' % key)
+
+ fields_to_set[key] = value
+
+
+def PrepareOptions():
+ global parser
+ for field in all_mode_fields:
+ parser.add_option('--' + field, action='callback', type='int',
+ callback=OptionHandler)
+ parser.add_option('--acpi_file', dest='acpi_file')
+ parser.add_option('--nvram_file', dest='nvram_file')
+
+
+def ParseOptions():
+ global acpi_file
+ global nvram_file
+ (opts, args) = parser.parse_args()
+
+ if opts.acpi_file is not None:
+ acpi_file = opts.acpi_file
+
+ if opts.nvram_file is not None:
+ nvram_file = opts.nvram_file
+
+
+def GetRDBOffset():
+ global rdb_offset
+ try:
+ f = open(acpi_file, 'r')
+ rdb_offset = int(f.read())
+ f.close()
+ except IOError, e:
+ raise RebootModeError('Trying to read %s got this: %s' % (acpi_file, e))
+ except ValueError:
+ raise RebootModeError('%s contents are corrupted' % acpi_file)
+
+
+def ReadNvram():
+ global rdb_value
+ try:
+ f = open(nvram_file, 'rb')
+ f.seek(rdb_offset)
+ rdb_value = ord(f.read(1)[0])
+ f.close()
+ except IOError, e:
+ if e[0] == 2:
+ raise RebootModeError(
+ '%s does not exist. Is nvram module installed?' % nvram_file)
+ if e[0] == 13:
+ raise RebootModeError('Access to %s denied. Are you root?' % nvram_file)
+ raise RebootModeError(e[1])
+ except IndexError, e:
+ raise RebootModeError('Failed reading mode byte from %s' % nvram_file)
+
+
+def PrintCurrentMode():
+ print 'Current reboot mode settings:'
+ for (field, mask) in all_mode_fields.iteritems():
+ print '%-15s: %d' % (field, int(not not (rdb_value & mask)))
+
+
+def SetNewMode():
+ new_mode = 0
+ updated_bits_mask = 0
+
+ for (opt, value) in fields_to_set.iteritems():
+ mask = all_mode_fields[opt]
+ if value:
+ new_mode |= mask
+ updated_bits_mask |= mask
+
+ if (rdb_value & updated_bits_mask) == new_mode:
+ print 'No update required'
+ return
+
+ f = open(nvram_file, 'rb+')
+ f.seek(rdb_offset)
+ new_mode |= (rdb_value & ~updated_bits_mask)
+ f.write('%c' % new_mode)
+ f.close()
+
+
+def DoRebootMode():
+ PrepareOptions()
+ ParseOptions()
+ GetRDBOffset()
+ ReadNvram()
+ if fields_to_set:
+ SetNewMode()
+ else:
+ PrintCurrentMode()
+
+
+if __name__ == '__main__':
+ try:
+ DoRebootMode()
+ except RebootModeError, e:
+ print >> sys.stderr, '%s: %s' % (sys.argv[0].split('/')[-1], e)
+ sys.exit(1)
+ sys.exit(0)
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698