adv

评论已经自动封存,请勿再发言论
显示选项 样式:
声明: 下面的评论属于其发表者所有,不代表本站的观点和立场,我们不负责他们说什么。
  • re:Cowards(得分:0 离题)

    cuthead(2701) Neutral 发表于2017年03月23日 15时23分 星期四
    UEFI&EDKII Introduction:UEFI&EDKII概述[1]
    2015-07 北京海淀区 张俊浩
    本篇博文主要介绍UEFI规范、EDKII项目涉及的相关概念:EFI, UEFI, Tianocore, EDK, EDKII, Package, Library Class/Library Instance, PCD, Module, UEFI Application and UEFI Driver。概念性术语较多,大多参考《EDKII_UserManual_0_7》(http://www.tianocore.org -> EDK II Documents -> EDK II User Documentation ->EDKII User Manual V 0.7)和戴正华《UEFI原理与编程》第一章UEFI概述。
    本篇博客框架如下:
    1. UEFI&EDKII Introduction(UEFI&EDKII概述)
    ->1.1 EFI, UEFI, PI, Tianocore, EDK, EDKII
    ->1.2 Several key concepts introduced by EDKII:
    Package,Library Class/Library Instance, PCD, Module, UEFI Application and UEFI Driver
    1.1 EFI,UEFI,PI,Tianocore,EDK,EDKII
    从我们按下开机键到进入操作系统,对于用户来说是一个短暂的等待过程,而对计算机来说是一个漫长而复杂的过程。作为操作系统与硬件之间的桥梁,诞生于1975年的CP/M的BIOS(Basic Input Output System,基本输入/输出系统,一组固化在计算机内主板上一个ROM芯片上的启动代码)“统治”计算机系统30余年,这段时间里CPU每18个月性能提升一倍。计算机软硬件繁衍了无数代,BIOS诞生之初与之配套的8位CPU、DOS系统都已经推出历史舞台,而BIOS依然顽强的存在于计算机中。随着64位CPU逐渐取代32位CPU,存在开发效率低、性能低、扩展性差、升级慢、安全性差等多方面弊端,BIOS越来越不能满足市场需求,从2000年开始Intel就开始计划用EFI(Extensible Firmware Interface,可扩展固件接口)作为BIOS的代替者,逐步取代传统的BIOS。[参考《UEFI原理与编程》第一章UEFI概述]
    2005年英特尔公司联合AMD, American Megatrends, Apple, Dell, HP, IBM, Insyde Software, Lenovo, Microsoft, and Phoenix Technologies11家公司成立Unified EFI Forum(www.uefi.org),负责指定统一的EFI标准.UEFI( Unified Extensible Firmware Interface)所有者已不再是Intel,属于open source。第一个UEFI标准UEFI2.0在2006年1月发布。目前[2015-07]最新的版本是2015年发布的UEFI2.5。
    UEFI(Unified Extensible Firmware Interface,统一的可扩展固件接口)定义了操作系统和固件平台之间的接口(The Unified Extensible Firmware Interface (UEFI) Specification defines a group of standard interfaces [自己看部分源码,对统一、标准接口的理解是一组约定的数据结构以及函数接口声明] between the operating system (OS) and the platform firmware.),它是UEFI Forum发布的一种标准。它只是一种标准,没有提供实现。其实现由其它公司或者开源组织提供,软件厂商可以根据UEFI标准开发自己的UEFI实现,UEFI实现一般可分为两部分:平台初始化(遵循Platform Initialization标准,同样由UEFI Forum发布);固件,操作系统接口。例如英特尔公司提供的开源UEFI实现Tianocore(www.tianocore.org)和Phoenix公司的SecureCore Tiano,其中常用的开源实现是Tianocore官网发布的EDKII(EFI Developer KitII)项目。
    EDK(EFI Developer Kit,EFI开发工具包)是一个基础框架的开源版本,在框架核心接口规范(CIS)定义之上加一组驱动实例和三个平台模拟器实现实例:Nt32, Unix, and DUET 。除了开放框架基础代码外,EDK允许开发、调试和测试EFI和DXE(Driver Execution Environment,驱动执行环境)驱动,选择ROMs,预启动应用程序。为了解决客户所反馈的在使用EDK时暴露出的问题,英特尔开始重建现在被称为EDKII的计划。EDKII更注重于如何使客户能够更容易编写一个便于移植和定制到特定平台的具体类型的模块。 EDKII (EFI Developer Kit II)是遵循UEFI标准和PI (Platform Initialization)标准的扩平台固件开发环境。(The EFI Developer Kit (EDK) is an Open Source release of the Framework Foundations, defined in the Framework Core Interface Specifications (CIS), plus a set of sample drivers and three sample targets implemented for the Nt32, Unix, and DUET platforms.In addition to Open Sourcing the Framework Foundation code, the EDK allows for the development, debugging, and testing of EFI and DXE drivers, Option ROMs, and pre-Boot applications. To solve customer feedback exposed by using EDK, Intel started a remodeling plan now known as EDKII. It focuses on how to make it easy for customers to write a specific kind of module, to port and to customize modules to a platform. )
    [参考《EDKII_UserManual_0_7》第一章EDKII Introduction,《UEFI原理与编程》第一章UEFI概述]
    Unified EFI Forum(www.uefi.org)发布的UEFI规范版本与Tianocore(www.tianocore.org)发布的相应开源版UEFI规范版本的实现:

    UEFI与legacy BIOS相比,UEFI几大优势在于:
    (1)UEFI的开发效率
    BIOS开发一般采用汇编语言,代码多是和硬件相关的。而UEFI编码99%都是由C语言完成,UEFI应用程序和驱动程序甚至可以使用C++编写。UEFI通过固件-操作系统接口(BS(Boot Services,启动服务)和RT(Runtime Services,运行时服务)服务)为OS和OS加载器屏蔽了底层硬件细节,使得UEFI上层应用可以方便重用。
    (2)UEFI系统的扩展性
    UEFI系统的可扩展性体现在两个方面:一是驱动的模块化设计;而是软硬件升级的兼容性。
    大部分硬件的初始化通过UEFI驱动实现。每个驱动是一个独立的模块,可以包含在固件中,也可以放在设备上,运行时根据需要动态加载。
    UEFI中每个表、每个protocol(包括驱动)都有版本号,这使得系统的平滑升级变得简单。
    还有对于第三方的开发,BIOS基本上做不到,除非参与BIOS的设计,但是还要受到ROM的大小限制,而UEFI允许开发厂商或者开源组织可以根据UEFI标准开发自己的UEFI实现。
    (3)UEFI系统的性能
    UEFI相比于BIOS性能有较大提升,从上电启动到进入操作系统的时间大大缩短。性能改善的原因:
    UEFI提供了异步操作。基于时间的异步操作,提高了CPU的利用率,减少了总的等待时间。
    UEFI舍弃了中断这种比较耗时的外部设备操作方式,仅仅保留了时钟中断。外部设备的操作采用“事件+异步操作”完成。
    可伸缩的遍历设备的方式,启动时可以仅仅遍历启动所需要的设备,从而加速系统启动。
    (4)UEFI系统的安全性
    UEFI一个重要突破就是安全性方面的考虑。当系统的安全启动功能被打开后,UEFI在执行应用程序和驱动前会监测程序和驱动的证书,仅当证书被信任时才执行这个应用程序或驱动。UEFI应用程序和驱动采用PE/COFF格式,其签名放在签名块中。
    1.2Several key concepts : Package,Library Class/Library Instance, PCD, Module, UEFI Application and UEFI Driver
    第二部分解释EDKII项目源码中涉及到的几个关键性概念。
    *Package(包)
    在EDKII根目录下,有很多*Pkg命名的文件夹,每一个这样的文件夹成为一个包。当然,这样说很不准确,准确的说“包”是一组平台及平台描述文件(.dsc文件,EDKII Platform Description File)、包声明文件(.dec文件,EDKII Declaration File)组成的集合。
    没有整个源码树EDK无法编译。此外,需要EDK整个源码树作为源码发布单元。为了解决这个矛盾EDKII引入了“包”的概念。这样发布和开发可以在包单位层次上进行而不必需要“全部的源码树”。一个包是最小的源码发布单元,也是一个有多种用途大项目的自然分割。例如,从硬件的角度来看,开发人员会把处理器/片上设备/平台相关的定义和驱动程序分割到三个单独的包,方便用户的发布和重用。开发者也可以把所有平台无关的模块放到一个单独的包中。因此当开发者往新平台移植模块是只需要专注于平台相关的代码就可以。有些包对于构建一个给定的模块或固件不是必须的,固件开发人员只需要选择相关包来完成编译和发布。此外,开发人员还可以基于EDKII源码库创建和发布他或她自己的包。
    (The EDK could not be compiled without the entire source tree. Furthermore, the unit of distribution required the EDK as the whole tree. To solve this issue, EDKII introduced the new concept, the \"Package\". Using this, a release and its work can be made with \"Packages\" as opposed to requiring the “Whole Source Tree”.
    A package is the minimal unit of distribution—as well as providing a natural split in a big projectwhich serves various purposes.For example, from the viewpoint of hardware a developer may divide CPU/chipset/platform related definitions and drivers into three individual packages that facilitate a user\'s distribution and reuse. Developers also can put all modules that are independent of various platforms into a single package. Therefore, developers only need focus on platform-specific code when porting to a new platform. As some of the packages are not necessary for building a given module or firmware, Firmware developers can only choose relevant packages to finish building or releasing. Additionally, a developer can also create and distribute his or her own package based on the EDKII code base.)
    每一个包具有类似的结构,例如MdePkg具有如下的目录结构:(Each package has the similar structure of directories. For example, MdePkg has the following directories and sub-directories: )
    Include\\ -- public header files of MDE Package (Mde包的公共头文件)
    Ia32\\ -- internal header files specified to IA-32 architecture
    X64\\ -- internal header files specified to x64 architecture
    Ipf\\ -- internal header files specified to IPF architecture
    (Itanium processor family安腾处理器家族)
    Ebc\\ -- internal header files specified to EBC architecture
    (EFI Byte Code)
    Uefi\\ -- public header files containing UEFI2.1 definitions
    Pi\\ -- public header files containing PI1.0 definitions
    Protocol\\ -- public header files containing PROTOCOLs definitions
    Ppi\\ -- public header files containing PPIs definitions
    Guid\\ -- public header files containing GUIDs definitions
    IndustryStandard\\ -- public header files containing Industry Standard
    Library\\ -- public header files containing MDE Libraries classes
    Library\\ -- MDE libraries instances
    The internal header files only could be referred by those public header files.(内部头文件只能被公共头文件引用。)
    EDKII包之间的依赖关系。(A dependency relationship exists among EDKII packages.)

    *Library class/Library Instance (类库和库实例)
    因为在固件开发中,存在相同的功能的需求,但需要不同的实现,例如:(Because demand exists for the same functionality in the development of firmware, but different implementations may be needed, such as:)
    使用C语言实现模块跨平台能力,而非用汇编实现模块高效能
    (using C code to provide cross-architecture ability rather than using assembly to provide better performance);
    使用I / O端口执行PCI配置周期而非用内存I/O指令。(using I/O port to perform PCI configuration cycles but not using memory I/O instructions.)
    类库是一组用于提供某些功能的标准接口定义。
    (The Library Class is a set of standard API definitions that are used to provide certain functionality.)[进入源码模块目录Include/ Library/ -- public header files containing MDE Libraries classes,是头文件源码,头文件中是函数声明] 模块编程人员可以直接使用它们来编程。(A module writer can directly use them to program.)
    一个库实例提供了这些类库接口定义的实现。(A library instance supplies the implementation of these APIs.)[进入源码Library/ -- MDE libraries instances,是C源文件,头文件中函数声明的(类库)的函数实现] 类库和库实例的关系是一对多。一个类库可以有多个具体实现,也即可以有多个库实例。
    (The relationship between library class and library instance is one-to-many. A library class may have multiple implementations, that is, multiple library instances.)
    模块的编写依赖类库接口而不是具体的库实现,这样同一模块源码根据不同需求可以很容易配置链接到不同的类库实现。
    (A module only depends on a library class and not concrete implementations, so the same module source code can be easily configured to link with different library instances for various requirements. )
    EDKII在MdePkg包中提供了很多类库/库实例,便于开发者编程。
    The EDKII provides many library classes/library instances to facilitate user development in the MdePkg.
    平台的开发者可以有针对性的选择不同的库实例。(The platform integrator can selectively choose various library instances. )
    *Platform Configuration Database (平台配置数据库)
    PCD是一个实现模块从外部源获取数据和控制程序行为的统一机制。数据信息可以来自不同的地方。数据信息可以在编译时,在固件镜像生成时,程序执行时被获取。模块编程人员不需要知道数据信息来自哪里,因为平台开发者会做出选择。模块的源代码可以保持不变,来支持多个平台,因为所有的外部输入信息通过统一的PCD接口获取。
    (PCD is a unified mechanism used by a module to extract information from external sources and control procedure behavior.
    The information can come from many different places.Information could be known at compile time, at flash image generation time, on the fly (when firmware code is being executed).
    The module writer does not need to know where the information has come from because the platform developer can make the selection.
    The module\'s source code can remain unchanged to support multiple platforms, as all the external input information is extracted by unified PCD interfaces.)
    *Module (模块)
    模块是一个可执行映像或库实例。(A module is either an executable image or a library instance.)模块是UEFI的一个特色,模块(.efi文件,可执行文件)可以像插件一样动态加载到UEFI内核中。对应到源文件,EDKII中的每个工程模块由源文件(.c文件)和工程文件(.inf,类似Linux下makefile工程管理文件)组成(有些情况下也包括.efi文件)。
    *UEFI Application(UEFI应用程序)
    UEFI应用程序遵循UEFI规范。(An application that follows the UEFI specification.)UEFI Application和UEFI库函数提供基本的内存、磁盘以、控制台及字符串操作功能。UEFI Application以可执行.efi的形式存在,执行完返回控制权,不会驻留在内存,可以方便移植到不同平台。
    一个简单的标准应用程序工程模块包括一个C程序源文件和一个工程文件*.inf。
    *UEFI Driver (UEFI驱动)
    驱动与应用程序的最大区别是驱动会常驻内存,而应用程序执行完毕后会从内存清楚。(The only difference between a UEFI application and a UEFI driver is that an application is unloaded from memory when it exits regardless of return status, while a driver that returns a successful return status is not unloaded when its entry point exits.)
    通过本篇博客的整理,一是希望整理这些概念,再次梳理UEFI的框架脉络,二是希望共同学习共同进步。很多概念也处在需要进一步更深入本质、更明晰的认知过程中。