| [f2b4aa3] | 1 | Submitted By: Ken Moffat <ken@linuxfromscratch.org> | 
|---|
|  | 2 | Date: 2005-11-23 | 
|---|
|  | 3 | Initial Package Version: 1.1.3 | 
|---|
|  | 4 | Upstream Status: Package is maintained by debian, this cherry-picks | 
|---|
|  | 5 | Origin: From debian 1.1.3-18.diff, edited | 
|---|
|  | 6 | Description: Makes it work on New World, fixes compile error, updated to | 
|---|
|  | 7 | allow -m32 to be passed via EXTRACFLAGS in multilib. | 
|---|
|  | 8 |  | 
|---|
|  | 9 | Some of the debian powerpc-utils_1.1.3-18.diff, but only the parts relevant | 
|---|
|  | 10 | to nvsetenv and nvsetvol - the remainder may be useful on an Old World Mac, | 
|---|
|  | 11 | but they are no use on New World.  The -D_GNU_SOURCE apparently helps on | 
|---|
|  | 12 | powerpc64.  I've also removed bogus messages advising you to update your | 
|---|
|  | 13 | headers when IOC_NVRAM_SYNC isn't defined : it hasn't existed for a long | 
|---|
|  | 14 | time.  Finally, I ran the nvsetenv.sgml through docbook2txt -man to get a | 
|---|
|  | 15 | proper man page, because most people won't have docbook utils installed. | 
|---|
|  | 16 |  | 
|---|
|  | 17 | diff -Nuar pmac-utils.orig/Makefile pmac-utils/Makefile | 
|---|
|  | 18 | --- pmac-utils.orig/Makefile    1998-07-21 14:22:28.000000000 +0100 | 
|---|
|  | 19 | +++ pmac-utils/Makefile 2005-11-17 15:16:52.000000000 +0000 | 
|---|
|  | 20 | @@ -22,8 +22,8 @@ | 
|---|
|  | 21 |  | 
|---|
|  | 22 | SGMLMAN        = sgml2txt -man | 
|---|
|  | 23 | CC     = gcc -Wall -Wstrict-prototypes | 
|---|
|  | 24 | -CFLAGS = -O2 -fsigned-char | 
|---|
|  | 25 | -LDFLAGS = -s | 
|---|
|  | 26 | +CFLAGS = $(EXTRACFLAGS) -O2 -fsigned-char -D_GNU_SOURCE | 
|---|
|  | 27 | +LDFLAGS = | 
|---|
|  | 28 | INSTALL        = /usr/bin/install -c | 
|---|
|  | 29 | SOUND_INC = -I. | 
|---|
|  | 30 |  | 
|---|
|  | 31 | @@ -42,8 +42,12 @@ | 
|---|
|  | 32 | mousemode: | 
|---|
|  | 33 | $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c | 
|---|
|  | 34 |  | 
|---|
|  | 35 | -nvsetenv: | 
|---|
|  | 36 | +nvsetenv: nvsetenv.c nwnvsetenv.c | 
|---|
|  | 37 | +       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c nwnvsetenv.c | 
|---|
|  | 38 | + | 
|---|
|  | 39 | +nvsetvol: | 
|---|
|  | 40 | $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c | 
|---|
|  | 41 | + | 
|---|
|  | 42 |  | 
|---|
|  | 43 | nvvideo: | 
|---|
|  | 44 | $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c | 
|---|
|  | 45 | diff -Nuar pmac-utils.orig/nvsetenv.8 pmac-utils/nvsetenv.8 | 
|---|
|  | 46 | --- pmac-utils.orig/nvsetenv.8  1970-01-01 01:00:00.000000000 +0100 | 
|---|
|  | 47 | +++ pmac-utils/nvsetenv.8       2005-11-17 20:39:47.000000000 +0000 | 
|---|
|  | 48 | @@ -0,0 +1,256 @@ | 
|---|
|  | 49 | +.if n .ds Q \&" | 
|---|
|  | 50 | +.if t .ds Q `` | 
|---|
|  | 51 | +.if n .ds U \&" | 
|---|
|  | 52 | +.if t .ds U '' | 
|---|
|  | 53 | +.TH "NVSETENV" 8 | 
|---|
|  | 54 | +.tr \& | 
|---|
|  | 55 | +.nr bi 0 | 
|---|
|  | 56 | +.nr ll 0 | 
|---|
|  | 57 | +.nr el 0 | 
|---|
|  | 58 | +.de DS | 
|---|
|  | 59 | +.. | 
|---|
|  | 60 | +.de DE | 
|---|
|  | 61 | +.. | 
|---|
|  | 62 | +.de Pp | 
|---|
|  | 63 | +.ie \\n(ll>0 \{\ | 
|---|
|  | 64 | +.ie \\n(bi=1 \{\ | 
|---|
|  | 65 | +.nr bi 0 | 
|---|
|  | 66 | +.if \\n(t\\n(ll=0 \{.IP \\(bu\} | 
|---|
|  | 67 | +.if \\n(t\\n(ll=1 \{.IP \\n+(e\\n(el.\} | 
|---|
|  | 68 | +.\} | 
|---|
|  | 69 | +.el .sp | 
|---|
|  | 70 | +.\} | 
|---|
|  | 71 | +.el \{\ | 
|---|
|  | 72 | +.ie \\nh=1 \{\ | 
|---|
|  | 73 | +.LP | 
|---|
|  | 74 | +.nr h 0 | 
|---|
|  | 75 | +.\} | 
|---|
|  | 76 | +.el .PP | 
|---|
|  | 77 | +.\} | 
|---|
|  | 78 | +.. | 
|---|
|  | 79 | +.SH NAME | 
|---|
|  | 80 | + | 
|---|
|  | 81 | +.Pp | 
|---|
|  | 82 | +\fBnvsetenv\fP - change/view Open Firmware environment variables | 
|---|
|  | 83 | +.Pp | 
|---|
|  | 84 | +.SH SYNOPSIS | 
|---|
|  | 85 | + | 
|---|
|  | 86 | +.Pp | 
|---|
|  | 87 | +\fBnvsetenv | 
|---|
|  | 88 | +\f(CR[\fP\fIvariable\fP \f(CR[\fP\fIvalue\fP\f(CR\fB]]\fP\fP\fP | 
|---|
|  | 89 | +.Pp | 
|---|
|  | 90 | +.SH DESCRIPTION | 
|---|
|  | 91 | + | 
|---|
|  | 92 | +.Pp | 
|---|
|  | 93 | +\fBnvsetenv\fP is a program to adjust or view the Open Firmware (OF) | 
|---|
|  | 94 | +boot parameters stored in non-volatile (battery-powered) RAM. | 
|---|
|  | 95 | +\fBnvsetenv\fP will show the current values of all OF's environment | 
|---|
|  | 96 | +variables when no parameters are given. | 
|---|
|  | 97 | +.Pp | 
|---|
|  | 98 | +.SH OPTIONS | 
|---|
|  | 99 | + | 
|---|
|  | 100 | +.Pp | 
|---|
|  | 101 | +.nr ll +1 | 
|---|
|  | 102 | +.nr t\n(ll 2 | 
|---|
|  | 103 | +.if \n(ll>1 .RS | 
|---|
|  | 104 | +.IP "\fIvariable\fP" | 
|---|
|  | 105 | +.nr bi 1 | 
|---|
|  | 106 | +.Pp | 
|---|
|  | 107 | +nvsetenv will show current value of an OF's | 
|---|
|  | 108 | +variable, if no value is given | 
|---|
|  | 109 | +.IP "\fIvariable value\fP" | 
|---|
|  | 110 | +.nr bi 1 | 
|---|
|  | 111 | +.Pp | 
|---|
|  | 112 | +nvsetenv will set \fIvariable\fP to | 
|---|
|  | 113 | +\fIvalue\fP | 
|---|
|  | 114 | +.if \n(ll>1 .RE | 
|---|
|  | 115 | +.nr ll -1 | 
|---|
|  | 116 | +.Pp | 
|---|
|  | 117 | +.SH EXAMPLES | 
|---|
|  | 118 | + | 
|---|
|  | 119 | +.Pp | 
|---|
|  | 120 | +This example will set the boot device to the first SCSI disk on the | 
|---|
|  | 121 | +internal SCSI bus, using /vmlinux as boot image, trying to | 
|---|
|  | 122 | +use the third partition as root partition. | 
|---|
|  | 123 | +.DS | 
|---|
|  | 124 | +.sp | 
|---|
|  | 125 | +.ft RR | 
|---|
|  | 126 | +.nf | 
|---|
|  | 127 | +        > nvsetenv boot-device  \&"scsi-int/sd@0:0\&" | 
|---|
|  | 128 | +        > nvsetenv boot-file    \&" /vmlinux root=/dev/sda3\&" | 
|---|
|  | 129 | +.DE | 
|---|
|  | 130 | +.fi | 
|---|
|  | 131 | +.ec | 
|---|
|  | 132 | +.ft P | 
|---|
|  | 133 | +.sp | 
|---|
|  | 134 | +.Pp | 
|---|
|  | 135 | +Alternatives boot devices are: | 
|---|
|  | 136 | +.DS | 
|---|
|  | 137 | +.sp | 
|---|
|  | 138 | +.ft RR | 
|---|
|  | 139 | +.nf | 
|---|
|  | 140 | +        scsi/sd@1:0             SCSI disk at ID 1 | 
|---|
|  | 141 | +        ata/ata-disk@0:0        Internal IDE disk | 
|---|
|  | 142 | +.DE | 
|---|
|  | 143 | +.fi | 
|---|
|  | 144 | +.ec | 
|---|
|  | 145 | +.ft P | 
|---|
|  | 146 | +.sp | 
|---|
|  | 147 | +.Pp | 
|---|
|  | 148 | +You can also boot from a floppy, you need a XCOFF-format kernel image | 
|---|
|  | 149 | +(in this example: vmlinux.coff), copied to a HFS format high-density | 
|---|
|  | 150 | +(1.44Mb) floppy. | 
|---|
|  | 151 | +.DS | 
|---|
|  | 152 | +.sp | 
|---|
|  | 153 | +.ft RR | 
|---|
|  | 154 | +.nf | 
|---|
|  | 155 | +        > nvsetenv boot-device  \&"fd:vmlinux.coff\&" | 
|---|
|  | 156 | +        > nvsetenv boot-file    \&" root=/dev/sda3\&" | 
|---|
|  | 157 | +.DE | 
|---|
|  | 158 | +.fi | 
|---|
|  | 159 | +.ec | 
|---|
|  | 160 | +.ft P | 
|---|
|  | 161 | +.sp | 
|---|
|  | 162 | + | 
|---|
|  | 163 | +To return to MacOS, do: | 
|---|
|  | 164 | +.DS | 
|---|
|  | 165 | +.sp | 
|---|
|  | 166 | +.ft RR | 
|---|
|  | 167 | +.nf | 
|---|
|  | 168 | +        > nvsetenv boot-device  \&"/AAPL,ROM\&" | 
|---|
|  | 169 | +.DE | 
|---|
|  | 170 | +.fi | 
|---|
|  | 171 | +.ec | 
|---|
|  | 172 | +.ft P | 
|---|
|  | 173 | +.sp | 
|---|
|  | 174 | +.Pp | 
|---|
|  | 175 | +Valid values for \&"input-devices\&" are: | 
|---|
|  | 176 | +.DS | 
|---|
|  | 177 | +.sp | 
|---|
|  | 178 | +.ft RR | 
|---|
|  | 179 | +.nf | 
|---|
|  | 180 | +        ttya                    Modem serial port | 
|---|
|  | 181 | +        ttyb                    Printer serial port | 
|---|
|  | 182 | +        kbd                     Keyboard | 
|---|
|  | 183 | +        enet                    Ethernet interface | 
|---|
|  | 184 | +.DE | 
|---|
|  | 185 | +.fi | 
|---|
|  | 186 | +.ec | 
|---|
|  | 187 | +.ft P | 
|---|
|  | 188 | +.sp | 
|---|
|  | 189 | +.Pp | 
|---|
|  | 190 | +Valid values for \&"output-devices\&" are (machine and/or OF dependent): | 
|---|
|  | 191 | +.DS | 
|---|
|  | 192 | +.sp | 
|---|
|  | 193 | +.ft RR | 
|---|
|  | 194 | +.nf | 
|---|
|  | 195 | +        screen                  Screen display (newer machines) | 
|---|
|  | 196 | +        /chaos/control          Screen display (7500, 7600 and 8500) | 
|---|
|  | 197 | +        /bandit/ATY,264GT-B     Screen display (6500) | 
|---|
|  | 198 | +.DE | 
|---|
|  | 199 | +.fi | 
|---|
|  | 200 | +.ec | 
|---|
|  | 201 | +.ft P | 
|---|
|  | 202 | +.sp | 
|---|
|  | 203 | +.Pp | 
|---|
|  | 204 | +OF is not designed to wait for your hard disk to spin up | 
|---|
|  | 205 | +(remember MacOS boots from ROM). | 
|---|
|  | 206 | +Use the following setting to have OF retry to boot from your disk | 
|---|
|  | 207 | +until is has spun up: | 
|---|
|  | 208 | +.DS | 
|---|
|  | 209 | +.sp | 
|---|
|  | 210 | +.ft RR | 
|---|
|  | 211 | +.nf | 
|---|
|  | 212 | +        > nvsetenv boot-command \&"begin ['] boot catch 1000 ms cr again\&" | 
|---|
|  | 213 | +.DE | 
|---|
|  | 214 | +.fi | 
|---|
|  | 215 | +.ec | 
|---|
|  | 216 | +.ft P | 
|---|
|  | 217 | +.sp | 
|---|
|  | 218 | +.Pp | 
|---|
|  | 219 | +You only have to append an \&"S\&" to the \&"boot-file\&" variable to boot | 
|---|
|  | 220 | +Linux in single user mode. | 
|---|
|  | 221 | +.Pp | 
|---|
|  | 222 | +You can use install your own nvramrc patch using the following command: | 
|---|
|  | 223 | +.DS | 
|---|
|  | 224 | +.sp | 
|---|
|  | 225 | +.ft RR | 
|---|
|  | 226 | +.nf | 
|---|
|  | 227 | +        > nvsetenv nvramrc \&"`cat file.patch`\&" | 
|---|
|  | 228 | +.DE | 
|---|
|  | 229 | +.fi | 
|---|
|  | 230 | +.ec | 
|---|
|  | 231 | +.ft P | 
|---|
|  | 232 | +.sp | 
|---|
|  | 233 | + | 
|---|
|  | 234 | +(please note the backticks!), or: | 
|---|
|  | 235 | +.DS | 
|---|
|  | 236 | +.sp | 
|---|
|  | 237 | +.ft RR | 
|---|
|  | 238 | +.nf | 
|---|
|  | 239 | +        > nvsetenv nvramrc \&"$(cat file.patch)\&" | 
|---|
|  | 240 | +.DE | 
|---|
|  | 241 | +.fi | 
|---|
|  | 242 | +.ec | 
|---|
|  | 243 | +.ft P | 
|---|
|  | 244 | +.sp | 
|---|
|  | 245 | +.Pp | 
|---|
|  | 246 | +.SH FILES | 
|---|
|  | 247 | + | 
|---|
|  | 248 | +.Pp | 
|---|
|  | 249 | +.nr ll +1 | 
|---|
|  | 250 | +.nr t\n(ll 2 | 
|---|
|  | 251 | +.if \n(ll>1 .RS | 
|---|
|  | 252 | +.IP "\fI/dev/nvram\fP" | 
|---|
|  | 253 | +.nr bi 1 | 
|---|
|  | 254 | +.Pp | 
|---|
|  | 255 | +character device with major number 10 | 
|---|
|  | 256 | +and minor number 144 | 
|---|
|  | 257 | +.IP "\fI/proc/cpuinfo\fP" | 
|---|
|  | 258 | +.nr bi 1 | 
|---|
|  | 259 | +.Pp | 
|---|
|  | 260 | +to identify New/Old-World machines | 
|---|
|  | 261 | +.if \n(ll>1 .RE | 
|---|
|  | 262 | +.nr ll -1 | 
|---|
|  | 263 | +.Pp | 
|---|
|  | 264 | +.SH SEE ALSO | 
|---|
|  | 265 | + | 
|---|
|  | 266 | +.Pp | 
|---|
|  | 267 | +macos(8) | 
|---|
|  | 268 | +.Pp | 
|---|
|  | 269 | +.SH AUTHORS | 
|---|
|  | 270 | + | 
|---|
|  | 271 | +.Pp | 
|---|
|  | 272 | +.DS | 
|---|
|  | 273 | +.sp | 
|---|
|  | 274 | +.ft RR | 
|---|
|  | 275 | +.nf | 
|---|
|  | 276 | +Paul Mackerras <paulus@cs.anu.edu.au> (program) | 
|---|
|  | 277 | +.DE | 
|---|
|  | 278 | +.fi | 
|---|
|  | 279 | +.ec | 
|---|
|  | 280 | +.ft P | 
|---|
|  | 281 | +.sp | 
|---|
|  | 282 | + | 
|---|
|  | 283 | +.DS | 
|---|
|  | 284 | +.sp | 
|---|
|  | 285 | +.ft RR | 
|---|
|  | 286 | +.nf | 
|---|
|  | 287 | +Richard van Hees <R.M.vanHees@phys.uu.nl> (documentation) | 
|---|
|  | 288 | +.DE | 
|---|
|  | 289 | +.fi | 
|---|
|  | 290 | +.ec | 
|---|
|  | 291 | +.ft P | 
|---|
|  | 292 | +.sp | 
|---|
|  | 293 | + | 
|---|
|  | 294 | +.DS | 
|---|
|  | 295 | +.sp | 
|---|
|  | 296 | +.ft RR | 
|---|
|  | 297 | +.nf | 
|---|
|  | 298 | +Klaus Halfmann  <halfmann@libra.de> (NewWorld code) | 
|---|
|  | 299 | +.DE | 
|---|
|  | 300 | +.fi | 
|---|
|  | 301 | +.ec | 
|---|
|  | 302 | +.ft P | 
|---|
|  | 303 | +.sp | 
|---|
|  | 304 | +.Pp | 
|---|
|  | 305 | diff -Nuar pmac-utils.orig/nvsetenv.c pmac-utils/nvsetenv.c | 
|---|
|  | 306 | --- pmac-utils.orig/nvsetenv.c  1997-04-28 14:29:05.000000000 +0100 | 
|---|
|  | 307 | +++ pmac-utils/nvsetenv.c       2005-11-17 14:57:57.000000000 +0000 | 
|---|
|  | 308 | @@ -1,15 +1,32 @@ | 
|---|
|  | 309 | +/*     nvsetnv.c | 
|---|
|  | 310 | + | 
|---|
|  | 311 | +       used to set the Envenrioment variables in power macs NVram. | 
|---|
|  | 312 | +       Decides via /proc/cpuinfo which type of machine is used. | 
|---|
|  | 313 | + | 
|---|
|  | 314 | +               Copyright (C) 1996-1998 by Paul Mackerras. | 
|---|
|  | 315 | +       nwcode: Copyright (C) 2000      by Klaus Halfmann | 
|---|
|  | 316 | + | 
|---|
|  | 317 | +       see README for details | 
|---|
|  | 318 | +*/ | 
|---|
|  | 319 | + | 
|---|
|  | 320 | #include <stdio.h> | 
|---|
|  | 321 | #include <stdlib.h> | 
|---|
|  | 322 | #include <string.h> | 
|---|
|  | 323 | #include <unistd.h> | 
|---|
|  | 324 | #include <fcntl.h> | 
|---|
|  | 325 | +#include <sys/ioctl.h> | 
|---|
|  | 326 | +#include <asm/nvram.h> | 
|---|
|  | 327 | +#ifndef IOC_NVRAM_SYNC | 
|---|
|  | 328 | +#define IOC_NVRAM_SYNC _IO('p', 0x43) | 
|---|
|  | 329 | +#endif | 
|---|
|  | 330 |  | 
|---|
|  | 331 | -#define NVSTART        0x1800 | 
|---|
|  | 332 | -#define NVSIZE 0x800 | 
|---|
|  | 333 | +#define NVSTART                0x1800  // Start of the NVRam OF partition | 
|---|
|  | 334 | +#define NVSIZE         0x800   // Size of of the NVRam | 
|---|
|  | 335 | #define MXSTRING        128 | 
|---|
|  | 336 | #define N_NVVARS       (int)(sizeof(nvvars) / sizeof(nvvars[0])) | 
|---|
|  | 337 | +#define NVMAGIC                0x1275 | 
|---|
|  | 338 |  | 
|---|
|  | 339 | -static int nvfd, nvstr_used; | 
|---|
|  | 340 | +static int  nvstr_used; | 
|---|
|  | 341 | static char nvstrbuf[NVSIZE]; | 
|---|
|  | 342 |  | 
|---|
|  | 343 | struct nvram { | 
|---|
|  | 344 | @@ -24,12 +41,13 @@ | 
|---|
|  | 345 | unsigned long  vals[1]; | 
|---|
|  | 346 | }; | 
|---|
|  | 347 |  | 
|---|
|  | 348 | -union { | 
|---|
|  | 349 | -    struct nvram nv; | 
|---|
|  | 350 | -    char c[NVSIZE]; | 
|---|
|  | 351 | -    unsigned short s[NVSIZE/2]; | 
|---|
|  | 352 | -} nvbuf; | 
|---|
|  | 353 | +typedef union { | 
|---|
|  | 354 | +    struct nvram       nv; | 
|---|
|  | 355 | +    char               c[NVSIZE]; | 
|---|
|  | 356 | +    unsigned short     s[NVSIZE/2]; | 
|---|
|  | 357 | +} nvbuftype; | 
|---|
|  | 358 |  | 
|---|
|  | 359 | +nvbuftype nvbuf; | 
|---|
|  | 360 |  | 
|---|
|  | 361 | enum nvtype { | 
|---|
|  | 362 | boolean, | 
|---|
|  | 363 | @@ -70,16 +88,21 @@ | 
|---|
|  | 364 | {"boot-command", string}, | 
|---|
|  | 365 | }; | 
|---|
|  | 366 |  | 
|---|
|  | 367 | +       // Calculated number of variables | 
|---|
|  | 368 | +#define N_NVVARS       (int)(sizeof(nvvars) / sizeof(nvvars[0])) | 
|---|
|  | 369 | + | 
|---|
|  | 370 | union nvval { | 
|---|
|  | 371 | -    unsigned long word_val; | 
|---|
|  | 372 | -    char *str_val; | 
|---|
|  | 373 | +    unsigned long      word_val; | 
|---|
|  | 374 | +    char               *str_val; | 
|---|
|  | 375 | } nvvals[32]; | 
|---|
|  | 376 |  | 
|---|
|  | 377 | -int | 
|---|
|  | 378 | -nvcsum( void ) | 
|---|
|  | 379 | +extern int checkNewWorld(void);                // from nwnvsetenv | 
|---|
|  | 380 | +extern int nvNew(int ac, char** av, int nfd);  // from nwnvsetenv | 
|---|
|  | 381 | + | 
|---|
|  | 382 | +int nvcsum( void ) | 
|---|
|  | 383 | { | 
|---|
|  | 384 | -    int i; | 
|---|
|  | 385 | -    unsigned c; | 
|---|
|  | 386 | +    int        i; | 
|---|
|  | 387 | +    unsigned   c; | 
|---|
|  | 388 |  | 
|---|
|  | 389 | c = 0; | 
|---|
|  | 390 | for (i = 0; i < NVSIZE/2; ++i) | 
|---|
|  | 391 | @@ -89,28 +112,29 @@ | 
|---|
|  | 392 | return c & 0xffff; | 
|---|
|  | 393 | } | 
|---|
|  | 394 |  | 
|---|
|  | 395 | -void | 
|---|
|  | 396 | -nvload( void ) | 
|---|
|  | 397 | +static void nvload( int nvfd ) | 
|---|
|  | 398 | { | 
|---|
|  | 399 | int s; | 
|---|
|  | 400 |  | 
|---|
|  | 401 | if (lseek(nvfd, NVSTART, 0) < 0 | 
|---|
|  | 402 | || read(nvfd, &nvbuf, NVSIZE) != NVSIZE) { | 
|---|
|  | 403 | -       perror("Error reading /dev/nvram"); | 
|---|
|  | 404 | +       perror("Error reading nvram device"); | 
|---|
|  | 405 | exit(EXIT_FAILURE); | 
|---|
|  | 406 | } | 
|---|
|  | 407 | +    if (nvbuf.nv.magic != NVMAGIC) | 
|---|
|  | 408 | +       (void) fprintf(stderr, "Warning: Bad magic number %x\n", | 
|---|
|  | 409 | +                        nvbuf.nv.magic); | 
|---|
|  | 410 | s = nvcsum(); | 
|---|
|  | 411 | if (s != 0xffff) | 
|---|
|  | 412 | (void) fprintf(stderr, "Warning: checksum error (%x) on nvram\n", | 
|---|
|  | 413 | s ^ 0xffff); | 
|---|
|  | 414 | } | 
|---|
|  | 415 |  | 
|---|
|  | 416 | -void | 
|---|
|  | 417 | -nvstore(void) | 
|---|
|  | 418 | +static void nvstore(int nvfd) | 
|---|
|  | 419 | { | 
|---|
|  | 420 | if (lseek(nvfd, NVSTART, 0) < 0 | 
|---|
|  | 421 | || write(nvfd, &nvbuf, NVSIZE) != NVSIZE) { | 
|---|
|  | 422 | -       perror("Error writing /dev/nvram"); | 
|---|
|  | 423 | +       perror("Error writing nvram device"); | 
|---|
|  | 424 | exit(EXIT_FAILURE); | 
|---|
|  | 425 | } | 
|---|
|  | 426 | } | 
|---|
|  | 427 | @@ -145,8 +169,7 @@ | 
|---|
|  | 428 | } | 
|---|
|  | 429 | } | 
|---|
|  | 430 |  | 
|---|
|  | 431 | -void | 
|---|
|  | 432 | -nvpack( void ) | 
|---|
|  | 433 | +void nvpack( void ) | 
|---|
|  | 434 | { | 
|---|
|  | 435 | int     i, vi; | 
|---|
|  | 436 | size_t  off, len; | 
|---|
|  | 437 | @@ -184,7 +207,7 @@ | 
|---|
|  | 438 | nvbuf.nv.cksum = (unsigned short int) (~nvcsum()); | 
|---|
|  | 439 | } | 
|---|
|  | 440 |  | 
|---|
|  | 441 | -void | 
|---|
|  | 442 | +static void | 
|---|
|  | 443 | print_var(int i, int indent) | 
|---|
|  | 444 | { | 
|---|
|  | 445 | char *p; | 
|---|
|  | 446 | @@ -207,8 +230,7 @@ | 
|---|
|  | 447 | (void) printf("\n"); | 
|---|
|  | 448 | } | 
|---|
|  | 449 |  | 
|---|
|  | 450 | -void | 
|---|
|  | 451 | -parse_val(int i, char *str) | 
|---|
|  | 452 | +void parse_val(int i, char *str) | 
|---|
|  | 453 | { | 
|---|
|  | 454 | char *endp; | 
|---|
|  | 455 |  | 
|---|
|  | 456 | @@ -238,12 +260,38 @@ | 
|---|
|  | 457 | } | 
|---|
|  | 458 | } | 
|---|
|  | 459 |  | 
|---|
|  | 460 | -int | 
|---|
|  | 461 | -main(int ac, char **av) | 
|---|
|  | 462 | + | 
|---|
|  | 463 | +void nvOld(int ac, char** av, int i, int nvfd) | 
|---|
|  | 464 | +{ | 
|---|
|  | 465 | +    nvload(nvfd); | 
|---|
|  | 466 | +    nvunpack(); | 
|---|
|  | 467 | + | 
|---|
|  | 468 | +    switch (ac) { | 
|---|
|  | 469 | +    case 1: | 
|---|
|  | 470 | +       for (i = 0; i < N_NVVARS; ++i) { | 
|---|
|  | 471 | +           (void) printf("%-16s", nvvars[i].name); | 
|---|
|  | 472 | +           print_var(i, 16); | 
|---|
|  | 473 | +       } | 
|---|
|  | 474 | +       break; | 
|---|
|  | 475 | + | 
|---|
|  | 476 | +    case 2: | 
|---|
|  | 477 | +       print_var(i, 0); | 
|---|
|  | 478 | +       break; | 
|---|
|  | 479 | + | 
|---|
|  | 480 | +    case 3: | 
|---|
|  | 481 | +       parse_val(i, av[2]); | 
|---|
|  | 482 | +       nvpack(); | 
|---|
|  | 483 | +       nvstore(nvfd); | 
|---|
|  | 484 | +       break; | 
|---|
|  | 485 | +    } | 
|---|
|  | 486 | +} | 
|---|
|  | 487 | + | 
|---|
|  | 488 | +int main(int ac, char **av) | 
|---|
|  | 489 | { | 
|---|
|  | 490 | -    int i = 0, l, print; | 
|---|
|  | 491 | +    int i = 0, l, print, nvfd, newWorld; | 
|---|
|  | 492 |  | 
|---|
|  | 493 | l = (int) strlen(av[0]); | 
|---|
|  | 494 | +    // print when no value is set OR we are aclled as <xxx>printenv | 
|---|
|  | 495 | print = (int) (ac <= 2 || | 
|---|
|  | 496 | (l > 8 && strcmp(&av[0][l-8], "printenv") == 0)); | 
|---|
|  | 497 | if (print != 0 && ac > 2) { | 
|---|
|  | 498 | @@ -255,7 +303,9 @@ | 
|---|
|  | 499 | exit(EXIT_FAILURE); | 
|---|
|  | 500 | } | 
|---|
|  | 501 |  | 
|---|
|  | 502 | -    if (ac >= 2) { | 
|---|
|  | 503 | +    newWorld = checkNewWorld(); | 
|---|
|  | 504 | + | 
|---|
|  | 505 | +    if (!newWorld && ac >= 2) { | 
|---|
|  | 506 | for (i = 0; i < N_NVVARS; ++i) | 
|---|
|  | 507 | if (strcmp(av[1], nvvars[i].name) == 0) | 
|---|
|  | 508 | break; | 
|---|
|  | 509 | @@ -266,33 +316,21 @@ | 
|---|
|  | 510 | } | 
|---|
|  | 511 | } | 
|---|
|  | 512 |  | 
|---|
|  | 513 | -    nvfd = open("/dev/nvram", ac <= 2 ? O_RDONLY: O_RDWR); | 
|---|
|  | 514 | +    nvfd = open("/dev/misc/nvram", ac <= 2 ? O_RDONLY: O_RDWR); | 
|---|
|  | 515 | if (nvfd < 0) { | 
|---|
|  | 516 | -       perror("Couldn't open /dev/nvram"); | 
|---|
|  | 517 | +      nvfd = open("/dev/nvram", ac <= 2 ? O_RDONLY: O_RDWR); | 
|---|
|  | 518 | +      if (nvfd < 0) { | 
|---|
|  | 519 | +       perror("Couldn't open nvram device"); | 
|---|
|  | 520 | exit(EXIT_FAILURE); | 
|---|
|  | 521 | -    } | 
|---|
|  | 522 | -    nvload(); | 
|---|
|  | 523 | -    nvunpack(); | 
|---|
|  | 524 | - | 
|---|
|  | 525 | -    switch (ac) { | 
|---|
|  | 526 | -    case 1: | 
|---|
|  | 527 | -       for (i = 0; i < N_NVVARS; ++i) { | 
|---|
|  | 528 | -           (void) printf("%-16s", nvvars[i].name); | 
|---|
|  | 529 | -           print_var(i, 16); | 
|---|
|  | 530 | -       } | 
|---|
|  | 531 | -       break; | 
|---|
|  | 532 | - | 
|---|
|  | 533 | -    case 2: | 
|---|
|  | 534 | -       print_var(i, 0); | 
|---|
|  | 535 | -       break; | 
|---|
|  | 536 | - | 
|---|
|  | 537 | -    case 3: | 
|---|
|  | 538 | -       parse_val(i, av[2]); | 
|---|
|  | 539 | -       nvpack(); | 
|---|
|  | 540 | -       nvstore(); | 
|---|
|  | 541 | -       break; | 
|---|
|  | 542 | +      } | 
|---|
|  | 543 | } | 
|---|
|  | 544 |  | 
|---|
|  | 545 | +    if (newWorld) | 
|---|
|  | 546 | +       nvNew(ac, av, nvfd); | 
|---|
|  | 547 | +    else | 
|---|
|  | 548 | +       nvOld(ac, av, i, nvfd); | 
|---|
|  | 549 | + | 
|---|
|  | 550 | +    (void) ioctl(nvfd, IOC_NVRAM_SYNC); | 
|---|
|  | 551 | (void) close(nvfd); | 
|---|
|  | 552 | exit(EXIT_SUCCESS); | 
|---|
|  | 553 | } | 
|---|
|  | 554 | diff -Nuar pmac-utils.orig/nvsetvol.8 pmac-utils/nvsetvol.8 | 
|---|
|  | 555 | --- pmac-utils.orig/nvsetvol.8  1970-01-01 01:00:00.000000000 +0100 | 
|---|
|  | 556 | +++ pmac-utils/nvsetvol.8       2005-11-17 21:37:20.000000000 +0000 | 
|---|
|  | 557 | @@ -0,0 +1,27 @@ | 
|---|
|  | 558 | +.TH NVSETVOL 8 "16th February 2003" | 
|---|
|  | 559 | + | 
|---|
|  | 560 | +.SH NAME | 
|---|
|  | 561 | +nvsetvol \- tool for changing startup volume of PowerMac machines | 
|---|
|  | 562 | + | 
|---|
|  | 563 | +.SH SYNOPSIS | 
|---|
|  | 564 | +.B nvsetvol | 
|---|
|  | 565 | +[ | 
|---|
|  | 566 | +.B volume | 
|---|
|  | 567 | +] | 
|---|
|  | 568 | + | 
|---|
|  | 569 | +.SH DESCRIPTION | 
|---|
|  | 570 | +.B nvsetvol | 
|---|
|  | 571 | +queries and sets the base volume of a PowerMac machine.  With no options, | 
|---|
|  | 572 | +.B nvsetvol | 
|---|
|  | 573 | +displays the current volume; with a numerical argument, it sets the volume. | 
|---|
|  | 574 | +The | 
|---|
|  | 575 | +.B volume | 
|---|
|  | 576 | +argument should be a number from 0 to 255.  0 will turn off the annoying | 
|---|
|  | 577 | +startup chime. | 
|---|
|  | 578 | + | 
|---|
|  | 579 | +.SH AUTHOR | 
|---|
|  | 580 | +.B nvsetvol | 
|---|
|  | 581 | +was written by Matteo Frigo <athena@fftw.org>. | 
|---|
|  | 582 | + | 
|---|
|  | 583 | +This manual page was written by Daniel Jacobowitz <dan@debian.org> for the | 
|---|
|  | 584 | +Debian GNU/Linux distribution. | 
|---|
|  | 585 | diff -Nuar pmac-utils.orig/nvsetvol.c pmac-utils/nvsetvol.c | 
|---|
|  | 586 | --- pmac-utils.orig/nvsetvol.c  1970-01-01 01:00:00.000000000 +0100 | 
|---|
|  | 587 | +++ pmac-utils/nvsetvol.c       2005-11-17 21:43:16.000000000 +0000 | 
|---|
|  | 588 | @@ -0,0 +1,110 @@ | 
|---|
|  | 589 | +/* set volume of the startup chime in the PowerMac nvram. | 
|---|
|  | 590 | + | 
|---|
|  | 591 | +   Written by Matteo Frigo <athena@fftw.org>. | 
|---|
|  | 592 | +   $Id: nvsetvol.c,v 1.1 2003/01/11 11:26:30 athena Exp $ | 
|---|
|  | 593 | + | 
|---|
|  | 594 | +   This program is in the public domain. | 
|---|
|  | 595 | +*/ | 
|---|
|  | 596 | + | 
|---|
|  | 597 | +/* The volume is stored as a byte at address 8 in the parameter ram. */ | 
|---|
|  | 598 | + | 
|---|
|  | 599 | +#include <string.h> | 
|---|
|  | 600 | +#include <stdio.h> | 
|---|
|  | 601 | +#include <stdlib.h> | 
|---|
|  | 602 | +#include <sys/types.h> | 
|---|
|  | 603 | +#include <sys/stat.h> | 
|---|
|  | 604 | +#include <unistd.h> | 
|---|
|  | 605 | +#include <fcntl.h> | 
|---|
|  | 606 | +#include <sys/ioctl.h> | 
|---|
|  | 607 | +#include <asm/nvram.h> | 
|---|
|  | 608 | +#ifndef IOC_NVRAM_SYNC | 
|---|
|  | 609 | +#define IOC_NVRAM_SYNC _IO('p', 0x43) | 
|---|
|  | 610 | +#endif | 
|---|
|  | 611 | + | 
|---|
|  | 612 | +typedef struct { | 
|---|
|  | 613 | +     unsigned char sig; | 
|---|
|  | 614 | +     unsigned char cksum; | 
|---|
|  | 615 | +     unsigned short len; | 
|---|
|  | 616 | +     char name[12]; | 
|---|
|  | 617 | +} header; | 
|---|
|  | 618 | + | 
|---|
|  | 619 | +void die(const char *s) __attribute__((noreturn)); | 
|---|
|  | 620 | +void die(const char *s) | 
|---|
|  | 621 | +{ | 
|---|
|  | 622 | +     perror(s); | 
|---|
|  | 623 | +     exit(1); | 
|---|
|  | 624 | +} | 
|---|
|  | 625 | + | 
|---|
|  | 626 | +void seek_pram(int fd, int offset) | 
|---|
|  | 627 | +{ | 
|---|
|  | 628 | +     if (lseek(fd, offset, SEEK_SET) < 0) | 
|---|
|  | 629 | +         die("lseek"); | 
|---|
|  | 630 | +} | 
|---|
|  | 631 | + | 
|---|
|  | 632 | +// MSch: only works for newworld - oldworld have XPRAM at offset 0x1300 fixed. | 
|---|
|  | 633 | + | 
|---|
|  | 634 | +int find_pram(int fd, int *size) | 
|---|
|  | 635 | +{ | 
|---|
|  | 636 | +     header buf; | 
|---|
|  | 637 | +     int offset = 0; | 
|---|
|  | 638 | +     int rc = 0; | 
|---|
|  | 639 | +     while((rc = read(fd, &buf, sizeof(header))) == sizeof(header)) { | 
|---|
|  | 640 | +         int sz = buf.len * 16; | 
|---|
|  | 641 | +         // what's the sig in char? | 
|---|
|  | 642 | +         // 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); | 
|---|
|  | 643 | +         // 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); | 
|---|
|  | 644 | +         // 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); | 
|---|
|  | 645 | +         if (!strncmp(buf.name, "APL,MacOS75", 11)) { | 
|---|
|  | 646 | +              *size = sz - sizeof(header); | 
|---|
|  | 647 | +              // fprintf(stderr, "XPRAM offset %x size %x\n", offset + sizeof(header), *size); | 
|---|
|  | 648 | +              return offset + sizeof(header); | 
|---|
|  | 649 | +         } | 
|---|
|  | 650 | +         if (sz) | 
|---|
|  | 651 | +           offset += sz; | 
|---|
|  | 652 | +          else | 
|---|
|  | 653 | +            offset += sizeof(header); | 
|---|
|  | 654 | +         seek_pram(fd, offset); | 
|---|
|  | 655 | +     } | 
|---|
|  | 656 | +     // no Core99 style PRAM found - just assume hard coded values as set in kernel: | 
|---|
|  | 657 | +     // XPRAM 0x1300 | 
|---|
|  | 658 | +     // NR    0x1400 | 
|---|
|  | 659 | +     // OF    0x1800 | 
|---|
|  | 660 | +     // TODO: use ioctl to get PRAM offset | 
|---|
|  | 661 | +     // fprintf(stderr, "no NW PRAM found, assuming OW XPRAM offset 0x1300 size 0x100\n"); | 
|---|
|  | 662 | +     *size = 0x100; | 
|---|
|  | 663 | +     return (0x1300); | 
|---|
|  | 664 | +     die("no PRAM found"); | 
|---|
|  | 665 | +} | 
|---|
|  | 666 | + | 
|---|
|  | 667 | +#define VOLADDR 8 | 
|---|
|  | 668 | + | 
|---|
|  | 669 | +int main(int argc, char *argv[]) | 
|---|
|  | 670 | +{ | 
|---|
|  | 671 | +     int fd, offset, size; | 
|---|
|  | 672 | +     char *buf; | 
|---|
|  | 673 | + | 
|---|
|  | 674 | +     fd = open("/dev/nvram", O_RDWR); | 
|---|
|  | 675 | +     if (fd < 0) die("can't open /dev/nvram"); | 
|---|
|  | 676 | + | 
|---|
|  | 677 | +     offset = find_pram(fd, &size); | 
|---|
|  | 678 | +     buf = malloc(size); | 
|---|
|  | 679 | +     if (!buf) die("can't malloc()"); | 
|---|
|  | 680 | + | 
|---|
|  | 681 | +     seek_pram(fd, offset); | 
|---|
|  | 682 | +     if (read(fd, buf, size) != size) | 
|---|
|  | 683 | +         die("error reading /dev/nvram"); | 
|---|
|  | 684 | + | 
|---|
|  | 685 | +     printf("current volume is %d\n", (unsigned char) buf[VOLADDR]); | 
|---|
|  | 686 | + | 
|---|
|  | 687 | +     if (argc > 1) { | 
|---|
|  | 688 | +         buf[VOLADDR] = atoi(argv[1]); | 
|---|
|  | 689 | + | 
|---|
|  | 690 | +         seek_pram(fd, offset); | 
|---|
|  | 691 | +         if (write(fd, buf, size) != size) | 
|---|
|  | 692 | +              die("error writing /dev/nvram"); | 
|---|
|  | 693 | +         printf("new volume is %d\n", (unsigned char) buf[VOLADDR]); | 
|---|
|  | 694 | +     } | 
|---|
|  | 695 | +     ioctl(fd, IOC_NVRAM_SYNC); | 
|---|
|  | 696 | +     close(fd); | 
|---|
|  | 697 | +     return 0; | 
|---|
|  | 698 | +} | 
|---|
|  | 699 | diff -Nuar pmac-utils.orig/nwnvsetenv.c pmac-utils/nwnvsetenv.c | 
|---|
|  | 700 | --- pmac-utils.orig/nwnvsetenv.c        1970-01-01 01:00:00.000000000 +0100 | 
|---|
|  | 701 | +++ pmac-utils/nwnvsetenv.c     2005-11-17 21:37:27.000000000 +0000 | 
|---|
|  | 702 | @@ -0,0 +1,261 @@ | 
|---|
|  | 703 | +/*     nwnvsetnv.c | 
|---|
|  | 704 | + | 
|---|
|  | 705 | +       used to set the Envenrioment variables in power macs NVram. | 
|---|
|  | 706 | +       This is for the NewWorld nvram only | 
|---|
|  | 707 | + | 
|---|
|  | 708 | +       nwcode: Copyright (C) 2000      by Klaus Halfmann | 
|---|
|  | 709 | + | 
|---|
|  | 710 | +       see README for details | 
|---|
|  | 711 | +*/ | 
|---|
|  | 712 | +#include <stdio.h> | 
|---|
|  | 713 | +#include <stdlib.h> | 
|---|
|  | 714 | + | 
|---|
|  | 715 | +#define __USE_GNU      // need strnlen | 
|---|
|  | 716 | + | 
|---|
|  | 717 | +#include <string.h> | 
|---|
|  | 718 | +#include <unistd.h> | 
|---|
|  | 719 | +#include <fcntl.h> | 
|---|
|  | 720 | + | 
|---|
|  | 721 | +// #define MXSTRING        128: | 
|---|
|  | 722 | +// #define N_NVVARS    (int)(sizeof(nvvars) / sizeof(nvvars[0])) | 
|---|
|  | 723 | +// #define NVMAGIC             0x1275 | 
|---|
|  | 724 | + | 
|---|
|  | 725 | +/* CHRP NVRAM header */ | 
|---|
|  | 726 | +typedef struct { | 
|---|
|  | 727 | +  unsigned char                signature; | 
|---|
|  | 728 | +  unsigned char                cksum; | 
|---|
|  | 729 | +  unsigned short       len; | 
|---|
|  | 730 | +  char                 name[12]; | 
|---|
|  | 731 | +  // unsigned char data[0]; | 
|---|
|  | 732 | +} chrp_header; | 
|---|
|  | 733 | + | 
|---|
|  | 734 | +/* Check in proc/cpuinfo if this is a new world machine */ | 
|---|
|  | 735 | + | 
|---|
|  | 736 | +int checkNewWorld(void) | 
|---|
|  | 737 | +{ | 
|---|
|  | 738 | +    FILE* cpuf = fopen("/proc/cpuinfo","r"); | 
|---|
|  | 739 | +    char  buf[256]; // "pmac-generation    : NewWolrd|OldWorld | 
|---|
|  | 740 | +    int          result = 0, found = 0; | 
|---|
|  | 741 | + | 
|---|
|  | 742 | +    if (!cpuf) { | 
|---|
|  | 743 | +       perror("Couldn't open /proc/cpuinfo"); | 
|---|
|  | 744 | +       exit(EXIT_FAILURE); | 
|---|
|  | 745 | +    } | 
|---|
|  | 746 | + | 
|---|
|  | 747 | +    while (NULL != fgets(buf, 255, cpuf)) | 
|---|
|  | 748 | +    { | 
|---|
|  | 749 | +       if (!strncmp(buf, "pmac-generation" ,15)) | 
|---|
|  | 750 | +       { | 
|---|
|  | 751 | +           char* index = strchr(buf, ':') + 2; | 
|---|
|  | 752 | +           if (!index) // ??? | 
|---|
|  | 753 | +               continue; | 
|---|
|  | 754 | +           result = !strncmp(index,"NewWorld",8); | 
|---|
|  | 755 | +           found = 1; | 
|---|
|  | 756 | +           break; | 
|---|
|  | 757 | +       } | 
|---|
|  | 758 | +    } | 
|---|
|  | 759 | +    fclose(cpuf); | 
|---|
|  | 760 | + | 
|---|
|  | 761 | +    /* Some kernels don't have pmac-generation ( <= 2.2.15 and earlier 2.3.x ) */ | 
|---|
|  | 762 | +    /* Look for AAPL in /proc/device-tree/compatible instead. */ | 
|---|
|  | 763 | +    if (!found) { | 
|---|
|  | 764 | +       cpuf = fopen("/proc/device-tree/compatible", "r"); | 
|---|
|  | 765 | +       if(!cpuf) | 
|---|
|  | 766 | +           return 0; | 
|---|
|  | 767 | + | 
|---|
|  | 768 | +       fgets(buf, 255, cpuf); | 
|---|
|  | 769 | +       fclose(cpuf); | 
|---|
|  | 770 | +       if (strncmp(buf, "AAPL", 4) != 0) | 
|---|
|  | 771 | +           result = 1; | 
|---|
|  | 772 | +    } | 
|---|
|  | 773 | + | 
|---|
|  | 774 | +    return result; // assume OldWorld | 
|---|
|  | 775 | +} | 
|---|
|  | 776 | + | 
|---|
|  | 777 | +/* seek NVRAM until common (OF) part | 
|---|
|  | 778 | +   return the lenght of the part in case of sucess, | 
|---|
|  | 779 | +         0 otherwise. | 
|---|
|  | 780 | +   chrph is set to the value of the "coommon" blocek eventually found | 
|---|
|  | 781 | +   *nvstart is set to the seekpoint where common block starts. | 
|---|
|  | 782 | +*/ | 
|---|
|  | 783 | + | 
|---|
|  | 784 | +int nvscan(int nvfd, chrp_header* chrph, int* nvstart) | 
|---|
|  | 785 | +{ | 
|---|
|  | 786 | +    int                start = 0; | 
|---|
|  | 787 | + | 
|---|
|  | 788 | +    while (read(nvfd, chrph, sizeof(chrp_header)) == sizeof(chrp_header)) | 
|---|
|  | 789 | +    { | 
|---|
|  | 790 | +       int size = chrph->len * 0x10 - sizeof(chrp_header); | 
|---|
|  | 791 | +       if (!strncmp(chrph->name, "common", 7)) | 
|---|
|  | 792 | +       { | 
|---|
|  | 793 | +           *nvstart = start; | 
|---|
|  | 794 | +           return size; // seeked upto start | 
|---|
|  | 795 | +       } | 
|---|
|  | 796 | +       if (lseek(nvfd, size, SEEK_CUR) < 0) | 
|---|
|  | 797 | +          break; | 
|---|
|  | 798 | +       start += size + sizeof(chrp_header); | 
|---|
|  | 799 | +    } | 
|---|
|  | 800 | +    fprintf(stderr,"No common Block found\n"); | 
|---|
|  | 801 | +    exit(EXIT_FAILURE); | 
|---|
|  | 802 | +} | 
|---|
|  | 803 | + | 
|---|
|  | 804 | +static char* nvload( int nvfd , int nvsize) | 
|---|
|  | 805 | +{ | 
|---|
|  | 806 | +    char* nvbuf = malloc(nvsize); | 
|---|
|  | 807 | + | 
|---|
|  | 808 | +    if (!nvbuf) { | 
|---|
|  | 809 | +       perror("Error allocating buffer"); | 
|---|
|  | 810 | +       exit(EXIT_FAILURE); | 
|---|
|  | 811 | +    } | 
|---|
|  | 812 | +    if (read(nvfd, nvbuf, nvsize) != nvsize) { | 
|---|
|  | 813 | +       perror("Error reading /dev/nvram"); | 
|---|
|  | 814 | +       exit(EXIT_FAILURE); | 
|---|
|  | 815 | +    } | 
|---|
|  | 816 | +    return nvbuf; | 
|---|
|  | 817 | +} | 
|---|
|  | 818 | + | 
|---|
|  | 819 | +static void | 
|---|
|  | 820 | +print_vars(char* nvbuf, int nvsize) | 
|---|
|  | 821 | +{ | 
|---|
|  | 822 | +    int i = 0; | 
|---|
|  | 823 | + | 
|---|
|  | 824 | +    while (i < nvsize) | 
|---|
|  | 825 | +    { | 
|---|
|  | 826 | +       int size = strnlen(nvbuf, nvsize); | 
|---|
|  | 827 | +       if (size == 0) | 
|---|
|  | 828 | +           break; | 
|---|
|  | 829 | +       printf("%s\n",nvbuf); | 
|---|
|  | 830 | +       nvbuf += (size + 1);    // count 0-byte, too | 
|---|
|  | 831 | +    } | 
|---|
|  | 832 | +} | 
|---|
|  | 833 | + | 
|---|
|  | 834 | +/* move memory around to insert the value. | 
|---|
|  | 835 | + * | 
|---|
|  | 836 | + * @param nvbufend     byte AFTER the end of the buffer | 
|---|
|  | 837 | + * @param varsize      length of the variable name | 
|---|
|  | 838 | + * @param buf          byte where varaible NAME starts | 
|---|
|  | 839 | + * @param newval       new value to replace old one | 
|---|
|  | 840 | + * @param foundsize    lenght of varible + '=' + value | 
|---|
|  | 841 | + * @param equalpos     position relative to buf where '=' was found | 
|---|
|  | 842 | + */ | 
|---|
|  | 843 | +static void | 
|---|
|  | 844 | +insert_val (char* nvbufend, int varsize,   char* buf, | 
|---|
|  | 845 | +           char* newval,   int foundsize, int equalpos) | 
|---|
|  | 846 | +{ | 
|---|
|  | 847 | +    int        oldlen  = foundsize - equalpos -1; // account for the '=' | 
|---|
|  | 848 | +    int                newlen  = strlen(newval); | 
|---|
|  | 849 | +    char*      valpos  = buf + varsize + 1; | 
|---|
|  | 850 | +    int        delta   = newlen - oldlen; | 
|---|
|  | 851 | + | 
|---|
|  | 852 | +    if (delta > 0) // expand mem | 
|---|
|  | 853 | +       memmove(valpos + newlen, | 
|---|
|  | 854 | +               valpos + oldlen, (nvbufend - valpos - newlen)); | 
|---|
|  | 855 | +    else if (delta < 0) // shrink mem | 
|---|
|  | 856 | +    { | 
|---|
|  | 857 | +       memmove(valpos + newlen, | 
|---|
|  | 858 | +               valpos + oldlen, (nvbufend - valpos - oldlen)); | 
|---|
|  | 859 | +       memset (nvbufend + delta, 0, -delta ); | 
|---|
|  | 860 | +    } | 
|---|
|  | 861 | +    strncpy(valpos, newval, newlen); | 
|---|
|  | 862 | +} | 
|---|
|  | 863 | + | 
|---|
|  | 864 | +/* return position where variable is found, | 
|---|
|  | 865 | + * newval may be null. | 
|---|
|  | 866 | + */ | 
|---|
|  | 867 | + | 
|---|
|  | 868 | +static char* set_var(char* nvbuf, int nvsize, char* varname, char* newval) | 
|---|
|  | 869 | +{ | 
|---|
|  | 870 | +    int i =0; | 
|---|
|  | 871 | +    int varsize = strlen(varname); | 
|---|
|  | 872 | +    int equalpos; | 
|---|
|  | 873 | +    while (i < nvsize) | 
|---|
|  | 874 | +    { | 
|---|
|  | 875 | +       char* buf = &nvbuf[i]; | 
|---|
|  | 876 | +       int foundsize = strnlen(buf, nvsize -i); | 
|---|
|  | 877 | +       if (foundsize == 0) | 
|---|
|  | 878 | +           break; | 
|---|
|  | 879 | +       equalpos = (int) (strchr(buf, '=') - buf); | 
|---|
|  | 880 | +       if (equalpos == varsize && | 
|---|
|  | 881 | +           !strncmp(buf, varname, equalpos)) | 
|---|
|  | 882 | +       { | 
|---|
|  | 883 | +           if (newval) // set the value | 
|---|
|  | 884 | +               insert_val(nvbuf + nvsize, varsize, buf, | 
|---|
|  | 885 | +                          newval, foundsize, equalpos); | 
|---|
|  | 886 | +           return buf; | 
|---|
|  | 887 | +       } | 
|---|
|  | 888 | +       i += foundsize + 1;     // count 0-byte, too | 
|---|
|  | 889 | +    } | 
|---|
|  | 890 | +    return NULL; | 
|---|
|  | 891 | +} | 
|---|
|  | 892 | + | 
|---|
|  | 893 | +static void | 
|---|
|  | 894 | +print_var(char* nvbuf, int nvsize, char* varname) | 
|---|
|  | 895 | +{ | 
|---|
|  | 896 | +    char* buf = set_var(nvbuf, nvsize, varname, NULL); | 
|---|
|  | 897 | +    if (buf) | 
|---|
|  | 898 | +       printf("%s\n",buf); | 
|---|
|  | 899 | +} | 
|---|
|  | 900 | + | 
|---|
|  | 901 | +/* This fucntion is not used here, it is left | 
|---|
|  | 902 | +   her for the curious */ | 
|---|
|  | 903 | + | 
|---|
|  | 904 | +unsigned short chrp_checksum(chrp_header* hdr, char* nvbuf, int nvsize) | 
|---|
|  | 905 | +{ | 
|---|
|  | 906 | +    unsigned char*     ptr = (unsigned char*) &hdr->len; | 
|---|
|  | 907 | +    unsigned char*     end = ptr + sizeof(chrp_header); | 
|---|
|  | 908 | +    unsigned short     sum = hdr->signature; | 
|---|
|  | 909 | +       // this in fact skips the checksum | 
|---|
|  | 910 | +    for (; ptr < end; ptr++) | 
|---|
|  | 911 | +       sum += *ptr; | 
|---|
|  | 912 | +    while (sum > 0xFF) | 
|---|
|  | 913 | +       sum = (sum & 0xFF) + (sum>>8); | 
|---|
|  | 914 | +    return sum; | 
|---|
|  | 915 | +} | 
|---|
|  | 916 | + | 
|---|
|  | 917 | +static void | 
|---|
|  | 918 | +nvstore(int nvfd, chrp_header* chrph, char* nvbuf, int nvstart, int nvsize) | 
|---|
|  | 919 | +{ | 
|---|
|  | 920 | +    // mmh, the checksum is calculated for the header only | 
|---|
|  | 921 | +    // since we did not modify the header we can just ignore it. | 
|---|
|  | 922 | +    ssize_t written; | 
|---|
|  | 923 | +    ssize_t seek =  nvstart + sizeof(chrp_header); | 
|---|
|  | 924 | +    written = lseek(nvfd, seek, SEEK_SET); | 
|---|
|  | 925 | +    if (written != seek) | 
|---|
|  | 926 | +    { | 
|---|
|  | 927 | +       fprintf(stderr,"Error seeking /dev/nvram\n"); | 
|---|
|  | 928 | +       exit(EXIT_FAILURE); | 
|---|
|  | 929 | +    } | 
|---|
|  | 930 | +    written = write(nvfd, nvbuf, nvsize); | 
|---|
|  | 931 | +    if (written != nvsize) | 
|---|
|  | 932 | +    { | 
|---|
|  | 933 | +       fprintf(stderr,"Error writing /dev/nvram %x %x\n", nvsize, seek); | 
|---|
|  | 934 | +       exit(EXIT_FAILURE); | 
|---|
|  | 935 | +    } | 
|---|
|  | 936 | +} | 
|---|
|  | 937 | + | 
|---|
|  | 938 | +/* print / set the New World NVRAM */ | 
|---|
|  | 939 | + | 
|---|
|  | 940 | +void nvNew(int ac, char** av, int nvfd) | 
|---|
|  | 941 | +{ | 
|---|
|  | 942 | +    int                nvsize, nvstart; | 
|---|
|  | 943 | +    chrp_header                chrph; | 
|---|
|  | 944 | +    char*              nvbuf; | 
|---|
|  | 945 | + | 
|---|
|  | 946 | +    nvsize = nvscan(nvfd, &chrph, &nvstart); | 
|---|
|  | 947 | +    nvbuf  = nvload(nvfd, nvsize); | 
|---|
|  | 948 | + | 
|---|
|  | 949 | +    switch (ac) { | 
|---|
|  | 950 | +    case 1: | 
|---|
|  | 951 | +       print_vars(nvbuf, nvsize); | 
|---|
|  | 952 | +       break; | 
|---|
|  | 953 | + | 
|---|
|  | 954 | +    case 2: | 
|---|
|  | 955 | +       print_var(nvbuf, nvsize, av[1]); | 
|---|
|  | 956 | +       break; | 
|---|
|  | 957 | + | 
|---|
|  | 958 | +    case 3: | 
|---|
|  | 959 | +       set_var(nvbuf, nvsize, av[1], av[2]); | 
|---|
|  | 960 | +       nvstore(nvfd, &chrph, nvbuf, nvstart, nvsize); | 
|---|
|  | 961 | +       break; | 
|---|
|  | 962 | +    } | 
|---|
|  | 963 | +} | 
|---|