linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* how to allocate 9MB of memory in kernel ?
@ 2008-07-17  7:26 Misbah khan
  2008-07-17  7:51 ` Marco Stornelli
                   ` (2 more replies)
  0 siblings, 3 replies; 28+ messages in thread
From: Misbah khan @ 2008-07-17  7:26 UTC (permalink / raw)
  To: linuxppc-embedded


Hi all,

I need to allocate 9 MB of memory in to the kernel space which i need to
mmap for the application to access.

I need to know what could be the best possible way of doing the same.

Please share your experience in this regard .

Thank you in advance 

----Misbah <><
-- 
View this message in context: http://www.nabble.com/how-to-allocate-9MB-of-memory-in-kernel---tp18503022p18503022.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-17  7:26 how to allocate 9MB of memory in kernel ? Misbah khan
@ 2008-07-17  7:51 ` Marco Stornelli
  2008-07-17  8:34   ` Misbah khan
  2008-07-17  7:56 ` Arnd Bergmann
  2008-07-17  8:02 ` Sylvain Joyeau
  2 siblings, 1 reply; 28+ messages in thread
From: Marco Stornelli @ 2008-07-17  7:51 UTC (permalink / raw)
  To: Misbah khan; +Cc: linuxppc-embedded

Misbah khan ha scritto:
> Hi all,
> 
> I need to allocate 9 MB of memory in to the kernel space which i need to
> mmap for the application to access.
> 
> I need to know what could be the best possible way of doing the same.
> 
> Please share your experience in this regard .
> 
> Thank you in advance 
> 
> ----Misbah <><
You can use the mem option to tell to the kernel that you've got less 
ram you really have. However you can read Linux device drivers chapter 8 
"Obtaining Large Buffers" :).

Regards,

-- 
Marco Stornelli
Embedded Software Engineer
CoRiTeL - Consorzio di Ricerca sulle Telecomunicazioni
http://www.coritel.it

marco.stornelli@coritel.it
+39 06 72582838

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-17  7:26 how to allocate 9MB of memory in kernel ? Misbah khan
  2008-07-17  7:51 ` Marco Stornelli
@ 2008-07-17  7:56 ` Arnd Bergmann
  2008-07-17  8:19   ` Misbah khan
  2008-07-18  4:44   ` Misbah khan
  2008-07-17  8:02 ` Sylvain Joyeau
  2 siblings, 2 replies; 28+ messages in thread
From: Arnd Bergmann @ 2008-07-17  7:56 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: Misbah khan

On Thursday 17 July 2008, Misbah khan wrote:
> I need to allocate 9 MB of memory in to the kernel space which i need to
> mmap for the application to access.
> 
> I need to know what could be the best possible way of doing the same.
> 

If you don't need the memory to be physically contiguous, you can use
vmalloc to get the memory, but then you need to use remap_vmalloc_range
for mapping the memory into a user address space.

	Arnd <><

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-17  7:26 how to allocate 9MB of memory in kernel ? Misbah khan
  2008-07-17  7:51 ` Marco Stornelli
  2008-07-17  7:56 ` Arnd Bergmann
@ 2008-07-17  8:02 ` Sylvain Joyeau
  2008-07-17  8:41   ` Misbah khan
  2 siblings, 1 reply; 28+ messages in thread
From: Sylvain Joyeau @ 2008-07-17  8:02 UTC (permalink / raw)
  To: Misbah khan; +Cc: linuxppc-embedded

Misbah,

Please, give some more details about your application: the answer(s)
heavily depends on the kind of memory you want to allocate: contiguous
(implied in DMA purpose) or not (for process memory sharing only).

--
sj


2008/7/17 Misbah khan <misbah_khan@engineer.com>:
>
> Hi all,
>
> I need to allocate 9 MB of memory in to the kernel space which i need to
> mmap for the application to access.
>
> I need to know what could be the best possible way of doing the same.
>
> Please share your experience in this regard .
>
> Thank you in advance
>
> ----Misbah <><
> --
> View this message in context: http://www.nabble.com/how-to-allocate-9MB-o=
f-memory-in-kernel---tp18503022p18503022.html
> Sent from the linuxppc-embedded mailing list archive at Nabble.com.
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>



--=20
------------------
Sylvain JOYEAU
Freelance Engineer
Software RT-OS R&D
sylvain.joyeau@gmail.com
T=E9l: +33-(0)667 477 052
"A good idea is one side of the coin. The other side is the practical
usefulness". J. Liedke.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-17  7:56 ` Arnd Bergmann
@ 2008-07-17  8:19   ` Misbah khan
  2008-07-17  8:24     ` Arnd Bergmann
  2008-07-18  4:44   ` Misbah khan
  1 sibling, 1 reply; 28+ messages in thread
From: Misbah khan @ 2008-07-17  8:19 UTC (permalink / raw)
  To: linuxppc-embedded


vmalloc can only allocate 128k i guess where in i need 9MB allocated when
driver is inserted and would be released only when its removed. mapping to
user space is not a concern 

--- Misbah <><


Arnd Bergmann wrote:
> 
> On Thursday 17 July 2008, Misbah khan wrote:
>> I need to allocate 9 MB of memory in to the kernel space which i need to
>> mmap for the application to access.
>> 
>> I need to know what could be the best possible way of doing the same.
>> 
> 
> If you don't need the memory to be physically contiguous, you can use
> vmalloc to get the memory, but then you need to use remap_vmalloc_range
> for mapping the memory into a user address space.
> 
> 	Arnd <><
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> 
> 

-- 
View this message in context: http://www.nabble.com/how-to-allocate-9MB-of-memory-in-kernel---tp18503022p18503765.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-17  8:19   ` Misbah khan
@ 2008-07-17  8:24     ` Arnd Bergmann
  0 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2008-07-17  8:24 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: Misbah khan

On Thursday 17 July 2008, Misbah khan wrote:
> vmalloc can only allocate 128k i guess where in i need 9MB allocated when
> driver is inserted and would be released only when its removed. mapping to
> user space is not a concern 

The 128kb limitation is in kmalloc, not vmalloc. The latter is
specifically meant to have no limitations on the memory size
(other than the available resources), at the expense of having
to create a new virtual mapping.

	Arnd <><

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-17  7:51 ` Marco Stornelli
@ 2008-07-17  8:34   ` Misbah khan
  2008-07-17  9:04     ` Marco Stornelli
  0 siblings, 1 reply; 28+ messages in thread
From: Misbah khan @ 2008-07-17  8:34 UTC (permalink / raw)
  To: linuxppc-embedded


>>You can use the mem option to tell to the kernel that you've got less 
>>ram you really have. 
I really didnt got the point you made. Can you please elaborate it for my
understanding.
>>However you can read Linux device drivers chapter 8 
i dont need to allocate large memory at the boot time also vmalloc and
kmalloc i cant use as it can allocate free page up to 128kb, hence if you
could suggest me a better technique i would really appriciate .

---Misbah <><


Marco Stornelli wrote:
> 
> Misbah khan ha scritto:
>> Hi all,
>> 
>> I need to allocate 9 MB of memory in to the kernel space which i need to
>> mmap for the application to access.
>> 
>> I need to know what could be the best possible way of doing the same.
>> 
>> Please share your experience in this regard .
>> 
>> Thank you in advance 
>> 
>> ----Misbah <><
> You can use the mem option to tell to the kernel that you've got less 
> ram you really have. However you can read Linux device drivers chapter 8 
> "Obtaining Large Buffers" :).
> 
> Regards,
> 
> -- 
> Marco Stornelli
> Embedded Software Engineer
> CoRiTeL - Consorzio di Ricerca sulle Telecomunicazioni
> http://www.coritel.it
> 
> marco.stornelli@coritel.it
> +39 06 72582838
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> 
> 

-- 
View this message in context: http://www.nabble.com/how-to-allocate-9MB-of-memory-in-kernel---tp18503022p18503965.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-17  8:02 ` Sylvain Joyeau
@ 2008-07-17  8:41   ` Misbah khan
  0 siblings, 0 replies; 28+ messages in thread
From: Misbah khan @ 2008-07-17  8:41 UTC (permalink / raw)
  To: linuxppc-embedded



In have a sdram of size 9MB which i would map to kernel space (ioremap woul=
d
do that ) the whole 9 MB kernel virtual memory i need to map to the
application , the application would read when driver has complited writing
and vice versa this implimentation would be in a circular buffer type. The
size of my RAM is 128 MB=20



Sylvain Joyeau wrote:
>=20
> Misbah,
>=20
> Please, give some more details about your application: the answer(s)
> heavily depends on the kind of memory you want to allocate: contiguous
> (implied in DMA purpose) or not (for process memory sharing only).
>=20
> --
> sj
>=20
>=20
> 2008/7/17 Misbah khan <misbah_khan@engineer.com>:
>>
>> Hi all,
>>
>> I need to allocate 9 MB of memory in to the kernel space which i need to
>> mmap for the application to access.
>>
>> I need to know what could be the best possible way of doing the same.
>>
>> Please share your experience in this regard .
>>
>> Thank you in advance
>>
>> ----Misbah <><
>> --
>> View this message in context:
>> http://www.nabble.com/how-to-allocate-9MB-of-memory-in-kernel---tp185030=
22p18503022.html
>> Sent from the linuxppc-embedded mailing list archive at Nabble.com.
>>
>> _______________________________________________
>> Linuxppc-embedded mailing list
>> Linuxppc-embedded@ozlabs.org
>> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>>
>=20
>=20
>=20
> --=20
> ------------------
> Sylvain JOYEAU
> Freelance Engineer
> Software RT-OS R&D
> sylvain.joyeau@gmail.com
> T=C3=A9l: +33-(0)667 477 052
> "A good idea is one side of the coin. The other side is the practical
> usefulness". J. Liedke.
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>=20
>=20

--=20
View this message in context: http://www.nabble.com/how-to-allocate-9MB-of-=
memory-in-kernel---tp18503022p18504063.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-17  8:34   ` Misbah khan
@ 2008-07-17  9:04     ` Marco Stornelli
  0 siblings, 0 replies; 28+ messages in thread
From: Marco Stornelli @ 2008-07-17  9:04 UTC (permalink / raw)
  To: Misbah khan; +Cc: linuxppc-embedded

Misbah khan ha scritto:
>>> You can use the mem option to tell to the kernel that you've got less 
>>> ram you really have. 
> I really didnt got the point you made. Can you please elaborate it for my
> understanding.
If you've got 128MB of ram you can use the mem option to tell to the 
kernel the it can use only (128 - 9) MB of ram, after that you can use 
that chunk of ram, however I think it's not the case if your goal is to 
use a sdram as you said in the previous message.

>>> However you can read Linux device drivers chapter 8 
> i dont need to allocate large memory at the boot time also vmalloc and
> kmalloc i cant use as it can allocate free page up to 128kb, hence if you
> could suggest me a better technique i would really appriciate .
> 
The problem about 128KB is only for kmalloc. If I understood correctly 
you need only to remap the 9MB of your sdram.

> ---Misbah <><
> 
> 
> Marco Stornelli wrote:
>> Misbah khan ha scritto:
>>> Hi all,
>>>
>>> I need to allocate 9 MB of memory in to the kernel space which i need to
>>> mmap for the application to access.
>>>
>>> I need to know what could be the best possible way of doing the same.
>>>
>>> Please share your experience in this regard .
>>>
>>> Thank you in advance 
>>>
>>> ----Misbah <><
>> You can use the mem option to tell to the kernel that you've got less 
>> ram you really have. However you can read Linux device drivers chapter 8 
>> "Obtaining Large Buffers" :).
>>
>> Regards,
>>
>> -- 
>> Marco Stornelli
>> Embedded Software Engineer
>> CoRiTeL - Consorzio di Ricerca sulle Telecomunicazioni
>> http://www.coritel.it
>>
>> marco.stornelli@coritel.it
>> +39 06 72582838
>> _______________________________________________
>> Linuxppc-embedded mailing list
>> Linuxppc-embedded@ozlabs.org
>> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>>
>>
> 


-- 
Marco Stornelli
Embedded Software Engineer
CoRiTeL - Consorzio di Ricerca sulle Telecomunicazioni
http://www.coritel.it

marco.stornelli@coritel.it
+39 06 72582838

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
       [not found] <mailman.2280.1216290829.2883.linuxppc-embedded@ozlabs.org>
@ 2008-07-17 20:15 ` Siva Prasad
  0 siblings, 0 replies; 28+ messages in thread
From: Siva Prasad @ 2008-07-17 20:15 UTC (permalink / raw)
  To: linuxppc-embedded

Misbah,

May be I am missing some thing. I am sure you looked at the obvious.

Is there any reason why you are not using blocked read in application
pthread (a separate thread if necessary), so that driver provides that
value back to the application. Isn't that the right way to implement?

- Siva

Misbah khan <misbah_khan@engineer.com> wrote:

In have a sdram of size 9MB which i would map to kernel space (ioremap
would
do that ) the whole 9 MB kernel virtual memory i need to map to the
application , the application would read when driver has complited
writing
and vice versa this implimentation would be in a circular buffer type.
The
size of my RAM is 128 MB=20

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-17  7:56 ` Arnd Bergmann
  2008-07-17  8:19   ` Misbah khan
@ 2008-07-18  4:44   ` Misbah khan
  2008-07-18  6:50     ` Marco Stornelli
  1 sibling, 1 reply; 28+ messages in thread
From: Misbah khan @ 2008-07-18  4:44 UTC (permalink / raw)
  To: linuxppc-embedded


This i am not very sure with  :-
Can we allocate 9MB using vmalloc and assure it to be low memory and not
highmem ?
can we ioremap 9 MB SDRAM to kernel virtual ?
can we use vmalloc and do mmap to that allocated memory ,if the pages are
not continues then is it going to concern mapping to user space ?

---Misbah <><



Arnd Bergmann wrote:
> 
> On Thursday 17 July 2008, Misbah khan wrote:
>> I need to allocate 9 MB of memory in to the kernel space which i need to
>> mmap for the application to access.
>> 
>> I need to know what could be the best possible way of doing the same.
>> 
> 
> If you don't need the memory to be physically contiguous, you can use
> vmalloc to get the memory, but then you need to use remap_vmalloc_range
> for mapping the memory into a user address space.
> 
> 	Arnd <><
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> 
> 

-- 
View this message in context: http://www.nabble.com/how-to-allocate-9MB-of-memory-in-kernel---tp18503022p18522535.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-18  4:44   ` Misbah khan
@ 2008-07-18  6:50     ` Marco Stornelli
  2008-07-18  8:48       ` Misbah khan
  0 siblings, 1 reply; 28+ messages in thread
From: Marco Stornelli @ 2008-07-18  6:50 UTC (permalink / raw)
  To: Misbah khan; +Cc: linuxppc-embedded

Misbah khan ha scritto:
> This i am not very sure with  :-
> Can we allocate 9MB using vmalloc and assure it to be low memory and not
> highmem ?

Why do you need only low memory? And why do you need to allocate memory? 
If I understood correctly you need only to "ioremap" a chunk of memory.

> can we ioremap 9 MB SDRAM to kernel virtual ?

Yep.

> can we use vmalloc and do mmap to that allocated memory ,if the pages are
> not continues then is it going to concern mapping to user space ?

The "contiguous" problem is related only to DMA operations.

> 
> ---Misbah <><
> 
> 
> 
> Arnd Bergmann wrote:
>> On Thursday 17 July 2008, Misbah khan wrote:
>>> I need to allocate 9 MB of memory in to the kernel space which i need to
>>> mmap for the application to access.
>>>
>>> I need to know what could be the best possible way of doing the same.
>>>
>> If you don't need the memory to be physically contiguous, you can use
>> vmalloc to get the memory, but then you need to use remap_vmalloc_range
>> for mapping the memory into a user address space.
>>
>> 	Arnd <><
>> _______________________________________________
>> Linuxppc-embedded mailing list
>> Linuxppc-embedded@ozlabs.org
>> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>>
>>
> 


-- 
Marco Stornelli
Embedded Software Engineer
CoRiTeL - Consorzio di Ricerca sulle Telecomunicazioni
http://www.coritel.it

marco.stornelli@coritel.it
+39 06 72582838

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-18  6:50     ` Marco Stornelli
@ 2008-07-18  8:48       ` Misbah khan
  2008-07-18 14:57         ` Timur Tabi
  2008-07-18 15:39         ` Arnd Bergmann
  0 siblings, 2 replies; 28+ messages in thread
