Howto convert from process virtual (linear address) to physical address?

Alex Bennee <[email protected]> Fri, 08 Oct 2004 17:40:32 +0100
Newsgroups gmane.linux.ports.sh.devel,gmane.linux.ports.sh.general
Organization Hackers Inc
Message-ID <1097253631.2510.19.camel@cambridge>
Hi,

Continuing on from the hacky user-space backtrace I posted earlier I'm
trying to convert the virtual addresses to real physical addresses. The
reason I want the real physical address is I'm using a BDM ICE to poke
around my board.

Now I'm probably just lost because I haven't got my head fully wrapped
around the multi-level page tables but this is what I've got:

    do {
	pgd_t *pgd;
	pmd_t *pmd;
	pte_t *ptep, pte;
	struct page *the_page;
	unsigned long phys_addr;
	
 	get_user(addr, start_addr);
	start_addr++;

        pgd = pgd_offset(tsk->mm, addr);
        if (pgd_none(*pgd) || pgd_bad(*pgd))
	    goto out;
 
        pmd = pmd_offset(pgd, addr);
        if (pmd_none(*pmd) || pmd_bad(*pmd))
	    goto out;
 
        ptep = pte_offset(pmd, addr);
        if (!ptep)
	    goto out;
 
        pte = *ptep;

	the_page = pte_page(pte);
	phys_addr = page_to_phys(the_page)+(addr&PAGE_MASK);
      out:
	    printk("%p=>%p, %p, %p, %p, %p => %p?\n", addr, pgd, pmd, ptep,
pte, the_page, phys_addr);
	
    } while (start_addr<=end_addr);

For example for one frame I get the output:

Frame  0: 0x0045c8c8 0x7afffad8 0x29617240 0x00000000 0xffffffff :
<0x00413dc8>

The relevant virt to phy line give:
00413dc8=>882be804, 882be804, 89b6c04c, 09a44558, 882093bc => 09e57000?

And looking at the object file @ 0x413dc8 I see:
 413dc8:       07 d1           mov.l   413de8
<sh_fs_codec_frame+0x148>,r1     ! 0x42a124
  413dca:       12 61           mov.l   @r1,r1
  413dcc:       11 50           mov.l   @(4,r1),r0
  413dce:       01 88           cmp/eq  #1,r0
  413dd0:       01 89           bt      413dd6 <sh_fs_codec_frame+0x136>
  413dd2:       75 a0           bra     413ec0 <sh_fs_codec_frame+0x220>
  413dd4:       09 00           nop

But looking under gdb via the ST micro connent I see:
(gdb) x/10i 0x09e57000
0x9e57000:      mov     #-32,r0
0x9e57002:      mov     #-32,r0
0x9e57004:      mov     #12,r0
0x9e57006:      mov     #12,r0
0x9e57008:      mov     #20,r0
0x9e5700a:      mov     #20,r0
0x9e5700c:      mov     #28,r0
0x9e5700e:      mov     #28,r0
0x9e57010:      mov.l   @r15+,r12
0x9e57012:      mov.l   @r15+,r12

The address looks as though its been munged to a page boundry so if a
frig it:
(gdb) p/x 0x00413dc8 &0xfff
$7 = 0xdc8
(gdb) x/10i 0x09e57000+$7
0x9e57dc8:      stc     sr,r0
0x9e57dca:      stc     sr,r0
0x9e57dcc:      .word 0x0000
0x9e57dce:      .word 0x0000
0x9e57dd0:      .word 0x0000
0x9e57dd2:      .word 0x0000
0x9e57dd4:      .word 0x0000
0x9e57dd6:      .word 0x0000
0x9e57dd8:      .word 0x0800
0x9e57dda:      .word 0x0800

Any idea where I'm going wrong? A pointer to code that actually needs to
convert from user-space linear address to actual physical address would
be cool if anyone can point me to one.

-- 
Alex, Kernel Hacker: http://www.bennee.com/~alex/

Think of it!  With VLSI we can pack 100 ENIACs in 1 sq. cm.!



-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl