Netboot Mailing List (by thread)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bootrom



I was successful using the Atmel At29C010A 128K chip for the 3c905b but I'm
sure the 64K chip will work too.   I had trouble with the neboot rom
image so I used etherboot instead, you might want to take a look at etherboot,
it is much easier to install and use and there is a reference in the etherboot
source directory that refers to a well-known bug associated witht he way the
3c905b it maps it's ROM and etherboot works around the problem.   Also, I
flashed it using the attached romutil (compile it and run it from
Linux)...It's pretty cool and saved me a lot of time.

Cood luck!

Richard Schroeder
richard.schroeder@splashtech.com
ricks@rixrockets.com

Marcel.Andre.Beltz@Student.Uni-Augsburg.DE wrote:

> Hi,
> i Have a little hardware problem! Who can help me?
>
> I have a running diskless-system by using 3c905b-cards, but the rom-image
> is still on a floppy. Who is apple to build eproms for this card or where
> can i buy same?
>
> Marcel Beltz
>
> ===========================================================================
> This Mail was sent to netboot mailing list by:
> Marcel.Andre.Beltz@Student.Uni-Augsburg.DE
> To get help about this list, send a mail with 'help' as the only string in
> it's body to majordomo@baghira.han.de. If you have problems with this list,
> send a mail to netboot-owner@baghira.han.de.

I wrote the attached little util program to try out the basic approach
and thought that you might find it useful as well as providing some
simple testing. It isn't a final solution so the interface is rough. The
program must be run as root on an Intel based machine.

The key point is that the IO address needs to be entered - I grab it
from the dmesg output:

eth0: 3Com 3c905B Cyclone 100baseTx at 0xe400,  00:10:4b:d2:5e:0d, IRQ
11

Some example commands are:

romutil 0xe400 erase            - erases the ROM contents
romutil 0xe400 protect            - enables the Software Data Protection
on the ROM
romutil 0xe400 unprotect       - disables the Software Data Protection
on the ROM
romutil 0xe400 id                    - displays the manufacturer and
device IDs
romutil 0xe400 read >file    - writes the contents of the ROM to stdout
romutil 0xe400 prog <file    - writes the contents of the stdin into the
ROM (<64k)

I tried reading and writing the ROM while doing large ftp transfers and
experienced no problems. I didn't spend much time worrying about the
possible race conditions. My system has lots of resources (450MHx P2,
128MB RAM) so it might not provide the best test candidate.

Let me know what results you get if you try it out.

Thanks

John
/* 
 * readutil.c - perform various control ops on the 3c509b bios rom
 *
 */

#ifndef __i386__
#  error "This program can't compile or run on non-intel computers"
#else

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/io.h>