From: Misbah khan @ 2008-07-18  8:48 UTC (permalink / raw)
  To: linuxppc-embedded


In our implimentation we have 9MB sdram which we want our application to
directly access 3 MB at a time due to following reasons :-
1. We dont want our application to make a read call and copy to user 3 MB
and go for context switching ?
2. We thought mmap could be a better solution to this as only one thread
will act upon it and also we planed to have a circular buffer in the kernel
having 3 frame of 3 MB size of the total 9MB ,each time we will block on
read and get the read index and copy the frame of data for user application
to process . We want our kernel circular buffer shared 
3. In order to avoid switching we are going for circular buffer mapping to
user space .
4. Now we want our 9MB SDRAM to point to the kernel circular buffer we want
our circular buffer to be mapped to continues paged so that we could map it
to user space.

Now my concern is How can i map SDRAM one to one to circular buffer of such
a huge size ???? 

My idea is that i will ioreamp SDRAM and do memcpy_toio() when ever i am
writing to the the circular buffer which is dma allocated and pages are set
reserved . and read the frame from user space .

I may be totally wrong in the idea thats why i need your experience and
suggession in this matter .

I hope i have answered to your concern including shiva's.

----- Misbah <><

Marco Stornelli wrote:
> 
> Misbah khan ha scritto:
>> This i am not very sure with  :-
>> Can we allocate 9MB using vmalloc and assure it to be low memory and not
>> highmem ?
> 
> Why do you need only low memory? And why do you need to allocate memory? 
> If I understood correctly you need only to "ioremap" a chunk of memory.
> 
>> can we ioremap 9 MB SDRAM to kernel virtual ?
> 
> Yep.
> 
>> can we use vmalloc and do mmap to that allocated memory ,if the pages are
>> not continues then is it going to concern mapping to user space ?
> 
> The "contiguous" problem is related only to DMA operations.
> 
>> 
>> ---Misbah <><
>> 
>> 
>> 
>> Arnd Bergmann wrote:
>>> On Thursday 17 July 2008, Misbah khan wrote:
>>>> I need to allocate 9 MB of memory in to the kernel space which i need
>>>> to
>>>> mmap for the application to access.
>>>>
>>>> I need to know what could be the best possible way of doing the same.
>>>>
>>> If you don't need the memory to be physically contiguous, you can use
>>> vmalloc to get the memory, but then you need to use remap_vmalloc_range
>>> for mapping the memory into a user address space.
>>>
>>> 	Arnd <><
>>> _______________________________________________
>>> Linuxppc-embedded mailing list
>>> Linuxppc-embedded@ozlabs.org
>>> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>>>
>>>
>> 
> 
> 
> -- 
> Marco Stornelli
> Embedded Software Engineer
> CoRiTeL - Consorzio di Ricerca sulle Telecomunicazioni
> http://www.coritel.it
> 
> marco.stornelli@coritel.it
> +39 06 72582838
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> 
> 

-- 
View this message in context: http://www.nabble.com/how-to-allocate-9MB-of-memory-in-kernel---tp18503022p18525063.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-18  8:48       ` Misbah khan
@ 2008-07-18 14:57         ` Timur Tabi
  2008-07-18 15:39         ` Arnd Bergmann
  1 sibling, 0 replies; 28+ messages in thread
From: Timur Tabi @ 2008-07-18 14:57 UTC (permalink / raw)
  To: Misbah khan; +Cc: linuxppc-embedded

Misbah khan wrote:

> 4. Now we want our 9MB SDRAM to point to the kernel circular buffer we want
> our circular buffer to be mapped to continues paged so that we could map it
> to user space.

Physically contiguous or virtually contiguous?  I think you only need the 
buffer to be virtually contiguous, which vmalloc gives you.  You only need it 
to be physically contiguous if you are passing this buffer to hardware via DMA 
(and the hardware cannot handle scatter/gather).

If you need it to be physically contiguous, you'll have to use a function like 
alloc_pages() (or the new alloc_pages_exact, which will be in 2.6.27).  To 
allocate 9MB, you'll need to increase CONFIG_FORCE_MAX_ZONEORDER to 12.

-- 
Timur Tabi
Linux Kernel Developer @ Freescale

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-18  8:48       ` Misbah khan
  2008-07-18 14:57         ` Timur Tabi
@ 2008-07-18 15:39         ` Arnd Bergmann
  2008-07-22  5:23           ` Misbah khan
  1 sibling, 1 reply; 28+ messages in thread
From: Arnd Bergmann @ 2008-07-18 15:39 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: Misbah khan

On Friday 18 July 2008, Misbah khan wrote:

> Now my concern is How can i map SDRAM one to one to circular buffer of such
> a huge size ???? 

As I mentioned, use vmalloc to get the memory, and provide an mmap function
that uses remap_vmalloc_range to put it into the user address space.

> My idea is that i will ioreamp SDRAM and do memcpy_toio() when ever i am
> writing to the the circular buffer which is dma allocated and pages are set
> reserved . and read the frame from user space .

ioremap and memcpy_toio style accesses only make sense for stuff that is
*not* your main memory. Memory is alrady directly accessible in the kernel
after allocating with get_free_pages, kmalloc or vmalloc. No need to
play with __iomem pointers for this.

	Arnd <><

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-18 15:39         ` Arnd Bergmann
@ 2008-07-22  5:23           ` Misbah khan
  2008-07-22  6:43             ` Marco Stornelli
  2008-07-22  9:31             ` Arnd Bergmann
  0 siblings, 2 replies; 28+ messages in thread
From: Misbah khan @ 2008-07-22  5:23 UTC (permalink / raw)
  To: linuxppc-embedded


Hi all,

I am getting kernel panic while trying these as suggested by you ,the
following points will elaborate my concern :-

My circular buffer defination is this :-
/* Frame */
typedef struct
{
	char buffer[SIZE_FRAME];
	unsigned int count;
}frame_S;

/* Circular Buffer Structured */
/* Mmaped area Structure */
typedef struct
{

	frame_S  fluke[NO_FRAMES];
	unsigned int count_index;
	unsigned int read_index;
	unsigned int write_index;

}circularbuffer_S;

circularbuffer_S   *buf_area=NULL;

i am allocating memory using vmalloc and remaping to the SDRAM area as :-

buf_area = vmalloc(sizeof(circularbuffer_S));
	if(!buf_area)
	{
		printk(KERN_ALERT"vmalloc failed \n");
		return -1;
	}

	buf_area = (circularbuffer_S *)ioremap(7700000,900000);
	if(!buf_area)
	{
		printk(KERN_ALERT"ioremap failed \n");
		return -1;
	}


mmap Implimentation is this :-

unsigned long start = vma->vm_start;
	unsigned long size = vma->vm_end - vma->vm_start; //0x900000;
	unsigned long phy_add = virt_to_phys(buf_area); //0x7700000;
	int ret = 0;

	/* Make the mmaped area noncacheable */
	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

	/* Set the Flags to give permissions to Mmaped area */
	vma->vm_flags |=VM_RESERVED;
	vma->vm_flags |=VM_READ;
	vma->vm_flags |=VM_WRITE;
	vma->vm_flags |=VM_IO;
	//vma->vm_flags |=VM_SHARED;
	//vma->vm_flags |=VM_LOCKED;

	printk(KERN_DEBUG"In mmap function\n");

	if(remap_vmalloc_range(vma,buf_area,(phy_add >> PAGE_SHIFT)))
	{
		printk(KERN_ALERT"remap_vmalloc_range failed\n");
		goto mmap_exit;

   	}

I am getting mmap failed .....

some times i am getting this error .......


/***************************************************/

insmod fluke_driver.ko
 Ioremap mapped to virtual 0x0c7900e20
