BIOS/UEFI基础——Protocol介绍
简要说明
Protocol是UEFI中的一个重要概念(事实上《UEFI SPEC》中有超过70%的内容都是在讲Protocol),下面简单说明下:
1. 首先,非常重要的一点,Protocol不是什么特殊的东西,它就是一个结构体,比如说下面是一个用于存储设备访问的Protocol:
- ///
- /// This protocol provides control over block devices.
- ///
- struct _EFI_BLOCK_IO_PROTOCOL {
- ///
- /// The revision to which the block IO interface adheres. All future
- /// revisions must be backwards compatible. If a future version is not
- /// back wards compatible, it is not the same GUID.
- ///
- UINT64 Revision;
- ///
- /// Pointer to the EFI_BLOCK_IO_MEDIA data for this device.
- ///
- EFI_BLOCK_IO_MEDIA *Media;
- EFI_BLOCK_RESET Reset;
- EFI_BLOCK_READ ReadBlocks;
- EFI_BLOCK_WRITE WriteBlocks;
- EFI_BLOCK_FLUSH FlushBlocks;
- };
2. 其次,Protocol不是UEFI BIOS一开始就可以用的。我们知道UEFI BIOS启动时分为不同的阶段,SEC-PEI-DXE-BDS等等。而Protocol需要等到DXE阶段才可以使用(不需要特别在意DXE阶段的哪个点开始,基本上我们开发时写的DXE模块都可以使用)。
3. UEFI框架下提供了函数来存取Protocol。
4. Protocol的作用跟普通的结构体没有区别,如果存放的是数据就作为存储用,如果存放的是函数指针就用作特定代码执行。
5. UEFI下将大部分的设备初始化和其它功能代码都包装成了一个个的Protocol,所以要学习UEFI,Protocol是必经之路。
Protocol的实现说明
首先一张图说明:
这里需要关注的图中红框部分的内容。
这里实际上是两种链表,一种是Handle的链表,一种是Protocol的链表。Handle其实就是一个不会重复的整型数字,而Protocol在之前已经说过就是一个结构体。各个Handle连接在一起构成一个链表,每个Handle上可以附着若干个不会重复的Protocol。
上述的两种链表交织成了一张网,这张网被称为“Handle Database”。
这个Handle Database会在DXE最开始的地方初始化起来,之后通过接口可以扩展,搜寻等等操作。
关于具体的代码实现这里不再介绍,可以参考DXE阶段开始的代码(DxeMain.c)。
Protocol的使用
在UEFI Boot Service中提供了如下的函数用来操作Protocol:
- //
- // Protocol Handler Services
- //
- EFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface;
- EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface;
- EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface;
- EFI_HANDLE_PROTOCOL HandleProtocol;
- VOID *Reserved;
- EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify;
- EFI_LOCATE_HANDLE LocateHandle;
- EFI_LOCATE_DEVICE_PATH LocateDevicePath;
- EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable;
- //
- // Open and Close Protocol Services
- //
- EFI_OPEN_PROTOCOL OpenProtocol;
- EFI_CLOSE_PROTOCOL CloseProtocol;
- EFI_OPEN_PROTOCOL_INFORMATION OpenProtocolInformation;
- //
- // Library Services
- //
- EFI_PROTOCOLS_PER_HANDLE ProtocolsPerHandle;
- EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer;
- EFI_LOCATE_PROTOCOL LocateProtocol;
- EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces;
- EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces;
它们可以分为几种不同的类型:
1. 安装和卸载接口,就是这里的IntallXXX,ReinstallXXX,UninstallXXX,IntallMultipleXXX,UninstallMultipleXXX等。
2. 获取和关闭接口,比如HandleProtocol,LocateHandle等等。
3. 其它辅助接口,比如OpenProtocolInformation,RegisterProtocolNotify等,其中RegisterProtocolNotify注册了一个回调函数,当指定的Protocol被安装时,这个回调函数就会被执行。
之后会有实际的代码来介绍如何使用这些接口。
几种特殊的Protocol
UEFI中的Protocol有一些比较特殊的类型,本节将介绍这些Protocol。
Architectural Protocol
UEFI规定了一些Protocol,这些Protocol在UEFI BIOS运行的过程中会安装,且一定需要被安装,如果没有被安装的话,系统就会报错。
这些Protocol如下所示:
- //
- // DXE Core Global Variables for all of the Architectural Protocols.
- // If a protocol is installed mArchProtocols[].Present will be TRUE.
- //
- // CoreNotifyOnArchProtocolInstallation () fills in mArchProtocols[].Event
- // and mArchProtocols[].Registration as it creates events for every array
- // entry.
- //
- EFI_CORE_PROTOCOL_NOTIFY_ENTRY mArchProtocols[] = {
- { &gEfiSecurityArchProtocolGuid, (VOID **)&gSecurity, NULL, NULL, FALSE },
- { &gEfiCpuArchProtocolGuid, (VOID **)&gCpu, NULL, NULL, FALSE },
- { &gEfiMetronomeArchProtocolGuid, (VOID **)&gMetronome, NULL, NULL, FALSE },
- { &gEfiTimerArchProtocolGuid, (VOID **)&gTimer, NULL, NULL, FALSE },
- { &gEfiBdsArchProtocolGuid, (VOID **)&gBds, NULL, NULL, FALSE },
- { &gEfiWatchdogTimerArchProtocolGuid, (VOID **)&gWatchdogTimer, NULL, NULL, FALSE },
- { &gEfiRuntimeArchProtocolGuid, (VOID **)&gRuntime, NULL, NULL, FALSE },
- { &gEfiVariableArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },
- { &gEfiVariableWriteArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },
- { &gEfiCapsuleArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },
- { &gEfiMonotonicCounterArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },
- { &gEfiResetArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },
- { &gEfiRealTimeClockArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },
- { NULL, (VOID **)NULL, NULL, NULL, FALSE }
- };
这些Protocol都是UEFI或者系统必须的最基础的Protocol,比如说这里的gEfiBdsArchProtocolGuid对应的Protocol,它是BDS阶段的如果,在DXEMain.c中有如下的代码:
- //
- // Transfer control to the BDS Architectural Protocol
- //
- gBds->Entry (gBds);
使DXE阶段过渡到BDS阶段。
Device Path Protocol
Device Path Protocol是一种纯数据的结构体,它表示的是一个设备的可编程路径,可以简称就是Device Path(后面就直接省略掉Protocol)。
这种说法比较抽象,而且这里说的“设备”也并不一定需要是真实的设备,它可以是虚拟设备,甚至可以是一个文件。
Device Path的具体说明有在其它的文章中介绍,这里不做具体的说明。
这里简单介绍一下它的结构体:
- /**
- This protocol can be used on any device handle to obtain generic path/location
- information concerning the physical device or logical device. If the handle does
- not logically map to a physical device, the handle may not necessarily support
- the device path protocol. The device path describes the location of the device
- the handle is for. The size of the Device Path can be determined from the structures
- that make up the Device Path.
- **/
- typedef struct {
- UINT8 Type; ///< 0x01 Hardware Device Path.
- ///< 0x02 ACPI Device Path.
- ///< 0x03 Messaging Device Path.
- ///< 0x04 Media Device Path.
- ///< 0x05 BIOS Boot Specification Device Path.
- ///< 0x7F End of Hardware Device Path.
- UINT8 SubType; ///< Varies by Type
- ///< 0xFF End Entire Device Path, or
- ///< 0x01 End This Instance of a Device Path and start a new
- ///< Device Path.
- UINT8 Length[2]; ///< Specific Device Path data. Type and Sub-Type define
- ///< type of data. Size of data is included in Length.
- } EFI_DEVICE_PATH_PROTOCOL;
它的结构非常的简单,是一个可变长的结构体。
成员包括了一个基本的头部(分为类型,子类型和长度三部分),以及之后的具体类型所需要包含的成员。
Device Path有一个非常重要的作用就是标记对应Handle的属性。
举一个简单的例子,现在有两个硬盘,那么它们都有一个_EFI_BLOCK_IO_PROTOCOL(见开头),然而我们想访问其中一个特定的硬盘,如何找到这个硬件,就可以依赖于Device Path。
以硬盘的Device Path举例,它的类型是HARDWARE_DEVICE_PATH,子类型是HW_CONTROLLER_DP,因此它的Device Path中包含如下的部分:
- ///
- /// Controller Device Path.
- ///
- typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- ///
- /// Controller number.
- ///
- UINT32 ControllerNumber;
- } CONTROLLER_DEVICE_PATH;
而两个不同的硬盘,其中的ControllerNumber可能是不同的(根据不同的硬件配置),因此就可以确定到底使用哪个Device Path,最终获取到正确的_EFI_BLOCK_IO_PROTOCOL,大致流程如下:
1. 调用LocateHandleBuffer获取到所有安装了_EFI_BLOCK_IO_PROTOCOL的Handle;
2. 遍历所有的Handle;
3. 根据上述Handle获取到Device Path Protocol,根据这个Device Path Protocol就能够确定该Handle是否是我们要找的那个Handle;
4. 通过找到的Handle,调用HandleProtocol来到对应的_EFI_BLOCK_IO_PROTOCOL,然后就可以使用这个Protocol来访问硬盘。
以上是使用Device Path Protocol的一个示例。
当然Device Path Protocol的用法还有很多,这个就需要自己摸索了。
EFI_DRIVER_BINDING_PROTOCOL
该类Protocol用在一种叫做UEFI Driver Model类型的驱动中。
这种驱动在DXE阶段安装,但实际使用是在BDS阶段。
这种Protocol的结构如下:
- ///
- /// This protocol provides the services required to determine if a driver supports a given controller.
- /// If a controller is supported, then it also provides routines to start and stop the controller.
- ///
- struct _EFI_DRIVER_BINDING_PROTOCOL {
- EFI_DRIVER_BINDING_SUPPORTED Supported;
- EFI_DRIVER_BINDING_START Start;
- EFI_DRIVER_BINDING_STOP Stop;
- ///
- /// The version number of the UEFI driver that produced the
- /// EFI_DRIVER_BINDING_PROTOCOL. This field is used by
- /// the EFI boot service ConnectController() to determine
- /// the order that driver's Supported() service will be used when
- /// a controller needs to be started. EFI Driver Binding Protocol
- /// instances with higher Version values will be used before ones
- /// with lower Version values. The Version values of 0x0-
- /// 0x0f and 0xfffffff0-0xffffffff are reserved for
- /// platform/OEM specific drivers. The Version values of 0x10-
- /// 0xffffffef are reserved for IHV-developed drivers.
- ///
- UINT32 Version;
- ///
- /// The image handle of the UEFI driver that produced this instance
- /// of the EFI_DRIVER_BINDING_PROTOCOL.
- ///
- EFI_HANDLE ImageHandle;
- ///
- /// The handle on which this instance of the
- /// EFI_DRIVER_BINDING_PROTOCOL is installed. In most
- /// cases, this is the same handle as ImageHandle. However, for
- /// UEFI drivers that produce more than one instance of the
- /// EFI_DRIVER_BINDING_PROTOCOL, this value may not be
- /// the same as ImageHandle.
- ///
- EFI_HANDLE DriverBindingHandle;
- };
下面是一个例子:
1. 声明:
- //
- // Simple Network Protocol Driver Global Variables
- //
- EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding = {
- SimpleNetworkDriverSupported,
- SimpleNetworkDriverStart,
- SimpleNetworkDriverStop,
- 0xa,
- NULL,
- NULL
- };
2. 安装:
- EFI_STATUS
- EFIAPI
- InitializeSnpNiiDriver (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
- {
- return EfiLibInstallDriverBindingComponentName2 (
- ImageHandle,
- SystemTable,
- &gSimpleNetworkDriverBinding,
- ImageHandle,
- &gSimpleNetworkComponentName,
- &gSimpleNetworkComponentName2
- );
- }
上述代码在Snp.c中,整个模块就是在DXE阶段安装了若干个Protocol(其它的不是很重要)。
这里的EFI_DRIVER_BINDING_PROTOCOL通常是不会通过HandleProtocol等函数去获取的,而是使用下面的接口(也在UEFI Boot Service中):
- //
- // DriverSupport Services
- //
- EFI_CONNECT_CONTROLLER ConnectController;
- EFI_DISCONNECT_CONTROLLER DisconnectController;
当调用ConnectController的时候,代码首先会去执行EFI_DRIVER_BINDING_PROTOCOL中的XXXSupported函数,判断传入的Handle是否符合该Protocol执行的要求,如果符合就执行XXXStart函数,否则就直接退出;而DisconnectController会去执行Protocol中的XXXStop函数。
EFI_DRIVER_BINDING_PROTOCOL或者说UEFI Driver Model实现了一种动态的方式来执行代码以完成初始化。
所以EFI_DRIVER_BINDING_PROTOCOL也是比较特殊的一种Protocol。
自己编写Protocol
下面简单的编写一个自己的Protocol,并使用该Protocol。
具体的代码可以在https://gitee.com/jiangwei0512/vUDK2017找到。
编写Protocol并安装
1. 首先需要定义一个Protocol,通常会在独立Package的Include/Protocol目录下创建一个头文件,这里是HelloWorldProtocol.h:
- /**
- * @Package : BeniPkg
- * @FileName : HelloWorldProtocol.h
- * @Date : 20190211
- * @Author : Wei Jiang
- * @Version : 0.1
- * @Description :
- * This file describes a protocol for test.
- *
- * @History:
- * 20190211: Initialize.
- *
- * This program and the accompanying materials
- * are licensed and made available under the terms and conditions of the BSD License
- * which accompanies this distribution. The full text of the license may be found at
- * http://opensource.org/licenses/bsd-license.php
- *
- * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
- **/
- #ifndef __BENI_HELLO_WORLD_PROTOCOL_H__
- #define __BENI_HELLO_WORLD_PROTOCOL_H__
- #include <Uefi.h>
- #define EFI_HELLO_WORLD_PROTOCOL_GUID \
- {0x038f1af5, 0x1c8d, 0x408f, { 0xab, 0x25, 0x30, 0xae, 0xb5, 0x96, 0x5d, 0x6e }}
- typedef struct _EFI_HELLO_WORLD_PROTOCOL EFI_HELLO_WORLD_PROTOCOL;
- /**
- Print "Hello Wrold".
- @param[in] This A pointer to the EFI_HELLO_WORLD_PROTOCOL instance.
- @retval EFI_SUCCESS Always return EFI_SUCCESS after print.
- **/
- typedef
- EFI_STATUS
- (EFIAPI *HELLO) (
- IN EFI_HELLO_WORLD_PROTOCOL *This
- );
- struct _EFI_HELLO_WORLD_PROTOCOL {
- UINTN Version;
- HELLO Hello;
- };
- extern EFI_GUID gEfiHelloWorldProtocolGuid;
- #endif // __BENI_HELLO_WORLD_PROTOCOL_H__
实际上上述代码中重要的有两个部分,一个就是Protocol,这里定义了一个包含一个整型和一个函数指针的Protocol;另一个是一个EFI_GUID,之前的说明中一直没有提到,它其实是对应Protocol的标记,前面提到的UEFI Boot Service中的Protocol处理接口需要通过这个EFI_GUID来操作Protocol。因为EFI_GUID是唯一的,所以能够对应特定的Protocol。
不仅在头文件中需要声明EFI_GUID,这里就是gEfiHelloWorldProtocolGuid,还需要在dec文件中定义该EFI_GUID:
- [Protocols]
- # // Include/Protocol/HelloWorldProtocol.h
- # // {038F1AF5-1C8D-408F-AB25-03AEB5965D6E}
- gEfiHelloWorldProtocolGuid = { 0x038f1af5, 0x1c8d, 0x408f, { 0xab, 0x25, 0x30, 0xae, 0xb5, 0x96, 0x5d, 0x6e } }
否则在其它代码中就无法使用gEfiHelloWorldProtocolGuid。
2. 之后就是EFI_HELLO_WORLD_PROTOCOL的实现和安装:
- /**
- * @Package : BeniPkg
- * @FileName : ProtocolServer.c
- * @Date : 20190211
- * @Author : Wei Jiang
- * @Version : 0.1
- * @Description :
- * Install EFI_HELLO_WORLD_PROTOCOL.
- *
- * @History:
- * 20190211: Initialize.
- *
- * This program and the accompanying materials
- * are licensed and made available under the terms and conditions of the BSD License
- * which accompanies this distribution. The full text of the license may be found at
- * http://opensource.org/licenses/bsd-license.php
- *
- * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
- **/
- #include <Uefi.h>
- #include <Library/UefiDriverEntryPoint.h>
- #include <Library/UefiBootServicesTableLib.h>
- #include <Library/MemoryAllocationLib.h>
- #include <Library/DebugLib.h>
- #include <Protocol/HelloWorldProtocol.h>
- /**
- Print "Hello Wrold".
- @param[in] This A pointer to the EFI_HELLO_WORLD_PROTOCOL instance.
- @retval EFI_SUCCESS Always return EFI_SUCCESS after print.
- **/
- EFI_STATUS
- EFIAPI
- Hello (
- IN EFI_HELLO_WORLD_PROTOCOL *This
- )
- {
- DEBUG ((EFI_D_ERROR, "Hello World\n"));
- return EFI_SUCCESS;
- }
- /**
- Main entry of the driver.
- @param[in] ImageHandle Image handle for this driver.
- @param[in] SystemTable Pointer to the System Table.
- @retval EFI_SUCCESS Driver executed successfully.
- @retval Others Error happened.
- **/
- EFI_STATUS
- EFIAPI
- ProtocolServerEntry (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
- {
- EFI_STATUS Status;
- EFI_HELLO_WORLD_PROTOCOL *Protocol;
- Protocol = AllocatePool (sizeof (EFI_HELLO_WORLD_PROTOCOL));
- if (NULL == Protocol) {
- DEBUG ((EFI_D_ERROR, "[BENI][%a][%d]: Out of resource.", __FUNCTION__, __LINE__));
- return EFI_OUT_OF_RESOURCES;
- }
- Protocol->Version = 0x01;
- Protocol->Hello = Hello;
- Status = gBS->InstallProtocolInterface (
- &ImageHandle,
- &gEfiHelloWorldProtocolGuid,
- EFI_NATIVE_INTERFACE,
- Protocol
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "[BENI]Install EFI_HELLO_WORLD_PROTOCOL failed. - %r\n", Status));
- FreePool (Protocol);
- return Status;
- }
- return EFI_SUCCESS;
- }
观察Protocol的安装,可以看到这里使用的参数:
ImageHandle:这个就是用来存放Protocol的EFI_HANDLE,当然也可以使用初始值为NULL的新的Handle,不过方便起见就使用了原有的;
gEfiHelloWorldProtocolGuid:这个就是用来标记EFI_HELLO_WORLD_PROTOCOL的EFI_GUID;
EFI_NATIVE_INTERFACE:这是Protocol的属性,类型是EFI_INTERFACE_TYPE,目前只有这一个值;
Protocol:就是本模块实现的Protocol实例,这里需要注意它的类型是XXX_PROTOCOL指针,有时候可能一时疏忽写成了&Protocol,就会导致使用该Protocol的时候异常挂死;
3. 最后就是对Protocol的使用:
- /**
- * @Package : BeniPkg
- * @FileName : ProtocolConsumer.c
- * @Date : 20190211
- * @Author : Wei Jiang
- * @Version : 0.1
- * @Description :
- * Use EFI_HELLO_WORLD_PROTOCOL.
- *
- * @History:
- * 20190211: Initialize.
- *
- * This program and the accompanying materials
- * are licensed and made available under the terms and conditions of the BSD License
- * which accompanies this distribution. The full text of the license may be found at
- * http://opensource.org/licenses/bsd-license.php
- *
- * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
- **/
- #include <Uefi.h>
- #include <Library/UefiDriverEntryPoint.h>
- #include <Library/UefiBootServicesTableLib.h>
- #include <Library/DebugLib.h>
- #include <Protocol/HelloWorldProtocol.h>
- /**
- Main entry of the driver.
- @param[in] ImageHandle Image handle for this driver.
- @param[in] SystemTable Pointer to the System Table.
- @retval EFI_SUCCESS Driver executed successfully.
- @retval Others Error happened.
- **/
- EFI_STATUS
- EFIAPI
- ProtocolConsumerEntry (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
- {
- EFI_STATUS Status;
- EFI_HELLO_WORLD_PROTOCOL *Protocol;
- Status = gBS->LocateProtocol (&gEfiHelloWorldProtocolGuid, NULL, (VOID **)&Protocol);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "[BENI]Locate EFI_HELLO_WORLD_PROTOCOL failed. - %r\n", Status));
- return Status;
- }
- DEBUG ((EFI_D_ERROR, "Protocol Version: 0x%08x\n", Protocol->Version));
- Status = Protocol->Hello (Protocol);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "[BENI]Protocol->Hello failed. - %r\n", Status));
- return Status;
- }
- return EFI_SUCCESS;
- }
关于实现就比较简单了,只是调用LocateProtocol来获取Protocol,然后使用即可。
以上就是对Protocol的一个实现以及简单的使用,对应的模块是ProtocolServer.inf和ProtocolConsumer.inf。
http://www.taodudu.cc/news/show-2786716.html
相关文章:
- HA高可用搭建
- UEFI----EFI_DRIVER_BINDING_PROTOCOL
- 【UEFI基础】Protocol介绍
- Jscex没有xxxAsync().stop()怎么办?
- LInux 实训二记录
- Windows下使用Jconsole远程监控Linux系统中java服务器资源占用情况
- net_device详解
- Darknet官方文档(含Yolo-V2和V3在win和Linux训练测试步骤、计算mAP、调参优化等)
- Linux下service xxx start/stop/restart启动服务、关闭服务、重启服务深入理解@
- UDS 服务 Service 0x31 - RoutineControl
- 【RPC】序列化与反序列化
- Java 序列化详解
- oracle 查找所有序列,Oracle查询所有序列
- 序列比对
- 序列的相关性
- 时间序列分析教程(一):基本性质
- 什么是序列化 怎么序列化 为什么序列化
- Json序列化技术
- 【生信MOOC】生物序列比对工具——多序列比对
- 时间序列预测
- postgres查询序列_PostgreSQL之序列(Sequence)
- SpringBoot的序列化和反序列化
- python创建时间序列_python 时间序列
- 序列化和反序列化
- postgres查询序列_PostgreSQL 序列使用
- 序列比对算法
- 序列化和反序列化的详解
- Python序列(包括序列类型和常用操作)
- 序列(sequence)(Python入门十二)
- 【python】什么是序列,Python序列详解
BIOS/UEFI基础——Protocol介绍相关推荐
- BIOS/UEFI基础——FDF文件
综述 FDF的全称是Flash Description File. 它是构成BIOS二进制的描述符,即FDF文件描述了BIOS二进制的组成结构. 本文的目的就是介绍FDF文件内部的组成以及它们是如何完 ...
- 【UEFI基础】Protocol介绍
简要说明 Protocol是UEFI中的一个重要概念(事实上<UEFI SPEC>中有超过70%的内容都是在讲Protocol),下面简单说明下: 1. 首先,非常重要的一点,Protoc ...
- 【UEFI基础】UEFI事件介绍
简述 在[UEFI基础]System Table和Architecture Protocols介绍Boot Service时提到有一部分与事件相关的接口,它们创建.触发.等待和关闭事件,来完成某些功能 ...
- 【UEFI基础】Device Path
什么是Device Path 没有在UEFI SPEC中找到一个非常清晰的Device Path的定义. 关于Device Path,UEFI SPEC中有如下的描述: A Device Path i ...
- 【UEFI基础】UEFI变量基础2
说明 之前已经写过一篇变量相关的文章[UEFI基础]UEFI变量基础,该文章使用的是模拟的变量,而本文更接近于实际的变量模块. 环境设置 为了测试BIOS的变量功能,需要修改QEMU的启动选项,如下所 ...
- 【UEFI基础】ACPI基础
什么是ACPI 高级配置和电源管理接口(Advanced Configuration and Power Management Interface). ACPI是一套协议标准,软硬件都需实现以配合使用 ...
- UEFI——UEFI 基础服务
文章目录 前言 BootService Table gBS EFI_BOOT_SERVICES SystemTable EFI_SYSTEM_TABLE SystemTable mBootServic ...
- uefi多linux系统启动盘,DIY制作无需格BIOS+UEFI双启动U盘工具|支持syslinux+grub+boomgr+grub2多启动...
如果你想让你的U盘可启动的话,要怎么做呢,可能很多人都知道借助软件能自动实现,但那些方式都需要把U盘格式化一遍,而这个工具完全不需要,只需要把下载的文件解压到U盘根目录就能实现多启动了,支持bios和 ...
- linux route 刷新_linux基础命令介绍十五:推陈出新
本文介绍ip.ss.journalctl和firewall-cmd,它们旨在代替linux中原有的一些命令或服务. 1.ip ip [OPTIONS] OBJECT COMMAND ip是iprout ...
最新文章
- 字符串-验证回文串(双指针法)
- linux查看当前的工作目录,Linux-查看当前工作目录(pwd)
- 把iPhone充电口改成Type-C,卖了56万!
- PAT甲级1074 Reversing Linked List :[C++题解]反转链表,借用vector
- 零基础学Python(第十七章 模块import)
- php获取flash上传视频文件大小,如何获取flash文件(.swf文件)的长度和宽度
- numpy 矩阵求逆_numpy 矩阵运算
- 华为18级工程师三年心血终成趣谈网络协议文档(附大牛讲解)
- linux java 错误日志_求大神解决啊啊 啊,看看这个怎么了,在LINUX运行完的错误日志...
- 2020最新教师资格证《中学综合素质》必考知识点大全
- from functools import reduce——从典型实例做抓手看reduce函数使用
- echarts 北京公交线路-线路效应
- 听说ES6中新增了能够与众不同的Symbol数据类型
- 独立分包中包含app.wxss的问题
- 数据挖掘与数据分析的主要区别是什么?
- echart地图隐藏南海诸岛
- 计算机显示字体怎么设置,电脑字体太小怎么调,教您怎样更改电脑界面的字体大小...
- Ipopt输出的含义
- iptables四表五链
- SLAM本质剖析-Boost之Geometry函数大全(二)