All of lore.kernel.org
 help / color / mirror / Atom feed
* How can I test if a physical address is already mapped or not.
@ 2011-10-17 20:04 StephanT
  2011-10-18  5:52 ` Rajat Sharma
  2011-10-19 16:04 ` Trouble removing character device Kai Meyer
  0 siblings, 2 replies; 20+ messages in thread
From: StephanT @ 2011-10-17 20:04 UTC (permalink / raw)
  To: kernelnewbies

Hi all,

In a kernel module is there a way to test if an address range has?
been already mapped by the kernel or not.?

Ex: ?(on a PC with the latest kernel)
- an access to physical 0xC0000000 will return the value at this address
- an access to physical 0x00100000 will have the kernel kill the module/application?
?? ? ? ? ? using the module. Dmesg: BUG: unable to handle kernel paging request at 00100000.


How can I test this condition before dereferencing the address.?

Thanks,
Stephan.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20111017/a587bfc3/attachment.html 

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

* How can I test if a physical address is already mapped or not.
  2011-10-17 20:04 How can I test if a physical address is already mapped or not StephanT
@ 2011-10-18  5:52 ` Rajat Sharma
  2011-10-18 17:23   ` StephanT
  2011-10-19 16:04 ` Trouble removing character device Kai Meyer
  1 sibling, 1 reply; 20+ messages in thread
From: Rajat Sharma @ 2011-10-18  5:52 UTC (permalink / raw)
  To: kernelnewbies

On Tue, Oct 18, 2011 at 1:34 AM, StephanT <stman937-linewbie@yahoo.com> wrote:
> Hi all,
> In a kernel module is there a way to test if an address range has
> been already mapped by the kernel or not.
> Ex: ?(on a PC with the latest kernel)
> - an access to physical 0xC0000000 will return the value at this address
> - an access to physical 0x00100000 will have the kernel kill the
> module/application
> ?? ? ? ? ? using the module. Dmesg: BUG: unable to handle kernel paging
> request at 00100000.
>
> How can I test this condition before dereferencing the address.
> Thanks,
> Stephan.
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>
>

When you say an access to physical address, how are you managing to
access the physical address directly?

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

* How can I test if a physical address is already mapped or not.
  2011-10-18  5:52 ` Rajat Sharma
@ 2011-10-18 17:23   ` StephanT
  2011-10-18 20:47     ` Jeff Haran
  0 siblings, 1 reply; 20+ messages in thread
From: StephanT @ 2011-10-18 17:23 UTC (permalink / raw)
  To: kernelnewbies


>>When you say an access to physical address, how are you managing to
>>access the physical address directly?

Like this:

unsigned long? ? * const pReg = (unsigned long*) 0XC0000000 ;?

printk( KERN_INFO"** read (%p) %08lX.\n", pReg, *pReg) ;

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

* How can I test if a physical address is already mapped or not.
  2011-10-18 17:23   ` StephanT
@ 2011-10-18 20:47     ` Jeff Haran
  2011-10-18 20:58       ` StephanT
  0 siblings, 1 reply; 20+ messages in thread
From: Jeff Haran @ 2011-10-18 20:47 UTC (permalink / raw)
  To: kernelnewbies

> -----Original Message-----
> From: kernelnewbies-bounces at kernelnewbies.org [mailto:kernelnewbies-
> bounces at kernelnewbies.org] On Behalf Of StephanT
> Sent: Tuesday, October 18, 2011 10:23 AM
> To: kernelnewbies
> Subject: Re: How can I test if a physical address is already mapped or not.
> 
> 
> >>When you say an access to physical address, how are you managing to
> >>access the physical address directly?
> 
> Like this:
> 
> unsigned long? ? * const pReg = (unsigned long*) 0XC0000000 ;
> 
> printk( KERN_INFO"** read (%p) %08lX.\n", pReg, *pReg) ;

On any virtual memory processor I am aware of, the above will cause pReg to contain a virtual address, not a physical address.

Jeff Haran

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

* How can I test if a physical address is already mapped or not.
  2011-10-18 20:47     ` Jeff Haran
@ 2011-10-18 20:58       ` StephanT
  2011-10-18 21:16         ` Jeff Haran
  0 siblings, 1 reply; 20+ messages in thread
From: StephanT @ 2011-10-18 20:58 UTC (permalink / raw)
  To: kernelnewbies

> unsigned long? ? * const pReg = (unsigned long*) 0XC0000000 ;

> 
> printk( KERN_INFO"** read (%p) %08lX.\n", pReg, *pReg) ;

On any virtual memory processor I am aware of, the above will cause pReg to contain a virtual address, not a physical address.



Jeff,

I do not follow you... Could you, please be more explicit.

Thanks.

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

