UEFI原理与编程实践--EFI System Table中的输入输出

2024-06-07 05:18

本文主要是介绍UEFI原理与编程实践--EFI System Table中的输入输出,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这一节UEFI原理与编程的书籍里面貌似没有提到,不过在我上次使用飞腾源代码增加功能的过程中发现logo界面的左上角有个光标,后来发现源代码也有,这就让有强迫症的人非常不爽啦,这个光标怎么来的呢,我找了几个地方,都不对,后来懒得找了,既然在logo出现前就有这个光标了,那我直接在logo显示前清屏不就ok了么,然后把这个问题顺利解决。

输入输出在UEFI中使用非常广泛,随便举个栗子,大家经常使用的Print打印输出在屏幕上:

UINTN
InternalPrint (IN  CONST CHAR16                     *Format,IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *Console,IN  VA_LIST                          Marker)
{EFI_STATUS  Status;UINTN       Return;CHAR16      *Buffer;UINTN       BufferSize;ASSERT (Format != NULL);ASSERT (((UINTN) Format & BIT0) == 0);ASSERT (Console != NULL);BufferSize = (PcdGet32 (PcdUefiLibMaxPrintBufferSize) + 1) * sizeof (CHAR16);Buffer = (CHAR16 *) AllocatePool(BufferSize);ASSERT (Buffer != NULL);Return = UnicodeVSPrint (Buffer, BufferSize, Format, Marker);if (Console != NULL && Return > 0) {//// To be extra safe make sure Console has been initialized//Status = Console->OutputString (Console, Buffer);if (EFI_ERROR (Status)) {Return = 0;}}FreePool (Buffer);return Return;
}UINTN
EFIAPI
Print (IN CONST CHAR16  *Format,...)
{VA_LIST Marker;UINTN   Return;VA_START (Marker, Format);Return = InternalPrint (Format, gST->ConOut, Marker);VA_END (Marker);return Return;
}

使用的就是EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL中的OutputString,那么我们来看下这个EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL里面都有什么:

struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL {EFI_TEXT_RESET                Reset;EFI_TEXT_STRING               OutputString;EFI_TEXT_TEST_STRING          TestString;EFI_TEXT_QUERY_MODE           QueryMode;EFI_TEXT_SET_MODE             SetMode;EFI_TEXT_SET_ATTRIBUTE        SetAttribute;EFI_TEXT_CLEAR_SCREEN         ClearScreen;EFI_TEXT_SET_CURSOR_POSITION  SetCursorPosition;EFI_TEXT_ENABLE_CURSOR        EnableCursor;////// Pointer to SIMPLE_TEXT_OUTPUT_MODE data.///EFI_SIMPLE_TEXT_OUTPUT_MODE   *Mode;
};

既然输入输出,有OUTPUT,那么肯定有INPUT:

struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL {EFI_INPUT_RESET     Reset;EFI_INPUT_READ_KEY  ReadKeyStroke;////// Event to use with WaitForEvent() to wait for a key to be available///EFI_EVENT           WaitForKey;
};

具体使用:

Reset:重新输出

gST->ConOut->Reset (gST->ConOut, FALSE);//有清屏作用?

OutputString:输出到显示屏幕

gST->ConOut->OutputString (gST->ConOut, L"XXXXXXXXX \n");

QueryMode:查询输出模式,和图像查询类似,但没那么多功能 ,Rows为行, Columns为列,所以这个查询很明显,就是查询当前输出位置在哪。 

 UINTN                                GetCol,GetRow;gST->ConOut->QueryMode (gST->ConOut,gST->ConOut->Mode->Mode,&GetCol,&GetRow);

 SetMode:设置输出模式

UINTN   LoopVar;
Status = gST->ConOut->SetMode(gST->ConOut, LoopVar);

看下dsc文件,这就是模式的区别,有可能是1、2、3,看具体那种模式,一般固定好不用设置

gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|80
gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|25gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|40
gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|56

SetAttribute:设置属性,什么属性?那就是输出文字的背景是什么,黑色、红色、还是其他,但是只能是纯色,还有文字颜色,蓝色、白色、黑色、高亮、低亮啥的:

gST->ConOut->SetAttribute( gST->ConOut, EFI_BACKGROUND_BLACK | EFI_LIGHTGRAY );

ClearScreen:清屏,看名字就能看出来:

gST->ConOut->ClearScreen( gST->ConOut );

EnableCursor:设置光标,也就是屏幕上会来个光标,当然前提得为TRUE

gST->ConOut->EnableCursor( gST->ConOut, TRUE );

SetCursorPosition:设置光标位置:

gST->ConOut->SetCursorPosition (gST->ConOut, Col, Row);

ok,上述输出的功能就已经写完了,输入的就不写了,部分没实践,特别是这个reset,是不是清屏有待验证

这篇关于UEFI原理与编程实践--EFI System Table中的输入输出的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1038265

相关文章

Linux进程CPU绑定优化与实践过程

《Linux进程CPU绑定优化与实践过程》Linux支持进程绑定至特定CPU核心,通过sched_setaffinity系统调用和taskset工具实现,优化缓存效率与上下文切换,提升多核计算性能,适... 目录1. 多核处理器及并行计算概念1.1 多核处理器架构概述1.2 并行计算的含义及重要性1.3 并

全面掌握 SQL 中的 DATEDIFF函数及用法最佳实践

《全面掌握SQL中的DATEDIFF函数及用法最佳实践》本文解析DATEDIFF在不同数据库中的差异,强调其边界计算原理,探讨应用场景及陷阱,推荐根据需求选择TIMESTAMPDIFF或inte... 目录1. 核心概念:DATEDIFF 究竟在计算什么?2. 主流数据库中的 DATEDIFF 实现2.1

Spring WebFlux 与 WebClient 使用指南及最佳实践

《SpringWebFlux与WebClient使用指南及最佳实践》WebClient是SpringWebFlux模块提供的非阻塞、响应式HTTP客户端,基于ProjectReactor实现,... 目录Spring WebFlux 与 WebClient 使用指南1. WebClient 概述2. 核心依

MyBatis-Plus 中 nested() 与 and() 方法详解(最佳实践场景)

《MyBatis-Plus中nested()与and()方法详解(最佳实践场景)》在MyBatis-Plus的条件构造器中,nested()和and()都是用于构建复杂查询条件的关键方法,但... 目录MyBATis-Plus 中nested()与and()方法详解一、核心区别对比二、方法详解1.and()

Spring Boot @RestControllerAdvice全局异常处理最佳实践

《SpringBoot@RestControllerAdvice全局异常处理最佳实践》本文详解SpringBoot中通过@RestControllerAdvice实现全局异常处理,强调代码复用、统... 目录前言一、为什么要使用全局异常处理?二、核心注解解析1. @RestControllerAdvice2

Spring事务传播机制最佳实践

《Spring事务传播机制最佳实践》Spring的事务传播机制为我们提供了优雅的解决方案,本文将带您深入理解这一机制,掌握不同场景下的最佳实践,感兴趣的朋友一起看看吧... 目录1. 什么是事务传播行为2. Spring支持的七种事务传播行为2.1 REQUIRED(默认)2.2 SUPPORTS2

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

MySQL 中 ROW_NUMBER() 函数最佳实践

《MySQL中ROW_NUMBER()函数最佳实践》MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重... 目录mysql 中 ROW_NUMBER() 函数详解一、基础语法二、核心特点三、典型应用场景1. 数据分