page
__get_free_pages申请的地址不能直接用page_to_phys()转换而可以使用virt_to_phys()完成转换,因为在page_to_phys()里面使用page_address()进行处理了。
所以需要使用virt_to_page()来转换下就可以了。
如下:
page_to_phys(virt_to_page(mypg)和virt_to_phys(mypg)结果一样
printk("================================############################\n");
printk("test ....\n");
struct page* mypg = __get_free_pages(GFP_KERNEL | GFP_DMA,
get_order(ROUND_UP(VFS_SIZE, SZ_4K)));
struct page* mypg1 = alloc_pages(GFP_KERNEL | __GFP_ZERO | GFP_DMA,
get_order(ROUND_UP(VFS_SIZE, SZ_4K)));
struct page* mypg2 = alloc_pages(GFP_KERNEL | __GFP_ZERO | GFP_DMA & ~__GFP_HIGHMEM,
get_order(ROUND_UP(VFS_SIZE, SZ_4K)));
printk("va = 0x%lx, pa = 0x%lx, pa = 0x%lx\n", boot_vfs_addr, page_to_phys((struct page *)boot_vfs_addr), virt_to_phys(boot_vfs_addr));
printk("va = 0x%lx, pa = 0x%lx, pa = 0x%lx 0x%x\n", mypg, page_to_phys(mypg), virt_to_phys(mypg), page_to_phys(virt_to_page(mypg)));
printk("va = 0x%lx, pa = 0x%lx, pa = 0x%lx\n", mypg1, page_to_phys(mypg1), virt_to_phys(mypg1));
printk("va = 0x%lx, pa = 0x%lx, pa = 0x%lx\n", mypg2, page_to_phys(mypg2), virt_to_phys(mypg2));
printk("================================############################\n");
进程上下文,可以睡眠 GFP_KERNEL
进程上下文,不可以睡眠 GFP_ATOMIC
中断处理程序 GFP_ATOMIC
软中断 GFP_ATOMIC
Tasklet GFP_ATOMIC
用于DMA的内存,可以睡眠 GFP_DMA | GFP_KERNEL
用于DMA的内存,不可以睡眠 GFP_DMA | GFP_ATOMIC
参考:
virt_to_phys virt_to_page page_to_virt phys_to_virt_June_Hou的博客-CSDN博客_page_to_virt
page
__get_free_pages申请的地址不能直接用page_to_phys()转换而可以使用virt_to_phys()完成转换,因为在page_to_phys()里面使用page_address()进行处理了。
所以需要使用virt_to_page()来转换下就可以了。
如下:
page_to_phys(virt_to_page(mypg)和virt_to_phys(mypg)结果一样
printk("================================############################\n");
printk("test ....\n");
struct page* mypg = __get_free_pages(GFP_KERNEL | GFP_DMA,
get_order(ROUND_UP(VFS_SIZE, SZ_4K)));
struct page* mypg1 = alloc_pages(GFP_KERNEL | __GFP_ZERO | GFP_DMA,
get_order(ROUND_UP(VFS_SIZE, SZ_4K)));
struct page* mypg2 = alloc_pages(GFP_KERNEL | __GFP_ZERO | GFP_DMA & ~__GFP_HIGHMEM,
get_order(ROUND_UP(VFS_SIZE, SZ_4K)));
printk("va = 0x%lx, pa = 0x%lx, pa = 0x%lx\n", boot_vfs_addr, page_to_phys((struct page *)boot_vfs_addr), virt_to_phys(boot_vfs_addr));
printk("va = 0x%lx, pa = 0x%lx, pa = 0x%lx 0x%x\n", mypg, page_to_phys(mypg), virt_to_phys(mypg), page_to_phys(virt_to_page(mypg)));
printk("va = 0x%lx, pa = 0x%lx, pa = 0x%lx\n", mypg1, page_to_phys(mypg1), virt_to_phys(mypg1));
printk("va = 0x%lx, pa = 0x%lx, pa = 0x%lx\n", mypg2, page_to_phys(mypg2), virt_to_phys(mypg2));
printk("================================############################\n");
进程上下文,可以睡眠 GFP_KERNEL
进程上下文,不可以睡眠 GFP_ATOMIC
中断处理程序 GFP_ATOMIC
软中断 GFP_ATOMIC
Tasklet GFP_ATOMIC
用于DMA的内存,可以睡眠 GFP_DMA | GFP_KERNEL
用于DMA的内存,不可以睡眠 GFP_DMA | GFP_ATOMIC
参考:
virt_to_phys virt_to_page page_to_virt phys_to_virt_June_Hou的博客-CSDN博客_page_to_virt