* How can I test if a physical address is already mapped or not.
  2011-10-18 20:58       ` StephanT
@ 2011-10-18 21:16         ` Jeff Haran
  2011-10-19  0:28           ` StephanT
  0 siblings, 1 reply; 20+ messages in thread
From: Jeff Haran @ 2011-10-18 21:16 UTC (permalink / raw)
  To: kernelnewbies

> -----Original Message-----
> From: StephanT [mailto:stman937-linewbie at yahoo.com]
> Sent: Tuesday, October 18, 2011 1:58 PM
> To: Jeff Haran; kernelnewbies
> Subject: Re: How can I test if a physical address is already mapped or not.
> 
> > unsigned long? ? * const pReg = (unsigned long*) 0XC0000000 ;
> 
> >
> > printk( KERN_INFO"** read (%p) %08lX.\n", pReg, *pReg) ;
> 
> On any virtual memory processor I am aware of, the above will cause pReg to
> contain a virtual address, not a physical address.
> 
> 
> 
> Jeff,
> 
> I do not follow you... Could you, please be more explicit.
> 
> Thanks.

I am assuming the processor you are running this on has an MMU (Memory Management Unit). This statement:

unsigned long    * const pReg = (unsigned long*) 0XC0000000 ;

will cause the variable pReg to contain the constant 0xC0000000.

When *pReg is evaluated in your printk(), the MMU will load the unsigned long located at virtual address 0xC0000000 into some processor register. How the mapping of the virtual address to physical address occurs is processor specific, but in Linux ultimately the physical address to get the data from will be derived from a page table that provides a mapping between the physical and virtual addresses of 4KB (usually 4KB) pages .

Do a search on "Understanding the Linux Virtual Memory Manager" by Mel Gorman. It's a little dated, but the PDF can be obtained for free. I suspect reading this will help you to understand what is going on better than I can explain in this post. I know it helped me out a lot many years ago when I was puzzling through a problem related to this.

Jeff Haran

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

* How can I test if a physical address is already mapped or not.
  2011-10-18 21:16         ` Jeff Haran
@ 2011-10-19  0:28           ` StephanT
  2011-10-19  0:46             ` Jeff Haran
  0 siblings, 1 reply; 20+ messages in thread
From: StephanT @ 2011-10-19  0:28 UTC (permalink / raw)
  To: kernelnewbies


>> 
>>? > unsigned long? ? * const pReg = (unsigned long*) 0XC0000000 ;
>> 
>>? >
>>? > printk( KERN_INFO"** read (%p) %08lX.\n", pReg, *pReg) ;
>> 
> 
> I am assuming the processor you are running this on has an MMU (Memory 
> Management Unit). This statement:
> 
> unsigned long? ? * const pReg = (unsigned long*) 0XC0000000 ;
> 
> will cause the variable pReg to contain the constant 0xC0000000.
> 
> When *pReg is evaluated in your printk(), the MMU will load the unsigned long 
> located at virtual address 0xC0000000 into some processor register. How the 
> mapping of the virtual address to physical address occurs is processor specific, 
> but in Linux ultimately the physical address to get the data from will be 
> derived from a page table that provides a mapping between the physical and 
> virtual addresses of 4KB (usually 4KB) pages .
> 


Jeff,

Thanks for your kind explanation. I understand now your comment.?

Yes you are right when you are in user space. However in a kernel
module this would be physical address. I test on an embedded
Linux board but I translated the problem to a PC which everyone?
can test.

The 0xC0000000 falls under PCI address range. I guess on a PC Linux
just doesn't map this address range or it maps it one2one (phys==virt)
I can dereference this address and I get something plausible. The?
physical 0x00100000 is the Linux load address - see /proc/iomap. It was
previously discussed on this group:?
(http://lists.kernelnewbies.org/pipermail/kernelnewbies/2011-October/003483.html)
When I try to dereference it (physical level) I get the error listed in my first
post and Linux kills my module (or if it is installed as a driver kills the application
which uses the driver). I guess it is normal because this address range is already?
mapped?by Linux - in virtual address Linux starts at 0xC0000000. By using ioremap?
I can?ask for a second map of this physical address and?I can dereference it without
getting killed.

To get back to my initial question I'd like to be able to check this status before
dereferencing?the physical address and avoid to be killed if the address is
already mapped :) ? Are there any kernel calls allowing me to do so ?

Thanks,
Stephan.

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

* How can I test if a physical address is already mapped or not.
  2011-10-19  0:28           ` StephanT
@ 2011-10-19  0:46             ` Jeff Haran
  2011-10-19  1:01               ` StephanT
  0 siblings, 1 reply; 20+ messages in thread
From: Jeff Haran @ 2011-10-19  0:46 UTC (permalink / raw)
  To: kernelnewbies

> -----Original Message-----
> From: StephanT [mailto:stman937-linewbie at yahoo.com]
> Sent: Tuesday, October 18, 2011 5:29 PM
> To: Jeff Haran; kernelnewbies
> Subject: Re: How can I test if a physical address is already mapped or not.
> 
> 
> >>
> >>? > unsigned long? ? * const pReg = (unsigned long*) 0XC0000000 ;
> >>
> >>? >
> >>? > printk( KERN_INFO"** read (%p) %08lX.\n", pReg, *pReg) ;
> >>
> >
> > I am assuming the processor you are running this on has an MMU (Memory
> > Management Unit). This statement:
> >
> > unsigned long? ? * const pReg = (unsigned long*) 0XC0000000 ;
> >
> > will cause the variable pReg to contain the constant 0xC0000000.
> >
> > When *pReg is evaluated in your printk(), the MMU will load the unsigned
> long
> > located at virtual address 0xC0000000 into some processor register. How
> the
> > mapping of the virtual address to physical address occurs is processor
> specific,
> > but in Linux ultimately the physical address to get the data from will be
> > derived from a page table that provides a mapping between the physical
> and
> > virtual addresses of 4KB (usually 4KB) pages .
> >
> 
> 
> Jeff,
> 
> Thanks for your kind explanation. I understand now your comment.
> 
> Yes you are right when you are in user space. However in a kernel
> module this would be physical address.

Nope. Unless you are using some really strange processor that I am not familiar with, a memory read is a memory read. *pReg is going to read what's at virtual address 0xc0000000 regardless of whether you are executing in user or kernel context. I know it's going to work this way on a PC with an Intel x86 processor.

> I test on an embedded
> Linux board but I translated the problem to a PC which everyone
> can test.
> 
> The 0xC0000000 falls under PCI address range. I guess on a PC Linux
> just doesn't map this address range or it maps it one2one (phys==virt)
> I can dereference this address and I get something plausible.

On most 32 bit Intel processors running "standard" Linux 0xC0000000 is the first address of kernel VM. This is a function of kernel configuration, but it's this way by default. It's still a virtual address. So yes, on your PC virtual address 0xC0000000 is mapped to physical RAM.

> The
> physical 0x00100000 is the Linux load address - see /proc/iomap. It was
> previously discussed on this group:
> (http://lists.kernelnewbies.org/pipermail/kernelnewbies/2011-
> October/003483.html)
> When I try to dereference it (physical level) I get the error listed in my first
> post and Linux kills my module (or if it is installed as a driver kills the
> application
> which uses the driver). I guess it is normal because this address range is
> already
> mapped?by Linux - in virtual address Linux starts at 0xC0000000. By using
> ioremap
> I can?ask for a second map of this physical address and?I can dereference it
> without
> getting killed.
> 
> To get back to my initial question I'd like to be able to check this status before
> dereferencing?the physical address and avoid to be killed if the address is
> already mapped :) ? Are there any kernel calls allowing me to do so ?

Not to my knowledge. Doesn't mean they don't exist, I just don't know of any such thing.

Jeff Haran

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

* How can I test if a physical address is already mapped or not.
  2011-10-19  0:46             ` Jeff Haran
