Intel 5100 EEPROM: Difference between revisions

From NoName e.V.
Jump to navigation Jump to search
No edit summary
No edit summary
 
(One intermediate revision by the same user not shown)
Line 19: Line 19:
* http://download.intel.com/design/network/applnots/an446.pdf ist ein Gigabit-Ethernet-Controller, der vor dem eigentlichen WLAN-Teil sitzt
* http://download.intel.com/design/network/applnots/an446.pdf ist ein Gigabit-Ethernet-Controller, der vor dem eigentlichen WLAN-Teil sitzt
* http://www.st.com/stonline/products/literature/ds/8028/m95160-w.pdf ist das EEPROM, welches wir verändern wollen
* http://www.st.com/stonline/products/literature/ds/8028/m95160-w.pdf ist das EEPROM, welches wir verändern wollen
== Das Board ==
Zum Einsatz kam ein Keil MCB2300 Evaluation Board, welches einen LPC2300 ARM Mikroprozessor beinhaltet. Nachdem man das EEPROM abgelötet hat und die pins mit drähten an die Pin-Outs des Boards verbunden hat, spielt man die Software auf, mit der man das EEPROM zunächst ausliest und anschließend neu programmiert.


== Nötige Änderungen ==
== Nötige Änderungen ==
Line 160: Line 164:
  0x000005b8: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
  0x000005b8: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
  *
  *
  0x000007ff: 00  
  0x000007ff: 00


'''To be continued…'''
= Das Programm zum Auslesen/Ändern =
#include "system.h"
#define WREN  0x0006 /* Write Enable */
#define WRDI  0x0004 /* Write Disable */
#define RDSR  0x0005 /* Read Status Register */
#define READ  0x0003 /* Read from Memory Array */
#define WRITE 0x0002 /* Write to Memory Array */
//#define WRITE_EEP
#define READ_EEP
/*
  * Der Chip reagiert auf die Befehle nur, wenn ChipSelect auf low steht während
  * wir die Befehle schicken
  *
  */
void select_chip(void) {
        /* ChipSelect auf Low */
        FIO0CLR = 0x01 << 8;
}
void unselect_chip(void) {
        /* ChipSelect auf High */
        FIO0SET = 0x01 << 8;
}
/* Das Datenblatt sagt, dass wir min. 90 ns warten müssen, siehe Seite 32 des PDFs,
  * Tabelle 21 (AC characteristics) */
void sleep_90ns(void) {
        __asm("nop;nop;nop;nop;nop;nop;nop;nop;nop;nop");
}
/*
  * Aktiviert das WRITE_ENABLE-bit, welches vor Schreibzugriffen gesetzt
  * werden muss.
  *
  */
void write_enable(void) {
        select_chip();
        spi_ReconfigTransceiveData(WREN, false, false);
        unselect_chip();
        sleep_90ns();
        printf("Write enable aktiviert\r\n");
}
void write_disable(void) {
        select_chip();
        spi_Transceive(WRDI);
        unselect_chip();
        sleep_90ns();
        printf("write disable\r\n");
}
/*
  * Prüft das Statusregister solange, bis das Write in Progress-Bit
  * nicht mehr gesetzt ist.
  *
  */
