嵌入式操作系统-wince编程实验chapter_第1页
嵌入式操作系统-wince编程实验chapter_第2页
嵌入式操作系统-wince编程实验chapter_第3页
嵌入式操作系统-wince编程实验chapter_第4页
嵌入式操作系统-wince编程实验chapter_第5页
免费预览已结束,剩余21页可下载查看

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第四章管嵌入式系统与一般计算机系统中所使用的管理(storagemanagement)有着性相当大,通常都使用硬盘做为系统(storagesystem)中的后备体(backupstorage)来包括操作系统和应用程序在内的,内存则用来就显得更为重要。在本章中,对WindowsCE中,管理采用的内存分在WindowsCE系统中,内存的实体结构大致可分为RAMROMM的全名为ndomesmoryM的大小而言。如前所述,AM在一般计算机系统中,来执行PU即执行存放在AM中的程序,程序执行时所需的hp和tak分别位在AM中不同的地址上。WindowsCE系统中,RAM被分为程序空间(programmemory)和对象空间(objectstore)。程序空间和一般计算机系统中RAM的使用类似,用来执行程序及所需数据。对象空间则类似一般计算机系统中的硬盘,用来应用程序及。对象空间中存放的数据可分为三大类:(1)系统(filesystem),(2)注册信息(registry),(3WindowsCE数据库(WindowsCEdatabase)。程序空间和对WindowsCE发现处理程序(process)的内存空间不敷使用的情况下,WindowsCE会要求使用者释放一些对象空间的内存来4.1是WindowsCE3.0在CompaqiPAQH3850所提供28.49MB7.270.52MB4.1CompaqiPAQH3850RAM内存既是电子装置,其所的数据则须靠电力来维持。换言之,电力来源一但中断,在RAM中的数据就了。一般计算机系统中电力的供应来自外接电源,一但停电或是关机,电力供应中断,RAM中的执行程序及数的电力供应是完全切断的,因此在RAM中的程序及数据,也会随着关机。WindowsCE系统中,RAM既被用来当作对象空间使用,电力的来源则靠电池提供,因此有效的使用有限的电力来维持RAM中所的数据,则显的更为重要。WindowsCE系统的电源管理机制,即使在关机状态时,仍旧有少量的电的数据才会,而当系统重新获得电力时,一切的数据与软件都必需新加ROM的全名为ReadOnlyMemory,又称只读器,故名思义,ROM中的内容只能被,而不能有写入或更改的动作。因为ROM不需电力的供应,仍然能保有的内容,因此在嵌入式系统中,常被用来操作系统,或是重要且不会更改的数据(如开机时需要的数据)。在WindowsCE系统中,ROM了包含操作系统在内相关的。系统程序:RAMROM执行模式。一般的系统程序执行采用RAM执行模式操作系统会先把程序从ROM中取出RAM中执行。RAMRAM内存空间等缺点。为此,WindowsCEXIP(ExecuteinPlace),也就是ROM执行模式,使得在ROM中的系统程序,可以在指定的ROM地址中直接执行,而不用加载RAM中。ROM的只读特性,使得更改其中内容这个动作,变的相当复杂。举例来说,若CompaqiPAQ只具有ROM作为操作系统的工具,要升级一个CompaqiPAQ的操作系统,必需先有一颗新的ROM,利用特殊的设备将新的操作系统写入,再用此ROM更换iPAQ中原有的ROM。因为此特殊的设备甚为昂贵且不易取得,近年来便有FlashROM的产生。FlashROM不仅保有原本ROM在电源后仍保有数据的好处,并且拥有RAM可写入的特性,因此我们可以用它来保存的PDA中所配有的ROM即是Flash 。使用者可以到paq或相关取得FlashROM写入程序,并利用此程序来进行操作系统升级或更换(例WindowsCE🡨Linux)WindowsCE系统的内存管理是建构在虚拟内存机制上。在本节中,介绍WindowsCE的虚拟内存机制其中所使用的分页机制及提供多任务作业的slot虚拟内计算机程序的运算大多是在循环(loop)结构内完成。循环执行时所表现出来的(addresslocality)(spacelocality),使得执行程序所需称为实体地址(physicaladdress),而虚拟内存内所使用的地址称为虚拟地址(virtualaddress)。32-bit地址长度的操作系统,4GB(232Bytes)32MB64MB。虚拟内存的设计,使得程序设计师撰写程序时,不必顾虑到系统的物理内存的大小另外虚拟内存允许不同程序共享相同的和程序代码图4.20實體實體位 ValidPagePagePagePagePagemPage24v4vk-v45Pagem

01234

Pagemv1v

6543210後備儲存

虛擬位址轉換為實體位

實體虛擬图 虚拟内存与实体转换概述分页机WindowsCE32-bit。换言之,其虚拟内存的大小为4GB(232Bytes)。WindowsCE4GB2GB及高地2GB2GB2GB专供WindowsCE模块使用。WindowsCE操作系统使用KDataStruct数据结构来存放低地址2GB4.1KDataStruct4.1KDataStructstructKDataStructLPDWORDlpvTls; /*0x000Currentthreadlocalstoragepointer*/HANDLEahSys[NUM_SYS_HANDLES]; /*0x004Ifthismoves,changekapi.h*/char /*0x084rescheduleflagchar /*0x085kernelexceptionnestingchar /*0x086TRUEduring"poweroff"processingchar /*0x087TRUEifprofilingenabledulong /*0x088PageTableDescriptorulong /*0x08cwasDiffMSecPPROCESS /*0x090ptrtocurrentPROCESSstructPTHREAD /*0x094ptrtocurrentTHREADstructDWORD /*0x098ulong /*0x09chandletablebaseaddressPSECTIONaSections[64]; /*0x0a0sectiontableforvirutalmemory*/LPEVENTalpeIntrEvents[SYSINTR_MAX_DEVICES];/*0x1a0*/LPVOID /*0x220ulong /*0x2a0directAPIreturnaddressforkernelmodeuchar /*0x2a4ptrtoMemoryMaparrayDWORD /*0x2a8!0whenindebuggerPTHREAD /*0x2accurrentFPUownerPPROCESSpC /*0x2b0currentASIDproclong /*0x2b4-paddingDWORD /*0x300-misc.kernelinfo/*0x380-interlockedapicode/*0x400-end};/*KDataStructKDataStructPSECTIONaSections[64]2GB分割成6432MB大小的空间,称之为Section。一个Section再被分割成51264KB大小的空间,称之为MemBlock,如程序代码4.2所示。一个MemBlock再被分(Page)(PAGE_SIZE)在不同的系统中略有不同。ARM4PAGE_SIZE4096,ARM920PAGE_SIZE1024,MIPS被分割成16个页。程序代码4.3列出MemBlock整个数据结构,其中aPages[PAGES_PER_BLOCK]字段虚拟内存中每一个页所对应到的物理内4.2BLOCK、SECTION#define typedefMEMBLOCK//每一个SECTION指向512个BLOCKtypedefSECTION*PSECTION;程序代码 MemBlock数据结#definePAGE_SIZE4096 /*pagesize*/#definePAGES_PER_BLOCK(0x10000/PAGE_SIZE)structMemBlockACCESSLOCK /*00:keycodeforthissetofpagesuchar /*04:#ofpagetableentriessharingthisleafuchar /*05:mapflagsshort /*06:firstblockinregionshort /*08:handletopagershortcLocks; /*0a:lockcount*/ulongaPages[PAGES_PER_BLOCK];};/*MemBlock我们以CEPC为例子来说明虚拟内存到物理内存的对映关系。CEPC是将WindowsCE操作系统在个人计算机上执行。在这个以x86处理器的平台上,虚4.54.64.5所示切割成五大区段312GB,310。第二区段有六个位即第30-25个位此地址所属的Section号码第三区段有九个位,即第24-16个位,此地址所属的MemBlock号第四区段有四个位,即第15-12个位,此地址所属的页号码第五区段有十二个位,即第11-0个位,此地址在所对映的物理内 0Section6Block9Page412图 x86处理器虚拟地址的划WindowsCE4.5所示将此地址切割,4.6中。]..Memory

图 虚拟内存与物理内存的对映关WindowsCE2GB3332MB的内存空间,称之为”slot”33SECTION,当处理程序要执行前,WindowsCE将处理程序加载至slot中执行,特别需要注意的是,slot0保留给目前正在执行的处理程序使用,其余的slot则留给非正在执行的处理程序使用。因此,WindowsCE系统中,最多只能有32个处理程序同时进行。图4.3是内存的配置情形,稍后将介绍memorymap的细节及其它的内存空间。slotslotslot…slot 于WindowsCEPlatformBuilder使用mi指令可获得CEPC4.4为图 mi指令的使用方式及结4.4为mi指令执行后的片段结果程序代码 CEPC内存信WindowsCEKernelMemoryUsageToolPagesize=4096,4958totalpages,4544freepages.4517MinFreepages( MaxUsedbytes)90pagesusedbykernel,0pagesheldbykernel,414pagesconsumed.Memoryusagefor :'NK.EXE'pidSECURESlotbase Sectionptr Pagesummary:code=0(0)datar/o=0r/w=2stack=3 //SECUREROMDLLCODESlot Sectionptr //Slot1的使用情Pagesummary:code=508(0)datar/o=68r/w=1stack=0MemoryusageforProcess :'filesys.exe'pid1 //Slot2被filesys.exeSlotbase Sectionptr83ff1000 Pagesummary:code=31(0)datar/o=1r/w=20stack=5MemoryusageforProcess817916c8: .exe'pid //Slot3被 Slotbase Sectionptr83fcf000 Pagesummary:code=10(0)datar/o=0r/w=7stack=2=330Memoryusagefor c:device.exepid //Slot4Slot Sectionptr Pagesummary:code=6(1)datar/o=0r/w=113stack=40=958//情SLOTWindowsCEDLLs(dynamiclinklibraries)DLLsDLLs的程序代码是只读性且不可变更的,若是重复放置将会是物理内存的一大浪费,因此WindowsCEDLLs对应到同样DLLs档是相同的,每个处理程DLLsDLLs变量数据并不是相同的。此时,产生了一个问题,DLLs档如何知道目前是哪一个处理程序在呼叫它?WindowsCEDLLsslot0的变量做变动,也就是目前正在执行的处理程序,这也是slot0存在的原因。CurrentDLLCurrentDLLDLLDLLslotslot

图 DLL档对应关系图:slo1和slot2相同的DLLs档,对应至相同的物理内DoVirtualAlloc()函WindowsCE系统配置内存有两种方式:保留(MEM_RESERVE)和提交 DoVirtualAlloc()(pagetable),由于原始码非常复杂,本章节提供流程图(图4.6):WINCEROOT\PRIVATE\WINCEOS\COREOS\NK\KERNEL\virtmem.c有兴趣的检检否否是否为安全址是否为安全址体地址 是否需要 交地址是否地址是否已经留报错退成是是是是否4.6可用内存串LogPt->pLit找到串行可用内存串行采用简单的双向串行形式所以串行的管理极简单。程序代码4.5是插入可用内存串行的程序代码:程序代码4.5插入可用内存串行程序代LPBYTE){*(LPBYTE*)((DWORD)pMem+ )=LogPtr-*(LPBYTE*)((DWORD)pMem+ )=if(LogPtr-*(LPBYTE*)((DWORD)LogPtr->pKList+0x )=pMem;LogPtr->pKList=pMem;}KCALLPROFON()KCALLPROFOFF()分别是开启、关闭与加入可取得物理内图4.6中,取得物理内存是利用GetHeldPage函式呼叫GrabFirstPhysPage函式取得实体页程序代码4.6GetHeldPage函式程序代码4.7GrabFirstPhysPage()程序代码 GetHeldPage函PHYSICAL_ADDRESS{PHYSICAL_ADDRESSpaRet;LPBYTEpMem;ifpMemLPBYTE)KCall((PKFN)GrabFirstPhysPage,1 PageFreeCount++;//sincewealreadyit paRet=}paRet=DEBUGMSG(ZONE_PHYSMEM,(TEXT("GetHeldPage:Returning%8.8lx\r\n"),paRet));returnpaRet;}程序代码 DWORDdwCount){PFREEINFOuintPHYSICAL_ADDRESSpaRet;LPBYTEpMem;//检查PageFreecount(可用实体页)的值是否不小于0,而不是检测LogPtr-//是否为空,因为后者可能导致PageFreecount<0if(PageFreeCount){pMem=LogPtr->pKList;paRet=GetPFN(pMem);pfi=GetRegionFromAddr(paRet);if(pfi){//从可用内存串行中取出一//不经过if(LogPtr->pKList=*(LPBYTE*)((DWORD)pMem+ ))*(LPBYTE*)((DWORD)LogPtr->pKList+ )=}*(LPDWORD)(pMem+ )=*(LPDWORD)(pMem+ )=//修改系统中的FREEINFO变量的值,将数目改为dwCountix=(paRet-pfi->paStart)/PFN_INCR;DEBUGCHK(pfi->pUseMap[ix]==0);DEBUGCHK(dwCount&&(dwCount<=0xff));pfi->pUseMap[ix]=(BYTE)dwCount;if(FreeCount<(long)KInfoTable[KINX_MINPAGEFREE]){KInfoTable[KINX_MINPAGEFREE]=PageFreeCount;}return}偏移量0x 定义了一个映像,因为系统(kernel)也工作在虚拟内存模用内存串行只是保留的实体值的指针。回收的过程与此类似,定义在tontiguouPges中,其基本策略是扫描各个区域(gion,找到第一个满足条件的连续实体块。这个函数在执行时的运行。实体CleanUp执行绪,并向系统发出警报。如果配置后实体页数低于某个阈值,则削减执行绪PthScavTarget的堆积(stack)GWEHoldPages4.7。GetHeldPage函数得到所需的实体页,该函数主要呼叫GrabFirstPhysPage从可用内存串行中摘出一个实体页。否是否

是否设置设置换页执行绪优先否修改可用内存否能否满

否强制

成功退图 实体页面抓取流ProcessPageFault函ProcessPageFault函式处理存取页内存时发生的错误,产生的原因可能为在ProcessPageFault函式定义了这几种情况下相应的处理方法。首先检查该虚拟内存地址是否有效,再检查当前处理程序是否对该地址限,最后根据该blockmapper则呼叫MapperPageIn,如果是处理程LoadPageIn,每次呼叫若不成功,则重复,2秒钟以后超时,程序代码 页错误处理的部分程序代=IsSecureVa(addr)?&NKSection:SectionTable[addr>>VA_SECTION];if(( !=NULL_SECTION)&&((pmb= )[ixBlock])!=NULL_BLOCK))if(pmb==_BLOCK)pmb=(* ,ixBlock)];pagerType=pmb->flags&MB_FLAG_PAGER_TYPE;}elseif(!bWrite||IsPageWritable(pmb->aPages[ixPage]))bRet=TRUE;pagerType=pmb->flags&}elseif(pmb->aPages[ixPage]!=pagerType=pmb->flags&}if(pagerType!=MB_PAGER_NONE){dwLast= //根据该虚拟内存段的类型确定调页函数MappedPageIn或if(pageresult==PAGEIN_RETRY)bRet=FALSE;gotoretryPagein;goto}bRet=(BOOL)pageresult;}}elsebRet= //Threadnotallowedaccess,return}}4.2堆栈当处理程序执行时,需要静态或动态配置内存,如变量或指针,此时所WindowsCE中,系统对堆栈的管理只允许申请固定大小的块。虚拟页的情况。在WindowsCE中,每个堆栈都有一个信号(signal)来控制顺序存本地堆栈(LocalHeap)和独立堆栈(Separate32MB堆栈序分配空间的基本单位是堆栈。每个堆栈着一个虚拟地址项(VAitem)和区域(region)的串行。项的大小可变,是实际进行分配时的最小单位。项和项之间在虚拟地址上是相邻的,所以项只在串行头记录该项的大小,下而直接由堆栈来structregion 00:pregion 04:区域串行上最后一个区域指针(只对第一个区域有效 //08:该区域中最大可用内存项的尺寸 //0C:邻接结束标志的最后一个可用内存项 //10:所属堆栈pregion 14: 18:structheap //00:堆栈的符号“Heap”pvaitem //04:vaitem的串 //08:堆栈串行中下一个堆 0C:创立堆栈的参#ifdef wMemType;//0E:的内存类 //0E:填充位,用作对 cbum;//10:堆栈大小的上限(0表示可增长CRITICAL_SECTIONcs;//14:管理该堆栈使用的临界region //28:该堆栈中第一个区 Item busyitemssize0prgn指向item所属的区 freeitems:size< holeitems:size>0andprgn== endmakersize0cbTail表示尾部之前的字节 virtualitemsize0并且sizestructitem //项的大小(包含头部和尾部unionpregion //项所属区域的指 //或是指向包含虚拟项的堆栈指 //该区域中尾部前边的字节#if cbTrueSize;//实际需要的字节 //structvaitempvaitempvaFwd; //堆栈中下一个虚拟地址项的指针pvaitempvaBak; //堆栈中前一个虚拟地址项的指针itemit; //项讯息堆栈堆栈的创建和初始化定义在HeapCreate(DWORDflOptions,DWORDdwInitialSize,DWORDdw umSize)函数中,flOptions是创建方式,dwInitialSize是初始分配尺寸,dw umSize是堆栈的尺寸上限,如果为零,说明堆栈是可以增长的。在创建的过程中,系统先将dwInitialSize, umSize都对齐到页的大小,然后呼叫VirtulAlloc保留dwumSize个虚拟页,然后再呼叫InitNewHeap分配dwInitialSize个虚拟页并对这个堆栈进4.10 //初始化堆栈中第一个可用pit=FIRSTITEM(&php-php->rgn.pitFree=php->rgn.pitLast=dwTempdwInitialSizeSIZE_HEAP_HEADsizeof(item&~(ALIGNBYTES-1);pit->size=-(int)dwTemp; pit->prgn=&php-pit=(pitem)((char*)pit+dwTemp);/*找到下一个项的起始地址*/pit->size=0; pit->cbTail=cbRegion-php->rgn.cbMaxFree=dwTemp; php->rgn.phpOwner=php;php->rgn.prgnLast=&php- /*设置串行指针堆栈的分配和回堆栈的分配过程首先计算堆栈所在的slot,如果分配方式为可增长且分配空间大于188k,那么直接从该slot分配虚拟地址给pVAitem。否则在已有区域中找出满4.11为堆栈分配过程的部分程序代码:4.11if(!php->cbum&&(dwBytes+sizeof(vaitem)>=CE_VALLOC_MINSIZE)){pitRet=DoLargeHeapAlloc(lpSlot,php,dwBytes);}elseintcbSeek=ALIGNSIZE(dwBytes+sizeof(item)+//进入该堆栈的临界区以控制存 &&!php->cb&&(prgn=CreateNewRegion(lpSlot,php,cbSeek)))//如果不能在已有的区域内找到,则创建一个新pitRet=FIRSTITEM}if(pitRet)//将得到的可用内存项细pitRet=CarveItem(prgn,pitRet,cbSeek,dwBytes,}FindFreeItem是寻找第一个可用项的函数主要呼叫FindFreeItemInRegion,dowhile((cbItem=pit->size)>0){ pit=(pitem)((char*)pit+cbItem);}pit=MergeFreeItems(prgn,pitRet=pit); cbItem=-pitRet->size;//if(cbItem>=cbSeek)if(cbItem-cbSeek>cbMax)cbMax=cbItem-cbSeek;}if(cbMax<cbItem)cbMax=cbItem;if(fEndReached&&(pit>=pitStart))但是在分外物理内存之前还不能使用*/if(!pit->size){fEndReached=TRUE;pitEnd=pitRet;pit=FIRSTITEM}}while(!fEndReached||(pit<CarveItem做的是将得到的项细化成所需空间大小的项,并尽可能的向左对if(cbItem<cbSeek)pitempitEnd=(pitem)((char*)pit+cbItem);intcbEx;//计算需要补齐的页数//注意补齐之后要标记一个新的结尾标cbEx=(cbSeek-cbItem+sizeof(item)+PAGE_SIZE-1)&- {return //内存不足,报错返}pitNext=(pitem)((char*)pitEnd+cbEx);pitNext->size=0;堆栈程序代码 堆栈的回ifsize&1){/*虚拟地址映像到项的标记*/if(php==pit->php){

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论