www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當前位置:首頁 > 公眾號精選 > CPP開發(fā)者
[導(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
我們知道,linux系統(tǒng)中用戶空間和內(nèi)核空間是隔離的,用戶空間程序不能隨意的訪問內(nèi)核空間數(shù)據(jù),只能通過中斷或者異常的方式進入內(nèi)核態(tài),一般情況下,我們使用copy_to_user和copy_from_user等內(nèi)核api來實現(xiàn)用戶空間和內(nèi)核空間的數(shù)據(jù)拷貝,但是像顯存這樣的設(shè)備如果也采用這樣的方式就顯的效率非常底下,因為用戶經(jīng)常需要在屏幕上進行繪制,要消除這種復(fù)制的操作就需要應(yīng)用程序直接能夠訪問顯存,但是顯存被映射到內(nèi)核空間,應(yīng)用程序是沒有訪問權(quán)限的,如果顯存也能同時映射到用戶空間那就不需要拷貝操作了,于是字符設(shè)備中提供了mmap接口,可以將內(nèi)核空間映射的那塊物理內(nèi)存再次映射到用戶空間,這樣用戶空間就可以直接訪問不需要任何拷貝操作,這就是我們今天要說的0拷貝技術(shù)。

下面是正常情況下用戶空間和內(nèi)核空間數(shù)據(jù)訪問圖示:

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",
    ?
  • 本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
    關(guān)閉
    關(guān)閉