Submitted By: Ken Moffat Date: 2005-11-17 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. 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 Makefile CFLAGS change 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 = -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; + } +}