blob: 3898da00d33d6637d8f36560ede4c8745b3b9fcb [file] [log] [blame]
Antoine Labourd1cfe322010-03-26 13:41:05 -07001#!/usr/bin/python
2#
3# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7from optparse import OptionParser
8import binascii
9import struct
10import sys
11
12# This script allows listing, reading and writing environment variables for
13# u-boot, that usually live in an area of a block device (NVRAM, e.g. NAND or
14# NOR flash).
15# The u-boot environment variable area is a crc (4 bytes) followed by all
16# environment variables as "key=value" strings (\0-terminated) with \0\0
17# (empty string) to indicate the end.
18
19
20class SizeError(Exception):
21 pass
22
23
24def ReadEnviron(file, size=0, offset=0):
25 """Reads the u-boot environment variables from a file into a dict."""
26 f = open(file, "rb")
27 f.seek(offset)
28 if size:
29 data = f.read(size)
30 else:
31 data = f.read()
32 f.close()
33
34 (crc,) = struct.unpack("I", data[0:4])
35 real_data = data[4:]
36 real_crc = binascii.crc32(real_data) & 0xffffffff
37 environ = {}
38 for s in real_data.split('\0'):
39 if not s:
40 break
41 key, value = s.split('=', 1)
42 environ[key] = value
43
44 return (environ, len(data), crc == real_crc)
45
46def WriteEnviron(file, environ, size, offset=0):
47 """Writes the u-boot environment variables from a dict into a file."""
48 strings = ['%s=%s' % (k, environ[k]) for k in environ]
49 data = '\0'.join(strings + [''])
50
51 # pad with \0
52 if len(data) <= size-4:
53 data = data + '\0'*(size-len(data)-4)
54 else:
55 raise SizeError
56
57 crc = binascii.crc32(data) & 0xffffffff
58
59 f = open(file, "r+b")
60 f.seek(offset)
61 f.write(struct.pack("I", crc)[0:4])
62 f.write(data)
63 f.close()
64
65
66def main(argv):
67 parser = OptionParser()
68 parser.add_option('-f', '--file', type='string', dest='filename')
69 parser.add_option('-o', '--offset', type='int', dest='offset', default=0)
70 parser.add_option('-s', '--size', type='int', dest='size', default=0)
71 parser.add_option('--out', type='string', dest='out_filename')
72 parser.add_option('--out-offset', type='string', dest='out_offset')
73 parser.add_option('--out-size', type='string', dest='out_size')
74 parser.add_option('--list', action='store_true', dest='list')
75 parser.add_option('--force', action='store_true', dest='force')
76 parser.add_option('--get', type='string', action='append', dest='get',
77 default=[])
78 parser.add_option('--set', type='string', action='append', dest='set',
79 default=[])
80 (options, args) = parser.parse_args()
81 (environ, size, crc) = ReadEnviron(options.filename, options.size,
82 options.offset)
83 if not crc:
84 sys.stderr.write('Bad CRC\n')
85 if not options.force:
86 sys.exit(1)
87
88 if options.list:
89 for key in environ:
90 print "%s=%s" % (key, environ[key])
91
92 for key in options.get:
93 try:
94 print environ[key]
95 except KeyError:
96 print ''
97
98 do_write = False
99 for key_value in options.set:
100 key, value = key_value.split('=', 1)
101 environ[key] = value
102 do_write = True
103
104 if do_write:
105 out_filename = options.out_filename
106 out_offset = options.out_offset
107 out_size = options.out_size
108 if not out_filename:
109 out_filename = options.filename
110 out_offset = options.offset
111 out_size = size
112 WriteEnviron(out_filename, environ, out_size, out_offset)
113
114
115if __name__ == '__main__':
116 main(sys.argv)