void wait_write(void) {
        while (1) {
                select_chip();
                spi_ReconfigTransceiveData(RDSR, false, false);
                readWord = (spi_Transceive(0x0000) & 0x00FF);
                unselect_chip();
                sleep_90ns();
                printf("Statusreg = %02x\n", readWord);
                if (!(readWord & 0x1)) {
                        printf("Fertig.\r\n");
                        break;
                }
        }
}
int main(void) {
        int i=0, j=0;
        BYTE readData[2048];
        BYTE readWord;
        BOARD_Init();
        SYSTEM_Init();
        printf("System Up \r\n");
#ifdef WRITE_EEP
        /* write enable bit setzen */
        write_enable();
        /* Daten schreiben */
        select_chip();
        spi_ReconfigTransceiveData(WRITE, false, false);
        /* 16-Bit Adresse senden, wir sind im 8-Bit-Modus */
        spi_Transceive(0x0000);
        spi_Transceive(0x0092);
        /* Daten senden */
        spi_Transceive(0x0016);
        spi_Transceive(0x0000);
        spi_Transceive(0x00e5);
        spi_Transceive(0x00ea);
        spi_Transceive(0x0091);
        spi_Transceive(0x007e);
        unselect_chip();
        sleep_90ns();
        printf("Write abgesetzt\r\n");
        /* Warten bis der Schreibvorgang fertig ist */
        wait_write();
        /* write-bit wieder deaktivieren */
        write_disable();
#endif
#ifdef READ_EEP
        printf("Begin\n\r");
        select_chip();
        spi_ReconfigTransceiveData(READ, false, false);
        /* 16-Bit Adresse senden, wir sind im 8-Bit-Modus */
        spi_Transceive(0x0000);
        spi_Transceive(0x0000);
        /* Daten zuerst in einen Buffer einlesen, wir können hier
        * nicht direkt ausgeben, da wir sonst zulange warten würden
        * (auf die serielle Schnittstelle) */
        for (i = 0; i < 2048; i++)
                readData[i] = (spi_Transceive(0x0000) & 0x00FF);
        unselect_chip();
        for (i = 0; i < 2048; i++) {
                printf("0x%08x: 0x%02x\r\n",i, readData[i]);
                /* Warten bis die Daten über die serielle Schnittstelle sind */
                for(j=0;j<500000;j++);
        }
        printf("End\r\n");
#endif
        /* Schleife um den ARM aufzufangen */
        while (1) {
                printf("nix zu tun\r\n");
                for(i=0;i<5000000;i++);
        }
}

Latest revision as of 14:43, 24 May 2009

Intel 5100agn

Aufkleber
Links das EEPROM
Das EEPROM, ausgelötet
Board mit Mikroprozessor

Die Intel 5100agn ist eine WLAN-Karte (MiniPCI-Express), die man z.B. in einem Thinkpad verbauen kann. Diese Karte gibt es in mehreren Varianten: Einmal rebranded von Lenovo, mit anderen IDs (kostet ca. 100 €) und einmal original von Intel (27 €). Der einzige Unterschied: Die IDs.

Die Idee war daher, entweder das BIOS zu modifizieren (siehe auch http://www.endeer.cz/bios.tools/ für Tools dazu und http://forum.thinkpads.com/viewtopic.php?f=29&t=55837 für den passenden Thread), was sich als frickelig herausgestellt hat. Wenn man das BIOS kaputtflashed, hat man einen sehr teuren Backstein in der Hand, somit haben wir also das EEPROM der Karte modifiziert ;-).

Getestet wurde diese Änderung übrigens mit dem derzeit aktuellen BIOS für das Thinkpad x200, also Version 3.01 (6DET51WW) von 2009-04-20.

Datenblätter

Das Board

Zum Einsatz kam ein Keil MCB2300 Evaluation Board, welches einen LPC2300 ARM Mikroprozessor beinhaltet. Nachdem man das EEPROM abgelötet hat und die pins mit drähten an die Pin-Outs des Boards verbunden hat, spielt man die Software auf, mit der man das EEPROM zunächst ausliest und anschließend neu programmiert.

Nötige Änderungen

Da man das EEPROM nicht beliebig oft auf- und ablöten kann, haben wir vorsichtshalber alle IDs geändert. Daher kann ich nicht genau sagen, welche Teile das BIOS prüft. Unsere Änderungen (durch Suchen im Netz die nötigen IDs gefunden):

  • PCI ID auf 8086:4237
  • Subsystem ID auf 8086:1211
  • Device ID auf 26-08-cb-ff-ff-ea-16-00
  • MAC-Adresse auf 00:16:ea:e5:7e:92

Hexdump vom EEPROM mit Anmerkungen

0x00000000: 5a 40 00 50 70 00 04 30   00 3c 00 00 02 80

/***************************************/
/* PCI ID START                        */
/***************************************/
0x0000000e: 0x80 -- PCI vendor ID
0x0000000f: 0x86 -- PCI vendor ID

0x00000010: 0x42 -- PCI device ID
0x00000011: 0x32 -- PCI device ID --> 0x37
/***************************************/
/* PCI ID END                          */
/***************************************/

/***************************************/
/* SUBSYSTEM ID START                  */
/***************************************/
0x00000012: 0x80 -- subsystem vendor ID
0x00000013: 0x86 -- subsystem vendor ID

0x00000014: 0x12 -- subsystem device ID
0x00000015: 0x01 -- subsystem device ID --> 0x11
/***************************************/
/* SUBSYSTEM ID END                    */
/***************************************/


0x00000016: 0d 01 03 8b 05 00 00 f0   00 40 de c9 14 50 24 3e 
0x00000026: 01 31 88 4b 

/***************************************/
/* DEVICE SERIAL NUMBER (MAC-Adresse)  */
/* geändert von f8-4e-0a-ff-ff-5d-21-00
            auf 26-08-cb-ff-ff-ea-16-00
   (siehe lspci -nv)                   */
/***************************************/
0x0000002a: 0x21 --> 0x16
0x0000002b: 0x00 
0x0000002c: 0x0a --> 0xcb
0x0000002d: 0x5d --> 0xea
0x0000002e: 0xf8 --> 0x26
0x0000002f: 0x4e --> 0x08
/***************************************/
/* DEVICE SERIAL NUMBER END            */
/***************************************/


0x00000030: 69 16 79 16 89 16 99 16   ff ff 00 10 ff fe 00 00 
0x00000040: 19 54 03 0c 00 00 60 04   ec fc 1f 5d f8 00 b2 44 
0x00000050: 77 cc 01 22 69 14 24 92   00 1a 31 98 cc 60 1f 8f 
0x00000060: cf e0 07 80 c1 e0 3f b8   ff 3f cc 30 00 00 00 20
0x00000070: 0a 28 0e 81 00 00 00 00   00 00 00 00 00 00 00 00 
0x00000080: 00 00 00 00 00 00 08 4c   01 1f 00 f0 10 34 00 00 
0x00000090: 31 09 

/****************************************/
/* "MAC Adresse" (siehe Aufkleber)      */
/* geändert von 00:21:5d:0a:4e:f8 auf
                00:16:ea:e5:7e:92       */
/****************************************/
0x00000092: 0x21 -> 0x16
0x00000093: 0x00 
0x00000094: 0x0a -> 0xe5
0x00000095: 0x5d -> 0xea
0x00000096: 0xf9 -> 0x92
0x00000097: 0x4e -> 0x7e
/*****************************************/
/* MAC Adresse ENDE                      */
/*****************************************/

0x00000098: 00 02 00 00 00 00 00 50   41 30 45 34 38 46 30 33 
0x000000a8: 43 38 45 58 39 33 32 31   30 36 34 30 00 00 a1 58 
0x000000b8: 38 f8 00 00 00 00 00 00   00 00 00 00 00 00 00 00 
0x000000c8: 00 6e 00 96 00 ab 01 0f   03 68 02 cb 00 00 00 00 
0x000000d8: 00 00 00 00 00 20 00 00   00 00 00 00 00 00 00 00 
0x000000e8: 00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00 
*
0x00000148: 00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 0e 
0x00000158: 6f 4d 00 57 00 00 0f 6f   0f 6f 0f 6f 0f 6f 0f 6f 
0x00000168: 0f 6f 0f 6f 0f 6f 0f 6f   0f 6f 0f 6f 0f 61 0f 61 
0x00000178: 00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00 
0x00000188: 00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00 
0x00000198: 00 00 0e e1 00 00 0f e1   00 00 0f e1 00 00 0f e1 
0x000001a8: 0f 31 0f 31 0f 31 0f 31   00 00 0f 31 0f 31 0f 31 
0x000001b8: 0f 31 0f 31 0f 31 0f 31   0f 31 0f 31 0f 31 0f 31 
0x000001c8: 00 00 00 00 0f a1 0f a1   0f a1 0f a1 0f a1 00 00 
0x000001d8: 0a 6f 0f 6f 0f 6f 0f 6f   0f 6f 0f 6f 0d 6f 00 00 
0x000001e8: 0a e1 0f e1 0f 31 0a 31   0f 31 0f 31 0f 31 0f 31 
0x000001f8: 0f 31 0f 61 0f 61 0c 0c   0f 0f 0f 0f 0f 0f 0f 0f 
0x00000208: 0f 0f 0f 0f 0f 0f 0f 0f   0f 0f 0c 0c 0f 0f 0f 0f 
0x00000218: 00 00 00 00 00 00 00 04   00 00 00 00 00 00 00 00 
0x00000228: 00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00 
*
0x000002d8: 00 00 00 00 00 00 00 00   00 00 00 00 00 00 22 45
0x000002e8: 28 c1 29 41 28 b4 32 3c   28 9c 3d 37 28 7d 45 33 
0x000002f8: 28 5c 00 00 00 00 06 28   f2 00 21 3c 28 ae 27 39 
0x00000308: 28 9e 34 32 28 70 3b 2e   28 51 46 29 28 2a 00 00 
0x00000318: 00 00 24 28 ee 00 21 3f   28 90 28 3b 28 73 32 36 
0x00000328: 28 49 3c 31 28 23 45 2c   2a 0f 00 00 00 00 40 28 
0x00000338: ee 00 22 3d 28 8b 28 3a   28 73 33 34 28 3f 3c 2f 
0x00000348: 28 22 44 2b 28 10 00 00   00 00 64 28 ee 00 22 3d 
0x00000358: 28 9b 28 3a 28 86 33 34   28 53 3d 2f 28 2e 45 2b 
0x00000368: 2a 19 00 00 00 00 74 28   ee 00 22 39 2a 9d 28 36 
0x00000378: 28 89 33 30 2a 58 3d 2b   28 31 45 27 2a 1b 00 00 
0x00000388: 00 00 8c 28 ee 00 20 37   28 a9 27 34 2a 96 33 2d 
0x00000398: 28 64 3b 29 2a 41 47 24   2a 1f 00 00 00 00 9d 28 
0x000003a8: ee 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00 
0x000003b8: 00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00 
*
0x00000468: 00 00 00 00 00 00 00 5d   00 5d 00 00 00 00 00 00 
0x00000478: 01 01 00 06 01 01 00 05   00 00 00 00 01 01 00 06 
0x00000488: 01 01 00 05 00 00 00 00   00 00 00 00 00 00 00 00 
0x00000498: 00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00 
0x000004a8: 01 02 00 08 01 02 00 08   00 00 00 00 01 02 00 09 
0x000004b8: 01 02 00 08 00 00 00 00   00 00 00 00 00 00 00 00 
0x000004c8: 00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00 
0x000004d8: 01 02 00 07 01 03 00 06   00 00 00 00 01 02 00 08 
0x000004e8: 01 03 00 07 00 00 00 00   00 00 00 00 00 00 00 00 
0x000004f8: 00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00 
0x00000508: 01 02 00 06 01 03 00 04   00 00 00 00 01 02 00 06 
0x00000518: 01 03 00 05 00 00 00 00   00 00 00 00 00 00 00 00 
0x00000528: 00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00 
0x00000538: 01 02 00 05 01 02 00 03   00 00 00 00 01 02 00 05 
0x00000548: 01 02 00 04 00 00 00 00   00 00 00 00 00 00 00 00 
0x00000558: 00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00 
0x00000568: 01 01 00 04 01 02 00 02   00 00 00 00 01 01 00 04 
0x00000578: 01 02 00 02 00 00 00 00   00 00 00 00 00 00 00 00 
0x00000588: 00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00 
0x00000598: 01 01 00 06 01 05 00 03   00 00 00 00 01 01 00 06 
0x000005a8: 01 06 00 03 00 00 00 00   00 00 00 00 00 00 00 00
0x000005b8: 00 00 00 00 00 00 00 00   00 00 00 00 00 00 00 00 
*
0x000007ff: 00

Das Programm zum Auslesen/Ändern

#include "system.h"

#define WREN  0x0006 /* Write Enable */
#define WRDI  0x0004 /* Write Disable */
#define RDSR  0x0005 /* Read Status Register */
#define READ  0x0003 /* Read from Memory Array */
#define WRITE 0x0002 /* Write to Memory Array */

//#define WRITE_EEP
#define READ_EEP

/*
 * Der Chip reagiert auf die Befehle nur, wenn ChipSelect auf low steht während
 * wir die Befehle schicken
 *
 */
void select_chip(void) {
       /* ChipSelect auf Low */
       FIO0CLR = 0x01 << 8;
}

void unselect_chip(void) {
       /* ChipSelect auf High */
       FIO0SET = 0x01 << 8;
}

/* Das Datenblatt sagt, dass wir min. 90 ns warten müssen, siehe Seite 32 des PDFs,
 * Tabelle 21 (AC characteristics) */
void sleep_90ns(void) {
       __asm("nop;nop;nop;nop;nop;nop;nop;nop;nop;nop");
}

/*
 * Aktiviert das WRITE_ENABLE-bit, welches vor Schreibzugriffen gesetzt
 * werden muss.
 *
 */
void write_enable(void) {
       select_chip();
       spi_ReconfigTransceiveData(WREN, false, false);
       unselect_chip();
       sleep_90ns();
       printf("Write enable aktiviert\r\n");
}

void write_disable(void) {
       select_chip();
       spi_Transceive(WRDI);
       unselect_chip();
       sleep_90ns();

       printf("write disable\r\n");
}

/*
 * Prüft das Statusregister solange, bis das Write in Progress-Bit
 * nicht mehr gesetzt ist.
 *
 */
void wait_write(void) {
       while (1) {
               select_chip();
               spi_ReconfigTransceiveData(RDSR, false, false);
               readWord = (spi_Transceive(0x0000) & 0x00FF);
               unselect_chip();
               sleep_90ns();

               printf("Statusreg = %02x\n", readWord);
               if (!(readWord & 0x1)) {
                       printf("Fertig.\r\n");
                       break;
               }
       }
}

int main(void) {
       int i=0, j=0;
       BYTE readData[2048];
       BYTE readWord;

       BOARD_Init();
       SYSTEM_Init();

       printf("System Up \r\n");

#ifdef WRITE_EEP
       /* write enable bit setzen */
       write_enable();

       /* Daten schreiben */
       select_chip();
       spi_ReconfigTransceiveData(WRITE, false, false);

       /* 16-Bit Adresse senden, wir sind im 8-Bit-Modus */
       spi_Transceive(0x0000);
       spi_Transceive(0x0092);

       /* Daten senden */
       spi_Transceive(0x0016);
       spi_Transceive(0x0000);
       spi_Transceive(0x00e5);
       spi_Transceive(0x00ea);
       spi_Transceive(0x0091);
       spi_Transceive(0x007e);

       unselect_chip();
       sleep_90ns();
       printf("Write abgesetzt\r\n");

       /* Warten bis der Schreibvorgang fertig ist */
       wait_write();

       /* write-bit wieder deaktivieren */
       write_disable();
#endif

#ifdef READ_EEP
       printf("Begin\n\r");

       select_chip();
       spi_ReconfigTransceiveData(READ, false, false);

       /* 16-Bit Adresse senden, wir sind im 8-Bit-Modus */
       spi_Transceive(0x0000);
       spi_Transceive(0x0000);

       /* Daten zuerst in einen Buffer einlesen, wir können hier
        * nicht direkt ausgeben, da wir sonst zulange warten würden
        * (auf die serielle Schnittstelle) */
       for (i = 0; i < 2048; i++)
               readData[i] = (spi_Transceive(0x0000) & 0x00FF);

       unselect_chip();

       for (i = 0; i < 2048; i++) {
               printf("0x%08x: 0x%02x\r\n",i, readData[i]);

               /* Warten bis die Daten über die serielle Schnittstelle sind */
               for(j=0;j<500000;j++);
       }

       printf("End\r\n");
#endif

       /* Schleife um den ARM aufzufangen */
       while (1) {
               printf("nix zu tun\r\n");

               for(i=0;i<5000000;i++);
       }
}