4 * $Id: fconfig.c,v 1.1 2006/02/13 09:58:08 andrzej Exp $
6 * Redboot Flash Configuration parser.
9 * Copyright (C) 2006 Ekiert sp z o.o.
10 * Author: Andrzej Ekiert <a.ekiert@ekiert.com>
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version
15 * 2 of the License, or (at your option) any later version.
18 * The 'device' is probably going to be an MTD device. You may also operate
19 * on an ordinary file. However, if you're working with MTD, it's highly
20 * recommended to open it as a character device, not as a block device
21 * (eg. open /dev/mtd[n], not /dev/mtdblock[n]). If an MTD device is emulating
22 * a block device, then the OS will do heavy caching (a lot of unneccessary
23 * reads), and will do block writes, while in character device mode it's
24 * possible to actually write exactly these bytes, that have been changed
25 * (see my 24xx I2C EEPROM driver - ee24.c). In case of operation with slow
26 * I2C EEPROMs this allows to speed up things and to save on EEPROM wear-out.
28 * The above should explain why mmap() is not used in this application ;-)
29 * (initially it was, but the performance was poor, when we're forced to work
30 * with slow block devices).
44 * Parse type name, return type ID.
45 * Type ID is the type number in the type table.
48 static int8_t parse_type(uint8_t *type)
52 MESSAGE(VERB_HIGH, "Parsing type: %s\n", type);
53 for (i = 0; i < NUM_TYPES; i++) {
54 if (strncmp(TYPE_NAME(i), type, MAX_TYPE_NAME)==0) {
55 MESSAGE(VERB_HIGH, "Found type: ID = %d\n", i);
65 * Print usage information.
67 static void usage(void)
74 fputs("Read or write Redboot configuration\n", stdout);
75 fputs("usage: fconfig [-r|-w] -d dev -n nickname -x value\n", stdout);
76 fputs("'dev' may be a char device, block device or a file\n", stdout);
77 fputs("Supported types: \n", stdout);
78 for (i = 0; i < NUM_TYPES; i++) {
79 printf(" - %s\n", TYPE_NAME(i));
81 fputs("Additional switches: \n", stdout);
82 fputs(" -v:\tVerbose mode, use more to increase verbosity\n", stdout);
83 fputs(" -s:\tSilent mode, absolutely no messages printed\n", stdout);
87 * Open the file or device containing configuration and copy the configuration
88 * data to a buffer. We could mmap() here and operate directly on mmaped data
89 * (it'd make life easier later), but that would force us to work with MTD in
90 * block device emulation mode (see comments at the top of this file).
92 * Remember, that the MTD partition is likely to be "forced read-only",
93 * if the partition size is not equal to erase block size.
95 static uint8_t buffer[MAX_CONFIG_DATA];
96 struct config_data *get_fconfig_handle(struct config_data *data,
97 uint8_t *dev, mode_t mode)
101 if ((data->fd = open(dev, mode)) < 0) {
102 MESSAGE(VERB_LOW, "Failed to open device or file %s!\n", dev);
106 count = read(data->fd, buffer, MAX_CONFIG_DATA);
108 MESSAGE(VERB_LOW, "Nothing read!\n");
112 MESSAGE(VERB_NORMAL, "Read %d bytes\n", count);
115 data->maxlen = count;
120 * Synchronize the data back and close the file or device containing
121 * the configuration data.
123 void close_fconfig_handle(struct config_data *data)
129 * Write mode of operation: set parameter values in the configuration.
131 static int write_mode(struct config_data *data, uint8_t *device,
132 uint8_t *nickname, uint8_t *value)
135 MESSAGE(VERB_LOW, "You must provide a value in WRITE mode\n");
139 if (get_fconfig_handle(data, device, O_RDWR) == NULL) {
140 MESSAGE(VERB_LOW, "Could not get a config data handle!\n");
143 if (verify_fconfig(data)) {
144 MESSAGE(VERB_LOW, "Config verification failed!\n");
148 if (set_key_value(data, nickname, value)) {
152 recalculate_crc(data);
154 close_fconfig_handle(data);
158 close_fconfig_handle(data);
163 * Read mode of operation: get parameter values from the configuration.
165 static int read_mode(struct config_data *data, uint8_t *device,
168 if (get_fconfig_handle(data, device, O_RDONLY) == NULL) {
169 MESSAGE(VERB_LOW, "Could not get a config data handle!\n");
172 if (verify_fconfig(data)) {
173 MESSAGE(VERB_LOW, "Config verification failed!\n");
177 if (get_key_value(data, nickname)) {
181 close_fconfig_handle(data);
185 close_fconfig_handle(data);
194 * main(). ...nuff said.
196 int main(int argc, char **argv)
198 struct config_data data;
200 uint8_t mode = MODE_NONE;
201 uint8_t *nickname = NULL;
202 uint8_t *value = NULL;
203 uint8_t *device = NULL;
205 while ((c = getopt(argc, argv, "hrwvsd:n:x:")) != -1) {
239 MESSAGE(VERB_LOW, "Low verbosity messages are printed.\n");
240 MESSAGE(VERB_NORMAL, "Normal verbosity messages are printed.\n");
241 MESSAGE(VERB_HIGH, "High verbosity messages are printed.\n");
243 if (nickname == NULL) {
248 if (device == NULL) {
249 MESSAGE(VERB_LOW, "You must provide a device name.\n");
255 ret = write_mode(&data, device, nickname, value);
258 ret = read_mode(&data, device, nickname);
261 MESSAGE(VERB_LOW, "Unknown mode of operation\n");