Author Topic: mtd sees flash  (Read 20713 times)

0 Members and 1 Guest are viewing this topic.

Offline sbingner

  • Administrator
  • Veteran.
  • *****
  • Posts: 1301
Re: mtd sees flash
« Reply #20 on: July 20, 2005, 10:40:50 am »
Oh yea, the protection bits I read all showed up as 0, I tried that a couple days ago heh... just tried random offsets and they all showed 0... the chip erase erased the whole chip tho, so it's definately not protected.

Offline sbingner

  • Administrator
  • Veteran.
  • *****
  • Posts: 1301
Re: mtd sees flash
« Reply #21 on: July 20, 2005, 10:42:45 am »
hmm, so does that mean all the address bits should be shifted left one? and the last bit should be moved to the first?

Shifting the unlock locations 0xAAA, 0x555, 0xAAA left one bit works...

That wouldn't explain why writing to 0x02 shows up on 0x02 AND 0x03

Code: [Select]

/ # ./debugwc 1554=aa ; ./debugwc aaa=55; ./debugwc 1554=a0; ./debugwc 0x04=fe
Offset: 0x1554=aa
Offset: 0xaaa=55
Offset: 0x1554=a0
Offset: 0x4=fe
Unable to handle kernel paging request at virtual address e1a04000
« Last Edit: July 20, 2005, 10:49:35 am by sbingner »

Offline sbingner

  • Administrator
  • Veteran.
  • *****
  • Posts: 1301
Re: mtd sees flash
« Reply #22 on: July 20, 2005, 10:56:42 am »
You do see it doubled in memory, you see the chip from 0x0 to 0x1FFFF and again from 0x20000 to 0x3FFFF

Offline sbingner

  • Administrator
  • Veteran.
  • *****
  • Posts: 1301
Re: mtd sees flash
« Reply #23 on: July 20, 2005, 11:09:42 am »
sweet, the following works, so it seems to validate 16-bit mode:

Code: [Select]

/ # ./debugwc 1554=aa; ./debugwc AA8=55 ;./debugwc 1554=90
Offset: 0x1554=aa
Offset: 0xaa8=55
Offset: 0x1554=90
/ # ./debugr 0x00
Offset: 0=20
/ # ./debugr 0x04
Offset: 4=57


then

Code: [Select]

/ # ./debugwc 1554=aa; ./debugwc AA8=55 ;./debugwc 1554=a0; ./debugw 0x0C=90
Offset: 0x1554=aa
Offset: 0xaa8=55
Offset: 0x1554=a0
Offset: 0xC=90
/ # ./debugr 0x0C
Offset: C=9090

I'm writing it like
Code: [Select]
*(volatile unsigned short *) (bios + off) = val;


why did it write 0x9090, or is that caused by a0 on the cpu not being connected?  If so, why doesn't this happen on their original flash? -- at least it's not crashing the kernel now, probably just need to make sure the last two bits are always zero (by shifting left 2 bits of course)
« Last Edit: July 20, 2005, 11:27:48 am by sbingner »

Offline RobM

  • Senior Member
  • A few posts under my belt.
  • *****
  • Posts: 48
Re: mtd sees flash
« Reply #24 on: July 20, 2005, 01:09:53 pm »
Quote
why did it write 0x9090, or is that caused by a0 on the cpu not being connected?  If so, why doesn't this happen on their original flash? -- at least it's not crashing the kernel now, probably just need to make sure the last two bits are always zero (by shifting left 2 bits of course)


This is because the flash is configured for 16 bit access only, and D[31:24], D[23:16], D[15:8] are duplicates of D[7:0] when doing a byte-wise write (I think).

So for things to work right you'll need to do 16 bit writes.

Offline RobM

  • Senior Member
  • A few posts under my belt.
  • *****
  • Posts: 48
Re: mtd sees flash
« Reply #25 on: July 20, 2005, 03:01:51 pm »
Actually, since the flash is configured as 16 bit wide, a 32 bit write will also work (the CPU will do two 16 bit writes).

