• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            milkyway的窩

            最初想法的誕生地

             

            Windows CE下訪問(wèn)物理內(nèi)存的方法

            嵌入式設(shè)備與桌面PC的一個(gè)顯著不同是它的應(yīng)用程序中通常需要直接訪問(wèn)某一段物理內(nèi)存,這在驅(qū)動(dòng)程序中對(duì)物理內(nèi)存的訪問(wèn)尤為重要,尤其是像ARM體系結(jié)構(gòu)下,I/O端口也被映射成某一個(gè)物理內(nèi)存地址。因此,與桌面版本W(wǎng)indows相比,Windows?CE提供了相對(duì)簡(jiǎn)單的物理內(nèi)存訪問(wèn)方式。無(wú)論是驅(qū)動(dòng)程序還是應(yīng)用程序都可以通過(guò)API訪問(wèn)某一段物理內(nèi)存。
            Windows?CE的有些函數(shù)中需要用到物理內(nèi)存結(jié)構(gòu)體PHYSICAL_ADDRESS,?Windows?CE在ceddk.h中定義了PHYSICAL_ADDRESS,它其實(shí)是LARGE_INTEGER類型,其定義如下:
            //?in?ceddk.h
            typedef?LARGE_INTEGER?PHYSICAL_ADDRESS,?*PPHYSICAL_ADDRESS;
            //?in?winnt.h
            typedef?union?_LARGE_INTEGER{
            ??struct{
            ????DWORD?LowPart;
            ????LONG?HighPart;
            ??};
            ??LONGLONG?QuadPart;
            }?LARGE_INTEGER;
            可見(jiàn),Windows?CE中用64個(gè)Bit來(lái)代表物理地址,對(duì)于大多數(shù)32位的CPU而言,只需要把它的HighPart設(shè)置為0就可以了。
            如果要直接訪問(wèn)某一個(gè)地址的物理內(nèi)存,Windows?CE提供了VirtualAlloc()和VirtualCopy()函數(shù),VirtualAlloc負(fù)責(zé)在虛擬內(nèi)存空間內(nèi)保留一段虛擬內(nèi)存,而VirtualCopy負(fù)責(zé)把一段物理內(nèi)存和虛擬內(nèi)存綁定,這樣,最終對(duì)物理內(nèi)存的訪問(wèn)還是通過(guò)虛擬地址進(jìn)行。它們的聲明如下:
            //?申請(qǐng)?zhí)摂M內(nèi)存
            LPVOID?VirtualAlloc(
            ??LPVOID?lpAddress,?????????//?希望的虛擬內(nèi)存起始地址
            ??DWORD?dwSize,?????????????????//?以字節(jié)為單位的大小
            ??DWORD?flAllocationType,?????//?申請(qǐng)類型,分為Reserve和Commit
            ??DWORD?flProtect?????????????//?訪問(wèn)權(quán)限
            );
            //?把物理內(nèi)存綁定到虛擬地址空間
            BOOL?VirtualCopy(?
            ??LPVOID?lpvDest,?????????????//?虛擬內(nèi)存的目標(biāo)地址
            ??LPVOID?lpvSrc,?????????????//?物理內(nèi)存地址
            ??DWORD?cbSize,?????????????????//?要綁定的大小
            ??DWORD?fdwProtect?????????????//?訪問(wèn)權(quán)限
            );
            VirtualAlloc對(duì)虛擬內(nèi)存的申請(qǐng)分為兩步,保留MEM_RESERVE和提交MEM_COMMIT。其中MEM_RESERVE只是在進(jìn)程的虛擬地址空間內(nèi)保留一段,并不分配實(shí)際的物理內(nèi)存,因此保留的虛擬內(nèi)存并不能被應(yīng)用程序直接使用。MEM_COMMIT階段才真正的為虛擬內(nèi)存分配物理內(nèi)存。
            下面的代碼顯示了如何使用VirtualAlloc和VirtualCopy來(lái)訪問(wèn)物理內(nèi)存。因?yàn)閂irtualCopy負(fù)責(zé)把一段物理內(nèi)存和虛擬內(nèi)存綁定,所以VirtualAlloc的時(shí)候只需要對(duì)內(nèi)存保留,沒(méi)有必要提交。
            FpDriverGlobals?=?
            (PDRIVER_GLOBALS)?VirtualAlloc(
            ????0,?
            ????DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,?
            ????MEM_RESERVE,?
            ????PAGE_NOACCESS);
            ?if?(FpDriverGlobals?==?NULL)?{
            ????ERRORMSG(DRIVER_ERROR_MSG,?(TEXT("?VirtualAlloc?failed!\r\n")));
            ????return;
            ?}
            ?else?{
            ????if?(!VirtualCopy(
            ????(PVOID)FpDriverGlobals,?
            ????(PVOID)(DRIVER_GLOBALS_PHYSICAL_MEMORY_START),?
            ????DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,?
            ????(PAGE_READWRITE?|?PAGE_NOCACHE)))?{
            ???????ERRORMSG(DRIVER_ERROR_MSG,?(TEXT("VirtualCopy?failed!\r\n")));
            ???????return;
            ????}
            ?}
            CEDDK還提供了函數(shù)MmMapIoSpace用來(lái)把一段物理內(nèi)存直接映射到虛擬內(nèi)存。用MmMapIoSpace申請(qǐng)的內(nèi)存要用MmUnmapIoSpace釋放,此函數(shù)的原形如下:
            PVOID?MmMapIoSpace(?
            ??PHYSICAL_ADDRESS?PhysicalAddress,?????//?起始物理地址
            ??ULONG?NumberOfBytes,?????????????????????//?要映射的字節(jié)數(shù)
            ??BOOLEAN?CacheEnable?????????????????????//?是否緩存
            );

            VOID?MmUnmapIoSpace(?
            ??PVOID?BaseAddress,?????????????????????//?MmMapIoSpace返回的起始虛擬地址
            ??ULONG?NumberOfBytes?????????????????????//?
            );
            其實(shí),MmMapIoSpace函數(shù)內(nèi)部也是調(diào)用VirtualAlloc和VirtualCopy函數(shù)來(lái)實(shí)現(xiàn)物理地址到虛擬地址的映射的。MmMapIoSpace函數(shù)的原代碼是公開的,我們可以從%_WINCEROOT%\PUBLIC\COMMON\OAK\DRIVERS\CEDDK\DDK_MAP\ddk_map.c得到。從MmMapIoSpace的實(shí)現(xiàn)我們也可以看出VirtualAlloc和VirtualCopy的用法:
            PVOID?MmMapIoSpace?(
            ????IN?PHYSICAL_ADDRESS?PhysicalAddress,
            ????IN?ULONG?NumberOfBytes,
            ????IN?BOOLEAN?CacheEnable
            ????)
            {
            PVOID?pVirtualAddress;?ULONGLONG?SourcePhys;?
            ULONG?SourceSize;?BOOL?bSuccess;

            ????SourcePhys?=?PhysicalAddress.QuadPart?&?~(PAGE_SIZE?-?1);
            ????SourceSize?=?NumberOfBytes?+?(PhysicalAddress.LowPart?&?(PAGE_SIZE?-?1));

            ????pVirtualAddress?=?VirtualAlloc(0,?SourceSize,?MEM_RESERVE,?PAGE_NOACCESS);
            ????if?(pVirtualAddress?!=?NULL)
            ????{
            ????????bSuccess?=?VirtualCopy(
            ????????????pVirtualAddress,?(PVOID)(SourcePhys?>>?8),?SourceSize,
            ????????????PAGE_PHYSICAL?|?PAGE_READWRITE?|?(CacheEnable???0?:?PAGE_NOCACHE));

            ????????if?(bSuccess)?{
            ????????????(ULONG)pVirtualAddress?+=?PhysicalAddress.LowPart?&?(PAGE_SIZE?-?1);
            ????????}
            ????????else?{
            ????????????VirtualFree(pVirtualAddress,?0,?MEM_RELEASE);
            ????????????pVirtualAddress?=?NULL;
            ????????}
            ????}
            ????return?pVirtualAddress;
            }
            此外,Windows?CE還供了AllocPhysMem函數(shù)和FreePhysMem函數(shù),用來(lái)申請(qǐng)和釋放一段連續(xù)的物理內(nèi)存。函數(shù)可以保證申請(qǐng)的物理內(nèi)存是連續(xù)的,如果函數(shù)成功,會(huì)返回虛擬內(nèi)存的句柄和物理內(nèi)存的起始地址。這對(duì)于DMA設(shè)備尤為有用。在這里就不詳細(xì)介紹了,讀者可以參考Windows?CE的聯(lián)機(jī)文檔。

            posted on 2007-02-02 09:25 milkyway 閱讀(2803) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            導(dǎo)航

            統(tǒng)計(jì)

            公告

            隨筆皆原創(chuàng),文章乃轉(zhuǎn)載. 歡迎留言!

            常用鏈接

            留言簿(37)

            隨筆分類(104)

            隨筆檔案(101)

            文章分類(51)

            文章檔案(53)

            wince牛人

            搜索

            積分與排名

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            久久国产色AV免费看| 亚洲国产成人久久笫一页| 久久伊人色| 看全色黄大色大片免费久久久| 国产精品一久久香蕉产线看 | 久久午夜夜伦鲁鲁片免费无码影视| …久久精品99久久香蕉国产| 久久国产色AV免费看| 久久婷婷五月综合色高清 | 久久99精品久久久久久秒播| 色综合久久久久网| 国产精品日韩深夜福利久久| 精品久久久无码中文字幕天天| 久久精品人妻一区二区三区| 久久久久亚洲AV成人网| 亚洲午夜精品久久久久久app| 一级做a爰片久久毛片免费陪 | 久久线看观看精品香蕉国产| 色偷偷888欧美精品久久久| 精品久久久久久无码免费| 午夜精品久久影院蜜桃 | 亚洲av伊人久久综合密臀性色| 亚洲国产精品无码久久一区二区| 国产成人无码精品久久久性色 | 午夜欧美精品久久久久久久| AV无码久久久久不卡网站下载| 伊人久久大香线蕉精品| 思思久久99热只有频精品66| 国产人久久人人人人爽| 久久久久久久久久免免费精品| 精品国产乱码久久久久久人妻 | 亚洲伊人久久成综合人影院 | 国产成人久久精品一区二区三区 | 综合网日日天干夜夜久久| 久久综合综合久久综合| 国内精品久久久久久久影视麻豆 | 精品无码久久久久久国产| 国产毛片欧美毛片久久久| 久久精品成人免费观看97| 99久久精品午夜一区二区 | 久久久精品人妻一区二区三区蜜桃|