acpitable解析过程分析_第1页
acpitable解析过程分析_第2页
acpitable解析过程分析_第3页
acpitable解析过程分析_第4页
acpitable解析过程分析_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

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

文档简介

acpitable解析过程分析acpi表结构⼤概是这样的知道了表的⼤概结构我问来分析的解析的过程解析的⼊⼝函数为acpi_tb_parse_root_table函数/*********************************************************************************FUNCTION:acpi_tb_parse_root_table**PARAMETERS:rsdp*-PointertotheRSDP*RETURN:*Status*DESCRIPTION:ThisfunctioniscalledtoparsetheRootSystemDescription*Table(RSDTorXSDT)**NOTE:Tablesaremapped(notcopied)forefficiency.TheFACSmustbemappedandcannotbecopiedbecauseitcontainstheactualmemorylocationoftheACPIGlobalLock.*********************************************************************************/acpi_status__initacpi_tb_parse_root_table(acpi_physical_addressrsdp_address){structacpi_table_rsdp*rsdp;u32table_entry_size;u32i;u32table_count;structacpi_table_header*table;acpi_physical_addressaddress;u32length;u8*table_entry;acpi_statusstatus;u32table_index;ACPI_FUNCTION_TRACE(tb_parse_root_table);/*MaptheentireRSDPandextracttheaddressoftheRSDTorXSDT*/rsdp=acpi_os_map_memory(rsdp_address,sizeof(structacpi_table_rsdp));if(!rsdp){return_ACPI_STATUS(AE_NO_MEMORY);}acpi_tb_print_table_header(rsdp_address,ACPI_CAST_PTR(structacpi_table_header,rsdp));/*UseXSDTifpresentandnotoverridden.Otherwise,useRSDT*/if((rsdp->revision>1)&&if((rsdp->revision>1)&&rsdp->xsdt_physical_address&&!acpi_gbl_do_not_use_xsdt){/**RSDPcontainsanXSDT(64-bitphysicaladdresses).Wemustuse*theXSDTiftherevisionis>1andtheXSDTpointerispresent,*aspertheACPIspecification.*/address=(acpi_physical_address)rsdp->xsdt_physical_address;table_entry_size=ACPI_XSDT_ENTRY_SIZE;}else{/*RoottableisanRSDT(32-bitphysicaladdresses)*/address=(acpi_physical_address)rsdp->rsdt_physical_address;table_entry_size=ACPI_RSDT_ENTRY_SIZE;}/**Itisnotpossibletomapmorethanoneentryinsomeenvironments,*sounmaptheRSDPherebeforemappingothertables*/acpi_os_unmap_memory(rsdp,sizeof(structacpi_table_rsdp));/*MaptheRSDT/XSDTtableheadertogetthefulltablelength*/table=acpi_os_map_memory(address,sizeof(structacpi_table_header));if(!table){return_ACPI_STATUS(AE_NO_MEMORY);}acpi_tb_print_table_header(address,table);/**Validatelengthofthetable,andmapentiretable.*Minimumlengthtablemustcontainatleastoneentry.*/length=table->length;acpi_os_unmap_memory(table,sizeof(structacpi_table_header));if(length<(sizeof(structacpi_table_header)+table_entry_size)){ACPI_BIOS_ERROR((AE_INFO,"Invalidtablelength0x%XinRSDT/XSDT",length));return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);}table=acpi_os_map_memory(address,length);if(!table){return_ACPI_STATUS(AE_NO_MEMORY);}/*Validatetheroottablechecksum*/status=acpi_tb_verify_checksum(table,length);if(ACPI_FAILURE(status)){acpi_os_unmap_memory(table,length);return_ACPI_STATUS(status);}/*Getthenumberofentriesandpointertofirstentry*/table_count=(u32)((table->length-sizeof(structacpi_table_header))/table_entry_size);table_entry=ACPI_ADD_PTR(u8,table,sizeof(structacpi_table_header));/**FirstthreeentriesinthetablearrayarereservedfortheDSDT*FirstthreeentriesinthetablearrayarereservedfortheDSDT*and32bit/64bitFACS,whicharenotactuallypresentinthe*RSDT/XSDT-theycomefromtheFADT*/acpi_gbl_root_table_list.current_table_count=3;/*InitializetheroottablearrayfromtheRSDT/XSDT*/for(i=0;i<table_count;i++){/*Getthetablephysicaladdress(32-bitforRSDT,64-bitforXSDT)*/address=acpi_tb_get_root_table_entry(table_entry,table_entry_size);/*SkipNULLentriesinRSDT/XSDT*/if(!address){gotonext_table;}status=acpi_tb_install_standard_table(address,ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,FALSE,TRUE,&table_index);if(ACPI_SUCCESS(status)&&ACPI_COMPARE_NAME(&acpi_gbl_root_table_list.tables[table_index].signature,ACPI_SIG_FADT)){acpi_tb_parse_fadt(table_index);}next_table:table_entry+=table_entry_size;}acpi_os_unmap_memory(table,length);return_ACPI_STATUS(AE_OK);}⾸先注释上说acpi表为了⾼效使⽤map映射,⽽FACS必须使⽤映射因为这段内存中存在全局锁1rsdp=acpi_os_map_memory(rsdp_address,sizeof(structacpi_table_rsdp));映射到虚拟地址RSDP2acpi_tb_print_table_header打印表头表头结构如下,注意表头是直接从rsdp转换得到的/*********************************************************************************MasterACPITableHeader.ThiscommonheaderisusedbyallACPItables*excepttheRSDPandFACS.*******************************************************************************/structacpi_table_header{charsignature[ACPI_NAME_SIZE];/*ASCIItablesignature*/u32length;/*Lengthoftableinbytes,includingthisheader*/u8revision;/*ACPISpecificationminorversionnumber*//*Tomakesumofentiretable==0*/u8checksum;charoem_id[ACPI_OEM_ID_SIZE];/*ASCIIOEMidentification*/charoem_table_id[ACPI_OEM_TABLE_ID_SIZE];/*ASCIIOEMtableidentification*/u32oem_revision;/*OEMrevisionnumber*/charasl_compiler_id[ACPI_NAME_SIZE];/*ASCIIASLcompilervendorID*/u32asl_compiler_revision;/*ASLcompilerversion*/};第⼀项signature是表的签名length为表的长度revision版本checksum校验值oem_id⼚商idoem_table_idtable的idoem_revision⼚商版本asl_compiler_id编译器idasl_compiler_revision编译器版本编译是为解释acpi操作语⾔ASL的编译器3根据版本选择使⽤xsdt还是rsdt,revision>1并且存在xsdt的情况必须使⽤XSDTXSDT表全称ExtendedRootSystemDescriptionTable,它的作⽤于RSDT⼀样,区别在于两者包含的指针地址⼀个是32位的,⼀个是64位的。XSDT表结构如下typedefstruct{EFI_ACPI_DESCRIPTION_HEADERHeader;UINT64Entry;RSDT结构如下typedefstruct{EFI_ACPI_DESCRIPTION_HEADERHeader;UINT32}Entry;4找到要具体使⽤的RSDT/XSDT就可以进⾏解析了,⾸先解除RSDP的映射,然后映射RSDT/XSDT表头,通过表头验证表长度是否正确,如果正确再映射整张表5验证表校验和6处表头后为entry,获取entry个数,able_count=(u32)((table->length-sizeof(structacpi_table_header))/table_entry_size)7acpi_gbl_root_table_list.current_table_count=3该值设置为3的理由是保留前三项⽤于存放DSDT和FACS,这两个表不是从RSDT和XSDT中获取的,⽽是从FADT中得到的8按照计算好的表项个数去遍历RSDT/XSDTacpi_tb_get_root_table_entry函数⽤于获取⼀个entryacpi_tb_install_standard_table⽤于安装标准table如果table是FADT则使⽤acpi_tb_parse_fadt函数去解析DSDT和FACS下⾯具体分析下acpi_tb_get_root_table_entry函数,acpi_tb_install_standard_table和acpi_tb_parse_fadtacpi_tb_get_root_table_entry⽤于从RSDT/XSDT中解析⼦table注意RSDT/XSDT的entry变量描述的就是⼦table的物理地址/*********************************************************************************FUNCTION:acpi_tb_get_root_table_entry**PARAMETERS:table_entry-PointertotheRSDT/XSDTtableentry**table_entry_size-sizeof32or64(RSDTorXSDT)*RETURN:*Physicaladdressextractedfromtheroottable*DESCRIPTION:Getoneroottableentry.Handles32-bitand64-bitcaseson*both32-bitand64-bitplatforms**NOTE:acpi_physical_addressis32-biton32-bitplatforms,64-biton64-bitplatforms.********************************************************************************/staticacpi_physical_addressacpi_tb_get_root_table_entry(u8*table_entry,u32table_entry_size){u64address64;/**Getthetablephysicaladdress(32-bitforRSDT,64-bitforXSDT):*Note:Addressesare32-bitaligned(not64)inbothRSDTandXSDT*/if(table_entry_size==ACPI_RSDT_ENTRY_SIZE){/**32-bitplatform,RSDT:Return32-bittableentry*64-bitplatform,RSDT:Expand32-bitto64-bitandreturn*/return((acpi_physical_address)(*ACPI_CAST_PTR(u32,table_entry)));}else{/**32-bitplatform,XSDT:Truncate64-bitto32-bitandreturn*64-bitplatform,XSDT:Move(unaligned)64-bittolocal,*return64-bit*/ACPI_MOVE_64_TO_64(&address64,table_entry);#ifACPI_MACHINE_WIDTH==32if(address64>ACPI_UINT32_MAX){/*Willtruncate64-bitaddressto32bits,issuewarning*/ACPI_BIOS_WARNING((AE_INFO,"64-bitPhysicalAddressinXSDTistoolarge(0x%8.8X%8.8X),""truncating",ACPI_FORMAT_UINT64(address64)));}#endifreturn((acpi_physical_address)(address64));}}其实很简单,就是按照RSDT(32位entry)或者XDDT(64位entry)转换⼀下。acpi_tb_install_standard_table函数⽤于安装前⾯解析到的tableentry指向的table/*******************************************************************************/*********************************************************************************FUNCTION:acpi_tb_install_standard_table**PARAMETERS:address-Addressofthetable(mightbeavirtual******addressdependingonthetable_flags)flags-Flagsforthetablereload-Whetherreloadshouldbeperformed-Whetheroverrideshouldbeperformed-Wherethetableindexisreturnedoverridetable_index*RETURN:*Status*DESCRIPTION:ThisfunctioniscalledtoinstallanACPItablethatis******neitherDSDTnorFACS(a"standard"table.)Whenthisfunctioniscalledby"Load"or"LoadTable"opcodes,orbyacpi_load_table()API,the"Reload"parameterisset.Aftersucessfullyreturningfromthisfunction,tableis"INSTALLED"butnot"VALIDATED".******************************************************************************/acpi_statusacpi_tb_install_standard_table(acpi_physical_addressaddress,u8flags,u8reload,u8override,u32*table_index){u32i;acpi_statusstatus=AE_OK;structacpi_table_descnew_table_desc;ACPI_FUNCTION_TRACE(tb_install_standard_table);/*Acquireatemporarytabledescriptorforvalidation*/status=acpi_tb_acquire_temp_table(&new_table_desc,address,flags);if(ACPI_FAILURE(status)){ACPI_ERROR((AE_INFO,"Couldnotacquiretablelengthat%8.8X%8.8X",ACPI_FORMAT_UINT64(address)));return_ACPI_STATUS(status);}/**OptionallydonotloadanySSDTsfromtheRSDT/XSDT.Thiscan*beusefulfordebuggingACPIproblemsonsomemachines.*/if(!reload&&acpi_gbl_disable_ssdt_table_install&&ACPI_COMPARE_NAME(&new_table_desc.signature,ACPI_SIG_SSDT)){"Ignoringinstallationof%4.4sat%8.8X%8.8X",new_table_desc.signature.ascii,ACPI_INFO((AE_INFO,ACPI_FORMAT_UINT64(address)));gotorelease_and_exit;}/*Validateandverifyatablebeforeinstallation*/status=acpi_tb_verify_temp_table(&new_table_desc,NULL);if(ACPI_FAILURE(status)){gotorelease_and_exit;}*Validatetheincomingtablesignature.**1)Originally,wecheckedthetablesignaturefor"SSDT"or"PSDT".tables,signature"OEM".*2)WeaddedsupportforOEMx*3)Validtableswereencounteredwithanullsignature,sowejust*gaveuponvalidatingthesignature,(05/2008).*4)Weencounterednon-AMLtablessuchastheMADT,whichcausedfaults.Sonow,weonceagainallow*interpretererrorsandkernel*only"SSDT","OEMx",andnow,alsoanullsignature.(05/2011).*/if((new_table_desc.signature.ascii[0]!=0x00)&&(!ACPI_COMPARE_NAME(&new_table_desc.signature,ACPI_SIG_SSDT))&&(ACPI_STRNCMP(new_table_desc.signature.ascii,"OEM",3)))ACPI_BIOS_ERROR((AE_INFO,"Tablehasinvalidsignature[%4.4s](0x%8.8X),""mustbeSSDTorOEMx",{acpi_ut_valid_acpi_name(new_table_desc.signature.ascii)?new_table_desc.signature.ascii:"",new_table_eger));status=AE_BAD_SIGNATURE;gotorelease_and_exit;}/*Checkiftableisalreadyregistered*/for(i=0;i<acpi_gbl_root_table_list.current_table_count;++i){/**Checkforatablematchontheentiretablelength,*notjusttheheader.*/if(!acpi_tb_compare_tables(&new_table_desc,i)){continue;}/**Note:thecurrentmechanismdoesnotunregisteratableifitis*dynamicallyunloaded.Therelatednamespaceentriesaredeleted,tablelist.*butthetableremainsintheroot**Theassumptionhereisthatthenumberofdifferenttablesthat*willbeloadedisactuallysmall,andthereisminimaloverhead*injustkeepingthetableincaseitisneededagain.**Ifthisassumptionchangesinthefuture(perhapsonlarge*machineswithmanytableload/unloadoperations),tableswill*needtobeunregisteredwhentheyareunloaded,andslotsintheempty.*roottablelistshouldbereusedwhen*/if(acpi_gbl_root_table_list.tables[i].flags&ACPI_TABLE_IS_LOADED){/*Tableisstillloaded,thisisanerror*/status=AE_ALREADY_EXISTS;gotorelease_and_exit;}else{*AswearegoingtoreturnAE_OKtothecaller,weshould*taketheresponsibilityoffreeingtheinputdescriptor.*Refilltheinputdescriptortoensure*acpi_tb_install_table_with_override()canbecalledagainto*indicatethere-installation.*/acpi_tb_uninstall_table(&new_table_desc);*table_index=i;return_ACPI_STATUS(AE_OK);}}}/*Addthetabletotheglobalroottablelist*/status=acpi_tb_get_next_root_index(&i);if(ACPI_FAILURE(status)){gotorelease_and_exit;}*table_index=i;acpi_tb_install_table_with_override(i,&new_table_desc,override);release_and_exit:/*Releasethetemporarytabledescriptor*/acpi_tb_release_temp_table(&new_table_desc);return_ACPI_STATUS(status);}这是⼀个⽐较凶恶的函数,代码很长1acpi_tb_acquire_temp_table⽤于创建⼀个acpi_table_desc结构,acpi_table_desc定义如下structacpi_table_desc{acpi_physical_addressaddress;structacpi_table_header*pointer;u32length;/*Lengthfixedat32bits(fixedintableheader)*/unionacpi_name_unionsignature;acpi_owner_idowner_id;u8flags;};主要描述了table的物理地址,table头地址和table长度,签名以及标志2acpi_tb_verify_temp_table验证table是否可⽤,主要验证包括签名,checksum,长度等信息3reload表⽰重新加载,要先卸载原来的再加载当前的4acpi_tb_install_table_with_override安装/*********************************************************************************FUNCTION:acpi_tb_install_table_with_override**PARAMETERS:table_index-Indexintoroottablearray-Newtabledescriptortoinstall***new_table_descoverride-Whetheroverrideshouldbeperformed*RETURN:*None*DESCRIPTION:InstallanACPItableintotheglobaldatastructure.The****tableoverridemechanismiscalledtoallowthehostOStoreplaceanytablebeforeitisinstalledintheroottablearray.******************************************************************************/voidacpi_tb_install_table_with_override(u32table_index,structacpi_table_desc*new_table_desc,u8override){if(table_index>=acpi_gbl_root_table_list.current_table_count){return;}/**ACPITableOverride:**Beforeweinstallthetable,letthehostOSoverrideitwithanew*oneifdesired.AnytablewithintheRSDT/XSDTcanbereplaced,*includingtheDSDTwhichispointedtobytheFADT.*/if(override){acpi_tb_override_table(new_table_desc);}acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list.tables[table_index],new_table_desc->address,new_table_desc->flags,new_table_desc->pointer);acpi_tb_print_table_header(new_table_desc->address,new_table_desc->pointer);/*Settheglobalintegerwidth(baseduponrevisionoftheDSDT)*/if(table_index==ACPI_TABLE_INDEX_DSDT){acpi_ut_set_integer_width(new_table_desc->pointer->revision);}}1如果覆盖参数为真,则⽤新表覆盖⽼表acpi_tb_override_table2acpi_tb_init_table_descriptor初始化表,注意这⾥的参数是&acpi_gbl_root_table_list.tables[table_index],也就是把table_descriptor安装到acpi_gbl_root_table_list.tables数组就算安装完成了acpi_tb_parse_fadt函数去解析DSDT和FACS/*********************************************************************************PARAMETERS:table_index*-IndexfortheFADT*RETURN:*None*DESCRIPTION:InitializetheFADT,DSDTandFACStables**(FADTcontainstheaddressesoftheDSDTandFACS)*********************************************************************

温馨提示

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

评论

0/150

提交评论