@ 2011-10-19  1:01               ` StephanT
  2011-10-19  1:16                 ` Jeff Haran
  0 siblings, 1 reply; 20+ messages in thread
From: StephanT @ 2011-10-19  1:01 UTC (permalink / raw)
  To: kernelnewbies



>>  Yes you are right when you are in user space. However in a kernel
>>  module this would be physical address.
> 
> Nope. Unless you are using some really strange processor that I am not familiar 
> with, a memory read is a memory read. *pReg is going to read what's at 
> virtual address 0xc0000000 regardless of whether you are executing in user or 
> kernel context. I know it's going to work this way on a PC with an Intel x86 
> processor.
> 


OK, but how do you explain I can read 0xC0000000 and I get?kicked?out if
I try 0x00100000.


>>  The 0xC0000000 falls under PCI address range. I guess on a PC Linux
>>  just doesn't map this address range or it maps it one2one (phys==virt)
>>  I can dereference this address and I get something plausible.
> 
> On most 32 bit Intel processors running "standard" Linux 0xC0000000 is 
> the first address of kernel VM. This is a function of kernel configuration, but 
> it's this way by default. It's still a virtual address. So yes, on your 
> PC virtual address 0xC0000000 is mapped to physical RAM.
> 


Would this mean by reading the 0xC0000000 I am reading the Linux code not
PCI registers?

Thanks,
Stephan.

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

* How can I test if a physical address is already mapped or not.
  2011-10-19  1:01               ` StephanT
@ 2011-10-19  1:16                 ` Jeff Haran
  2011-10-19  5:48                   ` Rajat Sharma
  0 siblings, 1 reply; 20+ messages in thread
From: Jeff Haran @ 2011-10-19  1:16 UTC (permalink / raw)
  To: kernelnewbies

> -----Original Message-----
> From: StephanT [mailto:stman937-linewbie at yahoo.com]
> Sent: Tuesday, October 18, 2011 6:01 PM
> To: Jeff Haran; kernelnewbies
> Subject: Re: How can I test if a physical address is already mapped or not.
> 
> 
> 
> >>  Yes you are right when you are in user space. However in a kernel
> >>  module this would be physical address.
> >
> > Nope. Unless you are using some really strange processor that I am not
> familiar
> > with, a memory read is a memory read. *pReg is going to read what's at
> > virtual address 0xc0000000 regardless of whether you are executing in user
> or
> > kernel context. I know it's going to work this way on a PC with an Intel x86
> > processor.
> >
> 
> 
> OK, but how do you explain I can read 0xC0000000 and I get?kicked?out if
> I try 0x00100000.

I can only assume that there is nothing mapped to virtual address 0x00100000. On a 32 bit PC, the bottom 3 GB of virtual memory is by default mapped to user space, so if anything you are accessing memory in the current process' virtual memory.

> 
> >>  The 0xC0000000 falls under PCI address range. I guess on a PC Linux
> >>  just doesn't map this address range or it maps it one2one (phys==virt)
> >>  I can dereference this address and I get something plausible.
> >
> > On most 32 bit Intel processors running "standard" Linux 0xC0000000 is
> > the first address of kernel VM. This is a function of kernel configuration, but
> > it's this way by default. It's still a virtual address. So yes, on your
> > PC virtual address 0xC0000000 is mapped to physical RAM.
> >
> 
>
> Would this mean by reading the 0xC0000000 I am reading the Linux code not
> PCI registers?

First part of the page table, I think. I don't really remember what the kernel maps down there but I don't think its code.
Read the Gorman book. It's a lot to get through, but you'll likely learn a lot. There might even be something newer out there.

Jeff Haran

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

* How can I test if a physical address is already mapped or not.
  2011-10-19  1:16                 ` Jeff Haran
@ 2011-10-19  5:48                   ` Rajat Sharma
  2011-10-19 17:10                     ` StephanT
  0 siblings, 1 reply; 20+ messages in thread
From: Rajat Sharma @ 2011-10-19  5:48 UTC (permalink / raw)
  To: kernelnewbies

