-----Original Message----- From: StephanT [mailto:stman937-linewbie@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