Unable to handle kernel paging request at virtual address c8200e34
pgd = c0444000
[c8200e34] *pgd=85c80011, *pte=00000000, *ppte=00000000
Internal error: Oops: 807 [#1]
Modules linked in: fluke_driver tstamp sig_router mvci_spi mvci_sf_pcd
mvci_sci_unidir_s1 mvci_sci_diff mvci_sci_bidir_s
1 g_ether mvci_rtmd_s1 mvci_kwiso_s1 mvci_kw1281_s1 mvci_kh_s1 mvci_j1850
mvci_gm_sbc mvci_diagh_s1 mvci_dcl mvci_can1 f
pga_conf arcotg_udc adc_dac keypad(F) splc501_lcd(F) cpld
CPU: 0
PC is at FlukeDriverInit+0xe4/0x140 [fluke_driver]
LR is at preempt_schedule+0x48/0x58
pc : [<bf01c0e4>]    lr : [<c0241e98>]    Tainted: GF
sp : c69b9ed0  ip : c69b9e28  fp : c69b9eec
r10: c7862000  r9 : 00000015  r8 : 00000016
r7 : bf01aaa0  r6 : c682a5f0  r5 : bf01ac24  r4 : 00000000
r3 : 00900014  r2 : c7900e20  r1 : c69b8000  r0 : 00000000
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  Segment user
Control: C5387F
Table: 80444000  DAC: 00000015
Process insmod (pid: 1089, stack limit = 0xc69b8250)
Stack: (0xc69b9ed0 to 0xc69ba000)
9ec0:                                     00000000 c682a5c4 c682a5c4
c682a400
9ee0: c69b9fa4 c69b9ef0 c005ec78 bf01c00c 00000000 00000000 00011008
00000000
9f00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000
9f20: 00000000 00000000 00000000 00000000 c78642e8 c6aad200 c7863820
c7863730
9f40: c7863848 00000000 0000006a 0000006a bf01aaac c00485d8 0000000a
c69b8000
9f60: bf01aae8 c7863474 c7863870 00000013 00000000 c0282764 c69b9f9c
00008608
9f80: 00000003 00011018 00000080 c0020f64 c69b8000 00011008 00000000
c69b9fa8
9fa0: c0020de0 c005d7d4 00008608 00000003 00011018 000025e8 00011008
0000002d
9fc0: 00008608 00000003 00011018 00000080 bec38f5e 00000000 00011008
00000000
9fe0: 00004000 bec38d14 000088dc 400db334 60000010 00011018 48010000
00000000
Backtrace:
[<bf01c000>] (FlukeDriverInit+0x0/0x140 [fluke_driver]) from [<c005ec78>]
(sys_init_module+0x14b0/0x1698)
 r5 = C682A400  r4 = C682A5C4
[<c005d7c8>] (sys_init_module+0x0/0x1698) from [<c0020de0>]
(ret_fast_syscall+0x0/0x2c)
Code: eb408e00 e5952000 e59f3058 e1a00004 (e7824003)
 Segmentation fault

/****************************************************/

Please suggest me what could be the problem and how to overcome this and do
my implimentation ....


------Misbah <><

Arnd Bergmann wrote:
> 
> On Friday 18 July 2008, Misbah khan wrote:
> 
>> Now my concern is How can i map SDRAM one to one to circular buffer of
>> such
>> a huge size ???? 
> 
> As I mentioned, use vmalloc to get the memory, and provide an mmap
> function
> that uses remap_vmalloc_range to put it into the user address space.
> 
>> My idea is that i will ioreamp SDRAM and do memcpy_toio() when ever i am
>> writing to the the circular buffer which is dma allocated and pages are
>> set
>> reserved . and read the frame from user space .
> 
> ioremap and memcpy_toio style accesses only make sense for stuff that is
> *not* your main memory. Memory is alrady directly accessible in the kernel
> after allocating with get_free_pages, kmalloc or vmalloc. No need to
> play with __iomem pointers for this.
> 
> 	Arnd <><
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> 
> 

-- 
View this message in context: http://www.nabble.com/how-to-allocate-9MB-of-memory-in-kernel---tp18503022p18582612.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-22  5:23           ` Misbah khan
@ 2008-07-22  6:43             ` Marco Stornelli
  2008-07-22  9:31             ` Arnd Bergmann
  1 sibling, 0 replies; 28+ messages in thread
From: Marco Stornelli @ 2008-07-22  6:43 UTC (permalink / raw)
  To: Misbah khan; +Cc: linuxppc-embedded

Misbah khan ha scritto:
> Hi all,
> 
> I am getting kernel panic while trying these as suggested by you ,the
> following points will elaborate my concern :-
> 
> My circular buffer defination is this :-
> /* Frame */
> typedef struct
> {
> 	char buffer[SIZE_FRAME];
> 	unsigned int count;
> }frame_S;
> 
> /* Circular Buffer Structured */
> /* Mmaped area Structure */
> typedef struct
> {
> 
> 	frame_S  fluke[NO_FRAMES];
> 	unsigned int count_index;
> 	unsigned int read_index;
> 	unsigned int write_index;
> 
> }circularbuffer_S;
> 
> circularbuffer_S   *buf_area=NULL;
> 
> i am allocating memory using vmalloc and remaping to the SDRAM area as :-
> 
> buf_area = vmalloc(sizeof(circularbuffer_S));
> 	if(!buf_area)
> 	{
> 		printk(KERN_ALERT"vmalloc failed \n");
> 		return -1;
> 	}
> 
> 	buf_area = (circularbuffer_S *)ioremap(7700000,900000);

Here you are overwriting buf_area!!!!!

> 	if(!buf_area)
> 	{
> 		printk(KERN_ALERT"ioremap failed \n");
> 		return -1;
> 	}
> 
> 
> mmap Implimentation is this :-
> 
> unsigned long start = vma->vm_start;
> 	unsigned long size = vma->vm_end - vma->vm_start; //0x900000;
> 	unsigned long phy_add = virt_to_phys(buf_area); //0x7700000;
> 	int ret = 0;
> 
> 	/* Make the mmaped area noncacheable */
> 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
> 
> 	/* Set the Flags to give permissions to Mmaped area */
> 	vma->vm_flags |=VM_RESERVED;
> 	vma->vm_flags |=VM_READ;
> 	vma->vm_flags |=VM_WRITE;
> 	vma->vm_flags |=VM_IO;
> 	//vma->vm_flags |=VM_SHARED;
> 	//vma->vm_flags |=VM_LOCKED;
> 
> 	printk(KERN_DEBUG"In mmap function\n");
> 
> 	if(remap_vmalloc_range(vma,buf_area,(phy_add >> PAGE_SHIFT)))
> 	{
> 		printk(KERN_ALERT"remap_vmalloc_range failed\n");
> 		goto mmap_exit;
> 
>    	}
> 
> I am getting mmap failed .....
> 
> some times i am getting this error .......
> 
> 
> /***************************************************/
> 
> insmod fluke_driver.ko
>  Ioremap mapped to virtual 0x0c7900e20
> Unable to handle kernel paging request at virtual address c8200e34
> pgd = c0444000
> [c8200e34] *pgd=85c80011, *pte=00000000, *ppte=00000000
> Internal error: Oops: 807 [#1]
> Modules linked in: fluke_driver tstamp sig_router mvci_spi mvci_sf_pcd
> mvci_sci_unidir_s1 mvci_sci_diff mvci_sci_bidir_s
> 1 g_ether mvci_rtmd_s1 mvci_kwiso_s1 mvci_kw1281_s1 mvci_kh_s1 mvci_j1850
> mvci_gm_sbc mvci_diagh_s1 mvci_dcl mvci_can1 f
> pga_conf arcotg_udc adc_dac keypad(F) splc501_lcd(F) cpld
> CPU: 0
> PC is at FlukeDriverInit+0xe4/0x140 [fluke_driver]
> LR is at preempt_schedule+0x48/0x58
> pc : [<bf01c0e4>]    lr : [<c0241e98>]    Tainted: GF
> sp : c69b9ed0  ip : c69b9e28  fp : c69b9eec
> r10: c7862000  r9 : 00000015  r8 : 00000016
> r7 : bf01aaa0  r6 : c682a5f0  r5 : bf01ac24  r4 : 00000000
> r3 : 00900014  r2 : c7900e20  r1 : c69b8000  r0 : 00000000
> Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  Segment user
> Control: C5387F
> Table: 80444000  DAC: 00000015
> Process insmod (pid: 1089, stack limit = 0xc69b8250)
> Stack: (0xc69b9ed0 to 0xc69ba000)
> 9ec0:                                     00000000 c682a5c4 c682a5c4
> c682a400
> 9ee0: c69b9fa4 c69b9ef0 c005ec78 bf01c00c 00000000 00000000 00011008
> 00000000
> 9f00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 00000000
> 9f20: 00000000 00000000 00000000 00000000 c78642e8 c6aad200 c7863820
> c7863730
> 9f40: c7863848 00000000 0000006a 0000006a bf01aaac c00485d8 0000000a
> c69b8000
> 9f60: bf01aae8 c7863474 c7863870 00000013 00000000 c0282764 c69b9f9c
> 00008608
> 9f80: 00000003 00011018 00000080 c0020f64 c69b8000 00011008 00000000
> c69b9fa8
> 9fa0: c0020de0 c005d7d4 00008608 00000003 00011018 000025e8 00011008
> 0000002d
> 9fc0: 00008608 00000003 00011018 00000080 bec38f5e 00000000 00011008
> 00000000
> 9fe0: 00004000 bec38d14 000088dc 400db334 60000010 00011018 48010000
> 00000000
> Backtrace:
> [<bf01c000>] (FlukeDriverInit+0x0/0x140 [fluke_driver]) from [<c005ec78>]
> (sys_init_module+0x14b0/0x1698)
>  r5 = C682A400  r4 = C682A5C4
> [<c005d7c8>] (sys_init_module+0x0/0x1698) from [<c0020de0>]
> (ret_fast_syscall+0x0/0x2c)
> Code: eb408e00 e5952000 e59f3058 e1a00004 (e7824003)
>  Segmentation fault
> 
> /****************************************************/
> 
> Please suggest me what could be the problem and how to overcome this and do
> my implimentation ....
> 
> 
> ------Misbah <><
> 
> Arnd Bergmann wrote:
>> On Friday 18 July 2008, Misbah khan wrote:
>>
>>> Now my concern is How can i map SDRAM one to one to circular buffer of
>>> such
>>> a huge size ???? 
>> As I mentioned, use vmalloc to get the memory, and provide an mmap
>> function
>> that uses remap_vmalloc_range to put it into the user address space.
>>
>>> My idea is that i will ioreamp SDRAM and do memcpy_toio() when ever i am
>>> writing to the the circular buffer which is dma allocated and pages are
>>> set
>>> reserved . and read the frame from user space .
>> ioremap and memcpy_toio style accesses only make sense for stuff that is
>> *not* your main memory. Memory is alrady directly accessible in the kernel
>> after allocating with get_free_pages, kmalloc or vmalloc. No need to
>> play with __iomem pointers for this.
>>
>> 	Arnd <><
>> _______________________________________________
>> Linuxppc-embedded mailing list
>> Linuxppc-embedded@ozlabs.org
>> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>>
>>
> 


-- 
Marco Stornelli
Embedded Software Engineer
CoRiTeL - Consorzio di Ricerca sulle Telecomunicazioni
http://www.coritel.it

marco.stornelli@coritel.it
+39 06 72582838

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-22  5:23           ` Misbah khan
  2008-07-22  6:43             ` Marco Stornelli
@ 2008-07-22  9:31             ` Arnd Bergmann
  2008-07-22  9:47               ` Marco Stornelli
  1 sibling, 1 reply; 28+ messages in thread
From: Arnd Bergmann @ 2008-07-22  9:31 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: Misbah khan

On Tuesday 22 July 2008, Misbah khan wrote:
> I am getting kernel panic while trying these as suggested by you ,the
> following points will elaborate my concern :-

Please post the entire driver, when you only post fragments that
don't compile, we can't really help you.

> i am allocating memory using vmalloc and remaping to the SDRAM area as :-
>=20
> buf_area =3D vmalloc(sizeof(circularbuffer_S));
> =A0=A0=A0=A0=A0=A0=A0=A0if(!buf_area)
> =A0=A0=A0=A0=A0=A0=A0=A0{
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0printk(KERN_ALERT"vmalloc=
 failed \n");
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0return -1;
> =A0=A0=A0=A0=A0=A0=A0=A0}
>=20
> =A0=A0=A0=A0=A0=A0=A0=A0buf_area =3D (circularbuffer_S *)ioremap(7700000,=
900000);
> =A0=A0=A0=A0=A0=A0=A0=A0if(!buf_area)
> =A0=A0=A0=A0=A0=A0=A0=A0{
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0printk(KERN_ALERT"ioremap=
 failed \n");
> =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0return -1;
> =A0=A0=A0=A0=A0=A0=A0=A0}

You really need to decide whether you want to allocate memory or
want to remap an I/O range. ioremap is *only* for I/O ranges
on SoC or similar devices, and when you have that, you don't allocate
memory. Besides, the addresses you pass are really strange,
e.g. 900,000 bytes are not 9MB. Normally, you would get the
I/O address from the device tree, using of_iomap(), and then
use of_translate_address/remap_pfn_range to map it to user
space.

	Arnd <><

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-22  9:31             ` Arnd Bergmann
@ 2008-07-22  9:47               ` Marco Stornelli
  2008-07-22 13:22                 ` Misbah khan
  0 siblings, 1 reply; 28+ messages in thread
From: Marco Stornelli @ 2008-07-22  9:47 UTC (permalink / raw)
  To: Misbah khan; +Cc: linuxppc-embedded

> On Tuesday 22 July 2008, Misbah khan wrote:
>> I am getting kernel panic while trying these as suggested by you ,the
>> following points will elaborate my concern :-
>> i am allocating memory using vmalloc and remaping to the SDRAM area as :-
>>
>> buf_area = vmalloc(sizeof(circularbuffer_S));
>>         if(!buf_area)
>>         {
>>                 printk(KERN_ALERT"vmalloc failed \n");
>>                 return -1;
>>         }
>>
>>         buf_area = (circularbuffer_S *)ioremap(7700000,900000);
>>         if(!buf_area)
>>         {
>>                 printk(KERN_ALERT"ioremap failed \n");
>>                 return -1;
>>         }

Misbah I suggest you, before to write in a Linux mailing list, to read 
Understanding the Linux kernel, Linux device drivers, Understanding the 
Linux virtual memory manager and so on, to study them very well, to 
think well about your problem and then ask for help in a mailing list.

Regards,

-- 
Marco Stornelli
Embedded Software Engineer
CoRiTeL - Consorzio di Ricerca sulle Telecomunicazioni
http://www.coritel.it

marco.stornelli@coritel.it
+39 06 72582838

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-22  9:47               ` Marco Stornelli
@ 2008-07-22 13:22                 ` Misbah khan
  2008-07-22 15:12                   ` Arnd Bergmann
  0 siblings, 1 reply; 28+ messages in thread
From: Misbah khan @ 2008-07-22 13:22 UTC (permalink / raw)
  To: linuxppc-embedded


Hi All ...

First of all let me thank you for your valuable suggessions ...

1. I wanted to allocate 9MB in kernel and wanted that memory to be mapped to
the physically continews SDRAM memory. but till now i could not found a way
to do so ???

2. So i thought to use ioremap to map SDRAM and make it accessible to user
using mmap technique but there is only one doubt and that is will it be
secure and stable and whether it is a right way of doing ???

3. Now i have allocated 3MB of memory in kernel for simulation purpose in
dma region and writing to 1 MB at a time in the driver and reading it in the
application this works good in the Linux PC where as in the board i could
just read '/0' char always .

4. When i do ioremap to a cpld memory mapped reg (as i am using simul board
which does not have the actual SDRAM mapping ) i could read write to it but
in the application i can read a value of '/0' always 

5. Can i actually do ioremap to 9 MB SDRAM memory and map it to the user
using function remap_pfn_range() ???


I am sorry Stornelli 
--- Since there is a time criticality hence i am not able to look the driver
books and documentation as of now and trying my little knowledge and your
suggessions .... 

------ Misbah <><

Marco Stornelli wrote:
> 
>> On Tuesday 22 July 2008, Misbah khan wrote:
>>> I am getting kernel panic while trying these as suggested by you ,the
>>> following points will elaborate my concern :-
>>> i am allocating memory using vmalloc and remaping to the SDRAM area as
>>> :-
>>>
>>> buf_area = vmalloc(sizeof(circularbuffer_S));
>>>         if(!buf_area)
>>>         {
>>>                 printk(KERN_ALERT"vmalloc failed \n");
>>>                 return -1;
>>>         }
>>>
>>>         buf_area = (circularbuffer_S *)ioremap(7700000,900000);
>>>         if(!buf_area)
>>>         {
>>>                 printk(KERN_ALERT"ioremap failed \n");
>>>                 return -1;
>>>         }
> 
> Misbah I suggest you, before to write in a Linux mailing list, to read 
> Understanding the Linux kernel, Linux device drivers, Understanding the 
> Linux virtual memory manager and so on, to study them very well, to 
> think well about your problem and then ask for help in a mailing list.
> 
> Regards,
> 
> -- 
> Marco Stornelli
> Embedded Software Engineer
> CoRiTeL - Consorzio di Ricerca sulle Telecomunicazioni
> http://www.coritel.it
> 
> marco.stornelli@coritel.it
> +39 06 72582838
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> 
> 

-- 
View this message in context: http://www.nabble.com/how-to-allocate-9MB-of-memory-in-kernel---tp18503022p18587466.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-22 13:22                 ` Misbah khan
@ 2008-07-22 15:12                   ` Arnd Bergmann
  2008-07-23  7:30                     ` Misbah khan
  2008-07-23 12:47                     ` Alessandro Rubini
  0 siblings, 2 replies; 28+ messages in thread
From: Arnd Bergmann @ 2008-07-22 15:12 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: Misbah khan

On Tuesday 22 July 2008, Misbah khan wrote:
> First of all let me thank you for your valuable suggessions ...
> 
> 1. I wanted to allocate 9MB in kernel and wanted that memory to be mapped to
> the physically continews SDRAM memory. but till now i could not found a way
> to do so ???
> 
> 2. So i thought to use ioremap to map SDRAM and make it accessible to user
> using mmap technique but there is only one doubt and that is will it be
> secure and stable and whether it is a right way of doing ???

As I have told you a few times now, you *either* allocate the memory *or*
ioremap it, NOT BOTH!!!

If you SDRAM is you main memory, you need vmalloc and remap_vmalloc_range.
If the SDRAM is not your main memory but some I/O attached buffer, you need
ioremap/of_iomap and remap_pfn_range.

	Arnd <><

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-22 15:12                   ` Arnd Bergmann
@ 2008-07-23  7:30                     ` Misbah khan
  2008-07-24  8:33                       ` Misbah khan
  2008-07-23 12:47                     ` Alessandro Rubini
  1 sibling, 1 reply; 28+ messages in thread
From: Misbah khan @ 2008-07-23  7:30 UTC (permalink / raw)
  To: linuxppc-embedded



If you SDRAM is you main memory, you need vmalloc and remap_vmalloc_range.
If the SDRAM is not your main memory but some I/O attached buffer, you need
ioremap/of_iomap and remap_pfn_range.

My SDRAM is the main memory of which 9MB i have to allocate in the driver. 

If i allocate 9BM using vmalloc and remap to user space how should it
address to the 9MB 
SDRAM contigues address which i need to map for user access ? 


Arnd Bergmann wrote:
> 
> On Tuesday 22 July 2008, Misbah khan wrote:
>> First of all let me thank you for your valuable suggessions ...
>> 
>> 1. I wanted to allocate 9MB in kernel and wanted that memory to be mapped
>> to
>> the physically continews SDRAM memory. but till now i could not found a
>> way
>> to do so ???
>> 
>> 2. So i thought to use ioremap to map SDRAM and make it accessible to
>> user
>> using mmap technique but there is only one doubt and that is will it be
>> secure and stable and whether it is a right way of doing ???
> 
> As I have told you a few times now, you *either* allocate the memory *or*
> ioremap it, NOT BOTH!!!
> 
> If you SDRAM is you main memory, you need vmalloc and remap_vmalloc_range.
> If the SDRAM is not your main memory but some I/O attached buffer, you
> need
> ioremap/of_iomap and remap_pfn_range.
> 
> 	Arnd <><
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> 
> 

-- 
View this message in context: http://www.nabble.com/how-to-allocate-9MB-of-memory-in-kernel---tp18503022p18605418.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-22 15:12                   ` Arnd Bergmann
  2008-07-23  7:30                     ` Misbah khan
@ 2008-07-23 12:47                     ` Alessandro Rubini
  1 sibling, 0 replies; 28+ messages in thread
From: Alessandro Rubini @ 2008-07-23 12:47 UTC (permalink / raw)
  To: misbah_khan; +Cc: linuxppc-embedded


> If i allocate 9BM using vmalloc and remap to user space how should it
> address to the 9MB 
> SDRAM contigues address which i need to map for user access ? 

Use the nopage method and vmalloc_to_page in it.

I have an example in ftp://gnudd.com/pub/samplecode, in the
smallsample26 package, the module is "smallmmap.c" (I'm sure there are
simlilar examples elsewhere).

/alessandro

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-23  7:30                     ` Misbah khan
@ 2008-07-24  8:33                       ` Misbah khan
  2008-07-24  9:31                         ` Arnd Bergmann
  0 siblings, 1 reply; 28+ messages in thread
From: Misbah khan @ 2008-07-24  8:33 UTC (permalink / raw)
  To: linuxppc-embedded


Hi all ...
 
I am uploading the source code which is doing the following :-

1. mapping cpld register using ioremap coping the data to circular buffer
and remapping it to user space .

2. It can also map kernel virtual dma memory to user space if compiled
conditionally .

following is the problem which i am facing ...

1. It is somitimes giving following kernel panic ....

nable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
[00000000] *pgd=00000000
Internal error: Oops: 17 [#1]
Modules linked in: fluke_driver tstamp sig_router mvci_spi mvci_sf_pcd
mvci_sci_unidir_s1 mvci_sci_diff mvci_sci_bidir_s
1 mvci_rtmd_s1 mvci_kwiso_s1 mvci_kw1281_s1 mvci_kh_s1 mvci_j1850
mvci_gm_sbc mvci_diagh_s1 g_ether mvci_dcl mvci_can1 f
pga_conf arcotg_udc adc_dac keypad(F) splc501_lcd(F) cpld
CPU: 0
PC is at cascade+0x64/0x8c
LR is at __init_begin+0x3fff8000/0x30
pc : [<c00484ac>]    lr : [<00000000>]    Tainted: GF
sp : c0293ea8  ip : 0040b000  fp : c0293ecc
r10: 8001d9f0  r9 : c0292000  r8 : 00000001
r7 : c0292000  r6 : 0000000c  r5 : c02fa048  r4 : 00000000
r3 : c02fa2f8  r2 : 0000261a  r1 : bf01ab70  r0 : c02fa2f8
Flags: Nzcv  IRQs off  FIQs on  Mode SVC_32  Segment kernel
Control: C5387F
Table: 8698C000  DAC: 00000017
Process swapper (pid: 0, stack limit = 0xc0292250)
Stack: (0xc0293ea8 to 0xc0294000)
3ea0:                   bf01ab70 c02fb440 0000000a 00000000 c02fa048
0000000a
3ec0: c0293efc c0293ed0 c0048810 c0048454 c0293eec c0293ee0 c002a30c
00000001
3ee0: c02f9e44 0000000a 00000002 00000001 c0293f1c c0293f00 c00442a0
c0048794
3f00: c0293f2c 0000001d c0294740 00000000 c0293f2c c0293f20 c00446d4
c0044254
3f20: c0293f4c c0293f30 c00217b0 c0044698 c0293f5c ffffffff 0000ffff
00000001
3f40: c0293fa4 c0293f50 c00209e4 c0021770 00000001 00000001 c0292000
00000000
3f60: c0022068 c0292000 c0298c44 c03121c0 8001da24 4107b364 8001d9f0
c0293fa4
3f80: c0293fa8 c0293f98 c0021d48 c002209c 60000013 ffffffff c0293fbc
c0293fa8
3fa0: c0021d48 c0022074 c02faae0 c02f292c c0293fcc c0293fc0 c00202e0
c0021d24
3fc0: c0293ff4 c0293fd0 c0008848 c00202b4 c00083c4 00000000 00000000
c02f29a8
3fe0: 00000000 00c5387d 00000000 c0293ff8 80008030 c00086e0 00000000
00000000
Backtrace:
[<c0048448>] (cascade+0x0/0x8c) from [<c0048810>]
(run_timer_softirq+0x88/0x1e8)
 r6 = 0000000A  r5 = C02FA048  r4 = 00000000
[<c0048788>] (run_timer_softirq+0x0/0x1e8) from [<c00442a0>]
(__do_softirq+0x58/0xc8)
 r8 = 00000001  r7 = 00000002  r6 = 0000000A  r5 = C02F9E44
 r4 = 00000001
[<c0044248>] (__do_softirq+0x0/0xc8) from [<c00446d4>] (irq_exit+0x48/0x5c)
 r6 = 00000000  r5 = C0294740  r4 = 0000001D
[<c004468c>] (irq_exit+0x0/0x5c) from [<c00217b0>] (asm_do_IRQ+0x4c/0x64)
[<c0021764>] (asm_do_IRQ+0x0/0x64) from [<c00209e4>] (__irq_svc+0x44/0x80)
 r6 = 00000001  r5 = 0000FFFF  r4 = FFFFFFFF
[<c0022068>] (default_idle+0x0/0x3c) from [<c0021d48>] (cpu_idle+0x30/0x5c)
[<c0021d18>] (cpu_idle+0x0/0x5c) from [<c00202e0>] (rest_init+0x38/0x40)
 r5 = C02F292C  r4 = C02FAAE0
[<c00202a8>] (rest_init+0x0/0x40) from [<c0008848>]
(start_kernel+0x174/0x1c0)
[<c00086d4>] (start_kernel+0x0/0x1c0) from [<80008030>] (0x80008030)
Code: e1530005 15822000 ebffffb6 e1a0e004 (e5944000)
 <0>Kernel panic - not syncing: Aiee, killing interrupt handler!


also when i run it on X86 PC i am able to get the data and no panic where in
on the board it is giving the above error ....

2. I can raed the data using the user application when i run it on X86 PC
where in i cant able to read the data when i run it on the board the data i
was getting was always '/0' filled buffer .


Here is the compilete code .............


/******************************************************************************
* McBSP_Driver.c
*
* Fluke Driver
*
* Description:
*
* Libraries Used:
*
*
* Unit Test Drivers (Binary):
*
*		<fix me >
*
*
* Special Compile Flags
*		Nil
*
* Revision History:
* 	(17/July/2008) Misbah
*    		Created the file
*
* Copyright (C)
*
******************************************************************************/

/******************************************************************************
*						Include Files
*****************************************************************************/

/* Standard linux files includes */
#include<linux/kernel.h>
//#include<linux/config.h>
#include<linux/ioctl.h>
#include<linux/types.h>
#include<linux/module.h>
#include<linux/fs.h>
#include<linux/delay.h>
#include<linux/init.h>
#include<linux/interrupt.h>
#include<linux/version.h>
#include<linux/wait.h>
#include<linux/poll.h>
#include<linux/timer.h>
#include<linux/irq.h>
#include<asm/uaccess.h>
#include<linux/time.h>
#include<asm/io.h>
#include<asm/bitops.h>
#include<linux/mm.h>
//#include<asm/mmzone.h>
#include<linux/bootmem.h>
#include <linux/dma-mapping.h>
#include <linux/vmalloc.h>
#include <asm/pgtable.h>
#include<asm/io.h>
#include<asm/bitops.h>
#include"fluke_driver.h"

static int McBSP_DriverOpen(struct inode *inode,struct file *file);
static int McBSP_DriverInit(void);
static int McBSP_DriverIoctl(struct inode *inode, struct file *file,\
					unsigned int cmd, unsigned long param);
static ssize_t McBSP_DriverWrite(struct file *file,
			const char __user *buf, size_t len,loff_t *offset);
static ssize_t McBSP_DriverRead(struct file *file,char __user *buf,size_t
len,
			loff_t *offset);
static int McBSP_DriverMmap(struct file *file,struct  vm_area_struct *vma);
static void MmapOpen(struct vm_area_struct *vma);
static void MmapClose(struct vm_area_struct *vma);
static void McBSP_DriverExit(void);
static int McBSP_DriverClose(struct inode *inode,struct file *file);
static int WriteBuf(void);
void timer_func(void);

static struct timer_list 		fluke_timer;
static dma_addr_t 				dma_addr;
static char						*buf_ptr;

static struct file_operations fluke_fops =
{
	.owner 		= THIS_MODULE,
	.open 		= McBSP_DriverOpen,
//	.read 		= McBSP_DriverRead,
	.ioctl 		= McBSP_DriverIoctl,
	.mmap		= McBSP_DriverMmap,
//	.write		= McBSP_DriverWrite,
	.release 	= McBSP_DriverClose,
};

/* File operation structure for mmap system call */
static struct vm_operations_struct mmap_op=
{
	.open		=	MmapOpen,
	.close		=	MmapClose,
};

static circularbuffer_S *buf_area = NULL;
static circularbuffer_index_S buf_index_area;
static int device_open_count	  = 0;
static int data_present_status    = 0;

void *ioremap_ptr;
static int phy_addr ;

/* static declaration of wait queue  */
static DECLARE_WAIT_QUEUE_HEAD(wait_queue);

static DECLARE_MUTEX(mutex);

module_init(McBSP_DriverInit);
module_exit(McBSP_DriverExit);

MODULE_AUTHOR("Misbah U K");
MODULE_LICENSE ("GPL");

#define SIMULATION
/****************************************************************************
*
* Description: This function will open fluke device
*
* Input:	File structure pointer and Inode structure pointer.
*			( passed by the kernel )
*
* output:	Returns 0 on Success.
*
***************************************************************************/
static int McBSP_DriverOpen(struct inode *inode,struct file *file)
{
	/* Reintialize file operation structure */
	file->f_op=&fluke_fops;

	printk(KERN_DEBUG" fluke driver open success \n");

	if (device_open_count == 0)
	{
		device_open_count = 1;

		/* Reset the read and write index*/
		buf_index_area.write_index=0;
		buf_index_area.read_index=-1;
		buf_index_area.count_index=0;

		#ifdef SIMULATION
		/* Initialize the Timer */
		init_timer(&fluke_timer);
		fluke_timer.expires = jiffies + (HZ*10);//Timer will Expire after 60 sec
		fluke_timer.data = 0;
		fluke_timer.function = (void *)timer_func;
		add_timer(&fluke_timer);
		#endif
	}

	return 0;
}

/******************************************************************************
 *
 * Description : Interrupt handler function.
 *
 * Input:		 NONE
 *
 * Output:		 NONE
 *

*****************************************************************************/
irqreturn_t DataAcqIntHandler(int irq,void *dev_id, struct pt_regs *regs)
{
	printk(KERN_ALERT" In Interrupt Handler\n");
	/* Data present status is set to wake up the read call */
	data_present_status=1;

	/* Wake up the blocked Select call */
	wake_up_interruptible(&wait_queue);

	#ifndef SIMULATION
	/* Clear the interrupt in the interrupt pending registor */
	cpi->ic_scprrh |=DATA_ACQ_INT_CLEAR;
	#endif

	return IRQ_HANDLED;

}/* End of PpsIntrHandler() */

#ifdef SIMULATION
void timer_func(void)
{

	printk(KERN_ALERT" In the timer function \n");
	/* Data present status is set to wake up the read call */
	data_present_status=1;

	/* Wake up the blocked Read call */
	wake_up_interruptible(&wait_queue);

}

#endif

/***************************************************************************
*
* Description: Register the device and perform Initialization.
*
* Input:		NIL
*
* Output:		Returns 0 on Success and -1 on failure
*
**************************************************************************/
static int __init McBSP_DriverInit(void)
{
	unsigned int virt_addr = 0;
	int mem = 0;

	//buf_area = vmalloc(sizeof(circularbuffer_S));
	//if(!buf_area)
	//{
	//	printk(KERN_ALERT"vmalloc failed \n");
	//	return -1;
	//}

#if 0
	/*
	* Allocate memory for the circular buffer in the DMA coherent area
	* and algin it in the Cache
	*/
	mem = L1_CACHE_ALIGN(sizeof(circularbuffer_S));

	buf_ptr = (char *)dma_alloc_coherent(NULL, mem, &dma_addr,GFP_KERNEL);
	printk(KERN_INFO" buf_ptr = 0x%x \n",(int )buf_ptr);
	if(NULL == buf_ptr )
	{
		printk(KERN_ALERT" Allocation of Memory failure ");
		return -1;
	}

	buf_area = (circularbuffer_S *)(((unsigned int )buf_ptr + PAGE_SIZE - 1) \
			& PAGE_MASK);

	printk(KERN_INFO" buf_area = 0x%x \n",(int )buf_area);

	if(NULL == buf_area)
	{
		printk(KERN_ALERT" Circular buffer memory not allocated \n");
		return -1;
	}

	/* Marking the Pages as reserved */
	for (virt_addr = (unsigned int)buf_area; \
	virt_addr < (unsigned int )buf_area + sizeof(circularbuffer_S);\
	virt_addr += PAGE_SIZE)
	{
		/* Set the pages as reserved */
		SetPageReserved(virt_to_page(virt_addr));
		//mem_map_reserve(virt_to_page(virt_addr));
	}

	phy_addr = virt_to_phys(buf_ptr);
	printk(KERN_INFO"Allocated Memory for Circular Buffer at physical
0x0%x\n",phy_addr);

#else

	buf_area = ioremap(0xB2000000,0x4000); //(0xB2000000,0x4000);
//(7700000,900000);
	if(!buf_area)
	{
		printk(KERN_ALERT"ioremap failed \n");
		return -1;
	}

	printk(" Ioremap mapped to virtual 0x0%x \n",buf_area);
	*((unsigned int *)buf_area) = 0xa5a5a5a5;
	printk(" Ioremap data  0x0%x \n",*((unsigned int *)buf_area + 0));

#endif

	/* Device major number is registered to set the driver entry point */
	if(register_chrdev(MAJOR_NO,MODULE_NAME, &fluke_fops)==0)
	{
		printk(KERN_DEBUG" Fluke driver registeration success \n");

	}
	else
	{
		printk(KERN_ALERT" Fluke driver registeration failed \n");
		return -1;
	}

	/*
	 * Register Data Acq interrupt request with specified irq and install the
	 * handler
	 */
	 if(request_irq(DATA_ACQ_INT,(void *)DataAcqIntHandler, SA_INTERRUPT,
	 						MODULE_NAME, NULL)==0)
	{
		printk(KERN_DEBUG" Data Acq interrupt request returns success \n");
	}
	else
	{
		printk(KERN_DEBUG" Data Acq interrupt request failed \n");
		unregister_chrdev(MAJOR_NO,MODULE_NAME);
		return -1;

	}

	/* Reset the read and write index*/
	buf_index_area.write_index=0;
	buf_index_area.read_index=0;
	buf_index_area.count_index=0;

	return 0;

}

/***************************************************************************
*
* Description: Input/Output entry point for driver.
*
* Input:		Inode pointer, File pointer, command and parameter.
*
* Output:		Returns 0 on success and -1 on failure.
*
**************************************************************************/

static int McBSP_DriverIoctl(struct inode *inode, struct file *file,\
									unsigned int cmd, unsigned long param)
{
	int i;
	daq_t daq_param;

	printk(KERN_DEBUG"In ioctl command \n");

	switch(cmd)
	{
		case START_ACQ_DATA:

			if(copy_from_user(&daq_param,(void *)param,sizeof(daq_param)))
			{

				return -1;
			}

			/* For Simulation we are writing the data */
			if(WriteBuf() < 0)
			{
				printk(" Writing to the memory failure \n");
				return -1;
			}

			/* Wait for the Interrupt to occur */
			wait_event_interruptible( wait_queue, data_present_status !=0);

			printk("Read Index before read %d\n",buf_index_area.read_index);
			data_present_status=0;

			buf_index_area.read_index++;
			buf_index_area.read_index%=NO_FRAMES;

			if(buf_index_area.read_index ==((buf_index_area.write_index +1) %
NO_FRAMES))
			//if(buf_index_area.read_index == buf_index_area.write_index )
			{
				printk("Read failure because read and write index are same\n");
				return -1;
			}

			/* Decrement the count index to indicate the data availibility */
			down(&mutex);
			buf_index_area.count_index--;
			up(&mutex);

			/* copy the circular buffer read index */
			daq_param.circular_index = buf_index_area.read_index;

			/*for(i = 0;i < SIZE_FRAME; i++)
			{
				printk("%c",buf_area->fluke[buf_index_area.read_index].buffer[i]);
			}
			*/
			/* Configure ADC unit for No of samples and period */
			/* < To Dod > */
			#ifdef SIMULATION
			/* Reinitialize the timer and run it again */
			init_timer(&fluke_timer);
			fluke_timer.function=(void *)timer_func;
			fluke_timer.data=0;
			fluke_timer.expires=jiffies + (HZ*10);
			del_timer(&fluke_timer);
			printk(KERN_DEBUG"Timer reinitialize in ioctl \n");
			add_timer(&fluke_timer);

			#endif
			printk("Read Index after read %d\n",buf_index_area.read_index);
			if(copy_to_user((void *)param,&daq_param,sizeof(daq_param)))
			{

				return -1;
			}

			break;
		default:
			return(0);
	}
	return (0);
}

/******************************************************************************
* Description: This function writes data to the device.
*
* Inputs:  NONE
*
* Outputs: Returns No of bytes copied or -1 on failure.
******************************************************************************/
static ssize_t McBSP_DriverWrite(struct file *file,
			const char __user *buf, size_t len,loff_t *offset)
{

	int i,write_index;
	write_index = buf_index_area.write_index;
	if(buf_index_area.read_index ==((buf_index_area.write_index +1) %
NO_FRAMES))
	//if(buf_index_area.read_index == buf_index_area.write_index )
	{
		printk(KERN_ALERT"Not able to write\n");
		return -1;
	}
	printk(KERN_INFO" Before Write index = %d\n",buf_index_area.write_index);
	for(i=0;i<len;i++)
	{
		buf_area->fluke[write_index].buffer[i]=buf[i];
		//memset(buf_area->fluke[write_index].buffer,'A',SIZE_FRAME);
		//for(i = 0;i < SIZE_FRAME; i++)
		//{
		//	printk("%c",buf_area->fluke[write_index].buffer[i]);
		//}
		//printk(" %c",buf_area->fluke[write_index].buffer[i]);
	}
	for(i = 0;i < SIZE_FRAME; i++)
	{
		printk("%c",buf_area->fluke[write_index].buffer[i]);
	}
	//len = copy_from_user(buf_area->fluke[write_index].buffer,buf,len);

	//memcpy_fromio(ioremap_ptr,buf_area->fluke[write_index].buffer,4);

	buf_index_area.count_index++;
	buf_index_area.write_index++;
	buf_index_area.write_index%=3;

	printk(KERN_INFO" After Write index = %d\n",buf_index_area.write_index);

	return len;

}

/******************************************************************************
* Description: This function writes data to the circular buffer.
*
* Inputs:  NONE
*
* Outputs: Returns No of bytes copied or -1 on failure.
******************************************************************************/
static int WriteBuf(void)
{
	int i;

	printk(" write Index is %d \n",buf_index_area.write_index);
	if(buf_index_area.read_index ==((buf_index_area.write_index +1) %
NO_FRAMES))
	//if(buf_index_area.read_index == buf_index_area.write_index )
	{
		printk(KERN_ALERT"Not able to write\n");
		return -1;
	}

	memset(buf_area->fluke[buf_index_area.write_index].buffer,'A',SIZE_FRAME);

	/*for(i = 0;i < SIZE_FRAME; i++)
	{
		printk("%c",buf_index_area.fluke[buf_index_area.write_index].buffer[i]);
	}
	*/
	buf_index_area.count_index++;
	buf_index_area.write_index++;
	buf_index_area.write_index%=3;
	printk(" write Index incremented to %d \n",buf_index_area.write_index);

	return 0;
}


/******************************************************************************
* Description: This function reads data from the shared mmap area.
*
* Inputs:  file structuer,data buffer pointer and length of data.
*
* Outputs: Return no of bytes read or -1 on failure.
*
******************************************************************************/
static ssize_t McBSP_DriverRead(struct file *file,char __user *buf,size_t
len,
			loff_t *offset)
{

	int temp_read_index,i;
	printk(KERN_INFO"Entering %s\n",__FUNCTION__);

	/* Wait till timer Expires */
	wait_event_interruptible( wait_queue, data_present_status !=0);

	data_present_status=0;

	buf_index_area.read_index++;
	buf_index_area.read_index%=NO_FRAMES;

	/* Decrement the count index to indicate the data availibility */
	down(&mutex);
	buf_index_area.count_index--;
	up(&mutex);

	temp_read_index = buf_index_area.read_index;

	printk(KERN_INFO"Exting %s\n",__FUNCTION__);

	printk(KERN_INFO"count_index=%d\n",buf_index_area.count_index);
	printk(KERN_INFO"read_index=%d\n",buf_index_area.read_index);
	/*for(i = 0 ;i < SIZE_FRAME ; i++)
	{
		printk("%c",buf_area->fluke[temp_read_index].buffer[i]);
	}
	*/
	return((temp_read_index));
}

/*****************************************************************************
* Description:This function is used to map the memory area to user
application.
*				There is a circular buffer which is created in the driver.
*			   This region is mmaped to the user application by this function.
*			   This fuction sets the permissions for that area accordingly.
*
* Inputs:file pointer, virtual memory area structure.
*
* Outputs: Returns 0 on success or -1 on failure.
*******************************************************************************/
static int McBSP_DriverMmap(struct file *file,struct  vm_area_struct *vma)
{

	unsigned long start = vma->vm_start;
	unsigned long size = vma->vm_end - vma->vm_start; //0x900000;
	unsigned long phy_add = virt_to_phys(buf_ptr); //0x7700000;
	int ret = 0;

	/* Make the mmaped area noncacheable */
	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

	/* Set the Flags to give permissions to Mmaped area */
	vma->vm_flags |=VM_RESERVED;
	vma->vm_flags |=VM_READ;
	vma->vm_flags |=VM_WRITE;
	vma->vm_flags |=VM_IO;
	//vma->vm_flags |=VM_SHARED;
	//vma->vm_flags |=VM_LOCKED;

	printk(KERN_DEBUG"In mmap function\n");

	/* Mmap the kernel buffer to user space */
	if(remap_pfn_range(vma,start,(phy_add >>
PAGE_SHIFT),size,vma->vm_page_prot))
	//if(remap_pfn_range(vma,start,vma->vm_pgoff,size,vma->vm_page_prot))
	{
		printk(KERN_ALERT"remap_pfn_range failed\n");
		goto mmap_exit;

   	}

   	printk(KERN_ALERT"phy addr 0x%08X mmapped to virt addr 0x%08X, size =
0x%08X\n",
		(unsigned int)phy_add, (unsigned int)start, (unsigned int)size);

	/* Initialize the file operation structure of Mmaped area */
	vma->vm_ops=&mmap_op;

	/* Open the Mmaped area */
	MmapOpen(vma);

	mmap_exit:
	   	return ret;
}

/******************************************************************************
* Description: This function opens mmaped area for the device.
*
* Inputs:  Virtual memory area structure.
*
* Outputs: none
******************************************************************************/
static void MmapOpen(struct vm_area_struct *vma)
{
	printk("Mmaped are is opened \n");

	printk("Virtual= %lx, Physical=%lx \n",vma->vm_start,
		(vma->vm_pgoff << PAGE_SHIFT));
	return;
}

/******************************************************************************
* Description: This function closes mmaped area for the device
*
* Inputs: Virtual Memory structure.
*
* Outputs: Return CASHEL_SUCCESS after closing the device.
******************************************************************************/
static void MmapClose(struct vm_area_struct *vma)
{
	printk(KERN_DEBUG"Mmaped are is closed\n ");
	return;
}

/******************************************************************************
*
* Description	: Unregisters the driver and makes the resources free.
*
* Input		: NIL
*
* Output		: NIL
*
*****************************************************************************/
static void __exit McBSP_DriverExit(void)
{
	unsigned int virt_addr;

#if 0
	/* Clear or Free the pages which are reserverd */
	for (virt_addr=(unsigned int)buf_area; virt_addr < (unsigned int)buf_area
										+ sizeof(circularbuffer_S);
	virt_addr += PAGE_SIZE)
	{
		// clear all pages
		ClearPageReserved(virt_to_page(virt_addr));
	}

	/* Free the mmaped buffer area */
	dma_free_coherent(NULL,L1_CACHE_ALIGN(sizeof(circularbuffer_S)),
												buf_ptr,dma_addr);
#else

	iounmap(buf_area);

#endif

	/* Unregister the device */
	if(unregister_chrdev(MAJOR_NO , MODULE_NAME)==0)
		printk(KERN_DEBUG" device cleanup success\n");
	else
		printk(KERN_ALERT" device cleanup failed \n");

	/* Free IRQ */
	free_irq(DATA_ACQ_INT,NULL);

	//if(buf_area)
	//	vfree(buf_area);

}

/******************************************************************************
* Description: This function closes the device
*
* Inputs:  Inode structure pointer, File structure pointer
*
* Outputs: Return 0 on success and -1 on failure.
******************************************************************************/
static int McBSP_DriverClose(struct inode *inode,struct file *file)
{
	device_open_count--;
	if(device_open_count == 0)
	{
		/* Delete the timer */
		del_timer(&fluke_timer);
	}

	printk(KERN_INFO" device closed %d\n",device_open_count);
	return 0;
}

/******************************************************************************
 *						 File Ends

*****************************************************************************/

#define MODULE_NAME						"fluke_driver"
#define MAJOR_NO							 333
#define NO_FRAMES							 3
#define SIZE_FRAME							 1024*5//(1024*1024*1)/* 3MB */
#define DATA_ACQ_INT						 23 /* To Do <for testing only > */
#define DATA_ACQ_INT_CLEAR					 1 /* To Do <for testing only > */

#define MAGIC_NUM      			'D'

#define START_ACQ_DATA   		_IOWR(MAGIC_NUM, 0,unsigned long)

/* Frame */
typedef struct
{
	char buffer[SIZE_FRAME];

}frame_S;

/* Circular Buffer Structured */
/* Mmaped area Structure */
typedef struct
{

	frame_S  fluke[NO_FRAMES];

}circularbuffer_S;

typedef struct
{
	unsigned int count_index;
	unsigned int read_index;
	unsigned int write_index;
}circularbuffer_index_S;

typedef struct
{
	int test_period_ms;		/*????? send to driver*/
	int req_no_sample;		/*send to driver*/
	int acq_no_of_sample;  /* return by driver*/
	int circular_index;    /* return by driver*/
	int sampling_rate_hz;  /*send to driver*/

}daq_t;


/******************************************************************************
 *						 File Ends

*****************************************************************************/

/******************************************************************************
* McBSP_appl.c
*
* Fluke Driver
*
* Description:
*
* Libraries Used:
*
*
* Unit Test Drivers (Binary):
*
*		<fix me >
*
*
* Special Compile Flags
*		Nil
*
* Revision History:
* 	(17/July/2008) Misbah
*    		Created the file
*
* Copyright (C)
*
******************************************************************************/

/******************************************************************************
*						Include Files
*****************************************************************************/
/* Standard linux files includes */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include "fluke_driver.h"

#define FLUKE_DRIVER		"/dev/fluke"

int main (int argc ,char *argv[])
{
	circularbuffer_S *mmap_ptr;
	int fd = -1,i;
	int size_mmap = sizeof(circularbuffer_S);
	int read_index = -1,ret = -1 ;
	FILE *fp1,*fp2,*fp3;
	char buf[1024];
	char *mmap_data;
	daq_t daq_param;

	/* Initialize the config param */
	daq_param.test_period_ms = 60*1000 ;
	daq_param.acq_no_of_sample = 0;
	daq_param.req_no_sample =0;
	daq_param.sampling_rate_hz = 0;

	mmap_data = (char *)malloc(sizeof(circularbuffer_S));

	/* creat files for frames */
	fp1 = fopen("frame1.txt","w");
	fp2 = fopen("frame2.txt","w");
	fp3 = fopen("frame3.txt","w");

	/* Open the device file */
	fd = open(FLUKE_DRIVER , O_RDWR);
	if (fd == -1)
	{
		printf(" Error in opening fluke device \n");
		return -1;
	}

	/* map the kernel memory to user space */
	mmap_ptr = mmap(NULL,size_mmap,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
	printf(" Virtual addr of the pointer is 0x%x \n",(unsigned int)mmap_ptr);

	if(mmap_ptr == NULL )
	{
		printf(" mapped ptr returns NULL from driver n");
		return -1;
	}

	while(1)
	{
		/* Write to driver for testing only */
		memset(buf,'Z',sizeof(buf));
		printf(" Writing to driver \n");
		//write(fd,buf,sizeof(buf));

		/* Block on read to get the circular buffer read index */
		//read_index = read(fd, buf , 1024);
		//printf(" Here is the read for you %s\n",buf);
		if (ioctl(fd , START_ACQ_DATA ,&daq_param) < 0)
		{
			printf(" ioctl failed \n");
			return -1 ;
		}

		read_index = daq_param.circular_index;

		printf(" read index from application %d \n",read_index);

		/* Print the data read */
		//for(i = 0;i <= 1024 ; i++)
			printf(" %s \n",mmap_ptr->fluke[read_index].buffer);

		/* Write the data read fron the driver to the file */
		if(read_index >= 0)
		{
			ret = (SIZE_FRAME) ;

			memcpy(mmap_data, \
				mmap_ptr->fluke[read_index].buffer,SIZE_FRAME);

			if(read_index == 0)
				fwrite(mmap_ptr->fluke[read_index].buffer ,SIZE_FRAME , 1 ,fp1);
			else if(read_index == 1)
				fwrite(mmap_ptr->fluke[read_index].buffer ,SIZE_FRAME , 1 ,fp2);
			else if(read_index == 2)
				fwrite(mmap_ptr->fluke[read_index].buffer ,SIZE_FRAME , 1 ,fp3);
			else
			{
				printf("Not able to write to file as read_index returns %d
\n",read_index );
				return -1;
			}

		}

	}

	if(mmap_data)
		free(mmap_data);
	fclose(fp1);
	fclose(fp2);
	fclose(fp3);

	return 0;
}


/******************************************************************************
 *						 File Ends

*****************************************************************************/



please help me to resolve this issue .......


Thanks in advance ...

---- Misbah <><

Misbah khan wrote:
> 
> 
> If you SDRAM is you main memory, you need vmalloc and remap_vmalloc_range.
> If the SDRAM is not your main memory but some I/O attached buffer, you
> need
> ioremap/of_iomap and remap_pfn_range.
> 
> My SDRAM is the main memory of which 9MB i have to allocate in the driver. 
> 
> If i allocate 9BM using vmalloc and remap to user space how should it
> address to the 9MB 
> SDRAM contigues address which i need to map for user access ? 
> 
> 
> Arnd Bergmann wrote:
>> 
>> On Tuesday 22 July 2008, Misbah khan wrote:
>>> First of all let me thank you for your valuable suggessions ...
>>> 
>>> 1. I wanted to allocate 9MB in kernel and wanted that memory to be
>>> mapped to
>>> the physically continews SDRAM memory. but till now i could not found a
>>> way
>>> to do so ???
>>> 
>>> 2. So i thought to use ioremap to map SDRAM and make it accessible to
>>> user
>>> using mmap technique but there is only one doubt and that is will it be
>>> secure and stable and whether it is a right way of doing ???
>> 
>> As I have told you a few times now, you *either* allocate the memory *or*
>> ioremap it, NOT BOTH!!!
>> 
>> If you SDRAM is you main memory, you need vmalloc and
>> remap_vmalloc_range.
>> If the SDRAM is not your main memory but some I/O attached buffer, you
>> need
>> ioremap/of_iomap and remap_pfn_range.
>> 
>> 	Arnd <><
>> _______________________________________________
>> Linuxppc-embedded mailing list
>> Linuxppc-embedded@ozlabs.org
>> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>> 
>> 
> 
> 

-- 
View this message in context: http://www.nabble.com/how-to-allocate-9MB-of-memory-in-kernel---tp18503022p18627544.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-24  8:33                       ` Misbah khan
@ 2008-07-24  9:31                         ` Arnd Bergmann
  2008-07-25  8:43                           ` Misbah khan
  0 siblings, 1 reply; 28+ messages in thread
From: Arnd Bergmann @ 2008-07-24  9:31 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: Misbah khan

On Thursday 24 July 2008, Misbah khan wrote:
> 
> Hi all ...
>  
> I am uploading the source code which is doing the following :-
> 
> 1. mapping cpld register using ioremap coping the data to circular buffer
> and remapping it to user space .
> 
> 2. It can also map kernel virtual dma memory to user space if compiled
> conditionally .
> 
> following is the problem which i am facing ...
> 
> 1. It is somitimes giving following kernel panic ....
> 
> nable to handle kernel NULL pointer dereference at virtual address 00000000
> pgd = c0004000
> [00000000] *pgd=00000000
> Internal error: Oops: 17 [#1]
> Modules linked in: fluke_driver tstamp sig_router mvci_spi mvci_sf_pcd
> mvci_sci_unidir_s1 mvci_sci_diff mvci_sci_bidir_s
> 1 mvci_rtmd_s1 mvci_kwiso_s1 mvci_kw1281_s1 mvci_kh_s1 mvci_j1850
> mvci_gm_sbc mvci_diagh_s1 g_ether mvci_dcl mvci_can1 f
> pga_conf arcotg_udc adc_dac keypad(F) splc501_lcd(F) cpld
> CPU: 0
> PC is at cascade+0x64/0x8c
> LR is at __init_begin+0x3fff8000/0x30
> pc : [<c00484ac>]    lr : [<00000000>]    Tainted: GF
> sp : c0293ea8  ip : 0040b000  fp : c0293ecc
> r10: 8001d9f0  r9 : c0292000  r8 : 00000001
> r7 : c0292000  r6 : 0000000c  r5 : c02fa048  r4 : 00000000
> r3 : c02fa2f8  r2 : 0000261a  r1 : bf01ab70  r0 : c02fa2f8
> Flags: Nzcv  IRQs off  FIQs on  Mode SVC_32  Segment kernel
> Control: C5387F
> Table: 8698C000  DAC: 00000017
> Process swapper (pid: 0, stack limit = 0xc0292250)
> Stack: (0xc0293ea8 to 0xc0294000)
> 3ea0:                   bf01ab70 c02fb440 0000000a 00000000 c02fa048
> 0000000a
> 3ec0: c0293efc c0293ed0 c0048810 c0048454 c0293eec c0293ee0 c002a30c
> 00000001
> 3ee0: c02f9e44 0000000a 00000002 00000001 c0293f1c c0293f00 c00442a0
> c0048794
> 3f00: c0293f2c 0000001d c0294740 00000000 c0293f2c c0293f20 c00446d4
> c0044254
> 3f20: c0293f4c c0293f30 c00217b0 c0044698 c0293f5c ffffffff 0000ffff
> 00000001
> 3f40: c0293fa4 c0293f50 c00209e4 c0021770 00000001 00000001 c0292000
> 00000000
> 3f60: c0022068 c0292000 c0298c44 c03121c0 8001da24 4107b364 8001d9f0
> c0293fa4
> 3f80: c0293fa8 c0293f98 c0021d48 c002209c 60000013 ffffffff c0293fbc
> c0293fa8
> 3fa0: c0021d48 c0022074 c02faae0 c02f292c c0293fcc c0293fc0 c00202e0
> c0021d24
> 3fc0: c0293ff4 c0293fd0 c0008848 c00202b4 c00083c4 00000000 00000000
> c02f29a8
> 3fe0: 00000000 00c5387d 00000000 c0293ff8 80008030 c00086e0 00000000
> 00000000
> Backtrace:
> [<c0048448>] (cascade+0x0/0x8c) from [<c0048810>]
> (run_timer_softirq+0x88/0x1e8)
>  r6 = 0000000A  r5 = C02FA048  r4 = 00000000
> [<c0048788>] (run_timer_softirq+0x0/0x1e8) from [<c00442a0>]
> (__do_softirq+0x58/0xc8)
>  r8 = 00000001  r7 = 00000002  r6 = 0000000A  r5 = C02F9E44
>  r4 = 00000001
> [<c0044248>] (__do_softirq+0x0/0xc8) from [<c00446d4>] (irq_exit+0x48/0x5c)
>  r6 = 00000000  r5 = C0294740  r4 = 0000001D
> [<c004468c>] (irq_exit+0x0/0x5c) from [<c00217b0>] (asm_do_IRQ+0x4c/0x64)
> [<c0021764>] (asm_do_IRQ+0x0/0x64) from [<c00209e4>] (__irq_svc+0x44/0x80)
>  r6 = 00000001  r5 = 0000FFFF  r4 = FFFFFFFF
> [<c0022068>] (default_idle+0x0/0x3c) from [<c0021d48>] (cpu_idle+0x30/0x5c)
> [<c0021d18>] (cpu_idle+0x0/0x5c) from [<c00202e0>] (rest_init+0x38/0x40)
>  r5 = C02F292C  r4 = C02FAAE0
> [<c00202a8>] (rest_init+0x0/0x40) from [<c0008848>]
> (start_kernel+0x174/0x1c0)
> [<c00086d4>] (start_kernel+0x0/0x1c0) from [<80008030>] (0x80008030)
> Code: e1530005 15822000 ebffffb6 e1a0e004 (e5944000)
>  <0>Kernel panic - not syncing: Aiee, killing interrupt handler!
> 
> 
> also when i run it on X86 PC i am able to get the data and no panic where in
> on the board it is giving the above error ....
> 
> 2. I can raed the data using the user application when i run it on X86 PC
> where in i cant able to read the data when i run it on the board the data i
> was getting was always '/0' filled buffer .
> 
> 
> Here is the compilete code .............
> 
> 
> static int McBSP_DriverOpen(struct inode *inode,struct file *file)
> {
> 	/* Reintialize file operation structure */
> 	file->f_op=&fluke_fops;
> 

this is already set.

> 	printk(KERN_DEBUG" fluke driver open success \n");
> 
> 	if (device_open_count == 0)
> 	{
> 		device_open_count = 1;
> 
> 		/* Reset the read and write index*/
> 		buf_index_area.write_index=0;
> 		buf_index_area.read_index=-1;
> 		buf_index_area.count_index=0;
> 
> 		#ifdef SIMULATION
> 		/* Initialize the Timer */
> 		init_timer(&fluke_timer);
> 		fluke_timer.expires = jiffies + (HZ*10);//Timer will Expire after 60 sec
> 		fluke_timer.data = 0;
> 		fluke_timer.function = (void *)timer_func;
> 		add_timer(&fluke_timer);
> 		#endif
> 	}
> 
> 	return 0;
> }

Using the count in this way is racy, best write the code so
that it can allow multiple opens.

> irqreturn_t DataAcqIntHandler(int irq,void *dev_id, struct pt_regs *regs)
> {
> 	printk(KERN_ALERT" In Interrupt Handler\n");
> 	/* Data present status is set to wake up the read call */
> 	data_present_status=1;
> 
> 	/* Wake up the blocked Select call */
> 	wake_up_interruptible(&wait_queue);
> 
> 	#ifndef SIMULATION
> 	/* Clear the interrupt in the interrupt pending registor */
> 	cpi->ic_scprrh |=DATA_ACQ_INT_CLEAR;
> 	#endif
> 
> 	return IRQ_HANDLED;
> 
> }/* End of PpsIntrHandler() */

The interrupt handler should be able to deal with shared interrupts,
and needs to check if the interrupt came from this device, returning
IRQ_NONE otherwise.

> static int __init McBSP_DriverInit(void)
> {
> 	unsigned int virt_addr = 0;
> 	int mem = 0;
> 
> 	//buf_area = vmalloc(sizeof(circularbuffer_S));
> 	//if(!buf_area)
> 	//{
> 	//	printk(KERN_ALERT"vmalloc failed \n");
> 	//	return -1;
> 	//}
> 
> #if 0
> 	/*
> 	* Allocate memory for the circular buffer in the DMA coherent area
> 	* and algin it in the Cache
> 	*/
> 	mem = L1_CACHE_ALIGN(sizeof(circularbuffer_S));
> 
> 	buf_ptr = (char *)dma_alloc_coherent(NULL, mem, &dma_addr,GFP_KERNEL);

no need for the cast.

> 	printk(KERN_INFO" buf_ptr = 0x%x \n",(int )buf_ptr);
> 	if(NULL == buf_ptr )
> 	{
> 		printk(KERN_ALERT" Allocation of Memory failure ");
> 		return -1;
> 	}
> 
> 	buf_area = (circularbuffer_S *)(((unsigned int )buf_ptr + PAGE_SIZE - 1) \
> 			& PAGE_MASK);
> 
> 	printk(KERN_INFO" buf_area = 0x%x \n",(int )buf_area);
> 
> 	if(NULL == buf_area)
> 	{
> 		printk(KERN_ALERT" Circular buffer memory not allocated \n");
> 		return -1;
> 	}
> 
> 	/* Marking the Pages as reserved */
> 	for (virt_addr = (unsigned int)buf_area; \
> 	virt_addr < (unsigned int )buf_area + sizeof(circularbuffer_S);\
> 	virt_addr += PAGE_SIZE)
> 	{
> 		/* Set the pages as reserved */
> 		SetPageReserved(virt_to_page(virt_addr));
> 		//mem_map_reserve(virt_to_page(virt_addr));
> 	}

no need for SetPageReserved, it already is marked as in use through
the allocation.

> 	phy_addr = virt_to_phys(buf_ptr);

You can't use virt_to_phys to get the dma address. You also don't need that
because you already have it in dma_addr.


> 	printk(KERN_INFO"Allocated Memory for Circular Buffer at physical
> 0x0%x\n",phy_addr);
> 
> #else
> 
> 	buf_area = ioremap(0xB2000000,0x4000); //(0xB2000000,0x4000);
> //(7700000,900000);
> 	if(!buf_area)
> 	{
> 		printk(KERN_ALERT"ioremap failed \n");
> 		return -1;
> 	}

Don't hardcode the numbers here, you should get the values from the
device tree, and use of_iomap().
 
> 	printk(" Ioremap mapped to virtual 0x0%x \n",buf_area);
> 	*((unsigned int *)buf_area) = 0xa5a5a5a5;
> 	printk(" Ioremap data  0x0%x \n",*((unsigned int *)buf_area + 0));
> 
> #endif
> 
> 	/* Device major number is registered to set the driver entry point */
> 	if(register_chrdev(MAJOR_NO,MODULE_NAME, &fluke_fops)==0)
> 	{
> 		printk(KERN_DEBUG" Fluke driver registeration success \n");
> 
> 	}
> 	else
> 	{
> 		printk(KERN_ALERT" Fluke driver registeration failed \n");
> 		return -1;
> 	}

Since it's just one device, it's easier to use a misc_device.
 
> 	/*
> 	 * Register Data Acq interrupt request with specified irq and install the
> 	 * handler
> 	 */
> 	 if(request_irq(DATA_ACQ_INT,(void *)DataAcqIntHandler, SA_INTERRUPT,
> 	 						MODULE_NAME, NULL)==0)
> 	{
> 		printk(KERN_DEBUG" Data Acq interrupt request returns success \n");
> 	}
> 	else
> 	{
> 		printk(KERN_DEBUG" Data Acq interrupt request failed \n");
> 		unregister_chrdev(MAJOR_NO,MODULE_NAME);
> 		return -1;
> 
> 	}

hardcoding interrupt numbers is broken, interrupt numbers are relative to
one interrupt controller. Use irq_of_parse_and_map.

> static int McBSP_DriverIoctl(struct inode *inode, struct file *file,\
> 									unsigned int cmd, unsigned long param)
> {
> 	int i;
> 	daq_t daq_param;
> 
> 	printk(KERN_DEBUG"In ioctl command \n");
> 
> 	switch(cmd)
> 	{
> 		case START_ACQ_DATA:
> 
> 			if(copy_from_user(&daq_param,(void *)param,sizeof(daq_param)))
> 			{
> 
> 				return -1;
> 			}
> 
> 			/* For Simulation we are writing the data */
> 			if(WriteBuf() < 0)
> 			{
> 				printk(" Writing to the memory failure \n");
> 				return -1;
> 			}
> 
> 			/* Wait for the Interrupt to occur */
> 			wait_event_interruptible( wait_queue, data_present_status !=0);
> 
> 			printk("Read Index before read %d\n",buf_index_area.read_index);
> 			data_present_status=0;

Racy, you could have multiple threads doing this ioctl.
Moreover, you should not block in an ioctl but rather
implement a poll() function for waiting.

> 			buf_index_area.read_index++;
> 			buf_index_area.read_index%=NO_FRAMES;
> 
> 			if(buf_index_area.read_index ==((buf_index_area.write_index +1) %
> NO_FRAMES))
> 			//if(buf_index_area.read_index == buf_index_area.write_index )
> 			{
> 				printk("Read failure because read and write index are same\n");
> 				return -1;
> 			}
> 
> 			/* Decrement the count index to indicate the data availibility */
> 			down(&mutex);
> 			buf_index_area.count_index--;
> 			up(&mutex);

New drivers should not use semaphores (up/down) in places where they can use real
mutexes (mutex_lock/mutex_unlock).

> static int McBSP_DriverMmap(struct file *file,struct  vm_area_struct *vma)
> {
> 
> 	unsigned long start = vma->vm_start;
> 	unsigned long size = vma->vm_end - vma->vm_start; //0x900000;
> 	unsigned long phy_add = virt_to_phys(buf_ptr); //0x7700000;

virt_to_phys doesn't work on vmalloc memory.


> 	int ret = 0;
> 
> 	/* Make the mmaped area noncacheable */
> 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
> 
> 	/* Set the Flags to give permissions to Mmaped area */
> 	vma->vm_flags |=VM_RESERVED;
> 	vma->vm_flags |=VM_READ;
> 	vma->vm_flags |=VM_WRITE;
> 	vma->vm_flags |=VM_IO;
> 	//vma->vm_flags |=VM_SHARED;
> 	//vma->vm_flags |=VM_LOCKED;

For memory, you typically want to set vm_page_prot to use non-guarded mapping,
so that user space accesses are faster.

Not sure if VM_IO is right for vmalloc.

	Arnd <><

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-24  9:31                         ` Arnd Bergmann
@ 2008-07-25  8:43                           ` Misbah khan
  2008-07-25  8:50                             ` Arnd Bergmann
  2008-08-02 19:13                             ` harihanv
  0 siblings, 2 replies; 28+ messages in thread
From: Misbah khan @ 2008-07-25  8:43 UTC (permalink / raw)
  To: linuxppc-embedded


> printk(KERN_INFO"Allocated Memory for Circular Buffer at physical 
> 0x0%x\n",phy_addr); 
> 
> #else 
> 
> buf_area = ioremap(0xB2000000,0x4000); //(0xB2000000,0x4000); 
> //(7700000,900000); 
> if(!buf_area) 
> { 
> printk(KERN_ALERT"ioremap failed \n"); 
> return -1; 
> } ...[show rest of quote]
Don't hardcode the numbers here, you should get the values from the 
device tree, and use of_iomap(). 

I am really unaware of how can we get this physical address from the device
tree which you have mentioned can you please explain this to me ???

Suppose there is one situation in which i have to map ram of the address
0x800000 to 9MB will it be good if i do this to map to user space 

static int McBSP_DriverMmap(struct file *file,struct  vm_area_struct *vma)
{

	unsigned long start = vma->vm_start ;
	unsigned long size = 0x900000 ;
	unsigned long phy_add = 0x800000;
	int ret = 0;

	/* Make the mmaped area noncacheable */
	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

	/* Set the Flags to give permissions to Mmaped area */
	vma->vm_flags |=VM_RESERVED;
	vma->vm_flags |=VM_READ;
	vma->vm_flags |=VM_WRITE;
	
	printk(KERN_DEBUG"In mmap function\n");

	/* Mmap the kernel buffer to user space */
	if(remap_pfn_range(vma,start,(phy_add >>
PAGE_SHIFT),size,vma->vm_page_prot))
	{
		printk(KERN_ALERT"remap_pfn_range failed\n");
		goto mmap_exit;

   	}

   	printk(KERN_ALERT"phy addr 0x%08X mmapped to virt addr 0x%08X, size =
0x%08X\n",
		(unsigned int)phy_add, (unsigned int)start, (unsigned int)size);

	/* Initialize the file operation structure of Mmaped area */
	vma->vm_ops=&mmap_op;

	/* Open the Mmaped area */
	MmapOpen(vma);

	mmap_exit:
	   	return ret;
}

suppose the same mapping i have to do using nopage method then shall i
specify the RAM physical address and sixe in the same manner ???


There is one more concern that i have now is that i am writing a pattern
(say 0xa5a5a5a5) to cpld by building the page using remap_pfn_range but when
i try to read it its showing the pattern as a5a5a5a50000000a5a5a5a50000000
like with zeros in between is it a non aligned page problem.

----- Misbah <><

Arnd Bergmann wrote:
> 
> On Thursday 24 July 2008, Misbah khan wrote:
>> 
>> Hi all ...
>>  
>> I am uploading the source code which is doing the following :-
>> 
>> 1. mapping cpld register using ioremap coping the data to circular buffer
>> and remapping it to user space .
>> 
>> 2. It can also map kernel virtual dma memory to user space if compiled
>> conditionally .
>> 
>> following is the problem which i am facing ...
>> 
>> 1. It is somitimes giving following kernel panic ....
>> 
>> nable to handle kernel NULL pointer dereference at virtual address
>> 00000000
>> pgd = c0004000
>> [00000000] *pgd=00000000
>> Internal error: Oops: 17 [#1]
>> Modules linked in: fluke_driver tstamp sig_router mvci_spi mvci_sf_pcd
>> mvci_sci_unidir_s1 mvci_sci_diff mvci_sci_bidir_s
>> 1 mvci_rtmd_s1 mvci_kwiso_s1 mvci_kw1281_s1 mvci_kh_s1 mvci_j1850
>> mvci_gm_sbc mvci_diagh_s1 g_ether mvci_dcl mvci_can1 f
>> pga_conf arcotg_udc adc_dac keypad(F) splc501_lcd(F) cpld
>> CPU: 0
>> PC is at cascade+0x64/0x8c
>> LR is at __init_begin+0x3fff8000/0x30
>> pc : [<c00484ac>]    lr : [<00000000>]    Tainted: GF
>> sp : c0293ea8  ip : 0040b000  fp : c0293ecc
>> r10: 8001d9f0  r9 : c0292000  r8 : 00000001
>> r7 : c0292000  r6 : 0000000c  r5 : c02fa048  r4 : 00000000
>> r3 : c02fa2f8  r2 : 0000261a  r1 : bf01ab70  r0 : c02fa2f8
>> Flags: Nzcv  IRQs off  FIQs on  Mode SVC_32  Segment kernel
>> Control: C5387F
>> Table: 8698C000  DAC: 00000017
>> Process swapper (pid: 0, stack limit = 0xc0292250)
>> Stack: (0xc0293ea8 to 0xc0294000)
>> 3ea0:                   bf01ab70 c02fb440 0000000a 00000000 c02fa048
>> 0000000a
>> 3ec0: c0293efc c0293ed0 c0048810 c0048454 c0293eec c0293ee0 c002a30c
>> 00000001
>> 3ee0: c02f9e44 0000000a 00000002 00000001 c0293f1c c0293f00 c00442a0
>> c0048794
>> 3f00: c0293f2c 0000001d c0294740 00000000 c0293f2c c0293f20 c00446d4
>> c0044254
>> 3f20: c0293f4c c0293f30 c00217b0 c0044698 c0293f5c ffffffff 0000ffff
>> 00000001
>> 3f40: c0293fa4 c0293f50 c00209e4 c0021770 00000001 00000001 c0292000
>> 00000000
>> 3f60: c0022068 c0292000 c0298c44 c03121c0 8001da24 4107b364 8001d9f0
>> c0293fa4
>> 3f80: c0293fa8 c0293f98 c0021d48 c002209c 60000013 ffffffff c0293fbc
>> c0293fa8
>> 3fa0: c0021d48 c0022074 c02faae0 c02f292c c0293fcc c0293fc0 c00202e0
>> c0021d24
>> 3fc0: c0293ff4 c0293fd0 c0008848 c00202b4 c00083c4 00000000 00000000
>> c02f29a8
>> 3fe0: 00000000 00c5387d 00000000 c0293ff8 80008030 c00086e0 00000000
>> 00000000
>> Backtrace:
>> [<c0048448>] (cascade+0x0/0x8c) from [<c0048810>]
>> (run_timer_softirq+0x88/0x1e8)
>>  r6 = 0000000A  r5 = C02FA048  r4 = 00000000
>> [<c0048788>] (run_timer_softirq+0x0/0x1e8) from [<c00442a0>]
>> (__do_softirq+0x58/0xc8)
>>  r8 = 00000001  r7 = 00000002  r6 = 0000000A  r5 = C02F9E44
>>  r4 = 00000001
>> [<c0044248>] (__do_softirq+0x0/0xc8) from [<c00446d4>]
>> (irq_exit+0x48/0x5c)
>>  r6 = 00000000  r5 = C0294740  r4 = 0000001D
>> [<c004468c>] (irq_exit+0x0/0x5c) from [<c00217b0>] (asm_do_IRQ+0x4c/0x64)
>> [<c0021764>] (asm_do_IRQ+0x0/0x64) from [<c00209e4>]
>> (__irq_svc+0x44/0x80)
>>  r6 = 00000001  r5 = 0000FFFF  r4 = FFFFFFFF
>> [<c0022068>] (default_idle+0x0/0x3c) from [<c0021d48>]
>> (cpu_idle+0x30/0x5c)
>> [<c0021d18>] (cpu_idle+0x0/0x5c) from [<c00202e0>] (rest_init+0x38/0x40)
>>  r5 = C02F292C  r4 = C02FAAE0
>> [<c00202a8>] (rest_init+0x0/0x40) from [<c0008848>]
>> (start_kernel+0x174/0x1c0)
>> [<c00086d4>] (start_kernel+0x0/0x1c0) from [<80008030>] (0x80008030)
>> Code: e1530005 15822000 ebffffb6 e1a0e004 (e5944000)
>>  <0>Kernel panic - not syncing: Aiee, killing interrupt handler!
>> 
>> 
>> also when i run it on X86 PC i am able to get the data and no panic where
>> in
>> on the board it is giving the above error ....
>> 
>> 2. I can raed the data using the user application when i run it on X86 PC
>> where in i cant able to read the data when i run it on the board the data
>> i
>> was getting was always '/0' filled buffer .
>> 
>> 
>> Here is the compilete code .............
>> 
>> 
>> static int McBSP_DriverOpen(struct inode *inode,struct file *file)
>> {
>> 	/* Reintialize file operation structure */
>> 	file->f_op=&fluke_fops;
>> 
> 
> this is already set.
> 
>> 	printk(KERN_DEBUG" fluke driver open success \n");
>> 
>> 	if (device_open_count == 0)
>> 	{
>> 		device_open_count = 1;
>> 
>> 		/* Reset the read and write index*/
>> 		buf_index_area.write_index=0;
>> 		buf_index_area.read_index=-1;
>> 		buf_index_area.count_index=0;
>> 
>> 		#ifdef SIMULATION
>> 		/* Initialize the Timer */
>> 		init_timer(&fluke_timer);
>> 		fluke_timer.expires = jiffies + (HZ*10);//Timer will Expire after 60
>> sec
>> 		fluke_timer.data = 0;
>> 		fluke_timer.function = (void *)timer_func;
>> 		add_timer(&fluke_timer);
>> 		#endif
>> 	}
>> 
>> 	return 0;
>> }
> 
> Using the count in this way is racy, best write the code so
> that it can allow multiple opens.
> 
>> irqreturn_t DataAcqIntHandler(int irq,void *dev_id, struct pt_regs *regs)
>> {
>> 	printk(KERN_ALERT" In Interrupt Handler\n");
>> 	/* Data present status is set to wake up the read call */
>> 	data_present_status=1;
>> 
>> 	/* Wake up the blocked Select call */
>> 	wake_up_interruptible(&wait_queue);
>> 
>> 	#ifndef SIMULATION
>> 	/* Clear the interrupt in the interrupt pending registor */
>> 	cpi->ic_scprrh |=DATA_ACQ_INT_CLEAR;
>> 	#endif
>> 
>> 	return IRQ_HANDLED;
>> 
>> }/* End of PpsIntrHandler() */
> 
> The interrupt handler should be able to deal with shared interrupts,
> and needs to check if the interrupt came from this device, returning
> IRQ_NONE otherwise.
> 
>> static int __init McBSP_DriverInit(void)
>> {
>> 	unsigned int virt_addr = 0;
>> 	int mem = 0;
>> 
>> 	//buf_area = vmalloc(sizeof(circularbuffer_S));
>> 	//if(!buf_area)
>> 	//{
>> 	//	printk(KERN_ALERT"vmalloc failed \n");
>> 	//	return -1;
>> 	//}
>> 
>> #if 0
>> 	/*
>> 	* Allocate memory for the circular buffer in the DMA coherent area
>> 	* and algin it in the Cache
>> 	*/
>> 	mem = L1_CACHE_ALIGN(sizeof(circularbuffer_S));
>> 
>> 	buf_ptr = (char *)dma_alloc_coherent(NULL, mem, &dma_addr,GFP_KERNEL);
> 
> no need for the cast.
> 
>> 	printk(KERN_INFO" buf_ptr = 0x%x \n",(int )buf_ptr);
>> 	if(NULL == buf_ptr )
>> 	{
>> 		printk(KERN_ALERT" Allocation of Memory failure ");
>> 		return -1;
>> 	}
>> 
>> 	buf_area = (circularbuffer_S *)(((unsigned int )buf_ptr + PAGE_SIZE - 1)
>> \
>> 			& PAGE_MASK);
>> 
>> 	printk(KERN_INFO" buf_area = 0x%x \n",(int )buf_area);
>> 
>> 	if(NULL == buf_area)
>> 	{
>> 		printk(KERN_ALERT" Circular buffer memory not allocated \n");
>> 		return -1;
>> 	}
>> 
>> 	/* Marking the Pages as reserved */
>> 	for (virt_addr = (unsigned int)buf_area; \
>> 	virt_addr < (unsigned int )buf_area + sizeof(circularbuffer_S);\
>> 	virt_addr += PAGE_SIZE)
>> 	{
>> 		/* Set the pages as reserved */
>> 		SetPageReserved(virt_to_page(virt_addr));
>> 		//mem_map_reserve(virt_to_page(virt_addr));
>> 	}
> 
> no need for SetPageReserved, it already is marked as in use through
> the allocation.
> 
>> 	phy_addr = virt_to_phys(buf_ptr);
> 
> You can't use virt_to_phys to get the dma address. You also don't need
> that
> because you already have it in dma_addr.
> 
> 
>> 	printk(KERN_INFO"Allocated Memory for Circular Buffer at physical
>> 0x0%x\n",phy_addr);
>> 
>> #else
>> 
>> 	buf_area = ioremap(0xB2000000,0x4000); //(0xB2000000,0x4000);
>> //(7700000,900000);
>> 	if(!buf_area)
>> 	{
>> 		printk(KERN_ALERT"ioremap failed \n");
>> 		return -1;
>> 	}
> 
> Don't hardcode the numbers here, you should get the values from the
> device tree, and use of_iomap().
>  
>> 	printk(" Ioremap mapped to virtual 0x0%x \n",buf_area);
>> 	*((unsigned int *)buf_area) = 0xa5a5a5a5;
>> 	printk(" Ioremap data  0x0%x \n",*((unsigned int *)buf_area + 0));
>> 
>> #endif
>> 
>> 	/* Device major number is registered to set the driver entry point */
>> 	if(register_chrdev(MAJOR_NO,MODULE_NAME, &fluke_fops)==0)
>> 	{
>> 		printk(KERN_DEBUG" Fluke driver registeration success \n");
>> 
>> 	}
>> 	else
>> 	{
>> 		printk(KERN_ALERT" Fluke driver registeration failed \n");
>> 		return -1;
>> 	}
> 
> Since it's just one device, it's easier to use a misc_device.
>  
>> 	/*
>> 	 * Register Data Acq interrupt request with specified irq and install
>> the
>> 	 * handler
>> 	 */
>> 	 if(request_irq(DATA_ACQ_INT,(void *)DataAcqIntHandler, SA_INTERRUPT,
>> 	 						MODULE_NAME, NULL)==0)
>> 	{
>> 		printk(KERN_DEBUG" Data Acq interrupt request returns success \n");
>> 	}
>> 	else
>> 	{
>> 		printk(KERN_DEBUG" Data Acq interrupt request failed \n");
>> 		unregister_chrdev(MAJOR_NO,MODULE_NAME);
>> 		return -1;
>> 
>> 	}
> 
> hardcoding interrupt numbers is broken, interrupt numbers are relative to
> one interrupt controller. Use irq_of_parse_and_map.
> 
>> static int McBSP_DriverIoctl(struct inode *inode, struct file *file,\
>> 									unsigned int cmd, unsigned long param)
>> {
>> 	int i;
>> 	daq_t daq_param;
>> 
>> 	printk(KERN_DEBUG"In ioctl command \n");
>> 
>> 	switch(cmd)
>> 	{
>> 		case START_ACQ_DATA:
>> 
>> 			if(copy_from_user(&daq_param,(void *)param,sizeof(daq_param)))
>> 			{
>> 
>> 				return -1;
>> 			}
>> 
>> 			/* For Simulation we are writing the data */
>> 			if(WriteBuf() < 0)
>> 			{
>> 				printk(" Writing to the memory failure \n");
>> 				return -1;
>> 			}
>> 
>> 			/* Wait for the Interrupt to occur */
>> 			wait_event_interruptible( wait_queue, data_present_status !=0);
>> 
>> 			printk("Read Index before read %d\n",buf_index_area.read_index);
>> 			data_present_status=0;
> 
> Racy, you could have multiple threads doing this ioctl.
> Moreover, you should not block in an ioctl but rather
> implement a poll() function for waiting.
> 
>> 			buf_index_area.read_index++;
>> 			buf_index_area.read_index%=NO_FRAMES;
>> 
>> 			if(buf_index_area.read_index ==((buf_index_area.write_index +1) %
>> NO_FRAMES))
>> 			//if(buf_index_area.read_index == buf_index_area.write_index )
>> 			{
>> 				printk("Read failure because read and write index are same\n");
>> 				return -1;
>> 			}
>> 
>> 			/* Decrement the count index to indicate the data availibility */
>> 			down(&mutex);
>> 			buf_index_area.count_index--;
>> 			up(&mutex);
> 
> New drivers should not use semaphores (up/down) in places where they can
> use real
> mutexes (mutex_lock/mutex_unlock).
> 
>> static int McBSP_DriverMmap(struct file *file,struct  vm_area_struct
>> *vma)
>> {
>> 
>> 	unsigned long start = vma->vm_start;
>> 	unsigned long size = vma->vm_end - vma->vm_start; //0x900000;
>> 	unsigned long phy_add = virt_to_phys(buf_ptr); //0x7700000;
> 
> virt_to_phys doesn't work on vmalloc memory.
> 
> 
>> 	int ret = 0;
>> 
>> 	/* Make the mmaped area noncacheable */
>> 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
>> 
>> 	/* Set the Flags to give permissions to Mmaped area */
>> 	vma->vm_flags |=VM_RESERVED;
>> 	vma->vm_flags |=VM_READ;
>> 	vma->vm_flags |=VM_WRITE;
>> 	vma->vm_flags |=VM_IO;
>> 	//vma->vm_flags |=VM_SHARED;
>> 	//vma->vm_flags |=VM_LOCKED;
> 
> For memory, you typically want to set vm_page_prot to use non-guarded
> mapping,
> so that user space accesses are faster.
> 
> Not sure if VM_IO is right for vmalloc.
> 
> 	Arnd <><
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> 
> 

-- 
View this message in context: http://www.nabble.com/how-to-allocate-9MB-of-memory-in-kernel---tp18503022p18647614.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-25  8:43                           ` Misbah khan
@ 2008-07-25  8:50                             ` Arnd Bergmann
  2008-08-02 19:13                             ` harihanv
  1 sibling, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2008-07-25  8:50 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: Misbah khan

On Friday 25 July 2008, Misbah khan wrote:
> 
> I am really unaware of how can we get this physical address from the device
> tree which you have mentioned can you please explain this to me ???

With current Linux versions, all powerpc machines come with an open-firmware
like device tree, which describes all devices that are part of the
system. If your machine doesn't run an actual open firmware implementation,
you most likely have the device tree source in arch/powerpc/boot/dts/,
and that needs to describe your device.

Your init function should then not assume that the device is there, but
register an of_platform_driver for that device.
When the driver is loaded, it is then bound to your hardware, and a
struct of_device gets passed to a probe() function that does the
actual initialization.
That is the device you pass to of_iomap in order to mmap the I/O range.

	Arnd <><

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: how to allocate 9MB of memory in kernel ?
  2008-07-25  8:43                           ` Misbah khan
  2008-07-25  8:50                             ` Arnd Bergmann
@ 2008-08-02 19:13                             ` harihanv
  1 sibling, 0 replies; 28+ messages in thread
From: harihanv @ 2008-08-02 19:13 UTC (permalink / raw)
  To: linuxppc-embedded


Hi,

I also want to allocate 4MB space for DMA from external device. if possible,
please let me know how did you overcome the problem of using mmap option
from the userspace

Regards
Harish



Misbah khan wrote:
> 
>> printk(KERN_INFO"Allocated Memory for Circular Buffer at physical 
>> 0x0%x\n",phy_addr); 
>> 
>> #else 
>> 
>> buf_area = ioremap(0xB2000000,0x4000); //(0xB2000000,0x4000); 
>> //(7700000,900000); 
>> if(!buf_area) 
>> { 
>> printk(KERN_ALERT"ioremap failed \n"); 
>> return -1; 
>> } ...[show rest of quote]
> Don't hardcode the numbers here, you should get the values from the 
> device tree, and use of_iomap(). 
> 
> I am really unaware of how can we get this physical address from the
> device tree which you have mentioned can you please explain this to me ???
> 
> Suppose there is one situation in which i have to map ram of the address
> 0x800000 to 9MB will it be good if i do this to map to user space 
> 
> static int McBSP_DriverMmap(struct file *file,struct  vm_area_struct *vma)
> {
> 
> 	unsigned long start = vma->vm_start ;
> 	unsigned long size = 0x900000 ;
> 	unsigned long phy_add = 0x800000;
> 	int ret = 0;
> 
> 	/* Make the mmaped area noncacheable */
> 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
> 
> 	/* Set the Flags to give permissions to Mmaped area */
> 	vma->vm_flags |=VM_RESERVED;
> 	vma->vm_flags |=VM_READ;
> 	vma->vm_flags |=VM_WRITE;
> 	
> 	printk(KERN_DEBUG"In mmap function\n");
> 
> 	/* Mmap the kernel buffer to user space */
> 	if(remap_pfn_range(vma,start,(phy_add >>
> PAGE_SHIFT),size,vma->vm_page_prot))
> 	{
> 		printk(KERN_ALERT"remap_pfn_range failed\n");
> 		goto mmap_exit;
> 
>    	}
> 
>    	printk(KERN_ALERT"phy addr 0x%08X mmapped to virt addr 0x%08X, size =
> 0x%08X\n",
> 		(unsigned int)phy_add, (unsigned int)start, (unsigned int)size);
> 
> 	/* Initialize the file operation structure of Mmaped area */
> 	vma->vm_ops=&mmap_op;
> 
> 	/* Open the Mmaped area */
> 	MmapOpen(vma);
> 
> 	mmap_exit:
> 	   	return ret;
> }
> 
> suppose the same mapping i have to do using nopage method then shall i
> specify the RAM physical address and sixe in the same manner ???
> 
> 
> There is one more concern that i have now is that i am writing a pattern
> (say 0xa5a5a5a5) to cpld by building the page using remap_pfn_range but
> when i try to read it its showing the pattern as
> a5a5a5a50000000a5a5a5a50000000 like with zeros in between is it a non
> aligned page problem.
> 
> ----- Misbah <><
> 
> Arnd Bergmann wrote:
>> 
>> On Thursday 24 July 2008, Misbah khan wrote:
>>> 
>>> Hi all ...
>>>  
>>> I am uploading the source code which is doing the following :-
>>> 
>>> 1. mapping cpld register using ioremap coping the data to circular
>>> buffer
>>> and remapping it to user space .
>>> 
>>> 2. It can also map kernel virtual dma memory to user space if compiled
>>> conditionally .
>>> 
>>> following is the problem which i am facing ...
>>> 
>>> 1. It is somitimes giving following kernel panic ....
>>> 
>>> nable to handle kernel NULL pointer dereference at virtual address
>>> 00000000
>>> pgd = c0004000
>>> [00000000] *pgd=00000000
>>> Internal error: Oops: 17 [#1]
>>> Modules linked in: fluke_driver tstamp sig_router mvci_spi mvci_sf_pcd
>>> mvci_sci_unidir_s1 mvci_sci_diff mvci_sci_bidir_s
>>> 1 mvci_rtmd_s1 mvci_kwiso_s1 mvci_kw1281_s1 mvci_kh_s1 mvci_j1850
>>> mvci_gm_sbc mvci_diagh_s1 g_ether mvci_dcl mvci_can1 f
>>> pga_conf arcotg_udc adc_dac keypad(F) splc501_lcd(F) cpld
>>> CPU: 0
>>> PC is at cascade+0x64/0x8c
>>> LR is at __init_begin+0x3fff8000/0x30
>>> pc : [<c00484ac>]    lr : [<00000000>]    Tainted: GF
>>> sp : c0293ea8  ip : 0040b000  fp : c0293ecc
>>> r10: 8001d9f0  r9 : c0292000  r8 : 00000001
>>> r7 : c0292000  r6 : 0000000c  r5 : c02fa048  r4 : 00000000
>>> r3 : c02fa2f8  r2 : 0000261a  r1 : bf01ab70  r0 : c02fa2f8
>>> Flags: Nzcv  IRQs off  FIQs on  Mode SVC_32  Segment kernel
>>> Control: C5387F
>>> Table: 8698C000  DAC: 00000017
>>> Process swapper (pid: 0, stack limit = 0xc0292250)
>>> Stack: (0xc0293ea8 to 0xc0294000)
>>> 3ea0:                   bf01ab70 c02fb440 0000000a 00000000 c02fa048
>>> 0000000a
>>> 3ec0: c0293efc c0293ed0 c0048810 c0048454 c0293eec c0293ee0 c002a30c
>>> 00000001
>>> 3ee0: c02f9e44 0000000a 00000002 00000001 c0293f1c c0293f00 c00442a0
>>> c0048794
>>> 3f00: c0293f2c 0000001d c0294740 00000000 c0293f2c c0293f20 c00446d4
>>> c0044254
>>> 3f20: c0293f4c c0293f30 c00217b0 c0044698 c0293f5c ffffffff 0000ffff
>>> 00000001
>>> 3f40: c0293fa4 c0293f50 c00209e4 c0021770 00000001 00000001 c0292000
>>> 00000000
>>> 3f60: c0022068 c0292000 c0298c44 c03121c0 8001da24 4107b364 8001d9f0
>>> c0293fa4
>>> 3f80: c0293fa8 c0293f98 c0021d48 c002209c 60000013 ffffffff c0293fbc
>>> c0293fa8
>>> 3fa0: c0021d48 c0022074 c02faae0 c02f292c c0293fcc c0293fc0 c00202e0
>>> c0021d24
>>> 3fc0: c0293ff4 c0293fd0 c0008848 c00202b4 c00083c4 00000000 00000000
>>> c02f29a8
>>> 3fe0: 00000000 00c5387d 00000000 c0293ff8 80008030 c00086e0 00000000
>>> 00000000
>>> Backtrace:
>>> [<c0048448>] (cascade+0x0/0x8c) from [<c0048810>]
>>> (run_timer_softirq+0x88/0x1e8)
>>>  r6 = 0000000A  r5 = C02FA048  r4 = 00000000
>>> [<c0048788>] (run_timer_softirq+0x0/0x1e8) from [<c00442a0>]
>>> (__do_softirq+0x58/0xc8)
>>>  r8 = 00000001  r7 = 00000002  r6 = 0000000A  r5 = C02F9E44
>>>  r4 = 00000001
>>> [<c0044248>] (__do_softirq+0x0/0xc8) from [<c00446d4>]
>>> (irq_exit+0x48/0x5c)
>>>  r6 = 00000000  r5 = C0294740  r4 = 0000001D
>>> [<c004468c>] (irq_exit+0x0/0x5c) from [<c00217b0>]
>>> (asm_do_IRQ+0x4c/0x64)
>>> [<c0021764>] (asm_do_IRQ+0x0/0x64) from [<c00209e4>]
>>> (__irq_svc+0x44/0x80)
>>>  r6 = 00000001  r5 = 0000FFFF  r4 = FFFFFFFF
>>> [<c0022068>] (default_idle+0x0/0x3c) from [<c0021d48>]
>>> (cpu_idle+0x30/0x5c)
>>> [<c0021d18>] (cpu_idle+0x0/0x5c) from [<c00202e0>] (rest_init+0x38/0x40)
>>>  r5 = C02F292C  r4 = C02FAAE0
>>> [<c00202a8>] (rest_init+0x0/0x40) from [<c0008848>]
>>> (start_kernel+0x174/0x1c0)
>>> [<c00086d4>] (start_kernel+0x0/0x1c0) from [<80008030>] (0x80008030)
>>> Code: e1530005 15822000 ebffffb6 e1a0e004 (e5944000)
>>>  <0>Kernel panic - not syncing: Aiee, killing interrupt handler!
>>> 
>>> 
>>> also when i run it on X86 PC i am able to get the data and no panic
>>> where in
>>> on the board it is giving the above error ....
>>> 
>>> 2. I can raed the data using the user application when i run it on X86
>>> PC
>>> where in i cant able to read the data when i run it on the board the
>>> data i
>>> was getting was always '/0' filled buffer .
>>> 
>>> 
>>> Here is the compilete code .............
>>> 
>>> 
>>> static int McBSP_DriverOpen(struct inode *inode,struct file *file)
>>> {
>>> 	/* Reintialize file operation structure */
>>> 	file->f_op=&fluke_fops;
>>> 
>> 
>> this is already set.
>> 
>>> 	printk(KERN_DEBUG" fluke driver open success \n");
>>> 
>>> 	if (device_open_count == 0)
>>> 	{
>>> 		device_open_count = 1;
>>> 
>>> 		/* Reset the read and write index*/
>>> 		buf_index_area.write_index=0;
>>> 		buf_index_area.read_index=-1;
>>> 		buf_index_area.count_index=0;
>>> 
>>> 		#ifdef SIMULATION
>>> 		/* Initialize the Timer */
>>> 		init_timer(&fluke_timer);
>>> 		fluke_timer.expires = jiffies + (HZ*10);//Timer will Expire after 60
>>> sec
>>> 		fluke_timer.data = 0;
>>> 		fluke_timer.function = (void *)timer_func;
>>> 		add_timer(&fluke_timer);
>>> 		#endif
>>> 	}
>>> 
>>> 	return 0;
>>> }
>> 
>> Using the count in this way is racy, best write the code so
>> that it can allow multiple opens.
>> 
>>> irqreturn_t DataAcqIntHandler(int irq,void *dev_id, struct pt_regs
>>> *regs)
>>> {
>>> 	printk(KERN_ALERT" In Interrupt Handler\n");
>>> 	/* Data present status is set to wake up the read call */
>>> 	data_present_status=1;
>>> 
>>> 	/* Wake up the blocked Select call */
>>> 	wake_up_interruptible(&wait_queue);
>>> 
>>> 	#ifndef SIMULATION
>>> 	/* Clear the interrupt in the interrupt pending registor */
>>> 	cpi->ic_scprrh |=DATA_ACQ_INT_CLEAR;
>>> 	#endif
>>> 
>>> 	return IRQ_HANDLED;
>>> 
>>> }/* End of PpsIntrHandler() */
>> 
>> The interrupt handler should be able to deal with shared interrupts,
>> and needs to check if the interrupt came from this device, returning
>> IRQ_NONE otherwise.
>> 
>>> static int __init McBSP_DriverInit(void)
>>> {
>>> 	unsigned int virt_addr = 0;
>>> 	int mem = 0;
>>> 
>>> 	//buf_area = vmalloc(sizeof(circularbuffer_S));
>>> 	//if(!buf_area)
>>> 	//{
>>> 	//	printk(KERN_ALERT"vmalloc failed \n");
>>> 	//	return -1;
>>> 	//}
>>> 
>>> #if 0
>>> 	/*
>>> 	* Allocate memory for the circular buffer in the DMA coherent area
>>> 	* and algin it in the Cache
>>> 	*/
>>> 	mem = L1_CACHE_ALIGN(sizeof(circularbuffer_S));
>>> 
>>> 	buf_ptr = (char *)dma_alloc_coherent(NULL, mem, &dma_addr,GFP_KERNEL);
>> 
>> no need for the cast.
>> 
>>> 	printk(KERN_INFO" buf_ptr = 0x%x \n",(int )buf_ptr);
>>> 	if(NULL == buf_ptr )
>>> 	{
>>> 		printk(KERN_ALERT" Allocation of Memory failure ");
>>> 		return -1;
>>> 	}
>>> 
>>> 	buf_area = (circularbuffer_S *)(((unsigned int )buf_ptr + PAGE_SIZE -
>>> 1) \
>>> 			& PAGE_MASK);
>>> 
>>> 	printk(KERN_INFO" buf_area = 0x%x \n",(int )buf_area);
>>> 
>>> 	if(NULL == buf_area)
>>> 	{
>>> 		printk(KERN_ALERT" Circular buffer memory not allocated \n");
>>> 		return -1;
>>> 	}
>>> 
>>> 	/* Marking the Pages as reserved */
>>> 	for (virt_addr = (unsigned int)buf_area; \
>>> 	virt_addr < (unsigned int )buf_area + sizeof(circularbuffer_S);\
>>> 	virt_addr += PAGE_SIZE)
>>> 	{
>>> 		/* Set the pages as reserved */
>>> 		SetPageReserved(virt_to_page(virt_addr));
>>> 		//mem_map_reserve(virt_to_page(virt_addr));
>>> 	}
>> 
>> no need for SetPageReserved, it already is marked as in use through
>> the allocation.
>> 
>>> 	phy_addr = virt_to_phys(buf_ptr);
>> 
>> You can't use virt_to_phys to get the dma address. You also don't need
>> that
>> because you already have it in dma_addr.
>> 
>> 
>>> 	printk(KERN_INFO"Allocated Memory for Circular Buffer at physical
>>> 0x0%x\n",phy_addr);
>>> 
>>> #else
>>> 
>>> 	buf_area = ioremap(0xB2000000,0x4000); //(0xB2000000,0x4000);
>>> //(7700000,900000);
>>> 	if(!buf_area)
>>> 	{
>>> 		printk(KERN_ALERT"ioremap failed \n");
>>> 		return -1;
>>> 	}
>> 
>> Don't hardcode the numbers here, you should get the values from the
>> device tree, and use of_iomap().
>>  
>>> 	printk(" Ioremap mapped to virtual 0x0%x \n",buf_area);
>>> 	*((unsigned int *)buf_area) = 0xa5a5a5a5;
>>> 	printk(" Ioremap data  0x0%x \n",*((unsigned int *)buf_area + 0));
>>> 
>>> #endif
>>> 
>>> 	/* Device major number is registered to set the driver entry point */
>>> 	if(register_chrdev(MAJOR_NO,MODULE_NAME, &fluke_fops)==0)
>>> 	{
>>> 		printk(KERN_DEBUG" Fluke driver registeration success \n");
>>> 
>>> 	}
>>> 	else
>>> 	{
>>> 		printk(KERN_ALERT" Fluke driver registeration failed \n");
>>> 		return -1;
>>> 	}
>> 
>> Since it's just one device, it's easier to use a misc_device.
>>  
>>> 	/*
>>> 	 * Register Data Acq interrupt request with specified irq and install
>>> the
>>> 	 * handler
>>> 	 */
>>> 	 if(request_irq(DATA_ACQ_INT,(void *)DataAcqIntHandler, SA_INTERRUPT,
>>> 	 						MODULE_NAME, NULL)==0)
>>> 	{
>>> 		printk(KERN_DEBUG" Data Acq interrupt request returns success \n");
>>> 	}
>>> 	else
>>> 	{
>>> 		printk(KERN_DEBUG" Data Acq interrupt request failed \n");
>>> 		unregister_chrdev(MAJOR_NO,MODULE_NAME);
>>> 		return -1;
>>> 
>>> 	}
>> 
>> hardcoding interrupt numbers is broken, interrupt numbers are relative to
>> one interrupt controller. Use irq_of_parse_and_map.
>> 
>>> static int McBSP_DriverIoctl(struct inode *inode, struct file *file,\
>>> 									unsigned int cmd, unsigned long param)
>>> {
>>> 	int i;
>>> 	daq_t daq_param;
>>> 
>>> 	printk(KERN_DEBUG"In ioctl command \n");
>>> 
>>> 	switch(cmd)
>>> 	{
>>> 		case START_ACQ_DATA:
>>> 
>>> 			if(copy_from_user(&daq_param,(void *)param,sizeof(daq_param)))
>>> 			{
>>> 
>>> 				return -1;
>>> 			}
>>> 
>>> 			/* For Simulation we are writing the data */
>>> 			if(WriteBuf() < 0)
>>> 			{
>>> 				printk(" Writing to the memory failure \n");
>>> 				return -1;
>>> 			}
>>> 
>>> 			/* Wait for the Interrupt to occur */
>>> 			wait_event_interruptible( wait_queue, data_present_status !=0);
>>> 
>>> 			printk("Read Index before read %d\n",buf_index_area.read_index);
>>> 			data_present_status=0;
>> 
>> Racy, you could have multiple threads doing this ioctl.
>> Moreover, you should not block in an ioctl but rather
>> implement a poll() function for waiting.
>> 
>>> 			buf_index_area.read_index++;
>>> 			buf_index_area.read_index%=NO_FRAMES;
>>> 
>>> 			if(buf_index_area.read_index ==((buf_index_area.write_index +1) %
>>> NO_FRAMES))
>>> 			//if(buf_index_area.read_index == buf_index_area.write_index )
>>> 			{
>>> 				printk("Read failure because read and write index are same\n");
>>> 				return -1;
>>> 			}
>>> 
>>> 			/* Decrement the count index to indicate the data availibility */
>>> 			down(&mutex);
>>> 			buf_index_area.count_index--;
>>> 			up(&mutex);
>> 
>> New drivers should not use semaphores (up/down) in places where they can
>> use real
>> mutexes (mutex_lock/mutex_unlock).
>> 
>>> static int McBSP_DriverMmap(struct file *file,struct  vm_area_struct
>>> *vma)
>>> {
>>> 
>>> 	unsigned long start = vma->vm_start;
>>> 	unsigned long size = vma->vm_end - vma->vm_start; //0x900000;
>>> 	unsigned long phy_add = virt_to_phys(buf_ptr); //0x7700000;
>> 
>> virt_to_phys doesn't work on vmalloc memory.
>> 
>> 
>>> 	int ret = 0;
>>> 
>>> 	/* Make the mmaped area noncacheable */
>>> 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
>>> 
>>> 	/* Set the Flags to give permissions to Mmaped area */
>>> 	vma->vm_flags |=VM_RESERVED;
>>> 	vma->vm_flags |=VM_READ;
>>> 	vma->vm_flags |=VM_WRITE;
>>> 	vma->vm_flags |=VM_IO;
>>> 	//vma->vm_flags |=VM_SHARED;
>>> 	//vma->vm_flags |=VM_LOCKED;
>> 
>> For memory, you typically want to set vm_page_prot to use non-guarded
>> mapping,
>> so that user space accesses are faster.
>> 
>> Not sure if VM_IO is right for vmalloc.
>> 
>> 	Arnd <><
>> _______________________________________________
>> Linuxppc-embedded mailing list
>> Linuxppc-embedded@ozlabs.org
>> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>> 
>> 
> 
> 

-- 
View this message in context: http://www.nabble.com/how-to-allocate-9MB-of-memory-in-kernel---tp18503022p18792322.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2008-08-02 19:13 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-17  7:26 how to allocate 9MB of memory in kernel ? Misbah khan
2008-07-17  7:51 ` Marco Stornelli
2008-07-17  8:34   ` Misbah khan
2008-07-17  9:04     ` Marco Stornelli
2008-07-17  7:56 ` Arnd Bergmann
2008-07-17  8:19   ` Misbah khan
2008-07-17  8:24     ` Arnd Bergmann
2008-07-18  4:44   ` Misbah khan
2008-07-18  6:50     ` Marco Stornelli
2008-07-18  8:48       ` Misbah khan
2008-07-18 14:57         ` Timur Tabi
2008-07-18 15:39         ` Arnd Bergmann
2008-07-22  5:23           ` Misbah khan
2008-07-22  6:43             ` Marco Stornelli
2008-07-22  9:31             ` Arnd Bergmann
2008-07-22  9:47               ` Marco Stornelli
2008-07-22 13:22                 ` Misbah khan
2008-07-22 15:12                   ` Arnd Bergmann
2008-07-23  7:30                     ` Misbah khan
2008-07-24  8:33                       ` Misbah khan
2008-07-24  9:31                         ` Arnd Bergmann
2008-07-25  8:43                           ` Misbah khan
2008-07-25  8:50                             ` Arnd Bergmann
2008-08-02 19:13                             ` harihanv
2008-07-23 12:47                     ` Alessandro Rubini
2008-07-17  8:02 ` Sylvain Joyeau
2008-07-17  8:41   ` Misbah khan
     [not found] <mailman.2280.1216290829.2883.linuxppc-embedded@ozlabs.org>
2008-07-17 20:15 ` Siva Prasad

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).