[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 | +} |
---|