int main(int argc, char **argv)
{
    unsigned int i, j, n;
    unsigned int ioaddr;
    unsigned long recvrstat;
    unsigned char buf[128];
    unsigned char b;

    setuid(0); /* if we're setuid, do it really */
    if (argc != 3) {
      printf("Usage: romid ioaddr [erase|protect|unprotect|id|read >file|prog <file]\n");
      exit(-1);
    }
    if (iopl(3)) {
      perror("iopl()");
      exit(1);
    }
    sscanf(argv[1],"%x",&ioaddr);
    /* Set the register window to 3 for the 3c905b */
    outw(0x803, ioaddr+0xe);
    recvrstat = inl(ioaddr);	/* save the receiver status */
    /* set the receiver type to MII so the full bios rom address space
       can be accessed */
    outl((recvrstat & 0xf00fffff)|0x00600000, ioaddr);
    /* Set the register window to 0 for the 3c905b */
    outw(0x800, ioaddr+0xe);

    if (strcmp(argv[2], "erase") == 0) {
      /* do the funky chicken to erase the rom contents */
      outl(0x5555, ioaddr+0x4);
      outb(0xaa, ioaddr+0x8);
      outl(0x2aaa, ioaddr+0x4);
      outb(0x55, ioaddr+0x8);
      outl(0x5555, ioaddr+0x4);
      outb(0x80, ioaddr+0x8);
      outl(0x5555, ioaddr+0x4);
      outb(0xaa, ioaddr+0x8);
      outl(0x2aaa, ioaddr+0x4);
      outb(0x55, ioaddr+0x8);
      outl(0x5555, ioaddr+0x4);
      outb(0x10, ioaddr+0x8);
      printf("Bios ROM at %04x has been erased\n", ioaddr);
    } else if (strcmp(argv[2], "protect") == 0) {
      outl(0x5555, ioaddr+0x4);
      outb(0xaa, ioaddr+0x8);
      outl(0x2aaa, ioaddr+0x4);
      outb(0x55, ioaddr+0x8);
      outl(0x5555, ioaddr+0x4);
      outb(0xa0, ioaddr+0x8);
      printf("Software Data Protection for Bios ROM at %04x has been enabled\n",
	     ioaddr);
    } else if (strcmp(argv[2], "unprotect") == 0) {
      outl(0x5555, ioaddr+0x4);
      outb(0xaa, ioaddr+0x8);
      outl(0x2aaa, ioaddr+0x4);
      outb(0x55, ioaddr+0x8);
      outl(0x5555, ioaddr+0x4);
      outb(0x80, ioaddr+0x8);
      outl(0x5555, ioaddr+0x4);
      outb(0xaa, ioaddr+0x8);
      outl(0x2aaa, ioaddr+0x4);
      outb(0x55, ioaddr+0x8);
      outl(0x5555, ioaddr+0x4);
      outb(0x20, ioaddr+0x8);
      printf("Software Data Protection for Bios ROM at %04x has been disabled\n",
	     ioaddr);
    } else if (strcmp(argv[2], "id") == 0) {
      outl(0x5555, ioaddr+0x4);
      outb(0xaa, ioaddr+0x8);
      outl(0x2aaa, ioaddr+0x4);
      outb(0x55, ioaddr+0x8);
      outl(0x5555, ioaddr+0x4);
      outb(0x90, ioaddr+0x8);
      /* 10ms delay needed */
      printf("Manufacturer ID - ");
      /* manuf. id */
      outl(0x0000, ioaddr+0x4);
      printf("%02x\n", inb(ioaddr+0x8));
      /* device id */
      outl(0x0001, ioaddr+0x4);
      printf("Device ID - %02x\n", inb(ioaddr+0x8));
      /* undo the funky chicken */
      outl(0x5555, ioaddr+0x4);
      outb(0xaa, ioaddr+0x8);
      outl(0x2aaa, ioaddr+0x4);
      outb(0x55, ioaddr+0x8);
      outl(0x5555, ioaddr+0x4);
      outb(0xf0, ioaddr+0x8);
    } else if (strcmp(argv[2], "read") == 0) {
      for (i = 0; i < 65536; i++) {
	outl(i, ioaddr+0x4);
	b = inb(ioaddr+0x8);
	write(1, &b, 1);
      }
    } else if (strcmp(argv[2], "prog") == 0) {
      /* program the rom in 128 bute chunks */
      for (i = 0, n = 0; i < 65536; i += n) {
	n = read(0, buf, 128);
	if (n == 0)
	  break;
	if (n < 0) {
	  perror("File Error");
	  exit(-3);
	}
	/* disable SDP temporarily for programming a sector */
	outl(0x5555, ioaddr+0x4);
	outb(0xaa, ioaddr+0x8);
	outl(0x2aaa, ioaddr+0x4);
	outb(0x55, ioaddr+0x8);
	outl(0x5555, ioaddr+0x4);
	outb(0xa0, ioaddr+0x8);
	for (j = 0; j < n; j++) {
	  outl(i+j, ioaddr+0x4);
	  outb(buf[j], ioaddr+0x8);
	}
	/* wait for the programming of this sector to coomplete */
	while (inb(ioaddr+0x8) != buf[j-1])
	  ;
      }
    }

    /* Set the register window to 3 for the 3c905b */
    outw(0x803, ioaddr+0xe);
    /* restore the receiver status */
    outl(recvrstat, ioaddr);
    return 0;
}

#endif /* __i386__ */





For requests or suggestions regarding this mailing list archive please write to netboot@gkminix.han.de.