Submitted By: Ken Moffat 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 --- pmac-utils.orig/Makefile 1998-07-21 14:22:28.000000000 +0100 +++ pmac-utils/Makefile 2005-11-17 15:16:52.000000000 +0000 @@ -22,8 +22,8 @@ SGMLMAN = sgml2txt -man CC = gcc -Wall -Wstrict-prototypes -CFLAGS = -O2 -fsigned-char -LDFLAGS = -s +CFLAGS = $(EXTRACFLAGS) -O2 -fsigned-char -D_GNU_SOURCE +LDFLAGS = INSTALL = /usr/bin/install -c SOUND_INC = -I. @@ -42,8 +42,12 @@ mousemode: $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c -nvsetenv: +nvsetenv: nvsetenv.c nwnvsetenv.c + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c nwnvsetenv.c + +nvsetvol: $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c + nvvideo: $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c diff -Nuar pmac-utils.orig/nvsetenv.8 pmac-utils/nvsetenv.8 --- pmac-utils.orig/nvsetenv.8 1970-01-01 01:00:00.000000000 +0100 +++ pmac-utils/nvsetenv.8 2005-11-17 20:39:47.000000000 +0000 @@ -0,0 +1,256 @@ +.if n .ds Q \&" +.if t .ds Q `` +.if n .ds U \&" +.if t .ds U '' +.TH "NVSETENV" 8 +.tr \& +.nr bi 0 +.nr ll 0 +.nr el 0 +.de DS +.. +.de DE +.. +.de Pp +.ie \\n(ll>0 \{\ +.ie \\n(bi=1 \{\ +.nr bi 0 +.if \\n(t\\n(ll=0 \{.IP \\(bu\} +.if \\n(t\\n(ll=1 \{.IP \\n+(e\\n(el.\} +.\} +.el .sp +.\} +.el \{\ +.ie \\nh=1 \{\ +.LP +.nr h 0 +.\} +.el .PP +.\} +.. +.SH NAME + +.Pp +\fBnvsetenv\fP - change/view Open Firmware environment variables +.Pp +.SH SYNOPSIS + +.Pp +\fBnvsetenv +\f(CR[\fP\fIvariable\fP \f(CR[\fP\fIvalue\fP\f(CR\fB]]\fP\fP\fP +.Pp +.SH DESCRIPTION + +.Pp +\fBnvsetenv\fP is a program to adjust or view the Open Firmware (OF) +boot parameters stored in non-volatile (battery-powered) RAM. +\fBnvsetenv\fP will show the current values of all OF's environment +variables when no parameters are given. +.Pp +.SH OPTIONS + +.Pp +.nr ll +1 +.nr t\n(ll 2 +.if \n(ll>1 .RS +.IP "\fIvariable\fP" +.nr bi 1 +.Pp +nvsetenv will show current value of an OF's +variable, if no value is given +.IP "\fIvariable value\fP" +.nr bi 1 +.Pp +nvsetenv will set \fIvariable\fP to +\fIvalue\fP +.if \n(ll>1 .RE +.nr ll -1 +.Pp +.SH EXAMPLES + +.Pp +This example will set the boot device to the first SCSI disk on the +internal SCSI bus, using /vmlinux as boot image, trying to +use the third partition as root partition. +.DS +.sp +.ft RR +.nf + > nvsetenv boot-device \&"scsi-int/sd@0:0\&" + > nvsetenv boot-file \&" /vmlinux root=/dev/sda3\&" +.DE +.fi +.ec +.ft P +.sp +.Pp +Alternatives boot devices are: +.DS +.sp +.ft RR +.nf + scsi/sd@1:0 SCSI disk at ID 1 + ata/ata-disk@0:0 Internal IDE disk +.DE +.fi +.ec +.ft P +.sp +.Pp +You can also boot from a floppy, you need a XCOFF-format kernel image +(in this example: vmlinux.coff), copied to a HFS format high-density +(1.44Mb) floppy. +.DS +.sp +.ft RR +.nf + > nvsetenv boot-device \&"fd:vmlinux.coff\&" + > nvsetenv boot-file \&" root=/dev/sda3\&" +.DE +.fi +.ec +.ft P +.sp + +To return to MacOS, do: +.DS +.sp +.ft RR +.nf + > nvsetenv boot-device \&"/AAPL,ROM\&" +.DE +.fi +.ec +.ft P +.sp +.Pp +Valid values for \&"input-devices\&" are: +.DS +.sp +.ft RR +.nf + ttya Modem serial port + ttyb Printer serial port + kbd Keyboard + enet Ethernet interface +.DE +.fi +.ec +.ft P +.sp +.Pp +Valid values for \&"output-devices\&" are (machine and/or OF dependent): +.DS +.sp +.ft RR +.nf + screen Screen display (newer machines) + /chaos/control Screen display (7500, 7600 and 8500) + /bandit/ATY,264GT-B Screen display (6500) +.DE +.fi +.ec +.ft P +.sp +.Pp +OF is not designed to wait for your hard disk to spin up +(remember MacOS boots from ROM). +Use the following setting to have OF retry to boot from your disk +until is has spun up: +.DS +.sp +.ft RR +.nf + > nvsetenv boot-command \&"begin ['] boot catch 1000 ms cr again\&" +.DE +.fi +.ec +.ft P +.sp +.Pp +You only have to append an \&"S\&" to the \&"boot-file\&" variable to boot +Linux in single user mode. +.Pp +You can use install your own nvramrc patch using the following command: +.DS +.sp +.ft RR +.nf + > nvsetenv nvramrc \&"`cat file.patch`\&" +.DE +.fi +.ec +.ft P +.sp + +(please note the backticks!), or: +.DS +.sp +.ft RR +.nf + > nvsetenv nvramrc \&"$(cat file.patch)\&" +.DE +.fi +.ec +.ft P +.sp +.Pp +.SH FILES + +.Pp +.nr ll +1 +.nr t\n(ll 2 +.if \n(ll>1 .RS +.IP "\fI/dev/nvram\fP" +.nr bi 1 +.Pp +character device with major number 10 +and minor number 144 +.IP "\fI/proc/cpuinfo\fP" +.nr bi 1 +.Pp +to identify New/Old-World machines +.if \n(ll>1 .RE +.nr ll -1 +.Pp +.SH SEE ALSO + +.Pp +macos(8) +.Pp +.SH AUTHORS + +.Pp +.DS +.sp +.ft RR +.nf +Paul Mackerras (program) +.DE +.fi +.ec +.ft P +.sp + +.DS +.sp +.ft RR +.nf +Richard van Hees (documentation) +.DE +.fi +.ec +.ft P +.sp + +.DS +.sp +.ft RR +.nf +Klaus Halfmann (NewWorld code) +.DE +.fi +.ec +.ft P +.sp +.Pp diff -Nuar pmac-utils.orig/nvsetenv.c pmac-utils/nvsetenv.c --- pmac-utils.orig/nvsetenv.c 1997-04-28 14:29:05.000000000 +0100 +++ pmac-utils/nvsetenv.c 2005-11-17 14:57:57.000000000 +0000 @@ -1,15 +1,32 @@ +/* nvsetnv.c + + used to set the Envenrioment variables in power macs NVram. + Decides via /proc/cpuinfo which type of machine is used. + + Copyright (C) 1996-1998 by Paul Mackerras. + nwcode: Copyright (C) 2000 by Klaus Halfmann + + see README for details +*/ + #include #include #include #include #include +#include +#include +#ifndef IOC_NVRAM_SYNC +#define IOC_NVRAM_SYNC _IO('p', 0x43) +#endif -#define NVSTART 0x1800 -#define NVSIZE 0x800 +#define NVSTART 0x1800 // Start of the NVRam OF partition +#define NVSIZE 0x800 // Size of of the NVRam #define MXSTRING 128 #define N_NVVARS (int)(sizeof(nvvars) / sizeof(nvvars[0])) +#define NVMAGIC 0x1275 -static int nvfd, nvstr_used; +static int nvstr_used; static char nvstrbuf[NVSIZE]; struct nvram { @@ -24,12 +41,13 @@ unsigned long vals[1]; }; -union { - struct nvram nv; - char c[NVSIZE]; - unsigned short s[NVSIZE/2]; -} nvbuf; +typedef union { + struct nvram nv; + char c[NVSIZE]; + unsigned short s[NVSIZE/2]; +} nvbuftype; +nvbuftype nvbuf; enum nvtype { boolean, @@ -70,16 +88,21 @@ {"boot-command", string}, }; + // Calculated number of variables +#define N_NVVARS (int)(sizeof(nvvars) / sizeof(nvvars[0])) + union nvval { - unsigned long word_val; - char *str_val; + unsigned long word_val; + char *str_val; } nvvals[32]; -int -nvcsum( void ) +extern int checkNewWorld(void); // from nwnvsetenv +extern int nvNew(int ac, char** av, int nfd); // from nwnvsetenv + +int nvcsum( void ) { - int i; - unsigned c; + int i; + unsigned c; c = 0; for (i = 0; i < NVSIZE/2; ++i) @@ -89,28 +112,29 @@ return c & 0xffff; } -void -nvload( void ) +static void nvload( int nvfd ) { int s; if (lseek(nvfd, NVSTART, 0) < 0 || read(nvfd, &nvbuf, NVSIZE) != NVSIZE) { - perror("Error reading /dev/nvram"); + perror("Error reading nvram device"); exit(EXIT_FAILURE); } + if (nvbuf.nv.magic != NVMAGIC) + (void) fprintf(stderr, "Warning: Bad magic number %x\n", + nvbuf.nv.magic); s = nvcsum(); if (s != 0xffff) (void) fprintf(stderr, "Warning: checksum error (%x) on nvram\n", s ^ 0xffff); } -void -nvstore(void) +static void nvstore(int nvfd) { if (lseek(nvfd, NVSTART, 0) < 0 || write(nvfd, &nvbuf, NVSIZE) != NVSIZE) { - perror("Error writing /dev/nvram"); + perror("Error writing nvram device"); exit(EXIT_FAILURE); } } @@ -145,8 +169,7 @@ } } -void -nvpack( void ) +void nvpack( void ) { int i, vi; size_t off, len; @@ -184,7 +207,7 @@ nvbuf.nv.cksum = (unsigned short int) (~nvcsum()); } -void +static void print_var(int i, int indent) { char *p; @@ -207,8 +230,7 @@ (void) printf("\n"); } -void -parse_val(int i, char *str) +void parse_val(int i, char *str) { char *endp; @@ -238,12 +260,38 @@ } } -int -main(int ac, char **av) + +void nvOld(int ac, char** av, int i, int nvfd) +{ + nvload(nvfd); + nvunpack(); + + switch (ac) { + case 1: + for (i = 0; i < N_NVVARS; ++i) { + (void) printf("%-16s", nvvars[i].name); + print_var(i, 16); + } + break; + + case 2: + print_var(i, 0); + break; + + case 3: + parse_val(i, av[2]); + nvpack(); + nvstore(nvfd); + break; + } +} + +int main(int ac, char **av) { - int i = 0, l, print; + int i = 0, l, print, nvfd, newWorld; l = (int) strlen(av[0]); + // print when no value is set OR we are aclled as printenv print = (int) (ac <= 2 || (l > 8 && strcmp(&av[0][l-8], "printenv") == 0)); if (print != 0 && ac > 2) { @@ -255,7 +303,9 @@ exit(EXIT_FAILURE); } - if (ac >= 2) { + newWorld = checkNewWorld(); + + if (!newWorld && ac >= 2) { for (i = 0; i < N_NVVARS; ++i) if (strcmp(av[1], nvvars[i].name) == 0) break; @@ -266,33 +316,21 @@ } } - nvfd = open("/dev/nvram", ac <= 2 ? O_RDONLY: O_RDWR); + nvfd = open("/dev/misc/nvram", ac <= 2 ? O_RDONLY: O_RDWR); if (nvfd < 0) { - perror("Couldn't open /dev/nvram"); + nvfd = open("/dev/nvram", ac <= 2 ? O_RDONLY: O_RDWR); + if (nvfd < 0) { + perror("Couldn't open nvram device"); exit(EXIT_FAILURE); - } - nvload(); - nvunpack(); - - switch (ac) { - case 1: - for (i = 0; i < N_NVVARS; ++i) { - (void) printf("%-16s", nvvars[i].name); - print_var(i, 16); - } - break; - - case 2: - print_var(i, 0); - break; - - case 3: - parse_val(i, av[2]); - nvpack(); - nvstore(); - break; + } } + if (newWorld) + nvNew(ac, av, nvfd); + else + nvOld(ac, av, i, nvfd); + + (void) ioctl(nvfd, IOC_NVRAM_SYNC); (void) close(nvfd); exit(EXIT_SUCCESS); } diff -Nuar pmac-utils.orig/nvsetvol.8 pmac-utils/nvsetvol.8 --- pmac-utils.orig/nvsetvol.8 1970-01-01 01:00:00.000000000 +0100 +++ pmac-utils/nvsetvol.8 2005-11-17 21:37:20.000000000 +0000 @@ -0,0 +1,27 @@ +.TH NVSETVOL 8 "16th February 2003" + +.SH NAME +nvsetvol \- tool for changing startup volume of PowerMac machines + +.SH SYNOPSIS +.B nvsetvol +[ +.B volume +] + +.SH DESCRIPTION +.B nvsetvol +queries and sets the base volume of a PowerMac machine. With no options, +.B nvsetvol +displays the current volume; with a numerical argument, it sets the volume. +The +.B volume +argument should be a number from 0 to 255. 0 will turn off the annoying +startup chime. + +.SH AUTHOR +.B nvsetvol +was written by Matteo Frigo . + +This manual page was written by Daniel Jacobowitz for the +Debian GNU/Linux distribution. diff -Nuar pmac-utils.orig/nvsetvol.c pmac-utils/nvsetvol.c --- pmac-utils.orig/nvsetvol.c 1970-01-01 01:00:00.000000000 +0100 +++ pmac-utils/nvsetvol.c 2005-11-17 21:43:16.000000000 +0000 @@ -0,0 +1,110 @@ +/* set volume of the startup chime in the PowerMac nvram. + + Written by Matteo Frigo . + $Id: nvsetvol.c,v 1.1 2003/01/11 11:26:30 athena Exp $ + + This program is in the public domain. +*/ + +/* The volume is stored as a byte at address 8 in the parameter ram. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef IOC_NVRAM_SYNC +#define IOC_NVRAM_SYNC _IO('p', 0x43) +#endif + +typedef struct { + unsigned char sig; + unsigned char cksum; + unsigned short len; + char name[12]; +} header; + +void die(const char *s) __attribute__((noreturn)); +void die(const char *s) +{ + perror(s); + exit(1); +} + +void seek_pram(int fd, int offset) +{ + if (lseek(fd, offset, SEEK_SET) < 0) + die("lseek"); +} + +// MSch: only works for newworld - oldworld have XPRAM at offset 0x1300 fixed. + +int find_pram(int fd, int *size) +{ + header buf; + int offset = 0; + int rc = 0; + while((rc = read(fd, &buf, sizeof(header))) == sizeof(header)) { + int sz = buf.len * 16; + // what's the sig in char? + // 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); + // 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); + // 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); + if (!strncmp(buf.name, "APL,MacOS75", 11)) { + *size = sz - sizeof(header); + // fprintf(stderr, "XPRAM offset %x size %x\n", offset + sizeof(header), *size); + return offset + sizeof(header); + } + if (sz) + offset += sz; + else + offset += sizeof(header); + seek_pram(fd, offset); + } + // no Core99 style PRAM found - just assume hard coded values as set in kernel: + // XPRAM 0x1300 + // NR 0x1400 + // OF 0x1800 + // TODO: use ioctl to get PRAM offset + // fprintf(stderr, "no NW PRAM found, assuming OW XPRAM offset 0x1300 size 0x100\n"); + *size = 0x100; + return (0x1300); + die("no PRAM found"); +} + +#define VOLADDR 8 + +int main(int argc, char *argv[]) +{ + int fd, offset, size; + char *buf; + + fd = open("/dev/nvram", O_RDWR); + if (fd < 0) die("can't open /dev/nvram"); + + offset = find_pram(fd, &size); + buf = malloc(size); + if (!buf) die("can't malloc()"); + + seek_pram(fd, offset); + if (read(fd, buf, size) != size) + die("error reading /dev/nvram"); + + printf("current volume is %d\n", (unsigned char) buf[VOLADDR]); + + if (argc > 1) { + buf[VOLADDR] = atoi(argv[1]); + + seek_pram(fd, offset); + if (write(fd, buf, size) != size) + die("error writing /dev/nvram"); + printf("new volume is %d\n", (unsigned char) buf[VOLADDR]); + } + ioctl(fd, IOC_NVRAM_SYNC); + close(fd); + return 0; +} diff -Nuar pmac-utils.orig/nwnvsetenv.c pmac-utils/nwnvsetenv.c --- pmac-utils.orig/nwnvsetenv.c 1970-01-01 01:00:00.000000000 +0100 +++ pmac-utils/nwnvsetenv.c 2005-11-17 21:37:27.000000000 +0000 @@ -0,0 +1,261 @@ +/* nwnvsetnv.c + + used to set the Envenrioment variables in power macs NVram. + This is for the NewWorld nvram only + + nwcode: Copyright (C) 2000 by Klaus Halfmann + + see README for details +*/ +#include +#include + +#define __USE_GNU // need strnlen + +#include +#include +#include + +// #define MXSTRING 128: +// #define N_NVVARS (int)(sizeof(nvvars) / sizeof(nvvars[0])) +// #define NVMAGIC 0x1275 + +/* CHRP NVRAM header */ +typedef struct { + unsigned char signature; + unsigned char cksum; + unsigned short len; + char name[12]; + // unsigned char data[0]; +} chrp_header; + +/* Check in proc/cpuinfo if this is a new world machine */ + +int checkNewWorld(void) +{ + FILE* cpuf = fopen("/proc/cpuinfo","r"); + char buf[256]; // "pmac-generation : NewWolrd|OldWorld + int result = 0, found = 0; + + if (!cpuf) { + perror("Couldn't open /proc/cpuinfo"); + exit(EXIT_FAILURE); + } + + while (NULL != fgets(buf, 255, cpuf)) + { + if (!strncmp(buf, "pmac-generation" ,15)) + { + char* index = strchr(buf, ':') + 2; + if (!index) // ??? + continue; + result = !strncmp(index,"NewWorld",8); + found = 1; + break; + } + } + fclose(cpuf); + + /* Some kernels don't have pmac-generation ( <= 2.2.15 and earlier 2.3.x ) */ + /* Look for AAPL in /proc/device-tree/compatible instead. */ + if (!found) { + cpuf = fopen("/proc/device-tree/compatible", "r"); + if(!cpuf) + return 0; + + fgets(buf, 255, cpuf); + fclose(cpuf); + if (strncmp(buf, "AAPL", 4) != 0) + result = 1; + } + + return result; // assume OldWorld +} + +/* seek NVRAM until common (OF) part + return the lenght of the part in case of sucess, + 0 otherwise. + chrph is set to the value of the "coommon" blocek eventually found + *nvstart is set to the seekpoint where common block starts. +*/ + +int nvscan(int nvfd, chrp_header* chrph, int* nvstart) +{ + int start = 0; + + while (read(nvfd, chrph, sizeof(chrp_header)) == sizeof(chrp_header)) + { + int size = chrph->len * 0x10 - sizeof(chrp_header); + if (!strncmp(chrph->name, "common", 7)) + { + *nvstart = start; + return size; // seeked upto start + } + if (lseek(nvfd, size, SEEK_CUR) < 0) + break; + start += size + sizeof(chrp_header); + } + fprintf(stderr,"No common Block found\n"); + exit(EXIT_FAILURE); +} + +static char* nvload( int nvfd , int nvsize) +{ + char* nvbuf = malloc(nvsize); + + if (!nvbuf) { + perror("Error allocating buffer"); + exit(EXIT_FAILURE); + } + if (read(nvfd, nvbuf, nvsize) != nvsize) { + perror("Error reading /dev/nvram"); + exit(EXIT_FAILURE); + } + return nvbuf; +} + +static void +print_vars(char* nvbuf, int nvsize) +{ + int i = 0; + + while (i < nvsize) + { + int size = strnlen(nvbuf, nvsize); + if (size == 0) + break; + printf("%s\n",nvbuf); + nvbuf += (size + 1); // count 0-byte, too + } +} + +/* move memory around to insert the value. + * + * @param nvbufend byte AFTER the end of the buffer + * @param varsize length of the variable name + * @param buf byte where varaible NAME starts + * @param newval new value to replace old one + * @param foundsize lenght of varible + '=' + value + * @param equalpos position relative to buf where '=' was found + */ +static void +insert_val (char* nvbufend, int varsize, char* buf, + char* newval, int foundsize, int equalpos) +{ + int oldlen = foundsize - equalpos -1; // account for the '=' + int newlen = strlen(newval); + char* valpos = buf + varsize + 1; + int delta = newlen - oldlen; + + if (delta > 0) // expand mem + memmove(valpos + newlen, + valpos + oldlen, (nvbufend - valpos - newlen)); + else if (delta < 0) // shrink mem + { + memmove(valpos + newlen, + valpos + oldlen, (nvbufend - valpos - oldlen)); + memset (nvbufend + delta, 0, -delta ); + } + strncpy(valpos, newval, newlen); +} + +/* return position where variable is found, + * newval may be null. + */ + +static char* set_var(char* nvbuf, int nvsize, char* varname, char* newval) +{ + int i =0; + int varsize = strlen(varname); + int equalpos; + while (i < nvsize) + { + char* buf = &nvbuf[i]; + int foundsize = strnlen(buf, nvsize -i); + if (foundsize == 0) + break; + equalpos = (int) (strchr(buf, '=') - buf); + if (equalpos == varsize && + !strncmp(buf, varname, equalpos)) + { + if (newval) // set the value + insert_val(nvbuf + nvsize, varsize, buf, + newval, foundsize, equalpos); + return buf; + } + i += foundsize + 1; // count 0-byte, too + } + return NULL; +} + +static void +print_var(char* nvbuf, int nvsize, char* varname) +{ + char* buf = set_var(nvbuf, nvsize, varname, NULL); + if (buf) + printf("%s\n",buf); +} + +/* This fucntion is not used here, it is left + her for the curious */ + +unsigned short chrp_checksum(chrp_header* hdr, char* nvbuf, int nvsize) +{ + unsigned char* ptr = (unsigned char*) &hdr->len; + unsigned char* end = ptr + sizeof(chrp_header); + unsigned short sum = hdr->signature; + // this in fact skips the checksum + for (; ptr < end; ptr++) + sum += *ptr; + while (sum > 0xFF) + sum = (sum & 0xFF) + (sum>>8); + return sum; +} + +static void +nvstore(int nvfd, chrp_header* chrph, char* nvbuf, int nvstart, int nvsize) +{ + // mmh, the checksum is calculated for the header only + // since we did not modify the header we can just ignore it. + ssize_t written; + ssize_t seek = nvstart + sizeof(chrp_header); + written = lseek(nvfd, seek, SEEK_SET); + if (written != seek) + { + fprintf(stderr,"Error seeking /dev/nvram\n"); + exit(EXIT_FAILURE); + } + written = write(nvfd, nvbuf, nvsize); + if (written != nvsize) + { + fprintf(stderr,"Error writing /dev/nvram %x %x\n", nvsize, seek); + exit(EXIT_FAILURE); + } +} + +/* print / set the New World NVRAM */ + +void nvNew(int ac, char** av, int nvfd) +{ + int nvsize, nvstart; + chrp_header chrph; + char* nvbuf; + + nvsize = nvscan(nvfd, &chrph, &nvstart); + nvbuf = nvload(nvfd, nvsize); + + switch (ac) { + case 1: + print_vars(nvbuf, nvsize); + break; + + case 2: + print_var(nvbuf, nvsize, av[1]); + break; + + case 3: + set_var(nvbuf, nvsize, av[1], av[2]); + nvstore(nvfd, &chrph, nvbuf, nvstart, nvsize); + break; + } +}