Show
Ignore:
Timestamp:
09/27/08 12:08:28 (3 months ago)
Author:
stepan
Message:

Add string support to nvramtool.

To add a string to your cmos.layout, you need to specify type 's':

#start len type unused name
416 512 s 0 boot_devices

With this patch you can do

$ nvramtool -w boot_devices="(hd0,0);(hd2,1);(hd3)"

And FILO will attempt to load a menu.lst from any of these devices in that
order.

The patch is not exactly pretty, but a cleaner solution might have resulted in
a complete rewrite of the tool, which I did not want.

Signed-off-by: Stefan Reinauer <stepan@…>
Acked-by: Joseph Smith <joe@…>

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/util/nvramtool/cmos_lowlevel.c

    r3122 r3613  
    11/*****************************************************************************\ 
    22 * cmos_lowlevel.c 
    3  * $Id$ 
    43 ***************************************************************************** 
    54 *  Copyright (C) 2002-2005 The Regents of the University of California. 
     
    7170static inline void put_bits (unsigned char value, unsigned bit, 
    7271                             unsigned nr_bits, unsigned long long *result) 
    73  { *result += (value & ((unsigned char) ((1 << nr_bits) - 1))) << bit; } 
     72 { *result += ((unsigned long long)(value & ((unsigned char) ((1 << nr_bits) - 1)))) << bit; } 
    7473 
    7574/**************************************************************************** 
     
    8079 * process must be set appropriately. 
    8180 ****************************************************************************/ 
    82 unsigned long long cmos_read (unsigned bit, unsigned length) 
     81unsigned long long cmos_read (const cmos_entry_t *e) 
    8382 { cmos_bit_op_location_t where; 
     83   unsigned bit = e->bit, length=e->length; 
    8484   unsigned next_bit, bits_left, nr_bits; 
    85    unsigned long long result; 
     85   unsigned long long result = 0; 
    8686   unsigned char value; 
    8787 
    88    assert(!verify_cmos_op(bit, length)); 
     88   assert(!verify_cmos_op(bit, length, e->config)); 
    8989   result = 0; 
    9090 
    91    for (next_bit = 0, bits_left = length; 
    92         bits_left; 
    93         next_bit += nr_bits, bits_left -= nr_bits) 
    94     { nr_bits = cmos_bit_op_strategy(bit + next_bit, bits_left, &where); 
    95       value = cmos_read_bits(&where, nr_bits); 
    96       put_bits(value, next_bit, nr_bits, &result); 
     91   if (e->config == CMOS_ENTRY_STRING) 
     92    { char *newstring = malloc((length+7)/8); 
     93      unsigned usize = (8 * sizeof(unsigned long long)); 
     94 
     95      if(!newstring) { out_of_memory(); } 
     96 
     97      for (next_bit = 0, bits_left = length; 
     98           bits_left; 
     99           next_bit += nr_bits, bits_left -= nr_bits) 
     100       { nr_bits = cmos_bit_op_strategy(bit + next_bit, bits_left>usize?usize:bits_left, &where); 
     101         value = cmos_read_bits(&where, nr_bits); 
     102         put_bits(value, next_bit % usize, nr_bits, &((unsigned long long *)newstring)[next_bit/usize]); 
     103         result = (unsigned long)newstring; 
     104       } 
     105    } 
     106   else 
     107    { for (next_bit = 0, bits_left = length; 
     108           bits_left; 
     109           next_bit += nr_bits, bits_left -= nr_bits) 
     110       { nr_bits = cmos_bit_op_strategy(bit + next_bit, bits_left, &where); 
     111         value = cmos_read_bits(&where, nr_bits); 
     112         put_bits(value, next_bit, nr_bits, &result); 
     113       } 
    97114    } 
    98115 
     
    107124 * appropriately. 
    108125 ****************************************************************************/ 
    109 void cmos_write (unsigned bit, unsigned length, unsigned long long value) 
     126void cmos_write (const cmos_entry_t *e, unsigned long long value) 
    110127 { cmos_bit_op_location_t where; 
     128   unsigned bit = e->bit, length=e->length; 
    111129   unsigned next_bit, bits_left, nr_bits; 
    112130 
    113    assert(!verify_cmos_op(bit, length)); 
    114  
    115    for (next_bit = 0, bits_left = length; 
    116         bits_left; 
    117         next_bit += nr_bits, bits_left -= nr_bits) 
    118     { nr_bits = cmos_bit_op_strategy(bit + next_bit, bits_left, &where); 
    119       cmos_write_bits(&where, nr_bits, get_bits(value, next_bit, nr_bits)); 
     131   assert(!verify_cmos_op(bit, length, e->config)); 
     132 
     133   if (e->config == CMOS_ENTRY_STRING)  
     134    { unsigned long long *data = (unsigned long long *)(unsigned long)value; 
     135      unsigned usize = (8 * sizeof(unsigned long long)); 
     136 
     137      for (next_bit = 0, bits_left = length; 
     138           bits_left; 
     139           next_bit += nr_bits, bits_left -= nr_bits) 
     140       { nr_bits = cmos_bit_op_strategy(bit + next_bit, bits_left>usize?usize:bits_left, &where); 
     141         value = data[next_bit/usize]; 
     142         cmos_write_bits(&where, nr_bits, get_bits(value, next_bit % usize, nr_bits)); 
     143       } 
     144    } 
     145   else 
     146    { for (next_bit = 0, bits_left = length; 
     147           bits_left; 
     148           next_bit += nr_bits, bits_left -= nr_bits) 
     149       { nr_bits = cmos_bit_op_strategy(bit + next_bit, bits_left, &where); 
     150         cmos_write_bits(&where, nr_bits, get_bits(value, next_bit, nr_bits)); 
     151       } 
    120152    } 
    121153 } 
     
    237269 * no problems were encountered, return OK.  Else return an error code. 
    238270 ****************************************************************************/ 
    239 int verify_cmos_op (unsigned bit, unsigned length) 
     271int verify_cmos_op (unsigned bit, unsigned length, cmos_entry_config_t config) 
    240272 { if ((bit >= (8 * CMOS_SIZE)) || ((bit + length) > (8 * CMOS_SIZE))) 
    241273      return CMOS_AREA_OUT_OF_RANGE; 
     
    243275   if (bit < (8 * CMOS_RTC_AREA_SIZE)) 
    244276      return CMOS_AREA_OVERLAPS_RTC; 
     277 
     278   if (config == CMOS_ENTRY_STRING) 
     279      return OK; 
    245280 
    246281   if (length > (8 * sizeof(unsigned long long)))