* mapping large amount of memory on physical addresses
@ 2005-03-08 16:15 scarayol
0 siblings, 0 replies; 2+ messages in thread
From: scarayol @ 2005-03-08 16:15 UTC (permalink / raw)
To: linux-mm
Hello,
Could you help me : I work on embedded Linux on a MPC885 processor
(PowerPC).
In the user space, I want to map 2 differents types of memory (with
separate components) to make data transferts between each others. So, i
want to affect each memory with their physical adress in the memory map
with the mmap instruction. It's the only way I found to affect the good
memory area to the physical component. Do you know another way ?
I mapped about 1 MB for a MC Memory and 1MB for DV memory. In my last code,
the size are shorter. For that, I reserved high Ram addresses by the use of
'mem=6M' (in u-boot) to reserve 2MB for my memories.
The successive mmap succeed but when I test the memory area with successive
writing and reading, several differents things appear : the program seems
blocked or it creates a kernel panic.
-> Why can it create a kernel panic though the memory is essentially out of
the kernel area and I allocate few memory ? And what's could happen ?
-> In the mapped zones, I realize that I can't use the first eight bytes
(writing doesn't work) : why ?
In the final application, MC will have a size of 2MB and DV a size of about
36MB. Is there any problem of mapping on physical addresses such a size of
36MB, is there any restrictions with the mmap instruction?
What the maximum size of allocating with malloc in user space, can i
allocate 36MB in a contiguous manner ?
You can see my code below. It works but only if secteur <= 2 and when I
increase this number, the problems begin. What is it wrong ?
Thank you really for your help.
Best regards.
----------------------------------------------------------
Sophie CARAYOL
Tel: +33 2 98 10 30 06
mailto:scarayol@assystembrime.com
----------------------------------------------------------
#define MEM_FILE "/dev/mem"
define MC_START 0x600000
#define MC_SIZE 0xFF000
#define DV_START 0x700000
#define DV_SIZE 0x200000
/* --------------------------------------- MC memory
----------------------------------------- */
// mapping of MC
// opening file descriptor associated with MC
if ((MC_fd = open(MEM_FILE,O_RDWR | O_SYNC))<0)
{
perror("Opening file descriptor MC");
return false;
}
pmyMC= (SecteurMC * )mmap((void *) MC_START, (size_t) MC_SIZE, PROT_READ
| PROT_WRITE, MAP_SHARED | MAP_FIXED, MC_fd, 0);
if (pmapMC == MAP_FAILED)
{
printf("Erreur de mmap pour MC:%s\n", strerror(errno));
close(MC_fd);
return false;
}
/* --------------------------------------- DV memory
---------------------------------------------- */
// mapping of DV
// opening file descriptor associated with DV
if ((DV_fd = open(MEM_FILE,O_RDWR | O_SYNC))<0)
{
perror("Opening file descriptor DV");
return false;
}
pmyDV = (Disque * )mmap((void *) DV_START, (size_t) DV_SIZE, PROT_READ |
PROT_WRITE, MAP_SHARED | MAP_FIXED, DV_fd, 0);
if (pmyDV == MAP_FAILED)
{
printf("Erreur de mmap pour DV:%s\n", strerror(errno));
close(DV_fd);
return false;
}
memory_mapped = 1;
// test de la memoire MC
for (secteur = 0; secteur < 2; secteur++)
{
test_memory_MC(0xAA, secteur);
}
printf("--- Memoire MC OK ---\n");
// test de la memoire DV
for (secteur = 0; secteur < 2; secteur++)
{
test_memory_DV(0x55, 0, secteur);
}
printf("--- Memoire DV OK ---\n");
release_memory();
/*******************************************************************************************************/
bool test_memory_MC(u8 value,u16 num_secteur)
{
#define OFFSET_MC 0
#define NB_OCTET MAX_MOT*sizeof(u16)
int i, piste, secteur;
u8 pb = false;
u16 TMot[MAX_MOT], value_MC;
u16 * pTab;
if (memory_mapped)
{
/* ------------------------------ test de MC
---------------------------------------------*/
pTab = (u16 *)malloc(NB_OCTET);
pTab = (u16 *)pmyMC;
pTab += num_secteur*MAX_MOT;
printf("pTab : %8X, OFFSET_MC = %i\n",pTab, OFFSET_MC);
// ecriture
memset(pTab, value,MAX_MOT*sizeof(u16));
// reading
memcpy(TMot,pTab,MAX_MOT*sizeof(u16));
value_MC = ((u16)value << 8) + value;
// comparing reading / writing
for (i = 0 + OFFSET_MC; i < MAX_MOT; i++)
{
if (TMot[i] != value_MC)
{
printf("Pb MC !!i = %i, adr =%8X, TMot = %X\n",i,pTab+i ,
TMot[i]);
pb = true;
}
}
if (pb == true)
{
return false;
}
} /* if (memory_mapped) */
return true;
} // fin de test_memory_MC()
/*
************************************************************************
* Function : test_memory_DV
************************************************************************
* Purpose : test de la memoire DV mappee
* Restrictions: a virer au final
*
************************************************************************
* Parameters :
* IN : value
*
* OUT : aucun
*
*
************************************************************************
*/
bool test_memory_DV(u8 value, u8 piste, u16 secteur)
{
#define OFFSET_DV 0
#define NB_OCTET MAX_MOT*sizeof(u16)
int i;
u8 pb = false;
u16 TMot[MAX_MOT], value_DV;
u16 * pTab;
if (memory_mapped)
{
/* ------------------------------ test de DV
---------------------------------------------*/
pTab = (u16 *)malloc(NB_OCTET);
pTab = (u16 *)pmyDV;
pTab += (piste*MAX_SECTEUR + secteur)*MAX_MOT;
printf(" sur piste =%i, secteur =%i - pmyDV: %8X\n",piste,
secteur,pTab);
// writing
memset(pTab, value,MAX_MOT*sizeof(u16));
value_DV = ((u16)value << 8) + value;
// reading and comparing
memcpy(TMot,pTab,NB_OCTET);
for (i = 0 + OFFSET_DV; i < MAX_MOT; i++)
{
if (TMot[i] != value_DV)
{
printf("Pb DV !!i = %i, adr =%8X, TMot = %X\n",i,pTab+i ,
TMot[i]);
pb = true;
}
}
if (pb == true)
{
return false;
}
} /* if (memory_mapped) */
return true;
} // fin de test_memory_DV()
/*
************************************************************************
* Function : release_memory
************************************************************************
* Purpose : Liberation des memoires mappees
* Restrictions:
*
************************************************************************
* Parameters :
* IN : aucun
*
* OUT : aucun
*
*
************************************************************************
*/
void release_memory(void)
{
if (memory_mapped)
{
munmap((void*)MC_START,(size_t) MC_SIZE);
munmap((void*)DV_START,(size_t) DV_SIZE);
close(MC_fd);
close(DV_fd);
memory_mapped = 0;
}
return;
} // fin de release_memory()
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"aart@kvack.org"> aart@kvack.org </a>
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: mapping large amount of memory on physical addresses
@ 2005-04-12 6:23 scarayol
0 siblings, 0 replies; 2+ messages in thread
From: scarayol @ 2005-04-12 6:23 UTC (permalink / raw)
To: linux-mm
Hello,
I wrote 2 drivers very close to the driver /dev/mem in order to write in
the physical memory at specific addresses. For that I use mmap
instruction.
I want to know, if there is a limit for the maximum amount of physical
memory that I can map with a single the mmap instruction.
My platform is a MPC885 (PowerPC) on a MPC885ADS board and I have a 2.4.26
kernel.
Now I map 2 zones of 1MB (first zone at 6MB and the 2nd at 7MB:I have 8MB
on my board), each on the same physical component (to have data
transfertsbetween the two zones). But, in the final application (on our
own card) one zone will represent 2MB for a component of 2MB and and the
other 216 MB for another component of 256MB. So, it will let 40MB for the
kernel, FileSystem, etc.
How can I be sure that linux let me reserve all these physical addresses ?
If I use the command 'mem=6M' in u-boot to force Linux in the first 6M,
the
mem driver accesses don't work any more.
If mmap doesn't work for such an amount of memory (216 MB) how can I do ?
Last question: How could I verify the mapping by a shell command or a
memory dump... ?
Thank you really for your help.
----------------------------------------------------------
Sophie CARAYOL
TECHNOLOGIES & SYSTEMES
50 rue du President Sadate
F - 29337 QUIMPER CEDEX
Tel: +33 2 98 10 30 06
mailto:scarayol@assystembrime.com
----------------------------------------------------------
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"aart@kvack.org"> aart@kvack.org </a>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2005-04-12 6:23 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-03-08 16:15 mapping large amount of memory on physical addresses scarayol
2005-04-12 6:23 scarayol
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox