1. linux内核文档Documentation/vm/pagemap.txt
1.2 用户空间获取物理地址的代码
-
cong@msi:/work/test/ctest/vaddr$ cat test.c
-
#include <stdio.h>
-
#include <unistd.h>
-
#include <inttypes.h>
-
#include <stdint.h>
-
#include <sys/types.h>
-
#include <sys/stat.h>
-
#include <fcntl.h>
-
-
#define page_map_file "/proc/self/pagemap"
-
-
#define PFN_MASK ((((uint64_t)1)<<55)-1)
-
-
#define PFN_PRESENT_FLAG (((uint64_t)1)<<63)
-
-
int mem_addr_vir2phy(unsigned long vir, unsigned long *phy)
-
{
-
int fd;
-
int page_size=getpagesize();
-
unsigned long vir_page_idx = vir/page_size;
-
unsigned long pfn_item_offset = vir_page_idx*sizeof(uint64_t);
-
uint64_t pfn_item;
-
-
fd = open(page_map_file, O_RDONLY);
-
if (fd<0)
-
{
-
printf("open %s failed", page_map_file);
-
return -1;
-
}
-
if ((off_t)-1 == lseek(fd, pfn_item_offset, SEEK_SET))
-
{
-
printf("lseek %s failed", page_map_file);
-
return -1;
-
}
-
if (sizeof(uint64_t) != read(fd, &pfn_item, sizeof(uint64_t)))
-
{
-
printf("read %s failed", page_map_file);
-
return -1;
-
}
-
if (0==(pfn_item & PFN_PRESENT_FLAG))
-
{
-
printf("page is not present");
-
return -1;
-
}
-
*phy = (pfn_item & PFN_MASK)*page_size + vir % page_size;
-
return 0;
-
}
-
-
void main()
-
{
-
int a=0x12345678;
-
unsigned long phy;
-
mem_addr_vir2phy((unsigned long)&a, &phy);
-
printf("vaddr=%p,phy=0x%lx\n", &a, phy);
-
while(1)
-
{
-
sleep(100);
-
}
-
}
注:函数mem_addr_vir2phy代码出自
《Linux下获取虚拟地址对应的物理地址的方法》
这儿我只是打了一个main函数进行测试
二.验证结果的正确性
2.1 使用方法
cong@msi:/work/test/ctest/vaddr/Access_Physical_Memory$ sudo mknod /dev/dram c 85 0
cong@msi:/work/test/ctest/vaddr/Access_Physical_Memory$ ./fileview /dev/dram
注:上述驱动与fileview出自
《Linux用户程序如何访问物理内存》
2.2.2 我的ubuntun 的内核版本是 3.13.0-49-generic
作了少许改动
-
27d26
-
< #include <linux/mm.h>
-
47,49c46,47
-
< unsigned long pages = get_num_physpages();
-
< //dram_size = (loff_t)num_physpages << PAGE_SHIFT;
-
< dram_size = pages << PAGE_SHIFT;
-
---
-
>
-
> dram_size = (loff_t)num_physpages << PAGE_SHIFT;
-
77c75
-
< #if 1
-
---
-
> #if 0
2.3 验证一下结果
2.3.1 这个是用户空间打印出来的物理地址是0x41F47284
2.3.2 这是物理内存0x41F47284处的数据
完全吻合,说明成功
2.4 代码下载
包括fileview和驱动
Access_Physical_Memory.rar(下载后改名为Access_Physical_Memory.tar.bz2)
这个代码出自
附录: 内核文档
Documentation/vm/pagemap.txt
-
pagemap, from the userspace perspective
-
---------------------------------------
-
-
pagemap is a new (as of 2.6.25) set of interfaces in the kernel that allow
-
userspace programs to examine the page tables and related information by
-
reading files in /proc.
-
-
There are three components to pagemap:
-
-
* /proc/pid/pagemap. This file lets a userspace process find out which
-
physical frame each virtual page is mapped to. It contains one 64-bit
-
value for each virtual page, containing the following data (from
-
fs/proc/task_mmu.c, above pagemap_read):
-
-
* Bits 0-54 page frame number (PFN) if present
-
* Bits 0-4 swap type if swapped
-
* Bits 5-54 swap offset if swapped
-
* Bits 55-60 page shift (page size = 1<<page shift)
-
* Bit 61 reserved for future use
-
* Bit 62 page swapped
-
* Bit 63 page present
-
-
If the page is not present but in swap, then the PFN contains an
-
encoding of the swap file number and the page's offset into the
-
swap. Unmapped pages return a null PFN. This allows determining
-
precisely which pages are mapped (or in swap) and comparing mapped
-
pages between processes.
-
-
Efficient users of this interface will use /proc/pid/maps to
-
determine which areas of memory are actually mapped and llseek to
-
skip over unmapped regions.
-
-
* /proc/kpagecount. This file contains a 64-bit count of the number of
-
times each page is mapped, indexed by PFN.
-
-
* /proc/kpageflags. This file contains a 64-bit set of flags for each
-
page, indexed by PFN.
-
-
The flags are (from fs/proc/page.c, above kpageflags_read):
-
-
0. LOCKED
-
1. ERROR
-
2. REFERENCED
-
3. UPTODATE
-
4. DIRTY
-
5. LRU
-
6. ACTIVE
-
7. SLAB
-
8. WRITEBACK
-
9. RECLAIM
-
10. BUDDY
-
11. MMAP
-
12. ANON
-
13. SWAPCACHE
-
14. SWAPBACKED
-
15. COMPOUND_HEAD
-
16. COMPOUND_TAIL
-
16. HUGE
-
18. UNEVICTABLE
-
19. HWPOISON
-
20. NOPAGE
-
21. KSM
-
-
Short descriptions to the page flags:
-
-
0. LOCKED
-
page is being locked for exclusive access, eg. by undergoing read/write IO
-
-
7. SLAB
-
page is managed by the SLAB/SLOB/SLUB/SLQB kernel memory allocator
-
When compound page is used, SLUB/SLQB will only set this flag on the head
-
page; SLOB will not flag it at all.
-
-
10. BUDDY
-
a free memory block managed by the buddy system allocator
-
The buddy system organizes free memory in blocks of various orders.
-
An order N block has 2^N physically contiguous pages, with the BUDDY flag
-
set for and _only_ for the first page.
-
-
15. COMPOUND_HEAD
-
16. COMPOUND_TAIL
-
A compound page with order N consists of 2^N physically contiguous pages.
-
A compound page with order 2 takes the form of "HTTT", where H donates its
-
head page and T donates its tail page(s). The major consumers of compound
-
pages are hugeTLB pages (Documentation/vm/hugetlbpage.txt), the SLUB etc.
-
memory allocators and various device drivers. However in this interface,
-
only huge/giga pages are made visible to end users.
-
17. HUGE
-
this is an integral part of a HugeTLB page
-
-
19. HWPOISON
-
hardware detected memory corruption on this page: don't touch the
-
-
20. NOPAGE
-
no page frame exists at the requested address
-
-
21. KSM
-
identical memory pages dynamically shared between one or more processes
-
-
[IO related page flags]
-
1. ERROR IO error occurred
-
3. UPTODATE page has up-to-date data
-
ie. for file backed page: (in-memory data revision >= on-disk one)
-
4. DIRTY page has been written to, hence contains new data
-
ie. for file backed page: (in-memory data revision > on-disk one)
-
8. WRITEBACK page is being synced to disk
-
-
[LRU related page flags]
-
5. LRU page is in one of the LRU lists
-
6. ACTIVE page is in the active LRU list
-
18. UNEVICTABLE page is in the unevictable (non-)LRU list
-
It is somehow pinned and not a candidate for LRU page reclaims,
-
eg. ramfs pages, shmctl(SHM_LOCK) and mlock() memory segments
-
2. REFERENCED page has been referenced since last LRU list enqueue/requeue
-
9. RECLAIM page will be reclaimed soon after its pageout IO completed
-
11. MMAP a memory mapped page
-
12. ANON a memory mapped page that is not part of a file
-
13. SWAPCACHE page is mapped to swap space, ie. has an associated swap entry
-
14. SWAPBACKED page is backed by swap/RAM
-
-
The page-types tool in this directory can be used to query the above flags.
-
-
Using pagemap to do something useful:
-
-
The general procedure for using pagemap to find out about a process' memory
-
usage goes like this:
-
-
1. Read /proc/pid/maps to determine which parts of the memory space are
-
mapped to what.
-
2. Select the maps you are interested in -- all of them, or a particular
-
library, or the stack or the heap, etc.
-
3. Open /proc/pid/pagemap and seek to the pages you would like to examine.
-
4. Read a u64 for each page from pagemap.
-
5. Open /proc/kpagecount and/or /proc/kpageflags. For each PFN you just
-
read, seek to that entry in the file, and read the data you want.
-
-
For example, to find the "unique set size" (USS), which is the amount of
-
memory that a process is using that is not shared with any other process,
-
you can go through every map in the process, find the PFNs, look those up
-
in kpagecount, and tally up the number of pages that are only referenced
-
once.
-
-
Other notes:
-
-
Reading from any of the files will return -EINVAL if you are not starting
-
the read on an 8-byte boundary (e.g., if you seeked an odd number of bytes
-
into the file), or if the size of the read is not a multiple of 8 bytes.
阅读(3668) | 评论(0) | 转发(0) |