On Wed, Oct 19, 2011 at 6:46 AM, Jeff Haran <jharan@bytemobile.com> wrote:
>> -----Original Message-----
>> From: StephanT [mailto:stman937-linewbie at yahoo.com]
>> Sent: Tuesday, October 18, 2011 6:01 PM
>> To: Jeff Haran; kernelnewbies
>> Subject: Re: How can I test if a physical address is already mapped or not.
>>
>>
>>
>> >> ?Yes you are right when you are in user space. However in a kernel
>> >> ?module this would be physical address.
>> >
>> > Nope. Unless you are using some really strange processor that I am not
>> familiar
>> > with, a memory read is a memory read. *pReg is going to read what's at
>> > virtual address 0xc0000000 regardless of whether you are executing in user
>> or
>> > kernel context. I know it's going to work this way on a PC with an Intel x86
>> > processor.
>> >
>>
>>
>> OK, but how do you explain I can read 0xC0000000 and I get?kicked?out if
>> I try 0x00100000.
>
> I can only assume that there is nothing mapped to virtual address 0x00100000. On a 32 bit PC, the bottom 3 GB of virtual memory is by default mapped to user space, so if anything you are accessing memory in the current process' virtual memory.
>
>>
>> >> ?The 0xC0000000 falls under PCI address range. I guess on a PC Linux
>> >> ?just doesn't map this address range or it maps it one2one (phys==virt)
>> >> ?I can dereference this address and I get something plausible.
>> >
>> > On most 32 bit Intel processors running "standard" Linux 0xC0000000 is
>> > the first address of kernel VM. This is a function of kernel configuration, but
>> > it's this way by default. It's still a virtual address. So yes, on your
>> > PC virtual address 0xC0000000 is mapped to physical RAM.
>> >
>>
>>
>> Would this mean by reading the 0xC0000000 I am reading the Linux code not
>> PCI registers?
>
> First part of the page table, I think. I don't really remember what the kernel maps down there but I don't think its code.
> Read the Gorman book. It's a lot to get through, but you'll likely learn a lot. There might even be something newer out there.
>
> Jeff Haran
>
>
>
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>

Stephan,

>From your post it looks like you are trying to simulate environment on
Embedded Linux board to your PC? Did you check if embedded Linux has
CONFIG_MMU kernel config option set? If that is the case then you
might be bypassing page-table translation on your board and CPU
assumes virtual address = physical address in that case. However same
may not be true on PC which uses page-tables.

"Understanding Linux Kernel" book is also a good reference for
understanding memory management in Linux.

One Advice: when shifting from one hardware to another, be ready for
surprises and open to unlearn things :)

Thanks,
Rajat

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

* Trouble removing character device
  2011-10-17 20:04 How can I test if a physical address is already mapped or not StephanT
  2011-10-18  5:52 ` Rajat Sharma
@ 2011-10-19 16:04 ` Kai Meyer
  2011-10-19 20:18   ` Daniel Baluta
  1 sibling, 1 reply; 20+ messages in thread
From: Kai Meyer @ 2011-10-19 16:04 UTC (permalink / raw)
  To: kernelnewbies

I can't seem to get my character device to remove itself from the 
/proc/devices list. I'm calling all of the following functions like so:

alloc_chrdev_region(&dev, 0, 5, "my_char");
cdev_init(&my_cdev, &my_ops);
cdev_add(&my_cdev, MKDEV(my_major, my_minor), 1);
cdev_del(&my_cdev);
unregister_chrdev_region(my_major, 5);

It seems like I'm missing something, but I can't find it. I'm 
referencing the Linux Device Drivers v3, chapter 3. In the example code, 
the scull_cleanup_module function calls cdev_dell and 
unregister_chrdev_region, just like I do.

To be clear, after I unload my module (after calling cdev_del and 
unregister_chrdev_region), my "my_char" string still shows up in 
/proc/devices.

-Kai Meyer

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

* How can I test if a physical address is already mapped or not.
  2011-10-19  5:48                   ` Rajat Sharma
@ 2011-10-19 17:10                     ` StephanT
  0 siblings, 0 replies; 20+ messages in thread
From: StephanT @ 2011-10-19 17:10 UTC (permalink / raw)
  To: kernelnewbies

>?

> One Advice: when shifting from one hardware to another, be ready for
> surprises and open to unlearn things :)
> 


Hi?Rajat,

Yes, you so right ! ? :)

Thanks for help to all,
Stephan.

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

* Trouble removing character device
  2011-10-19 16:04 ` Trouble removing character device Kai Meyer
@ 2011-10-19 20:18   ` Daniel Baluta
  2011-10-19 20:55     ` Kai Meyer
  0 siblings, 1 reply; 20+ messages in thread
From: Daniel Baluta @ 2011-10-19 20:18 UTC (permalink / raw)
  To: kernelnewbies

On Wed, Oct 19, 2011 at 7:04 PM, Kai Meyer <kai@gnukai.com> wrote:
> I can't seem to get my character device to remove itself from the
> /proc/devices list. I'm calling all of the following functions like so:
>
> alloc_chrdev_region(&dev, 0, 5, "my_char");
> cdev_init(&my_cdev, &my_ops);
> cdev_add(&my_cdev, MKDEV(my_major, my_minor), 1);
> cdev_del(&my_cdev);
> unregister_chrdev_region(my_major, 5);
>
> It seems like I'm missing something, but I can't find it. I'm
> referencing the Linux Device Drivers v3, chapter 3. In the example code,
> the scull_cleanup_module function calls cdev_dell and
> unregister_chrdev_region, just like I do.
>
> To be clear, after I unload my module (after calling cdev_del and
> unregister_chrdev_region), my "my_char" string still shows up in
> /proc/devices.

