source: patches/powerpc-utils_1.1.3-fixes-2.patch@ 14a6491

clfs-1.2 clfs-2.1 clfs-3.0.0-systemd clfs-3.0.0-sysvinit systemd sysvinit
Last change on this file since 14a6491 was f2b4aa3, checked in by Jim Gifford <clfs@…>, 18 years ago

r3499@server (orig r1599): ken | 2006-05-14 14:04:50 -0700
Add missing ppc64/ppc patches.

  • Property mode set to 100644
File size: 21.4 KB
  • pmac-utils

    Submitted By: Ken Moffat <ken@linuxfromscratch.org>
    Date: 2005-11-23
    Initial Package Version: 1.1.3
    Upstream Status: Package is maintained by debian, this cherry-picks
    Origin: From debian 1.1.3-18.diff, edited
    Description: Makes it work on New World, fixes compile error, updated to
     allow -m32 to be passed via EXTRACFLAGS in multilib.
    
     Some of the debian powerpc-utils_1.1.3-18.diff, but only the parts relevant
    to nvsetenv and nvsetvol - the remainder may be useful on an Old World Mac,
    but they are no use on New World.  The -D_GNU_SOURCE apparently helps on
    powerpc64.  I've also removed bogus messages advising you to update your
    headers when IOC_NVRAM_SYNC isn't defined : it hasn't existed for a long
    time.  Finally, I ran the nvsetenv.sgml through docbook2txt -man to get a
    proper man page, because most people won't have docbook utils installed. 
    
    diff -Nuar pmac-utils.orig/Makefile pmac-utils/Makefile
    old new  
    2222
    2323SGMLMAN = sgml2txt -man
    2424CC      = gcc -Wall -Wstrict-prototypes
    25 CFLAGS  = -O2 -fsigned-char
    26 LDFLAGS = -s
     25CFLAGS  = $(EXTRACFLAGS) -O2 -fsigned-char -D_GNU_SOURCE
     26LDFLAGS =
    2727INSTALL = /usr/bin/install -c
    2828SOUND_INC = -I.
    2929
     
    4242mousemode:
    4343        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c
    4444
    45 nvsetenv:
     45nvsetenv: nvsetenv.c nwnvsetenv.c
     46        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c nwnvsetenv.c
     47
     48nvsetvol:
    4649        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c
     50 
    4751
    4852nvvideo:
    4953        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c
  • nvsetenv.8

    diff -Nuar pmac-utils.orig/nvsetenv.8 pmac-utils/nvsetenv.8
    old new  
     1.if n .ds Q \&"
     2.if t .ds Q ``
     3.if n .ds U \&"
     4.if t .ds U ''
     5.TH "NVSETENV" 8
     6.tr \&
     7.nr bi 0
     8.nr ll 0
     9.nr el 0
     10.de DS
     11..
     12.de DE
     13..
     14.de Pp
     15.ie \\n(ll>0 \{\
     16.ie \\n(bi=1 \{\
     17.nr bi 0
     18.if \\n(t\\n(ll=0 \{.IP \\(bu\}
     19.if \\n(t\\n(ll=1 \{.IP \\n+(e\\n(el.\}
     20.\}
     21.el .sp
     22.\}
     23.el \{\
     24.ie \\nh=1 \{\
     25.LP
     26.nr h 0
     27.\}
     28.el .PP
     29.\}
     30..
     31.SH NAME
     32
     33.Pp
     34\fBnvsetenv\fP - change/view Open Firmware environment variables
     35.Pp
     36.SH SYNOPSIS
     37
     38.Pp
     39\fBnvsetenv
     40\f(CR[\fP\fIvariable\fP \f(CR[\fP\fIvalue\fP\f(CR\fB]]\fP\fP\fP
     41.Pp
     42.SH DESCRIPTION
     43
     44.Pp
     45\fBnvsetenv\fP is a program to adjust or view the Open Firmware (OF)
     46boot parameters stored in non-volatile (battery-powered) RAM.
     47\fBnvsetenv\fP will show the current values of all OF's environment
     48variables when no parameters are given.
     49.Pp
     50.SH OPTIONS
     51
     52.Pp
     53.nr ll +1
     54.nr t\n(ll 2
     55.if \n(ll>1 .RS
     56.IP "\fIvariable\fP"
     57.nr bi 1
     58.Pp
     59nvsetenv will show current value of an OF's
     60variable, if no value is given
     61.IP "\fIvariable value\fP"
     62.nr bi 1
     63.Pp
     64nvsetenv will set \fIvariable\fP to
     65\fIvalue\fP
     66.if \n(ll>1 .RE
     67.nr ll -1
     68.Pp
     69.SH EXAMPLES
     70
     71.Pp
     72This example will set the boot device to the first SCSI disk on the
     73internal SCSI bus, using /vmlinux as boot image, trying to
     74use the third partition as root partition.
     75.DS
     76.sp
     77.ft RR
     78.nf
     79        > nvsetenv boot-device  \&"scsi-int/sd@0:0\&"
     80        > nvsetenv boot-file    \&" /vmlinux root=/dev/sda3\&"
     81.DE
     82.fi
     83.ec
     84.ft P
     85.sp
     86.Pp
     87Alternatives boot devices are:
     88.DS
     89.sp
     90.ft RR
     91.nf
     92        scsi/sd@1:0             SCSI disk at ID 1
     93        ata/ata-disk@0:0        Internal IDE disk
     94.DE
     95.fi
     96.ec
     97.ft P
     98.sp
     99.Pp
     100You can also boot from a floppy, you need a XCOFF-format kernel image
     101(in this example: vmlinux.coff), copied to a HFS format high-density
     102(1.44Mb) floppy.
     103.DS
     104.sp
     105.ft RR
     106.nf
     107        > nvsetenv boot-device  \&"fd:vmlinux.coff\&"
     108        > nvsetenv boot-file    \&" root=/dev/sda3\&"
     109.DE
     110.fi
     111.ec
     112.ft P
     113.sp
     114
     115To return to MacOS, do:
     116.DS
     117.sp
     118.ft RR
     119.nf
     120        > nvsetenv boot-device  \&"/AAPL,ROM\&"
     121.DE
     122.fi
     123.ec
     124.ft P
     125.sp
     126.Pp
     127Valid values for \&"input-devices\&" are:
     128.DS
     129.sp
     130.ft RR
     131.nf
     132        ttya                    Modem serial port
     133        ttyb                    Printer serial port
     134        kbd                     Keyboard
     135        enet                    Ethernet interface
     136.DE
     137.fi
     138.ec
     139.ft P
     140.sp
     141.Pp
     142Valid values for \&"output-devices\&" are (machine and/or OF dependent):
     143.DS
     144.sp
     145.ft RR
     146.nf
     147        screen                  Screen display (newer machines)
     148        /chaos/control          Screen display (7500, 7600 and 8500)
     149        /bandit/ATY,264GT-B     Screen display (6500)
     150.DE
     151.fi
     152.ec
     153.ft P
     154.sp
     155.Pp
     156OF is not designed to wait for your hard disk to spin up
     157(remember MacOS boots from ROM).
     158Use the following setting to have OF retry to boot from your disk
     159until is has spun up:
     160.DS
     161.sp
     162.ft RR
     163.nf
     164        > nvsetenv boot-command \&"begin ['] boot catch 1000 ms cr again\&"
     165.DE
     166.fi
     167.ec
     168.ft P
     169.sp
     170.Pp
     171You only have to append an \&"S\&" to the \&"boot-file\&" variable to boot
     172Linux in single user mode.
     173.Pp
     174You can use install your own nvramrc patch using the following command:
     175.DS
     176.sp
     177.ft RR
     178.nf
     179        > nvsetenv nvramrc \&"`cat file.patch`\&"
     180.DE
     181.fi
     182.ec
     183.ft P
     184.sp
     185
     186(please note the backticks!), or:
     187.DS
     188.sp
     189.ft RR
     190.nf
     191        > nvsetenv nvramrc \&"$(cat file.patch)\&"
     192.DE
     193.fi
     194.ec
     195.ft P
     196.sp
     197.Pp
     198.SH FILES
     199
     200.Pp
     201.nr ll +1
     202.nr t\n(ll 2
     203.if \n(ll>1 .RS
     204.IP "\fI/dev/nvram\fP"
     205.nr bi 1
     206.Pp
     207character device with major number 10
     208and minor number 144
     209.IP "\fI/proc/cpuinfo\fP"
     210.nr bi 1
     211.Pp
     212to identify New/Old-World machines
     213.if \n(ll>1 .RE
     214.nr ll -1
     215.Pp
     216.SH SEE ALSO
     217
     218.Pp
     219macos(8)
     220.Pp
     221.SH AUTHORS
     222
     223.Pp
     224.DS
     225.sp
     226.ft RR
     227.nf
     228Paul Mackerras <paulus@cs.anu.edu.au> (program)
     229.DE
     230.fi
     231.ec
     232.ft P
     233.sp
     234
     235.DS
     236.sp
     237.ft RR
     238.nf
     239Richard van Hees <R.M.vanHees@phys.uu.nl> (documentation)
     240.DE
     241.fi
     242.ec
     243.ft P
     244.sp
     245
     246.DS
     247.sp
     248.ft RR
     249.nf
     250Klaus Halfmann  <halfmann@libra.de> (NewWorld code)
     251.DE
     252.fi
     253.ec
     254.ft P
     255.sp
     256.Pp
  • nvsetenv.c

    diff -Nuar pmac-utils.orig/nvsetenv.c pmac-utils/nvsetenv.c
    old new  
     1/*      nvsetnv.c
     2
     3        used to set the Envenrioment variables in power macs NVram.
     4        Decides via /proc/cpuinfo which type of machine is used.
     5
     6                Copyright (C) 1996-1998 by Paul Mackerras.
     7        nwcode: Copyright (C) 2000      by Klaus Halfmann
     8
     9        see README for details
     10*/
     11
    112#include <stdio.h>
    213#include <stdlib.h>
    314#include <string.h>
    415#include <unistd.h>
    516#include <fcntl.h>
     17#include <sys/ioctl.h>
     18#include <asm/nvram.h>
     19#ifndef IOC_NVRAM_SYNC
     20#define IOC_NVRAM_SYNC _IO('p', 0x43)
     21#endif
    622
    7 #define NVSTART 0x1800
    8 #define NVSIZE  0x800
     23#define NVSTART         0x1800  // Start of the NVRam OF partition
     24#define NVSIZE          0x800   // Size of of the NVRam
    925#define MXSTRING        128
    1026#define N_NVVARS        (int)(sizeof(nvvars) / sizeof(nvvars[0]))
     27#define NVMAGIC         0x1275
    1128
    12 static int nvfd, nvstr_used;
     29static int nvstr_used;
    1330static char nvstrbuf[NVSIZE];
    1431
    1532struct nvram {
     
    2441    unsigned long  vals[1];
    2542};
    2643
    27 union {
    28     struct nvram nv;
    29     char c[NVSIZE];
    30     unsigned short s[NVSIZE/2];
    31 } nvbuf;
     44typedef union {
     45    struct nvram        nv;
     46    char                c[NVSIZE];
     47    unsigned short      s[NVSIZE/2];
     48} nvbuftype;
    3249
     50nvbuftype nvbuf;
    3351
    3452enum nvtype {
    3553    boolean,
     
    7088    {"boot-command", string},
    7189};
    7290
     91        // Calculated number of variables
     92#define N_NVVARS        (int)(sizeof(nvvars) / sizeof(nvvars[0]))
     93
    7394union nvval {
    74     unsigned long word_val;
    75     char *str_val;
     95    unsigned long       word_val;
     96    char                *str_val;
    7697} nvvals[32];
    7798
    78 int
    79 nvcsum( void )
     99extern int checkNewWorld(void);                 // from nwnvsetenv
     100extern int nvNew(int ac, char** av, int nfd);   // from nwnvsetenv
     101
     102int nvcsum( void )
    80103{
    81     int i;
    82     unsigned c;
     104    int         i;
     105    unsigned    c;
    83106   
    84107    c = 0;
    85108    for (i = 0; i < NVSIZE/2; ++i)
     
    89112    return c & 0xffff;
    90113}
    91114
    92 void
    93 nvload( void )
     115static void nvload( int nvfd )
    94116{
    95117    int s;
    96118
    97119    if (lseek(nvfd, NVSTART, 0) < 0
    98120        || read(nvfd, &nvbuf, NVSIZE) != NVSIZE) {
    99         perror("Error reading /dev/nvram");
     121        perror("Error reading nvram device");
    100122        exit(EXIT_FAILURE);
    101123    }
     124    if (nvbuf.nv.magic != NVMAGIC)
     125        (void) fprintf(stderr, "Warning: Bad magic number %x\n",
     126                         nvbuf.nv.magic);
    102127    s = nvcsum();
    103128    if (s != 0xffff)
    104129       (void) fprintf(stderr, "Warning: checksum error (%x) on nvram\n",
    105130                      s ^ 0xffff);
    106131}
    107132
    108 void
    109 nvstore(void)
     133static void nvstore(int nvfd)
    110134{
    111135    if (lseek(nvfd, NVSTART, 0) < 0
    112136        || write(nvfd, &nvbuf, NVSIZE) != NVSIZE) {
    113         perror("Error writing /dev/nvram");
     137        perror("Error writing nvram device");
    114138        exit(EXIT_FAILURE);
    115139    }
    116140}
     
    145169    }
    146170}
    147171
    148 void
    149 nvpack( void )
     172void nvpack( void )
    150173{
    151174    int     i, vi;
    152175    size_t  off, len;
     
    184207    nvbuf.nv.cksum = (unsigned short int) (~nvcsum());
    185208}
    186209
    187 void
     210static void
    188211print_var(int i, int indent)
    189212{
    190213    char *p;
     
    207230    (void) printf("\n");
    208231}
    209232
    210 void
    211 parse_val(int i, char *str)
     233void parse_val(int i, char *str)
    212234{
    213235    char *endp;
    214236
     
    238260    }
    239261}
    240262
    241 int
    242 main(int ac, char **av)
     263
     264void nvOld(int ac, char** av, int i, int nvfd)
     265{
     266    nvload(nvfd);
     267    nvunpack();
     268
     269    switch (ac) {
     270    case 1:
     271        for (i = 0; i < N_NVVARS; ++i) {
     272            (void) printf("%-16s", nvvars[i].name);
     273            print_var(i, 16);
     274        }
     275        break;
     276
     277    case 2:
     278        print_var(i, 0);
     279        break;
     280       
     281    case 3:
     282        parse_val(i, av[2]);
     283        nvpack();
     284        nvstore(nvfd);
     285        break;
     286    }
     287}
     288
     289int main(int ac, char **av)
    243290{
    244     int i = 0, l, print;
     291    int i = 0, l, print, nvfd, newWorld;
    245292
    246293    l = (int) strlen(av[0]);
     294    // print when no value is set OR we are aclled as <xxx>printenv
    247295    print = (int) (ac <= 2 ||
    248296                   (l > 8 && strcmp(&av[0][l-8], "printenv") == 0));
    249297    if (print != 0 && ac > 2) {
     
    255303        exit(EXIT_FAILURE);
    256304    }
    257305
    258     if (ac >= 2) {
     306    newWorld = checkNewWorld();
     307   
     308    if (!newWorld && ac >= 2) {
    259309        for (i = 0; i < N_NVVARS; ++i)
    260310            if (strcmp(av[1], nvvars[i].name) == 0)
    261311                break;
     
    266316        }
    267317    }
    268318
    269     nvfd = open("/dev/nvram", ac <= 2 ? O_RDONLY: O_RDWR);
     319    nvfd = open("/dev/misc/nvram", ac <= 2 ? O_RDONLY: O_RDWR);
    270320    if (nvfd < 0) {
    271         perror("Couldn't open /dev/nvram");
     321      nvfd = open("/dev/nvram", ac <= 2 ? O_RDONLY: O_RDWR);
     322      if (nvfd < 0) {
     323        perror("Couldn't open nvram device");
    272324        exit(EXIT_FAILURE);
    273     }
    274     nvload();
    275     nvunpack();
    276 
    277     switch (ac) {
    278     case 1:
    279         for (i = 0; i < N_NVVARS; ++i) {
    280             (void) printf("%-16s", nvvars[i].name);
    281             print_var(i, 16);
    282         }
    283         break;
    284 
    285     case 2:
    286         print_var(i, 0);
    287         break;
    288        
    289     case 3:
    290         parse_val(i, av[2]);
    291         nvpack();
    292         nvstore();
    293         break;
     325      }
    294326    }
    295327
     328    if (newWorld)
     329        nvNew(ac, av, nvfd);
     330    else
     331        nvOld(ac, av, i, nvfd);
     332   
     333    (void) ioctl(nvfd, IOC_NVRAM_SYNC);
    296334    (void) close(nvfd);
    297335    exit(EXIT_SUCCESS);
    298336}
  • nvsetvol.8

    diff -Nuar pmac-utils.orig/nvsetvol.8 pmac-utils/nvsetvol.8
    old new  
     1.TH NVSETVOL 8 "16th February 2003"
     2
     3.SH NAME
     4nvsetvol \- tool for changing startup volume of PowerMac machines
     5
     6.SH SYNOPSIS
     7.B nvsetvol
     8[
     9.B volume
     10]
     11
     12.SH DESCRIPTION
     13.B nvsetvol
     14queries and sets the base volume of a PowerMac machine.  With no options,
     15.B nvsetvol
     16displays the current volume; with a numerical argument, it sets the volume.
     17The
     18.B volume
     19argument should be a number from 0 to 255.  0 will turn off the annoying
     20startup chime.
     21
     22.SH AUTHOR
     23.B nvsetvol
     24was written by Matteo Frigo <athena@fftw.org>.
     25
     26This manual page was written by Daniel Jacobowitz <dan@debian.org> for the
     27Debian GNU/Linux distribution.
  • nvsetvol.c

    diff -Nuar pmac-utils.orig/nvsetvol.c pmac-utils/nvsetvol.c
    old new  
     1/* set volume of the startup chime in the PowerMac nvram.
     2
     3   Written by Matteo Frigo <athena@fftw.org>.
     4   $Id: nvsetvol.c,v 1.1 2003/01/11 11:26:30 athena Exp $
     5
     6   This program is in the public domain.
     7*/
     8
     9/* The volume is stored as a byte at address 8 in the parameter ram. */
     10
     11#include <string.h>
     12#include <stdio.h>
     13#include <stdlib.h>
     14#include <sys/types.h>
     15#include <sys/stat.h>
     16#include <unistd.h>
     17#include <fcntl.h>
     18#include <sys/ioctl.h>
     19#include <asm/nvram.h>
     20#ifndef IOC_NVRAM_SYNC
     21#define IOC_NVRAM_SYNC _IO('p', 0x43)
     22#endif
     23
     24typedef struct {
     25     unsigned char sig;
     26     unsigned char cksum;
     27     unsigned short len;
     28     char name[12];
     29} header;
     30
     31void die(const char *s) __attribute__((noreturn));
     32void die(const char *s)
     33{
     34     perror(s);
     35     exit(1);
     36}
     37
     38void seek_pram(int fd, int offset)
     39{
     40     if (lseek(fd, offset, SEEK_SET) < 0)
     41          die("lseek");
     42}
     43
     44// MSch: only works for newworld - oldworld have XPRAM at offset 0x1300 fixed.
     45
     46int find_pram(int fd, int *size)
     47{
     48     header buf;
     49     int offset = 0;
     50     int rc = 0;
     51     while((rc = read(fd, &buf, sizeof(header))) == sizeof(header)) {
     52          int sz = buf.len * 16;
     53          // what's the sig in char?
     54          // if (buf.sig == 0x1275) fprintf(stderr, "sig at offset %d rc %d buf.len %d buf.name %s \n", offset, rc, buf.len, buf.name);
     55          // if (buf.sig == 0x5a) fprintf(stderr, "sig at offset %x rc %d buf.len %x buf.name %s \n", offset, rc, buf.len, buf.name);
     56          // if (sz) fprintf(stderr, "offset %x rc %d sig %x buf.len %x buf.name %s \n", offset, rc, buf.sig, buf.len, buf.name);
     57          if (!strncmp(buf.name, "APL,MacOS75", 11)) {
     58               *size = sz - sizeof(header);
     59               // fprintf(stderr, "XPRAM offset %x size %x\n", offset + sizeof(header), *size);
     60               return offset + sizeof(header);
     61          }
     62          if (sz)
     63            offset += sz;
     64          else
     65            offset += sizeof(header);
     66          seek_pram(fd, offset);
     67     }
     68     // no Core99 style PRAM found - just assume hard coded values as set in kernel:
     69     // XPRAM 0x1300
     70     // NR    0x1400
     71     // OF    0x1800
     72     // TODO: use ioctl to get PRAM offset
     73     // fprintf(stderr, "no NW PRAM found, assuming OW XPRAM offset 0x1300 size 0x100\n");
     74     *size = 0x100;
     75     return (0x1300);
     76     die("no PRAM found");
     77}
     78
     79#define VOLADDR 8
     80
     81int main(int argc, char *argv[])
     82{
     83     int fd, offset, size;
     84     char *buf;
     85
     86     fd = open("/dev/nvram", O_RDWR);
     87     if (fd < 0) die("can't open /dev/nvram");
     88     
     89     offset = find_pram(fd, &size);
     90     buf = malloc(size);
     91     if (!buf) die("can't malloc()");
     92
     93     seek_pram(fd, offset);
     94     if (read(fd, buf, size) != size)
     95          die("error reading /dev/nvram");
     96
     97     printf("current volume is %d\n", (unsigned char) buf[VOLADDR]);
     98     
     99     if (argc > 1) {
     100          buf[VOLADDR] = atoi(argv[1]);
     101
     102          seek_pram(fd, offset);
     103          if (write(fd, buf, size) != size)
     104               die("error writing /dev/nvram");
     105          printf("new volume is %d\n", (unsigned char) buf[VOLADDR]);
     106     }
     107     ioctl(fd, IOC_NVRAM_SYNC);
     108     close(fd);
     109     return 0;
     110}
  • nwnvsetenv.c

    diff -Nuar pmac-utils.orig/nwnvsetenv.c pmac-utils/nwnvsetenv.c
    old new  
     1/*      nwnvsetnv.c
     2
     3        used to set the Envenrioment variables in power macs NVram.
     4        This is for the NewWorld nvram only
     5
     6        nwcode: Copyright (C) 2000      by Klaus Halfmann
     7
     8        see README for details
     9*/
     10#include <stdio.h>
     11#include <stdlib.h>
     12
     13#define __USE_GNU       // need strnlen
     14
     15#include <string.h>
     16#include <unistd.h>
     17#include <fcntl.h>
     18
     19// #define MXSTRING        128:
     20// #define N_NVVARS     (int)(sizeof(nvvars) / sizeof(nvvars[0]))
     21// #define NVMAGIC              0x1275
     22
     23/* CHRP NVRAM header */
     24typedef struct {
     25  unsigned char         signature;
     26  unsigned char         cksum;
     27  unsigned short        len;
     28  char                  name[12];
     29  // unsigned char data[0];
     30} chrp_header;
     31
     32/* Check in proc/cpuinfo if this is a new world machine */
     33
     34int checkNewWorld(void)
     35{
     36    FILE* cpuf = fopen("/proc/cpuinfo","r");
     37    char  buf[256]; // "pmac-generation    : NewWolrd|OldWorld
     38    int   result = 0, found = 0;
     39
     40    if (!cpuf) {
     41        perror("Couldn't open /proc/cpuinfo");
     42        exit(EXIT_FAILURE);
     43    }
     44
     45    while (NULL != fgets(buf, 255, cpuf))
     46    {
     47        if (!strncmp(buf, "pmac-generation" ,15))
     48        {
     49            char* index = strchr(buf, ':') + 2;
     50            if (!index) // ???
     51                continue;
     52            result = !strncmp(index,"NewWorld",8);
     53            found = 1;
     54            break;
     55        }
     56    }
     57    fclose(cpuf);
     58
     59    /* Some kernels don't have pmac-generation ( <= 2.2.15 and earlier 2.3.x ) */
     60    /* Look for AAPL in /proc/device-tree/compatible instead. */
     61    if (!found) {
     62        cpuf = fopen("/proc/device-tree/compatible", "r");
     63        if(!cpuf)
     64            return 0;
     65       
     66        fgets(buf, 255, cpuf);
     67        fclose(cpuf);
     68        if (strncmp(buf, "AAPL", 4) != 0)
     69            result = 1;
     70    }
     71
     72    return result; // assume OldWorld
     73}
     74
     75/* seek NVRAM until common (OF) part
     76   return the lenght of the part in case of sucess,
     77          0 otherwise.
     78   chrph is set to the value of the "coommon" blocek eventually found
     79   *nvstart is set to the seekpoint where common block starts.
     80*/
     81   
     82int nvscan(int nvfd, chrp_header* chrph, int* nvstart)
     83{
     84    int         start = 0;
     85   
     86    while (read(nvfd, chrph, sizeof(chrp_header)) == sizeof(chrp_header))
     87    {
     88        int size = chrph->len * 0x10 - sizeof(chrp_header);     
     89        if (!strncmp(chrph->name, "common", 7))
     90        {
     91            *nvstart = start;
     92            return size; // seeked upto start
     93        }
     94        if (lseek(nvfd, size, SEEK_CUR) < 0)
     95           break;
     96        start += size + sizeof(chrp_header);
     97    }
     98    fprintf(stderr,"No common Block found\n");
     99    exit(EXIT_FAILURE);
     100}
     101
     102static char* nvload( int nvfd , int nvsize)
     103{
     104    char* nvbuf = malloc(nvsize);
     105
     106    if (!nvbuf) {
     107        perror("Error allocating buffer");
     108        exit(EXIT_FAILURE);
     109    }
     110    if (read(nvfd, nvbuf, nvsize) != nvsize) {
     111        perror("Error reading /dev/nvram");
     112        exit(EXIT_FAILURE);
     113    }
     114    return nvbuf;
     115}
     116
     117static void
     118print_vars(char* nvbuf, int nvsize)
     119{
     120    int i = 0;
     121
     122    while (i < nvsize)
     123    {
     124        int size = strnlen(nvbuf, nvsize);
     125        if (size == 0)
     126            break;
     127        printf("%s\n",nvbuf);
     128        nvbuf += (size + 1);    // count 0-byte, too
     129    }
     130}
     131
     132/* move memory around to insert the value.
     133 *
     134 * @param nvbufend      byte AFTER the end of the buffer
     135 * @param varsize       length of the variable name
     136 * @param buf           byte where varaible NAME starts
     137 * @param newval        new value to replace old one
     138 * @param foundsize     lenght of varible + '=' + value
     139 * @param equalpos      position relative to buf where '=' was found
     140 */
     141static void
     142insert_val (char* nvbufend, int varsize,   char* buf,
     143            char* newval,   int foundsize, int equalpos)
     144{
     145    int         oldlen  = foundsize - equalpos -1; // account for the '='
     146    int         newlen  = strlen(newval);
     147    char*       valpos  = buf + varsize + 1;
     148    int         delta   = newlen - oldlen;
     149
     150    if (delta > 0) // expand mem
     151        memmove(valpos + newlen,
     152                valpos + oldlen, (nvbufend - valpos - newlen));
     153    else if (delta < 0) // shrink mem
     154    {
     155        memmove(valpos + newlen,
     156                valpos + oldlen, (nvbufend - valpos - oldlen));
     157        memset (nvbufend + delta, 0, -delta );
     158    }
     159    strncpy(valpos, newval, newlen);
     160}
     161
     162/* return position where variable is found,
     163 * newval may be null.
     164 */
     165
     166static char* set_var(char* nvbuf, int nvsize, char* varname, char* newval)
     167{
     168    int i =0;
     169    int varsize = strlen(varname);
     170    int equalpos;
     171    while (i < nvsize)
     172    {
     173        char* buf = &nvbuf[i];
     174        int foundsize = strnlen(buf, nvsize -i);
     175        if (foundsize == 0)
     176            break;
     177        equalpos = (int) (strchr(buf, '=') - buf);
     178        if (equalpos == varsize &&
     179            !strncmp(buf, varname, equalpos))
     180        {
     181            if (newval) // set the value
     182                insert_val(nvbuf + nvsize, varsize, buf,
     183                           newval, foundsize, equalpos);
     184            return buf;
     185        }
     186        i += foundsize + 1;     // count 0-byte, too
     187    }
     188    return NULL;
     189}
     190
     191static void
     192print_var(char* nvbuf, int nvsize, char* varname)
     193{
     194    char* buf = set_var(nvbuf, nvsize, varname, NULL);
     195    if (buf)
     196        printf("%s\n",buf);
     197}
     198
     199/* This fucntion is not used here, it is left
     200   her for the curious */
     201
     202unsigned short chrp_checksum(chrp_header* hdr, char* nvbuf, int nvsize)
     203{
     204    unsigned char*      ptr = (unsigned char*) &hdr->len;
     205    unsigned char*      end = ptr + sizeof(chrp_header);
     206    unsigned short      sum = hdr->signature;
     207        // this in fact skips the checksum
     208    for (; ptr < end; ptr++)
     209        sum += *ptr;
     210    while (sum > 0xFF)
     211        sum = (sum & 0xFF) + (sum>>8);
     212    return sum;
     213}                                                                                                 
     214
     215static void
     216nvstore(int nvfd, chrp_header* chrph, char* nvbuf, int nvstart, int nvsize)
     217{
     218    // mmh, the checksum is calculated for the header only
     219    // since we did not modify the header we can just ignore it.
     220    ssize_t written;
     221    ssize_t seek =  nvstart + sizeof(chrp_header);
     222    written = lseek(nvfd, seek, SEEK_SET);
     223    if (written != seek)
     224    {
     225        fprintf(stderr,"Error seeking /dev/nvram\n");
     226        exit(EXIT_FAILURE);
     227    }
     228    written = write(nvfd, nvbuf, nvsize);
     229    if (written != nvsize)
     230    {
     231        fprintf(stderr,"Error writing /dev/nvram %x %x\n", nvsize, seek);
     232        exit(EXIT_FAILURE);
     233    }
     234}
     235
     236/* print / set the New World NVRAM */
     237
     238void nvNew(int ac, char** av, int nvfd)
     239{
     240    int                 nvsize, nvstart;
     241    chrp_header         chrph;
     242    char*               nvbuf;
     243
     244    nvsize = nvscan(nvfd, &chrph, &nvstart);
     245    nvbuf  = nvload(nvfd, nvsize);
     246
     247    switch (ac) {
     248    case 1:
     249        print_vars(nvbuf, nvsize);
     250        break;
     251
     252    case 2:
     253        print_var(nvbuf, nvsize, av[1]);
     254        break;
     255       
     256    case 3:
     257        set_var(nvbuf, nvsize, av[1], av[2]);
     258        nvstore(nvfd, &chrph, nvbuf, nvstart, nvsize);
     259        break;
     260    }
     261}
Note: See TracBrowser for help on using the repository browser.