How can I test if a physical address is already mapped or not.

Jeff Haran jharan at bytemobile.com
Tue Oct 18 20:46:58 EDT 2011


> -----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






More information about the Kernelnewbies mailing list