Did you check  return codes for all functions?
Also, can you post a link to the code?

thanks,
Daniel.

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

* Trouble removing character device
  2011-10-19 20:18   ` Daniel Baluta
@ 2011-10-19 20:55     ` Kai Meyer
  2011-10-19 21:34       ` Understanding memcpy Kai Meyer
  2011-10-20  3:47       ` Trouble removing character device rohan puri
  0 siblings, 2 replies; 20+ messages in thread
From: Kai Meyer @ 2011-10-19 20:55 UTC (permalink / raw)
  To: kernelnewbies

Unfortunately I can't share the source code, it belongs to the company I 
work for.

All of cdev_init, cdev_del, and unregister_chrdev_region are void 
functions, so they have no return value.

I check the return value of alloc_chrdev_region and cdev_add and check 
for errors with BUG_ON (for now).

-Kai Meyer

On 10/19/2011 02:18 PM, Daniel Baluta wrote:
> On Wed, Oct 19, 2011 at 7:04 PM, Kai Meyer<kai@gnukai.com>  wrote:
>> I can't seem to get my character device to remove itself from the
>> /proc/devices list. I'm calling all of the following functions like so:
>>
>> alloc_chrdev_region(&dev, 0, 5, "my_char");
>> cdev_init(&my_cdev,&my_ops);
>> cdev_add(&my_cdev, MKDEV(my_major, my_minor), 1);
>> cdev_del(&my_cdev);
>> unregister_chrdev_region(my_major, 5);
>>
>> It seems like I'm missing something, but I can't find it. I'm
>> referencing the Linux Device Drivers v3, chapter 3. In the example code,
>> the scull_cleanup_module function calls cdev_dell and
>> unregister_chrdev_region, just like I do.
>>
>> To be clear, after I unload my module (after calling cdev_del and
>> unregister_chrdev_region), my "my_char" string still shows up in
>> /proc/devices.
> Did you check  return codes for all functions?
> Also, can you post a link to the code?
>
> thanks,
> Daniel.
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

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

* Understanding memcpy
  2011-10-19 20:55     ` Kai Meyer
@ 2011-10-19 21:34       ` Kai Meyer
  2011-10-20  4:00         ` rohan puri
  2011-10-20  3:47       ` Trouble removing character device rohan puri
  1 sibling, 1 reply; 20+ messages in thread
From: Kai Meyer @ 2011-10-19 21:34 UTC (permalink / raw)
  To: kernelnewbies

I'm trying to poke around an ext4 file system. I can submit a bio for 
the correct block, and read in what seems to be the correct information, 
but when I try to memcpy my char *buffer to a reference to a struct I've 
made, it just doesn't seem to work. The relevant code looks like this:

typedef struct ext2_superblock {
         /* 00-03 */ uint32_t e2sb_inode_count;
         /* 04-07 */ uint32_t e2sb_block_count;
         /* 08-11 */ uint32_t e2sb_blocks_reserved;
         /* 12-15 */ uint32_t e2sb_unallocated_blocks;
         /* 16-19 */ uint32_t e2sb_unallocated_inodes;
         /* 20-23 */ uint32_t e2sb_sb_block;
         /* 24-27 */ uint32_t e2sb_log_block_size;
         /* 28-31 */ uint32_t e2sb_log_fragment_size;
         /* 32-35 */ uint32_t e2sb_num_blocks_per_group;
         /* 36-39 */ uint32_t e2sb_num_frag_per_group;
         /* 40-43 */ uint32_t e2sb_num_inodes_per_group;
         /* 44-47 */ uint32_t e2sb_last_mount_time;
         /* 48-51 */ uint32_t e2sb_last_written_time;
         /* 52-53 */ uint16_t e2sb_num_mounted;
         /* 54-55 */ uint16_t e2sb_num_allowed_mounts;
         /* 56-57 */ uint16_t e2sb_signature;
         /* 58-59 */ uint16_t e2sb_fs_state;
         /* 60-61 */ uint16_t e2sb_error_action;
         /* 62-63 */ uint16_t e2sb_ver_minor;
         /* 64-67 */ uint32_t e2sb_last_check;
         /* 68-71 */ uint32_t e2sb_time_between_checks;
         /* 72-75 */ uint32_t e2sb_os_id;
         /* 76-79 */ uint32_t e2sb_ver_major;
         /* 80-81 */ uint16_t e2sb_uid;
         /* 82-83 */ uint16_t e2sb_gid;
} e2sb;


char *buffer;
uint32_t *pointer;
e2sb sb;
buffer = __bio_kmap_atomic(bio, 0, KM_USER0);
pointer = (uint32_t *)buffer;
printk(KERN_DEBUG "sizeof pbd->sb %lu\n", sizeof(bpd->sb));
printk(KERN_DEBUG "Inode Count: %u\n", pointer[0]); /* Works! */
printk(KERN_DEBUG "Block Count: %u\n", pointer[1]); /* Works! */
printk(KERN_DEBUG "Block Reserved: %u\n", pointer[2]); /* Works! */
printk(KERN_DEBUG "Unallocated blocks: %u\n", pointer[3]); /* Works! */
printk(KERN_DEBUG "Unallocated inodes: %u\n", pointer[4]); /* Works! */
memcpy(buffer, &sb, sizeof(sb));
__bio_kunmap_atomic(bio, KM_USER0);
printk(KERN_DEBUG "e2sb_debug: Total number of inodes in file system 
%u\n", sb->e2sb_inode_count);/* Doesn't work! */
printk(KERN_DEBUG "e2sb_debug: Total number of blocks in file 
system%u\n", sb->e2sb_block_count); /* Doesn't work! */

My code is actually much more verbose. The values I get from indexing 
into pointer are correct, and match what I get from dumpe2fs. The values 
I get from the e2sb struct are not. They are usually 0. I would imagine 
that memcpy is the fastest way to copy data from buffer instead of 
casting the pointer to something else, and using array indexing to get 
the values.

I struggled to find where ext4 actually does this, so I'm making this up 
as I go along. Any thing that you see that I should be doing a different 
way that isn't actually part of my question is welcome too.

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

* Trouble removing character device
  2011-10-19 20:55     ` Kai Meyer
  2011-10-19 21:34       ` Understanding memcpy Kai Meyer
@ 2011-10-20  3:47       ` rohan puri
  2011-10-20 15:41         ` Kai Meyer
  1 sibling, 1 reply; 20+ messages in thread
From: rohan puri @ 2011-10-20  3:47 UTC (permalink / raw)
  To: kernelnewbies

On Thu, Oct 20, 2011 at 2:25 AM, Kai Meyer <kai@gnukai.com> wrote:

> Unfortunately I can't share the source code, it belongs to the company I
> work for.
>
> All of cdev_init, cdev_del, and unregister_chrdev_region are void
> functions, so they have no return value.
>
> I check the return value of alloc_chrdev_region and cdev_add and check
> for errors with BUG_ON (for now).
>
> -Kai Meyer
>
> On 10/19/2011 02:18 PM, Daniel Baluta wrote:
> > On Wed, Oct 19, 2011 at 7:04 PM, Kai Meyer<kai@gnukai.com>  wrote:
> >> I can't seem to get my character device to remove itself from the
> >> /proc/devices list. I'm calling all of the following functions like so:
> >>
> >> alloc_chrdev_region(&dev, 0, 5, "my_char");
> >> cdev_init(&my_cdev,&my_ops);
> >> cdev_add(&my_cdev, MKDEV(my_major, my_minor), 1);
> >> cdev_del(&my_cdev);
> >> unregister_chrdev_region(my_major, 5);
> >>
> >> It seems like I'm missing something, but I can't find it. I'm
> >> referencing the Linux Device Drivers v3, chapter 3. In the example code,
> >> the scull_cleanup_module function calls cdev_dell and
> >> unregister_chrdev_region, just like I do.
> >>
> >> To be clear, after I unload my module (after calling cdev_del and
> >> unregister_chrdev_region), my "my_char" string still shows up in
> >> /proc/devices.
> > Did you check  return codes for all functions?
> > Also, can you post a link to the code?
> >
> > thanks,
> > Daniel.
> >
> > _______________________________________________
> > Kernelnewbies mailing list
> > Kernelnewbies at kernelnewbies.org
> > http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>

During cleanup i think you need to call function unregister_chrdev_region().

Regards,
Rohan Puri
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20111020/e9db23f8/attachment.html 

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

* Understanding memcpy
  2011-10-19 21:34       ` Understanding memcpy Kai Meyer
@ 2011-10-20  4:00         ` rohan puri
  2011-10-20 15:40           ` Kai Meyer
  0 siblings, 1 reply; 20+ messages in thread
From: rohan puri @ 2011-10-20  4:00 UTC (permalink / raw)
  To: kernelnewbies

On Thu, Oct 20, 2011 at 3:04 AM, Kai Meyer <kai@gnukai.com> wrote:

> I'm trying to poke around an ext4 file system. I can submit a bio for
> the correct block, and read in what seems to be the correct information,
> but when I try to memcpy my char *buffer to a reference to a struct I've
> made, it just doesn't seem to work. The relevant code looks like this:
>
> typedef struct ext2_superblock {
>         /* 00-03 */ uint32_t e2sb_inode_count;
>         /* 04-07 */ uint32_t e2sb_block_count;
>         /* 08-11 */ uint32_t e2sb_blocks_reserved;
>         /* 12-15 */ uint32_t e2sb_unallocated_blocks;
>         /* 16-19 */ uint32_t e2sb_unallocated_inodes;
>         /* 20-23 */ uint32_t e2sb_sb_block;
>         /* 24-27 */ uint32_t e2sb_log_block_size;
>         /* 28-31 */ uint32_t e2sb_log_fragment_size;
>         /* 32-35 */ uint32_t e2sb_num_blocks_per_group;
>         /* 36-39 */ uint32_t e2sb_num_frag_per_group;
>         /* 40-43 */ uint32_t e2sb_num_inodes_per_group;
>         /* 44-47 */ uint32_t e2sb_last_mount_time;
>         /* 48-51 */ uint32_t e2sb_last_written_time;
>         /* 52-53 */ uint16_t e2sb_num_mounted;
>         /* 54-55 */ uint16_t e2sb_num_allowed_mounts;
>         /* 56-57 */ uint16_t e2sb_signature;
>         /* 58-59 */ uint16_t e2sb_fs_state;
>         /* 60-61 */ uint16_t e2sb_error_action;
>         /* 62-63 */ uint16_t e2sb_ver_minor;
>         /* 64-67 */ uint32_t e2sb_last_check;
>         /* 68-71 */ uint32_t e2sb_time_between_checks;
>         /* 72-75 */ uint32_t e2sb_os_id;
>         /* 76-79 */ uint32_t e2sb_ver_major;
>         /* 80-81 */ uint16_t e2sb_uid;
>         /* 82-83 */ uint16_t e2sb_gid;
> } e2sb;
>
>
> char *buffer;
> uint32_t *pointer;
> e2sb sb;
> buffer = __bio_kmap_atomic(bio, 0, KM_USER0);
> pointer = (uint32_t *)buffer;
> printk(KERN_DEBUG "sizeof pbd->sb %lu\n", sizeof(bpd->sb));
> printk(KERN_DEBUG "Inode Count: %u\n", pointer[0]); /* Works! */
> printk(KERN_DEBUG "Block Count: %u\n", pointer[1]); /* Works! */
> printk(KERN_DEBUG "Block Reserved: %u\n", pointer[2]); /* Works! */
> printk(KERN_DEBUG "Unallocated blocks: %u\n", pointer[3]); /* Works! */
> printk(KERN_DEBUG "Unallocated inodes: %u\n", pointer[4]); /* Works! */
> memcpy(buffer, &sb, sizeof(sb));
>
This should be : -
memcpy(&sb, buffer, sizeof(sb));


> __bio_kunmap_atomic(bio, KM_USER0);
> printk(KERN_DEBUG "e2sb_debug: Total number of inodes in file system
> %u\n", sb->e2sb_inode_count);/* Doesn't work! */
> printk(KERN_DEBUG "e2sb_debug: Total number of blocks in file
> system%u\n", sb->e2sb_block_count); /* Doesn't work! */
>
> My code is actually much more verbose. The values I get from indexing
> into pointer are correct, and match what I get from dumpe2fs. The values
> I get from the e2sb struct are not. They are usually 0. I would imagine
> that memcpy is the fastest way to copy data from buffer instead of
> casting the pointer to something else, and using array indexing to get
> the values.
>
> I struggled to find where ext4 actually does this, so I'm making this up
> as I go along. Any thing that you see that I should be doing a different
> way that isn't actually part of my question is welcome too.
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>

Regards,
Rohan Puri
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20111020/48bb9a9e/attachment.html 

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

* Understanding memcpy
  2011-10-20  4:00         ` rohan puri
@ 2011-10-20 15:40           ` Kai Meyer
  0 siblings, 0 replies; 20+ messages in thread
From: Kai Meyer @ 2011-10-20 15:40 UTC (permalink / raw)
  To: kernelnewbies

Thanks for catching that :) I knew it would be something simple.

On 10/19/2011 10:00 PM, rohan puri wrote:
>
>
> On Thu, Oct 20, 2011 at 3:04 AM, Kai Meyer <kai@gnukai.com 
> <mailto:kai@gnukai.com>> wrote:
>
>     I'm trying to poke around an ext4 file system. I can submit a bio for
>     the correct block, and read in what seems to be the correct
>     information,
>     but when I try to memcpy my char *buffer to a reference to a
>     struct I've
>     made, it just doesn't seem to work. The relevant code looks like this:
>
>     typedef struct ext2_superblock {
>             /* 00-03 */ uint32_t e2sb_inode_count;
>             /* 04-07 */ uint32_t e2sb_block_count;
>             /* 08-11 */ uint32_t e2sb_blocks_reserved;
>             /* 12-15 */ uint32_t e2sb_unallocated_blocks;
>             /* 16-19 */ uint32_t e2sb_unallocated_inodes;
>             /* 20-23 */ uint32_t e2sb_sb_block;
>             /* 24-27 */ uint32_t e2sb_log_block_size;
>             /* 28-31 */ uint32_t e2sb_log_fragment_size;
>             /* 32-35 */ uint32_t e2sb_num_blocks_per_group;
>             /* 36-39 */ uint32_t e2sb_num_frag_per_group;
>             /* 40-43 */ uint32_t e2sb_num_inodes_per_group;
>             /* 44-47 */ uint32_t e2sb_last_mount_time;
>             /* 48-51 */ uint32_t e2sb_last_written_time;
>             /* 52-53 */ uint16_t e2sb_num_mounted;
>             /* 54-55 */ uint16_t e2sb_num_allowed_mounts;
>             /* 56-57 */ uint16_t e2sb_signature;
>             /* 58-59 */ uint16_t e2sb_fs_state;
>             /* 60-61 */ uint16_t e2sb_error_action;
>             /* 62-63 */ uint16_t e2sb_ver_minor;
>             /* 64-67 */ uint32_t e2sb_last_check;
>             /* 68-71 */ uint32_t e2sb_time_between_checks;
>             /* 72-75 */ uint32_t e2sb_os_id;
>             /* 76-79 */ uint32_t e2sb_ver_major;
>             /* 80-81 */ uint16_t e2sb_uid;
>             /* 82-83 */ uint16_t e2sb_gid;
>     } e2sb;
>
>
>     char *buffer;
>     uint32_t *pointer;
>     e2sb sb;
>     buffer = __bio_kmap_atomic(bio, 0, KM_USER0);
>     pointer = (uint32_t *)buffer;
>     printk(KERN_DEBUG "sizeof pbd->sb %lu\n", sizeof(bpd->sb));
>     printk(KERN_DEBUG "Inode Count: %u\n", pointer[0]); /* Works! */
>     printk(KERN_DEBUG "Block Count: %u\n", pointer[1]); /* Works! */
>     printk(KERN_DEBUG "Block Reserved: %u\n", pointer[2]); /* Works! */
>     printk(KERN_DEBUG "Unallocated blocks: %u\n", pointer[3]); /*
>     Works! */
>     printk(KERN_DEBUG "Unallocated inodes: %u\n", pointer[4]); /*
>     Works! */
>     memcpy(buffer, &sb, sizeof(sb));
>
> This should be : -
> memcpy(&sb, buffer, sizeof(sb));
>
>     __bio_kunmap_atomic(bio, KM_USER0);
>     printk(KERN_DEBUG "e2sb_debug: Total number of inodes in file system
>     %u\n", sb->e2sb_inode_count);/* Doesn't work! */
>     printk(KERN_DEBUG "e2sb_debug: Total number of blocks in file
>     system%u\n", sb->e2sb_block_count); /* Doesn't work! */
>
>     My code is actually much more verbose. The values I get from indexing
>     into pointer are correct, and match what I get from dumpe2fs. The
>     values
>     I get from the e2sb struct are not. They are usually 0. I would
>     imagine
>     that memcpy is the fastest way to copy data from buffer instead of
>     casting the pointer to something else, and using array indexing to get
>     the values.
>
>     I struggled to find where ext4 actually does this, so I'm making
>     this up
>     as I go along. Any thing that you see that I should be doing a
>     different
>     way that isn't actually part of my question is welcome too.
>
>     _______________________________________________
>     Kernelnewbies mailing list
>     Kernelnewbies at kernelnewbies.org
>     <mailto:Kernelnewbies@kernelnewbies.org>
>     http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>
>
> Regards,
> Rohan Puri
>
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20111020/5980ab33/attachment.html 

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

* Trouble removing character device
  2011-10-20  3:47       ` Trouble removing character device rohan puri
@ 2011-10-20 15:41         ` Kai Meyer
  0 siblings, 0 replies; 20+ messages in thread
From: Kai Meyer @ 2011-10-20 15:41 UTC (permalink / raw)
  To: kernelnewbies

I do call unregister_chrdev_region. There are 5 functions in my original 
email that I call during the life of my module. Still no luck.

-Kai Meyer

On 10/19/2011 09:47 PM, rohan puri wrote:
>
>
> On Thu, Oct 20, 2011 at 2:25 AM, Kai Meyer <kai@gnukai.com 
> <mailto:kai@gnukai.com>> wrote:
>
>     Unfortunately I can't share the source code, it belongs to the
>     company I
>     work for.
>
>     All of cdev_init, cdev_del, and unregister_chrdev_region are void
>     functions, so they have no return value.
>
>     I check the return value of alloc_chrdev_region and cdev_add and check
>     for errors with BUG_ON (for now).
>
>     -Kai Meyer
>
>     On 10/19/2011 02:18 PM, Daniel Baluta wrote:
>     > On Wed, Oct 19, 2011 at 7:04 PM, Kai Meyer<kai@gnukai.com
>     <mailto:kai@gnukai.com>>  wrote:
>     >> I can't seem to get my character device to remove itself from the
>     >> /proc/devices list. I'm calling all of the following functions
>     like so:
>     >>
>     >> alloc_chrdev_region(&dev, 0, 5, "my_char");
>     >> cdev_init(&my_cdev,&my_ops);
>     >> cdev_add(&my_cdev, MKDEV(my_major, my_minor), 1);
>     >> cdev_del(&my_cdev);
>     >> unregister_chrdev_region(my_major, 5);
>     >>
>     >> It seems like I'm missing something, but I can't find it. I'm
>     >> referencing the Linux Device Drivers v3, chapter 3. In the
>     example code,
>     >> the scull_cleanup_module function calls cdev_dell and
>     >> unregister_chrdev_region, just like I do.
>     >>
>     >> To be clear, after I unload my module (after calling cdev_del and
>     >> unregister_chrdev_region), my "my_char" string still shows up in
>     >> /proc/devices.
>     > Did you check  return codes for all functions?
>     > Also, can you post a link to the code?
>     >
>     > thanks,
>     > Daniel.
>     >
>     > _______________________________________________
>     > Kernelnewbies mailing list
>     > Kernelnewbies at kernelnewbies.org
>     <mailto:Kernelnewbies@kernelnewbies.org>
>     > http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>
>     _______________________________________________
>     Kernelnewbies mailing list
>     Kernelnewbies at kernelnewbies.org
>     <mailto:Kernelnewbies@kernelnewbies.org>
>     http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>
>
> During cleanup i think you need to call function 
> unregister_chrdev_region().
>
> Regards,
> Rohan Puri
>
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20111020/6df5dea6/attachment.html 

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

end of thread, other threads:[~2011-10-20 15:41 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-17 20:04 How can I test if a physical address is already mapped or not StephanT
2011-10-18  5:52 ` Rajat Sharma
2011-10-18 17:23   ` StephanT
2011-10-18 20:47     ` Jeff Haran
2011-10-18 20:58       ` StephanT
2011-10-18 21:16         ` Jeff Haran
2011-10-19  0:28           ` StephanT
2011-10-19  0:46             ` Jeff Haran
2011-10-19  1:01               ` StephanT
2011-10-19  1:16                 ` Jeff Haran
2011-10-19  5:48                   ` Rajat Sharma
2011-10-19 17:10                     ` StephanT
2011-10-19 16:04 ` Trouble removing character device Kai Meyer
2011-10-19 20:18   ` Daniel Baluta
2011-10-19 20:55     ` Kai Meyer
2011-10-19 21:34       ` Understanding memcpy Kai Meyer
2011-10-20  4:00         ` rohan puri
2011-10-20 15:40           ` Kai Meyer
2011-10-20  3:47       ` Trouble removing character device rohan puri
2011-10-20 15:41         ` Kai Meyer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.