深入理解?mmap
時間:2021-08-19 16:30:43
手機看文章
掃描二維碼
隨時隨地手機看文章
[導(dǎo)讀]1.開場白環(huán)境:處理器架構(gòu):arm64內(nèi)核源碼:linux-5.11ubuntu版本:20.04.1代碼閱讀工具:vimctagscscope我們知道,linux系統(tǒng)中用戶空間和內(nèi)核空間是隔離的,用戶空間程序不能隨意的訪問內(nèi)核空間數(shù)據(jù),只能通過中斷或者異常的方式進入內(nèi)核態(tài),一般情...
1.開場白
- 環(huán)境:處理器架構(gòu):arm64內(nèi)核源碼:linux-5.11ubuntu版本:20.04.1代碼閱讀工具:vim ctags cscope
2. 體驗一下
首先我們通過一個例子來感受一下:驅(qū)動代碼:注:驅(qū)動代碼中使用misc框架來實現(xiàn)字符設(shè)備,misc框架會處理如創(chuàng)建字符設(shè)備,創(chuàng)建設(shè)備等通用的字符設(shè)備處理,我們只需要關(guān)心我們的實際的邏輯即可(內(nèi)核中大量使用misc設(shè)備框架來使用字符設(shè)備操作集如ioctl接口,像實現(xiàn)系統(tǒng)虛擬化kvm模塊,實現(xiàn)安卓進程間通信的binder模塊等)。0copy_demo.c
#include?
#include?
#include?
#include?
#include?
#define?MISC_DEV_MINOR?5
static?char?*kbuff;
static?ssize_t?misc_dev_read(struct?file?*filep,?char?__user?*buf,?size_t?count,?loff_t?*offset)
{
?int?ret;
?size_t?len?=?(count?>?PAGE_SIZE???PAGE_SIZE?:?count);
?pr_info("######?%s:%d?kbuff:%s?######\n",?__func__,?__LINE__,?kbuff);
?
?ret?=?copy_to_user(buf,?kbuff,?len);??//這里使用copy_to_user??來進程內(nèi)核空間到用戶空間拷貝
?return?len?-?ret;
}
static?ssize_t?misc_dev_write(struct?file?*filep,?const?char?__user?*buf,?size_t?count,?loff_t?*offset)
{
?pr_info("######?%s:%d?######\n",?__func__,?__LINE__);
?return?0;
}
static?int?misc_dev_mmap(struct?file?*filep,?struct?vm_area_struct?*vma)
{
?int?ret;
?unsigned?long?start;
?start?=?vma->vm_start;
?
?ret?=??remap_pfn_range(vma,?start,?virt_to_phys(kbuff)?>>?PAGE_SHIFT,
???PAGE_SIZE,?vma->vm_page_prot);?//使用remap_pfn_range來映射物理頁面到進程的虛擬內(nèi)存中??virt_to_phys(kbuff)?>>?PAGE_SHIFT作用是將內(nèi)核的虛擬地址轉(zhuǎn)化為實際的物理地址頁幀號??創(chuàng)建頁表的權(quán)限為通過mmap傳遞的?vma->vm_page_prot???映射大小為1頁
?return?ret;
}
static?long?misc_dev_ioctl(struct?file?*filep,?unsigned?int?cmd,?unsigned?long?args)
{
?pr_info("######?%s:%d?######\n",?__func__,?__LINE__);
?return?0;
}
static?int?misc_dev_open(struct?inode?*inodep,?struct?file?*filep)
{
?pr_info("######?%s:%d?######\n",?__func__,?__LINE__);
?return?0;
}
static?int?misc_dev_release(struct?inode?*inodep,?struct?file?*filep)
{
?pr_info("######?%s:%d?######\n",?__func__,?__LINE__);
?return?0;
}
static?struct?file_operations?misc_dev_fops?=?{
?.open?=?misc_dev_open,
?.release?=?misc_dev_release,
?.read?=?misc_dev_read,
?.write?=?misc_dev_write,
?.unlocked_ioctl?=?misc_dev_ioctl,
?.mmap?=?misc_dev_mmap,
};
static?struct?miscdevice?misc_dev?=?{
?MISC_DEV_MINOR,
?"misc_dev",
?