Project Home
Project Home
Trackers
Trackers
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - align physical memory: (5 Items)
   
align physical memory  
Hi every one,

I would like to get physical address of share memory. My code likes this:
 1. Create a share memory using shm_open();
 2. Using shm_ctl() to set attribute of that share memory
 3. Map memory object by mmap();
 4. Get physical address of this memory by mem_offset();

My problem is that, the physical address is not align to the size of memory. How can I align this physical address?

 For example: 
 - memsize = 4KBytes, the physical address must be multiples of 0x1000
 - memsize = 8MBytes, the physical address must be multiples of 0x800000

Thanks.

Zodiac
Re: align physical memory  
Hi,

You have to allocate 4KBytes + 0x1000 for your first example. When you get 
physical address just increase it to be multiples of 0x1000:

ptr = (ptr + 0x1000) & ~0xfff;

In general case:

ptr = ptr - (ptr % align) + align;

-- 
Respectfully,
Oleg

> Hi every one,
> 
> I would like to get physical address of share memory. My code likes
> this: 1. Create a share memory using shm_open();
>  2. Using shm_ctl() to set attribute of that share memory
>  3. Map memory object by mmap();
>  4. Get physical address of this memory by mem_offset();
> 
> My problem is that, the physical address is not align to the size of
> memory. How can I align this physical address?
> 
>  For example:
>  - memsize = 4KBytes, the physical address must be multiples of 0x1000
>  - memsize = 8MBytes, the physical address must be multiples of
> 0x800000
> 
> Thanks.
> 
> Zodiac
> 
> 
> 
> _______________________________________________
> 
> QNX4 Community Support
> http://community.qnx.com/sf/go/post83982
Re: align physical memory  
> Hi,
> 
> You have to allocate 4KBytes + 0x1000 for your first example. When you get 
> physical address just increase it to be multiples of 0x1000:
> 
> ptr = (ptr + 0x1000) & ~0xfff;
> 
> In general case:
> 
> ptr = ptr - (ptr % align) + align;
> 
> -- 
> Respectfully,
> Oleg
> 


Hi Oleg, 

Thanks for your reply.

But I have not understand your instruction very clearly yet.

Here is my code:

       int ret;
       int fd_shm;
       void * p_shm;
	int memsize;
	
       memsize = 4*1024;

	fd_shm = shm_open( "/dev/shm/mysharemem", O_RDWR | O_CREAT, 0777 );
	if( fd_shm == -1 ) {
		printf( "Create share memory failed:%s\n",strerror( errno ) );
		return EXIT_FAILURE;
	}

       /* Set the memory object's size */
	ret = shm_ctl(fd_shm,SHMCTL_ANON | SHMCTL_GLOBAL,0,memsize);
	if(ret == -1){
		printf( "shm_ctl error: %s\n",strerror( errno ) );
		close( fd_shm );
		shm_unlink(  "/dev/shm/mysharemem");
		return EXIT_FAILURE;
	}

	/* Map the memory object */
	p_shm = mmap( 0, memsize,
				PROT_READ | PROT_WRITE,
				MAP_SHARED, fd_shm, 0 );
	if( p_shm == MAP_FAILED ) {
		printf("mmap failed: %s\n", strerror( errno ) );
		close( fd_shm );
		shm_unlink( "/dev/shm/mysharemem" );
		return EXIT_FAILURE;
	}

	ret = mem_offset(p_shm, NOFD, memsize, &shm_addr, 0 );
	if(ret != 0){
		printf("mem_offset failed: %s\n",	strerror( errno ) );
		close( fd_shm );
		shm_unlink( "/dev/shm/mysharemem" );
		return EXIT_FAILURE;
	}


So, how can I increase this physical address to be multiples of 0x1000?

Regard,
Zodiac.

RE: align physical memory  

> -----Message d'origine-----
> De : h p [mailto:community-noreply@qnx.com]
> Envoyé : 15 mars 2011 11:29
> À : qnx4-community
> Objet : Re: align physical memory
> 
> 
> > Hi,
> >
> > You have to allocate 4KBytes + 0x1000 for your first example. When you
> > get physical address just increase it to be multiples of 0x1000:
> >
> > ptr = (ptr + 0x1000) & ~0xfff;
> >
> > In general case:
> >
> > ptr = ptr - (ptr % align) + align;
> >
> > --
> > Respectfully,
> > Oleg
> >
> 
> 
> Hi Oleg,
> 
> Thanks for your reply.
> 
> But I have not understand your instruction very clearly yet.
> 
> Here is my code:
> 
>        int ret;
>        int fd_shm;
>        void * p_shm;
> 	int memsize;
> 
>        memsize = 4*1024;
> 
> 	fd_shm = shm_open( "/dev/shm/mysharemem", O_RDWR |
> O_CREAT, 0777 );
> 	if( fd_shm == -1 ) {
> 		printf( "Create share memory failed:%s\n",strerror( errno ) );
> 		return EXIT_FAILURE;
> 	}
> 
>        /* Set the memory object's size */
> 	ret = shm_ctl(fd_shm,SHMCTL_ANON |
> SHMCTL_GLOBAL,0,memsize);
> 	if(ret == -1){
> 		printf( "shm_ctl error: %s\n",strerror( errno ) );
> 		close( fd_shm );
> 		shm_unlink(  "/dev/shm/mysharemem");
> 		return EXIT_FAILURE;
> 	}
> 
> 	/* Map the memory object */
> 	p_shm = mmap( 0, memsize,
> 				PROT_READ | PROT_WRITE,
> 				MAP_SHARED, fd_shm, 0 );
> 	if( p_shm == MAP_FAILED ) {
> 		printf("mmap failed: %s\n", strerror( errno ) );
> 		close( fd_shm );
> 		shm_unlink( "/dev/shm/mysharemem" );
> 		return EXIT_FAILURE;
> 	}
> 
> 	ret = mem_offset(p_shm, NOFD, memsize, &shm_addr, 0 );
> 	if(ret != 0){
> 		printf("mem_offset failed: %s\n",	strerror( errno ) );
> 		close( fd_shm );
> 		shm_unlink( "/dev/shm/mysharemem" );
> 		return EXIT_FAILURE;
> 	}
> 
> 
> So, how can I increase this physical address to be multiples of 0x1000?

Instead of requesting memsize to be 4x1024 do ( 4*1024 + alignmentrequest ). In your case it would give you 4*1024 + 
0x1000. The memory block you would get would be of 8K. What ever the alignment of the block is you can set a pointer 
within that block to comply with the aligment requirement.

For example if you the address point to physical address 0x10010.  Then you know to be aligned you need to set our 
pointer to 0x11000, and you know that there is enough space after 0x11000 because you resquested 8k so the last memory 
location would be at 0x12010.
> 
> Regard,
> Zodiac.
> 
> 
> 
> 
> 
> _______________________________________________
> 
> QNX4 Community Support
> http://community.qnx.com/sf/go/post84003
> 
Re: RE: align physical memory  
> 
> Instead of requesting memsize to be 4x1024 do ( 4*1024 + alignmentrequest ). 
> In your case it would give you 4*1024 + 0x1000. The memory block you would get
>  would be of 8K. What ever the alignment of the block is you can set a pointer
>  within that block to comply with the aligment requirement.
> 
> For example if you the address point to physical address 0x10010.  Then you 
> know to be aligned you need to set our pointer to 0x11000, and you know that 
> there is enough space after 0x11000 because you resquested 8k so the last 
> memory location would be at 0x12010.
>

Thanks Mario, I got it :)