I am a Chinese, I am now facing a trouble about embeded linux on the EP7312 platform.
Do you have time to help me?
The trouble is:
On the EP7312 platform, I connected the M_DOC flash to CS(1), also the address:0x10000000,
in the file:hardware.h,I maped the address as the following:
#define NANDFLASH_BASE 0x10000000
#define NANDFLASH_START REVERSE_MAPPING(0x10000000)
#define NANDFLASH_SIZE 0x00002000
and in the file:edb7212-mm.c, I maped the IO as the following:
static struct map_desc edb7212_io_desc[] __initdata = {
/* virtual, physical, length, domain, r, w, c, b */
/* flash banks */
{ CLPS7111_VIRT_BASE, CLPS7111_PHYS_BASE, CLPS7111_BASE_SIZE, DOMAIN_IO, 1, 1, 0, 0 },
{ FLASH0_BASE, FLASH0_START, FLASH0_SIZE, DOMAIN_IO, 1, 1, 0, 0 },//12/31 zhangfq
{ NANDFLASH_BASE, NANDFLASH_START, NANDFLASH_SIZE, DOMAIN_IO, 1, 1, 0, 0 },
{ PS2_BASE, PS2_START, PS2_SIZE, DOMAIN_IO, 1, 1, 0, 0 },
{ ETHER_BASE, ETHER_START, ETHER_SIZE, DOMAIN_IO, 1, 1, 0, 0 },
//zhangfq and luojianwen for MT8888 device
{ MT8888_BASE, MT8888_START, MT8888_SIZE, DOMAIN_IO, 1, 1, 0, 0 },
{ EXT_IO_BASE, EXT_IO_START, EXT_IO_SIZE, DOMAIN_IO, 1, 1, 0, 0 },
LAST_DESC
};
Then I created one char device /dev/docmem, write the device driver .../char/docmem.c as the following:
the mmap method is:
static int mmaptest_mmap(struct file *filp, struct vm_area_struct *vma)
{
unsigned long pos, page;
unsigned long start = (unsigned long)vma->vm_start;
unsigned long size = (unsigned long)(vma->vm_end-vma->vm_start);
//struct mm_struct *mm= current->mm;
//pgd_t *dir;
//pmd_t *pmd;
//pte_t *pte;
if (size>MMT_BUF_SIZE)
return -EINVAL;
//off= vma->vm_pgoff << PAGE_SHIFT;
pos = 0;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
//vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) & ~(L_PTE_CACHEABLE | L_PTE_BUFFERABLE) | L_PTE_USER);
//printk( "mmaptest_mmap:vm_page_prot:%x vm_start:%x off:%x\n", vma->vm_page_prot, vma->vm_start, off);
vma->vm_flags|= VM_IO;
//vma->vm_flags |= VM_RESERVED;
while (size > 0) {
if (remap_page_range(start, NANDFLASH_BASE+ pos, PAGE_SIZE, vma->vm_page_prot)){
printk("remap error !\n");
return -EAGAIN;
}
start+=PAGE_SIZE;
pos+=PAGE_SIZE;
size-=PAGE_SIZE;
}
//*(volatile char *)vma->vm_start= 0x1;
//dir= pgd_offset( mm, vma->vm_start);
//pmd= pmd_offset( dir, vma->vm_start);
//pte= pte_offset( pmd, vma->vm_start);
//printk( "mmaptest_mmap:*pgd:%x *pmd:%x *pte:%x pgd:%x pmd:%x pte:%x\n",
// *dir, *pmd, *pte, dir, pmd, pte);
test_mdoc( vma->vm_start);
return 0;
}
Finally, I wrote the test.c, hope that can mmap the DOC flash's 8k address space to my test process,
the code is:
int main (int argc, char *argv[])
{
char c;
int fd, i= 3;
unsigned long pMMapStart;
if ((fd = open("/dev/docmem", O_RDWR)) <= 0)//zhangfq 01/08 tmp->buffer
{
printf("Cannot open docmem !\n");
return -1;
}
printf( "test
pen /dev/docmem success\n");
pMMapStart = (unsigned long)mmap(0,0x2000, PROT_READ|PROT_WRITE, MAP_SHARED, fd,0);
if( pMMapStart== -1){ printf( "mmap fail\n"); exit(-1);};
fprintf(stderr, "virtual address: 0x%08x\n", pMMapStart);
c= *(volatile char *)(pMMapStart+ 0x1000);
printf("test:ID:%x \n", c);
sleep( 1);
do{
c= *(volatile char *)(pMMapStart+ 0x1046);
printf("toggle bits:%x \n", c);
sleep( 1);
}while( i-->0);
c= *(volatile char *)(pMMapStart+ 0x1006);
printf( "read:0x1006:%x\n", c);
printf( "start write...none\n");
*( volatile char *)(pMMapStart+ 0x1006)= 0x1d;
//*(volatile char *)(pMMapStart+ 0x1076)= 0xe2;
//printf( "0x1006:%x\n", c);
printf( "...test END \n");
close(fd);
return 0;
}
The result of running 'test' is: I can read correctly from 8k address space, but when to
write, the oops appears, even that they is the same address, such as pMMapStart+ 0x1006.the oops is:
virtual address: 0x40016000
test:ID:40
toggle bits:82
toggle bits:86
toggle bits:82
toggle bits:86
read:0x1006:1
start Unable to handle kernel paging request at virtual address bd2a504c
write...none
pgd = c1d08000
*pgd = 00000000, *pmd = 00000000
Internal error: Oops: 0
CPU: 0
pc : [<c003c594>] lr : [<c004bf84>]
sp : c1d0fef4 ip : c1d0ff08 fp : c1d0ff34
r10: c1d0e000 r9 : c1d0ffb8 r8 : 00000001
r7 : ffffffff r6 : 100010b3 r5 : 40017000 r4 : bd2a5044
r3 : c012b14c r2 : 00110011 r1 : 00000000 r0 : bd2a5044
Flags: nZCv IRQs on FIQs on Mode SVC_32 Segment user
Control: 017F Table: C1D08015 DAC: 00000015
Process test (pid: 44, stackpage=c1d0f000)
Code: e92dd810 e1a04000 (e5943008) e24cb004 e3530000
Stack:
c1d0fee0: c004bf84 c003c594 60000013 ffffffff c1d197a0 c1d0ff34 c1d0f
c1d0ff00: c004bf84 c003c598 00000000 c1d0e000 c1d197a0 c1d0e000 ffffffff 40017
c1d0ff20: ffffffff c1f912a0 c1d0ff5c c1d0ff38 c003b968 c004be54 c1f912bc c1d0e
c1d0ff40: c0100d0c c1f912a0 40017006 ffffffff c1d0ff90 c1d0ff60 c003baec c003b
c1d0ff60: c00341e0 00000000 c003ba78 40017006 c0100d0c c1d0ffb8 0000000f 02000
c1d0ff80: 40101ba8 c1d0ffb4 c1d0ff94 c003c50c c003ba88 e5c31000 00000001 4000c
c1d0ffa0: 0000017f 020006b4 00000000 c1d0ffb8 c0036604 c003c4dc 00000013 00000
c1d0ffc0: 0000001d 40017006 bffffddc 00000001 4000c350 0200032c 020006b4 02000
c1d0ffe0: 40101ba8 bffffda0 00000000 bffffd74 4005e3ec 02000610 60000010 fffff
Backtrace:
Function entered at [<c004be44>] from [<c003b968>]
Function entered at [<c003b8fc>] from [<c003baec>]
Function entered at [<c003ba78>] from [<c003c50c>]
Function entered at [<c003c4cc>] from [<c0036604>]
r8 = 020006B4 r7 = 0000017F r6 = 4000C350 r5 = 00000001
r4 = E5C31000
Segmentation fault
But in the driver docmem.c, I can write in the address space, as the following:
*(volatile char *)vma->vm_start= 0x1;
So the key trouble is: under the application, also the user space, I can't write in the 8k address space
mapped, but in kernel state, I can write.
By the way, if I maped the other address space in hardware.c, such as 0xfb000000, I can't read
the doc flash correctly, why happen that?
Best regards
zhang faquan
China