驅動代碼
dma.c
#include <linux/init.h> #include <linux/module.h> #include <linux/gfp.h> #include <linux/mm.h> MODULE_LICENSE("DUAL BSD/GPL"); static int __init alloc_pages_init(void); static void __exit alloc_pages_exit(void); struct page *pages = NULL; int __init alloc_pages_init(void) { pages = alloc_pages(GFP_KERNEL, 3); if(!pages) return -ENOMEM; else { printk(KERN_ALERT "alloc_pages Successfully!\n"); printk(KERN_ALERT "pages=0x%lx\n", (unsigned long)pages); printk(KERN_ALERT "size of 'pages'=%ld\n", sizeof pages); printk(KERN_ALERT "pages=0x%lx\n", pages); printk(KERN_ALERT "mem_map = 0x%lx\n",(unsigned long)mem_map); printk(KERN_ALERT "size of 'mem_map'=%ld\n", sizeof mem_map); printk(KERN_ALERT "mem_map = 0x%lx\n",mem_map); printk(KERN_ALERT "pages - mem_map = 0x%lx\n",(unsigned long)pages - (unsigned long)mem_map); printk(KERN_ALERT "pages - mem_map = 0x%lx\n",(unsigned long)(pages - mem_map)); //the physical address of the head of the pages printk(KERN_ALERT "(pages - mem_map) << 12 = 0x%lx\n",((unsigned long)pages - (unsigned long) mem_map) * 4096); printk(KERN_ALERT "(pages - mem_map) << 12 = 0x%lx\n",(unsigned long)(pages - mem_map) * 4096); //the kernel logic address of the head of the pages printk(KERN_ALERT "page_address(pages) = 0x%lx\n", (unsigned long)page_address(pages)); } return 0; } void __exit alloc_pages_exit(void) { if(pages) { __free_pages(pages, 3); printk(KERN_ALERT "__free_pages ok!\n"); } printk(KERN_ALERT "exit\n"); } module_init(alloc_pages_init); module_exit(alloc_pages_exit);
Makefile
KERNELDIR=/lib/modules/$(shell uname -r)/build
obj-m = dma.o
modules:
$(MAKE) -C $(KERNELDIR) M=`pwd` modules
clean:
rm -rf *~ *.o *.ko *.mod* *.order *.mar* *.sym*
測試腳本
make clean
make
sudo rmmod dma
sudo insmod dma.ko
dmesg
我想學習linux內存頁面分配相關的知識,用到alloc_pages和page_address函數,其中在alloc_pages函數中我遇到了一個問題。
參考地址代碼地址爲:http://hi.baidu.com/armlinuxqt/item/2c1f9e049f9106c775cd3c66
寫一個內核模塊,這個內核模塊在初始化時分配8個頁面大小的內存塊,然後打印出分配到的內存頁面的邏輯地址,進而得到頁框號pfn,最後使用page_address得到物理內存地址。
輸出結果爲:
alloc_pages Successfully!
pages=0xc1192700
size of 'pages'=4
pages=0xc1192700
mem_map = 0xc1000000
size of 'mem_map'=4
mem_map = 0xc1000000
pages - mem_map = 0x192700
pages - mem_map = 0xc938
(pages - mem_map) << 12 = 0x92700000
(pages - mem_map) << 12 = 0xc938000
page_address(pages) = 0xcc938000
我的問題是,究竟應該怎樣才能得到內存頁面的確切地址。