The even and odd locations are the same b/c A[0] is not connected to the flash chip.  The ARM only does 32 bit fetches for instructions (16 in Thumb mode which doesn't seem to be used in any of the PB stuff), so that's not a problem.

The flash is just not wired up for 8 bit access, so it doesn't appear A[0] or nBYTE/WORD are connected (they don't need to be if you're only doing aligned word accesses).

Offline bushing

  • Senior Member
  • Needs to get outside.
  • *****
  • Posts: 119
  • props to my peeps
Re: mtd sees flash
« Reply #26 on: July 20, 2005, 03:33:50 pm »
Quote
The flash is just not wired up for 8 bit access, so it doesn't appear A[0] or nBYTE/WORD are connected (they don't need to be if you're only doing aligned word accesses).



He said he's using this code:

Code: [Select]

*(volatile unsigned short *) (bios + off) = val;


Shouldn't that generate a 16-bit access?

-b

Offline RobM

  • Senior Member
  • A few posts under my belt.
  • *****
  • Posts: 48
Re: mtd sees flash
« Reply #27 on: July 20, 2005, 04:07:12 pm »
Quote


He said he's using this code:

Code: [Select]
*(volatile unsigned short *) (bios + off) = val;

Shouldn't that generate a 16-bit access?

-b


Yeah, true...  hrm, that's a headscratcher.  Unless val is a char and the compiler is generating some funky code...

Offline sbingner

  • Administrator
  • Veteran.
  • *****
  • Posts: 1301
Re: mtd sees flash
« Reply #28 on: July 20, 2005, 07:36:33 pm »
Quote

Yeah, true...  hrm, that's a headscratcher.  Unless val is a char and the compiler is generating some funky code...


Code: [Select]

int main(int argc, char *argv[])
{
       int fd_mem;
       volatile char *bios;
       unsigned long off,valint;
       unsigned short val;

       if ((fd_mem = open("/dev/mem", O_RDWR)) < 0) {
               perror("Can not open /dev/mem");
               exit(1);
       }

       bios = mmap(0, 0x40000, PROT_WRITE | PROT_READ, MAP_SHARED,
                   fd_mem, (off_t) (0x70000000));
       if (bios == MAP_FAILED) {
               perror("Error MMAP /dev/mem");
               exit(1);
       }

       sscanf(argv[1], "%x=%x", &off, &valint);
       val = valint&0xffff;
       printf("Offset: 0x%x=%02x\n", off, val);
       *(volatile unsigned short *) (bios + off) = val;
       munmap((void *) bios, 0x40000);
       return 0;
}


I can't do a 32-bit write can I?
« Last Edit: July 20, 2005, 07:38:01 pm by sbingner »

Offline RobM

  • Senior Member
  • A few posts under my belt.
  • *****
  • Posts: 48
Re: mtd sees flash
« Reply #29 on: July 20, 2005, 08:38:34 pm »
You could do a 32 bit write, but I think it will then be two 16 bit writes of indeterminate order.

What assembly is the compiler generating for your assignment?  (gcc -S)

Offline sbingner

  • Administrator
  • Veteran.
  • *****
  • Posts: 1301
Re: mtd sees flash
« Reply #30 on: July 21, 2005, 05:30:12 am »
Quote
You could do a 32 bit write, but I think it will then be two 16 bit writes of indeterminate order.

What assembly is the compiler generating for your assignment?  (gcc -S)


http://downloads.phathack.com/sbingner/debugw.S.gz

Offline bushing

  • Senior Member
  • Needs to get outside.
  • *****
  • Posts: 119
  • props to my peeps
Re: mtd sees flash
« Reply #31 on: July 21, 2005, 12:48:07 pm »
Quote

http://downloads.phathack.com/sbingner/debugw.S.gz



Here is your code:
Code: [Select]

;       *(volatile unsigned short *) (bios + off) = val;
       ldr
r3, [fp, #-28]

ldr
r2, [fp, #-32]

add
r3, r3, r2

ldr
r2, [fp, #-40]

mov
r1, r2, lsr #16

mov
r2, r1
@ movhi

strb
r2, [r3, #0]

mov
r2, r2, asr #8

strb
r2, [r3, #1]


Note the strb -- store byte -- instructions it generates.

Here's the code I would have tried:
Code: [Select]

;  volatile unsigned short *bios;
;#define WRITE_ADDR(x,y) bios[((x & 0x7FFF)<<1) | ((x & 0x8000) >> 15)]=(y)
;  WRITE_ADDR(0x555,0xAA);

       mov     r3, #5440
       add     r3, r3, #20
       ldr     r2, [fp, #-20]
       add     r3, r3, r2
       mov     r1, #170
       mov     r2, r1  @ movhi
       strh    r2, [r3, #0]    @ movhi


Note how it generates a "strh" instruction.  I think that you really want to use an array reference here, and I think that that macro I mentioned will do the proper mangling of the address bits -- but it's untested.

I say "would" have tested up there, because I think I somehow fried my PB this morning.  ;( I can't get it to power on anymore, and I'm not sure if I will bother to replace it, since I have other (incompatible) car audio equipment I am drooling over ...

That having been said, I'm gonna start another thread with my Last Great Idea... maybe someone can get it to work!

-b

Offline RobM

  • Senior Member
  • A few posts under my belt.
  • *****
  • Posts: 48
Re: mtd sees flash
« Reply #32 on: July 21, 2005, 07:55:18 pm »
Quote

http://downloads.phathack.com/sbingner/debugw.S.gz


What compiler are you using?  2.95?  I'm using 3.4.3 and it generates strh (16-bit half-word stores) with your code for -Os, -O0 and -O3.

Offline sbingner

  • Administrator
  • Veteran.
  • *****
  • Posts: 1301
Re: mtd sees flash
« Reply #33 on: July 22, 2005, 12:45:01 am »
Quote

What compiler are you using?  2.95?  I'm using 3.4.3 and it generates strh (16-bit half-word stores) with your code for -Os, -O0 and -O3.


I'm using uclibc-gcc 2.95.3 but I have glibc-gcc as well can can see if it does it the right way

Be cool if that was the root of the repetitions, could even have something to do with everything locking up when I do a chip erase?

I'll test when I get home

Offline sbingner

  • Administrator
  • Veteran.
  • *****
  • Posts: 1301
Re: mtd sees flash
« Reply #34 on: July 22, 2005, 07:25:58 am »
sweet, compiled w/ new gcc (made a huge file)  and did the following:

Code: [Select]

/ # ./debugwc 1554=aa; ./debugwc AA8=55 ;./debugwc 1554=a0; ./debugw 20=cedf
Offset: 0x1554=aa
Offset: 0xaa8=55
Offset: 0x1554=a0
Offset: 0x20=cedf
/ # ./debugr 0x20
Offset: 20=cedf


now I need to work on making it work en masse and figure out how to not lock up kernels on erase ;)

Offline sbingner

  • Administrator
  • Veteran.
  • *****
  • Posts: 1301
Re: mtd sees flash
« Reply #35 on: July 22, 2005, 09:19:50 am »
I keep getting errors like the following, do you have any idea what would cause it?  It manages to program all the blocks it tries to just fine, but it keeps crashing.   Also, erase operations keep making the kernel crash... is there anything you know of that can tell the kernel to ignore that area of memory or something perhaps?

Code: [Select]

Setting 0x0d=0xe3a0
0x0d=0xe3a0
Setting 0x0e=0x3807
0x0e=0x3807
Setting 0x0f=0xe283
0x0f=0xe283
Setting 0x10=0x3000
0x10=0x3000                                                                                                                  
Setting 0x11=0xe582                                                                                                          
0x11=0xe582                                                                                                                  
Setting 0x12=0xf00e                                                                                                          
0x12=0xf0pc : [<fffec0d8>]    lr : [<00028064>]    Not tainted                                                                
0e                                                                                                                            
Setting 0x13=0xe1a0                                                                                                          
0x13=0xe1a0                                                                                                                  
Setting 0x14=0x3200                                                                                                          
0x14=0x3200                                                                                                                  
Setting 0x15=0xe060                                                                                                          
0x15=0xe060                                                                                                                  
Setting 0x16=0x0000                                                                                                          
0x16=0x0000                                                                                                                  
Setting 0x17=0xe353                                                                                                          
0x17=0xe353                                                                                                                  
Setting 0x18=0xf00e                                                                                                          
0x18=0xf00e                                                                                                                  
Setting 0x19=0xd1a0                                                                                                          
0x19=0xd1a0                                                                                                                  
Setting 0x1a=0x3001                                                                                                          
0x1a=0x3001                                                                                                                  
Setting 0x1b=0xe253                                                                                                          
0x1b=0xe253                                                                                                                  
Setting 0x1c=0xfffd                                                                                                          
0x1c=0xfffd                                                                                                                  
Setting 0x1d=0x1aff                                                                                                          
0x1d=0x1aff                                                                                                                  
Setting 0x1e=0xf00e                                                                                                          
0x1e=0xf00e                                                                                                                  
Setting 0x1f=0xe1a0                                                                                                          
0x1f=0xe1a0                                                                                                                  
Setting 0x20=0x2043                                                                                                          
0x20=0x2043                                                                                                                  
Setting 0x21=0xe3a0                                                                                                          
0x21=0xe3a0                                                                                                                  
Setting 0x22=0x2102                                                                                                          
0x22=0x2102                                                                                                                  
sp : bffff6cc  ip : bffffc50  fp : bffffc4c                                                                                  
r10: 00000001  r9 : 000798a4  r8 : 000081c4                                                                                  
r7 : bffffcac  r6 : 00000001  r5 : 00000005  r4 : 00020400                                                                    
r3 : 00078a54  r2 : bffffc58  r1 : 0005d40c  r0 : 00078778                                                                    
Flags: Nzcv  IRQs on  FIQs on  Mode USER_32  Segment user                                                                    
Control: 217D  Table: C0C44015  DAC: 00000015                                                                                
Segmentation fault      

Offline sbingner

  • Administrator
  • Veteran.
  • *****
  • Posts: 1301
Re: mtd sees flash
« Reply #36 on: July 22, 2005, 09:22:28 am »
Oh yea, this is what I'm using to write....
Code: [Select]

#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define UADDR1 0xAAA
#define UADDR2 0x555

int main(int argc, char *argv[])
{
       int fd_mem, fd_flash, i, i2;
       volatile unsigned short *bios, *flash;
       unsigned long off,valint;
       unsigned short val, wrote;

       if ((fd_mem = open("/dev/mem", O_RDWR)) < 0) {
            perror("Can not open /dev/mem");
            exit(1);
       }

       if ((fd_flash = open("flash.rom", O_RDONLY)) < 0) {
            perror("Can not open flash.rom");
            exit(1);
       }

       bios = mmap(0, 0x20000, PROT_WRITE | PROT_READ, MAP_SHARED,
                fd_mem, (off_t) (0x70000000));
       if (bios == MAP_FAILED) {
            perror("Error MMAP /dev/mem");
            exit(1);
       }

       flash = mmap(0, 0x20000, PROT_READ, MAP_SHARED,
                fd_flash, (off_t) (0x0));
       if (flash == MAP_FAILED) {
            perror("Error MMAP flash.rom");
            exit(1);
       }


       /* Enter unlock bypass mode */
       bios[UADDR1] = 0xAA;
       bios[UADDR2] = 0x55;
       bios[UADDR1] = 0x20;

       for (i=0x0;i<0x10000;i++) {
            if (bios[i] == 0xffff) {
              wrote = flash[i];
              printf("Setting 0x%02x=0x%04x\n", i, wrote);
              bios[0] = 0xA0;
              bios[i] = wrote;
              usleep(100);
              while ((val = bios[i]) != wrote) {
                 printf("0x%02x=0x%04x\n", i, val);
                 usleep(100);
              }
              printf("0x%02x=0x%04x\n", i, val);
            } else {
              printf("0x%02x isn't erased\n", i);
            }
       }
       /* Exit unlock bypa s s mode */
       bios[0] = 0x90;
       bios[0] = 0x00;

       munmap((void *) bios, 0x20000);
       munmap((void *) flash, 0x20000);
       return 0;
}


http://downloads.phathack.com/sbingner/flashfile.S.gz
« Last Edit: July 22, 2005, 09:32:39 am by sbingner »

Offline bushing

  • Senior Member
  • Needs to get outside.
  • *****
  • Posts: 119
  • props to my peeps
Re: mtd sees flash
« Reply #37 on: July 22, 2005, 03:39:34 pm »
I'm having trouble following the error message ... it looks like you're getting the kernel oops mixed with the output ... wanna run dmesg and see if you can get a cleaned up version?

Also, can you put up the precompiled version in the downloads section?  If I can disassemble it, I can see what instruction that PC is pointing to...

-b

Offline bushing

  • Senior Member
  • Needs to get outside.
  • *****
  • Posts: 119
  • props to my peeps
Re: mtd sees flash
« Reply #38 on: July 22, 2005, 03:45:04 pm »
Any particular reason you're using mmap to read in the flash file?  that just seems like it's adding one more place for a seg fault.  why not change it to use read? something like this:

Code: [Select]

#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define UADDR1 0xAAA
#define UADDR2 0x555

int main(int argc, char *argv[])
{
       int fd_mem, fd_flash, i, i2;
       volatile unsigned short *bios, *flash;
       unsigned long off,valint;
       unsigned short val, wrote;

       if ((fd_mem = open("/dev/mem", O_RDWR)) < 0) {
            perror("Can not open /dev/mem");
            exit(1);
       }

       if ((fd_flash = open("flash.rom", O_RDONLY)) < 0) {
            perror("Can not open flash.rom");
            exit(1);
       }

       bios = mmap(0, 0x20000, PROT_WRITE | PROT_READ, MAP_SHARED,
                fd_mem, (off_t) (0x70000000));
       if (bios == MAP_FAILED) {
            perror("Error MMAP /dev/mem");
            exit(1);
       }

       /* Enter unlock byp butt mode */
       bios[UADDR1] = 0xAA;
       bios[UADDR2] = 0x55;
       bios[UADDR1] = 0x20;

       for (i=0x0;i<0x10000;i++) {
            if (bios[i] == 0xffff) {
//               wrote = flash[i];
              read(flash_fd,&wrote,2);
              printf("Setting 0x%02x=0x%04x\n", i, wrote);
              bios[0] = 0xA0;
              bios[i] = wrote;
              usleep(100);
              while ((val = bios[i]) != wrote) {
                 printf("0x%02x=0x%04x\n", i, val);
                 usleep(100);
              }
              printf("0x%02x=0x%04x\n", i, val);
            } else {
              printf("0x%02x isn't erased\n", i);
            }
       }
       /* Exit unlock bypa s s mode */
       bios[0] = 0x90;
       bios[0] = 0x00;

       munmap((void *) bios, 0x20000);
//        munmap((void *) flash, 0x20000);
       return 0;
}  
« Last Edit: July 22, 2005, 07:57:09 pm by bushing »

Offline RobM

  • Senior Member
  • A few posts under my belt.
  • *****
  • Posts: 48
Re: mtd sees flash
« Reply #39 on: July 22, 2005, 04:00:56 pm »
The .s looks good, but you should use the WRITE_ADDR macro bushing posted eariler to write the control instructions to the flash chip (the data should be written without it because that's how the CPU sees the flash).

#define WRITE_ADDR(x,y) bios[(((x) & 0x7FFF)<<1) | (((x) & 0x8000) >> 15)]=(y)

So instead of:

 bios[UADDR1] = 0xAA;

You'd do:

 WRITE_ADDR(UADDR1, 0xAA);

I don't know if that will solve your segfaulting issue, but it will properly twiddle the lines on the Flash chip.

Also, because only lines A[1:15] are connected, you should only write 0x10000 bytes (0x8000 words) to the chip (A[16] isn't connected, so that just wraps around again).