source:
patches/powerpc-utils_1.1.3-fixes-2.patch@
4260133
Last change on this file since 4260133 was f2b4aa3, checked in by , 18 years ago | |
---|---|
|
|
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 22 22 23 23 SGMLMAN = sgml2txt -man 24 24 CC = gcc -Wall -Wstrict-prototypes 25 CFLAGS = -O2 -fsigned-char26 LDFLAGS = -s25 CFLAGS = $(EXTRACFLAGS) -O2 -fsigned-char -D_GNU_SOURCE 26 LDFLAGS = 27 27 INSTALL = /usr/bin/install -c 28 28 SOUND_INC = -I. 29 29 … … 42 42 mousemode: 43 43 $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c 44 44 45 nvsetenv: 45 nvsetenv: nvsetenv.c nwnvsetenv.c 46 $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c nwnvsetenv.c 47 48 nvsetvol: 46 49 $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c 50 47 51 48 52 nvvideo: 49 53 $(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) 46 boot parameters stored in non-volatile (battery-powered) RAM. 47 \fBnvsetenv\fP will show the current values of all OF's environment 48 variables 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 59 nvsetenv will show current value of an OF's 60 variable, if no value is given 61 .IP "\fIvariable value\fP" 62 .nr bi 1 63 .Pp 64 nvsetenv 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 72 This example will set the boot device to the first SCSI disk on the 73 internal SCSI bus, using /vmlinux as boot image, trying to 74 use 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 87 Alternatives 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 100 You 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 115 To 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 127 Valid 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 142 Valid 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 156 OF is not designed to wait for your hard disk to spin up 157 (remember MacOS boots from ROM). 158 Use the following setting to have OF retry to boot from your disk 159 until 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 171 You only have to append an \&"S\&" to the \&"boot-file\&" variable to boot 172 Linux in single user mode. 173 .Pp 174 You 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 207 character device with major number 10 208 and minor number 144 209 .IP "\fI/proc/cpuinfo\fP" 210 .nr bi 1 211 .Pp 212 to identify New/Old-World machines 213 .if \n(ll>1 .RE 214 .nr ll -1 215 .Pp 216 .SH SEE ALSO 217 218 .Pp 219 macos(8) 220 .Pp 221 .SH AUTHORS 222 223 .Pp 224 .DS 225 .sp 226 .ft RR 227 .nf 228 Paul 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 239 Richard 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 250 Klaus 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 1 12 #include <stdio.h> 2 13 #include <stdlib.h> 3 14 #include <string.h> 4 15 #include <unistd.h> 5 16 #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 6 22 7 #define NVSTART 0x18008 #define NVSIZE 0x80023 #define NVSTART 0x1800 // Start of the NVRam OF partition 24 #define NVSIZE 0x800 // Size of of the NVRam 9 25 #define MXSTRING 128 10 26 #define N_NVVARS (int)(sizeof(nvvars) / sizeof(nvvars[0])) 27 #define NVMAGIC 0x1275 11 28 12 static int nvfd,nvstr_used;29 static int nvstr_used; 13 30 static char nvstrbuf[NVSIZE]; 14 31 15 32 struct nvram { … … 24 41 unsigned long vals[1]; 25 42 }; 26 43 27 union {28 struct nvram nv;29 char c[NVSIZE];30 unsigned short s[NVSIZE/2];31 } nvbuf ;44 typedef union { 45 struct nvram nv; 46 char c[NVSIZE]; 47 unsigned short s[NVSIZE/2]; 48 } nvbuftype; 32 49 50 nvbuftype nvbuf; 33 51 34 52 enum nvtype { 35 53 boolean, … … 70 88 {"boot-command", string}, 71 89 }; 72 90 91 // Calculated number of variables 92 #define N_NVVARS (int)(sizeof(nvvars) / sizeof(nvvars[0])) 93 73 94 union nvval { 74 unsigned long word_val;75 char *str_val;95 unsigned long word_val; 96 char *str_val; 76 97 } nvvals[32]; 77 98 78 int 79 nvcsum( void ) 99 extern int checkNewWorld(void); // from nwnvsetenv 100 extern int nvNew(int ac, char** av, int nfd); // from nwnvsetenv 101 102 int nvcsum( void ) 80 103 { 81 int i;82 unsigned 104 int i; 105 unsigned c; 83 106 84 107 c = 0; 85 108 for (i = 0; i < NVSIZE/2; ++i) … … 89 112 return c & 0xffff; 90 113 } 91 114 92 void 93 nvload( void ) 115 static void nvload( int nvfd ) 94 116 { 95 117 int s; 96 118 97 119 if (lseek(nvfd, NVSTART, 0) < 0 98 120 || read(nvfd, &nvbuf, NVSIZE) != NVSIZE) { 99 perror("Error reading /dev/nvram");121 perror("Error reading nvram device"); 100 122 exit(EXIT_FAILURE); 101 123 } 124 if (nvbuf.nv.magic != NVMAGIC) 125 (void) fprintf(stderr, "Warning: Bad magic number %x\n", 126 nvbuf.nv.magic); 102 127 s = nvcsum(); 103 128 if (s != 0xffff) 104 129 (void) fprintf(stderr, "Warning: checksum error (%x) on nvram\n", 105 130 s ^ 0xffff); 106 131 } 107 132 108 void 109 nvstore(void) 133 static void nvstore(int nvfd) 110 134 { 111 135 if (lseek(nvfd, NVSTART, 0) < 0 112 136 || write(nvfd, &nvbuf, NVSIZE) != NVSIZE) { 113 perror("Error writing /dev/nvram");137 perror("Error writing nvram device"); 114 138 exit(EXIT_FAILURE); 115 139 } 116 140 } … … 145 169 } 146 170 } 147 171 148 void 149 nvpack( void ) 172 void nvpack( void ) 150 173 { 151 174 int i, vi; 152 175 size_t off, len; … … 184 207 nvbuf.nv.cksum = (unsigned short int) (~nvcsum()); 185 208 } 186 209 187 void210 static void 188 211 print_var(int i, int indent) 189 212 { 190 213 char *p; … … 207 230 (void) printf("\n"); 208 231 } 209 232 210 void 211 parse_val(int i, char *str) 233 void parse_val(int i, char *str) 212 234 { 213 235 char *endp; 214 236 … … 238 260 } 239 261 } 240 262 241 int 242 main(int ac, char **av) 263 264 void 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 289 int main(int ac, char **av) 243 290 { 244 int i = 0, l, print ;291 int i = 0, l, print, nvfd, newWorld; 245 292 246 293 l = (int) strlen(av[0]); 294 // print when no value is set OR we are aclled as <xxx>printenv 247 295 print = (int) (ac <= 2 || 248 296 (l > 8 && strcmp(&av[0][l-8], "printenv") == 0)); 249 297 if (print != 0 && ac > 2) { … … 255 303 exit(EXIT_FAILURE); 256 304 } 257 305 258 if (ac >= 2) { 306 newWorld = checkNewWorld(); 307 308 if (!newWorld && ac >= 2) { 259 309 for (i = 0; i < N_NVVARS; ++i) 260 310 if (strcmp(av[1], nvvars[i].name) == 0) 261 311 break; … … 266 316 } 267 317 } 268 318 269 nvfd = open("/dev/ nvram", ac <= 2 ? O_RDONLY: O_RDWR);319 nvfd = open("/dev/misc/nvram", ac <= 2 ? O_RDONLY: O_RDWR); 270 320 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"); 272 324 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 } 294 326 } 295 327 328 if (newWorld) 329 nvNew(ac, av, nvfd); 330 else 331 nvOld(ac, av, i, nvfd); 332 333 (void) ioctl(nvfd, IOC_NVRAM_SYNC); 296 334 (void) close(nvfd); 297 335 exit(EXIT_SUCCESS); 298 336 } -
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 4 nvsetvol \- 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 14 queries and sets the base volume of a PowerMac machine. With no options, 15 .B nvsetvol 16 displays the current volume; with a numerical argument, it sets the volume. 17 The 18 .B volume 19 argument should be a number from 0 to 255. 0 will turn off the annoying 20 startup chime. 21 22 .SH AUTHOR 23 .B nvsetvol 24 was written by Matteo Frigo <athena@fftw.org>. 25 26 This manual page was written by Daniel Jacobowitz <dan@debian.org> for the 27 Debian 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 24 typedef struct { 25 unsigned char sig; 26 unsigned char cksum; 27 unsigned short len; 28 char name[12]; 29 } header; 30 31 void die(const char *s) __attribute__((noreturn)); 32 void die(const char *s) 33 { 34 perror(s); 35 exit(1); 36 } 37 38 void 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 46 int 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 81 int 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 */ 24 typedef 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 34 int 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 82 int 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 102 static 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 117 static void 118 print_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 */ 141 static void 142 insert_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 166 static 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 191 static void 192 print_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 202 unsigned 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 215 static void 216 nvstore(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 238 void 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.