| 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)
|
|
|