UEFI——获取UEFI MemoryMap

news2024/11/24 9:51:26

一、MemoryMap简介

首先讲一下什么是MemoryMap?

内存映射(Memory Mapping)是一种将文件内容映射到进程的虚拟地址空间的技术。在这种机制下,文件可以视为内存的一部分,从而允许程序直接对这部分内存进行读写操作,而无需传统的I/O调用。内存映射缓冲区利用虚拟内存机制,让操作系统将一部分磁盘文件映射到进程地址空间的一块连续区域当中。操作系统负责管理内存页的加载和卸载,应用程序只需要访问这块内存区域即可,从而避免了频繁的磁盘I/O操作和多余的系统调用。

UEFI的内存映射

  • UEFI内存映射是由UEFI固件提供的,主要用于在启动过程中描述系统的内存布局。它告诉操作系统和启动软件哪些内存区域是可用的,哪些是保留的。
  • 实现:UEFI内存映射通常是在系统启动的早期阶段由UEFI固件创建的,它包括了系统内存的详细信息,如内存大小、类型和状态。

UEFI MemoryMap指的是UEFI运行时环境中的一个数据结构,它包含了当前系统内存的详细信息.MemoryMap记录了系统内存的布局,包括所有可用的区域、内存类型、属性以及使用情况。

内存类型:MemoryMap中的每个内存区域都有一个与之关联的类型

        在UEFI中引入的内存类型由以下几种:

typedef enum {
  EfiReservedMemoryType, //没有用到的
  EfiLoaderCode, //已加载的UEFI应用程序的代码部分
  EfiLoaderData, //已加载的UEFI应用程序的数据部分和默认数据分配
  EfiBootServicesCode, //已加载的 Boot Services 驱动程序的代码部分
  EfiBootServicesData, //已加载的 Boot Services 驱动程序的数据部分
  EfiRuntimeServicesCode, //已加载的Runtime Services驱动的代码部分
  EfiRuntimeServicesData, //已加载的Runtime Services驱动的数据部分
  EfiConventionalMemory, //空闲(未分配)内存
  EfiUnusableMemory, //检测到错误的内存
  EfiACPIReclaimMemory, //保存ACPI表的内存
  EfiACPIMemoryNVS, //为固件保留的地址空间
  EfiMemoryMappedIO, //系统固件使用它来请求操作系统将内存映射的 IO 区域映射到虚拟地址,以便 EFI 运行时服务可以访问它。
  EfiMemoryMappedIOPortSpace, //系统内存映射的 IO 区域,处理器用它来将内存周期转换为 IO 周期。
  EfiPalCode, //固件为作为处理器一部分的代码保留的地址空间。
  EfiPersistentMemory, //一个内存区域,它作为 EfiConventionalMemory 运行,但它也恰好支持字节寻址的非易失性。
  EfiUnacceptedMemoryType, //描述未被接受的系统内存的内存区域。

  EfiMaxMemoryType,
  //
  // +---------------------------------------------------+
  // | 0..(EfiMaxMemoryType - 1)    - Normal memory type |
  // +---------------------------------------------------+
  // | EfiMaxMemoryType..0x6FFFFFFF - Invalid            |
  // +---------------------------------------------------+
  // | 0x70000000..0x7FFFFFFF       - OEM reserved       |
  // +---------------------------------------------------+
  // | 0x80000000..0xFFFFFFFF       - OS reserved        |
  // +---------------------------------------------------+
  //
  MEMORY_TYPE_OEM_RESERVED_MIN = 0x70000000,
  MEMORY_TYPE_OEM_RESERVED_MAX = 0x7FFFFFFF,
  MEMORY_TYPE_OS_RESERVED_MIN  = 0x80000000,
  MEMORY_TYPE_OS_RESERVED_MAX  = 0xFFFFFFFF
} EFI_MEMORY_TYPE;

内存属性:写保护、都保护、执行保护、非易失性、只读、运行时等等等等

内存区域:

使用情况:

UEFI MemoryMap的主要用途包括:

操作系统加载器:操作系统加载器在启动过程中会使用MemoryMap来确定哪些内存是可用的,以及如何配置和使用这些内存。

UEFI应用程序:UEFI应用程序可以使用MemoryMap来了解内存布局,以便它们可以请求和分配内存。

内存管理:UEFI固件使用MemoryMap来管理内存分配,确保不同组件之间不会发生内存冲突。

UEFI规范中用结构体EFI_MEMORY_DESCRIPTOR来描述内存区域,在UEFI环境中,EFI_MEMORY_DESCRIPTOR被用来标识内存映射(Memory Map)中的一个条目,即内存映射的每一项都是一个EFI_MEMORY_DESCRIPTOR结构。UEFI应用程序和驱动程序可以使用EFI_BOOT_SERVICES.GetMemoryMap服务来获取当前的内存映射,这个映射是一个EFI_MEMORY_DESCRIPTOR数组。通过便利这个数组,应用程序可以了解系统的内存布局,并据此进行内存管理操作。

EFI_MEMORY_DESCRIPTOR的代码原型为:

typedef struct {
  UINT32                Type;                   // 描述内存的类型
  EFI_PHYSICAL_ADDRESS  PhysicalStart;          // 内存区域的物理起始地址
  EFI_VIRTUAL_ADDRESS   VirtualStart;           // 内存区域的虚拟起始地址(如果适用)
  UINT64                NumberOfPages;          // 内存区域包含的页数
  UINT64                Attribute;              // 内存区域的属性
} EFI_MEMORY_DESCRIPTOR;

二、获取UEFI MemoryMap

UEFI的内存服务提供了EFI_GET_MEMORY_MAP.GetMemoryMap接口来获取当前的内存映射,其代码原型为:

//返回当前的Memory Map

  @retval EFI_SUCCESS           The memory map was returned in the MemoryMap buffer.
                                内存映射已经返回到Memmorymap缓冲区
  @retval EFI_BUFFER_TOO_SMALL  The MemoryMap buffer was too small. The current buffer size
                                needed to hold the memory map is returned in MemoryMapSize.
                                表示MemmoryMap缓冲区太小了,目前需要用来保存内存映射的缓冲区大小已经返回到MemmoryMapSize中。
  @retval EFI_INVALID_PARAMETER 1) MemoryMapSize is NULL.
                                2) The MemoryMap buffer is not too small and MemoryMap is
                                   NULL.
                                 表示MemorymapSize为空,
                                 或memmoryMap缓冲区并不小,但是MemMorymap是空的



typedef
EFI_STATUS
(EFIAPI *EFI_GET_MEMORY_MAP)(
  IN OUT UINTN                       *MemoryMapSize, //输入,输出参数,指向memorymap缓冲区大小的指针,单位为字节。在输入时,这是调用者分配的缓冲区大小。在输出时,如果缓冲区足够大,这是固件返回的缓冲区大小;如果缓冲区过小,则是包含映射所需要的缓冲区大小。
  OUT    EFI_MEMORY_DESCRIPTOR       *MemoryMap, //输出参数,指向固件存放当前内存映射的缓冲区的指针
  OUT    UINTN                       *MapKey, //输出参数,指向固件返回当前内存映射键的位置的指针
  OUT    UINTN                       *DescriptorSize, //输出参数,指向固件返回单个EFI_MEMORY_DESCRIPTOR的大小(以字节为单位)的位置的指针。
  OUT    UINT32                      *DescriptorVersion //指向固件返回与 EFI_MEMORY_DESCRIPTOR 关联的版本号的位置的指针。

  );

如果GetMemoryMap的返回值为EFI_BUFFER_TOO_SMALL,说明MemoryMap缓冲区太小,已经将用来保存内存映射的缓冲区大小返回到MemoryMapSize中了。接下来就需要使用AllocatePool重新分配缓冲区。其代码原型为

/**
    Allocates a buffer of type EfiBootServicesData.
    按照字节数分配EfiBootServicesData类型的内存,并返回一个指向所分配缓冲区的指针
**/
VOID *
EFIAPI
AllocatePool (
  IN UINTN  AllocationSize //需要分配的字节数
  );

完整代码如下:

#include <uefi.h>
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>



EFI_STATUS
EFIAPI
MyMemMapEntry(
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
)
{

  EFI_STATUS                Status;
  UINTN                     EfiMemoryMapSize;
  EFI_MEMORY_DESCRIPTOR     *EfiMemoryMap;
  EFI_MEMORY_DESCRIPTOR     *EfiMemoryMapEnd;
  EFI_MEMORY_DESCRIPTOR     *EfiEntry;
  UINTN                     EfiMapKey;
  UINTN                     EfiDescriptorSize;
  UINT32                    EfiDescriptorVersion;

  UINT64                    BootServicesDataPage = 0;
  UINT64                    BootServicesCodePage = 0;
  UINT64                    ACPIReclaimMemoryPage = 0;
  UINT64                    ACPIMemoryNVSPage = 0;
  UINT64                    ReservedMemoryTypePage = 0;
  UINT64                    RuntimeServicesCodePage = 0;
  UINT64                    RuntimeServicesDataPage = 0;
  UINT64                    LoaderCodePage = 0;
  UINT64                    LoaderDataPage = 0;
  UINT64                    MaxMemoryTypePage = 0;
  UINT64                    ConventionalMemoryPage = 0;
  UINT64                    UnusableMemoryPage = 0;
  UINT64                    MemoryMappedIOPage = 0;
  UINT64                    MemoryMappedIOPortSpacePage = 0;
  UINT64                    PalCodePage = 0;
  UINT64                    PersistentMemoryPage = 0;


  EfiMemoryMapSize = 0;
  EfiMemoryMap = NULL;
  Status = gBS->GetMemoryMap ( //获取MemoryMap
                  &EfiMemoryMapSize,
                  EfiMemoryMap,
                  &EfiMapKey,
                  &EfiDescriptorSize,
                  &EfiDescriptorVersion
                  );
  ASSERT (Status == EFI_BUFFER_TOO_SMALL); //过小重新分配
  do {

    EfiMemoryMap = AllocatePool (EfiMemoryMapSize);
    if (EfiMemoryMap == NULL){
      DEBUG ((EFI_D_ERROR, "ERROR!! Null Pointer returned by AllocatePool ()\n"));
      ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES);
      return Status;
    }
    Status = gBS->GetMemoryMap (
                    &EfiMemoryMapSize,
                    EfiMemoryMap,
                    &EfiMapKey,
                    &EfiDescriptorSize,
                    &EfiDescriptorVersion
                    );
    if (EFI_ERROR(Status)) {
      FreePool (EfiMemoryMap); //释放掉前面分配的
    }
  } while (Status == EFI_BUFFER_TOO_SMALL); //一直小一直分配,直到不再小

  DEBUG((DEBUG_ERROR | DEBUG_PAGE,"[CSDN] EfiMemoryMapSize=0x%x EfiDescriptorSize=0x%x EfiMemoryMap=0x%x \n", EfiMemoryMapSize, EfiDescriptorSize, (UINTN)EfiMemoryMap));

  EfiMemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)EfiMemoryMap + EfiMemoryMapSize); //映射区结尾
  EfiEntry = EfiMemoryMap; //映射区的开始地址

  DEBUG((DEBUG_ERROR | DEBUG_PAGE,"===========================%S============================== Start\n", L"CSDN MemMap"));

  while (EfiEntry < EfiMemoryMapEnd) { //循环获取各内存类型的信息

      if (EfiEntry->Type == EfiReservedMemoryType){
         DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiReservedMemoryType  %3d %16lx pn %16lx \n", EfiEntry->Type, EfiEntry->PhysicalStart, EfiEntry->NumberOfPages));
         ReservedMemoryTypePage = ReservedMemoryTypePage + EfiEntry->NumberOfPages;
      }else if (EfiEntry->Type == EfiLoaderCode){
         DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiLoaderCode  %3d %16lx pn %16lx \n", EfiEntry->Type, EfiEntry->PhysicalStart, EfiEntry->NumberOfPages));
         LoaderCodePage = LoaderCodePage + EfiEntry->NumberOfPages;
      }else if (EfiEntry->Type == EfiLoaderData){
         DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiLoaderData  %3d %16lx pn %16lx \n", EfiEntry->Type, EfiEntry->PhysicalStart, EfiEntry->NumberOfPages));
         LoaderDataPage = LoaderDataPage + EfiEntry->NumberOfPages;
      }else if (EfiEntry->Type == EfiBootServicesCode){
         DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiBootServicesCode  %3d %16lx pn %16lx \n", EfiEntry->Type, EfiEntry->PhysicalStart, EfiEntry->NumberOfPages));
         BootServicesCodePage = BootServicesCodePage + EfiEntry->NumberOfPages;
      }else if (EfiEntry->Type == EfiBootServicesData){
         DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiBootServicesData  %3d %16lx pn %16lx \n", EfiEntry->Type, EfiEntry->PhysicalStart, EfiEntry->NumberOfPages));
         BootServicesDataPage = BootServicesDataPage + EfiEntry->NumberOfPages;
      }else if (EfiEntry->Type == EfiRuntimeServicesCode){
         DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiRuntimeServicesCode  %3d %16lx pn %16lx \n", EfiEntry->Type, EfiEntry->PhysicalStart, EfiEntry->NumberOfPages));
         RuntimeServicesCodePage = RuntimeServicesCodePage + EfiEntry->NumberOfPages;
      }else if (EfiEntry->Type == EfiRuntimeServicesData){
         DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiRuntimeServicesData  %3d %16lx pn %16lx \n", EfiEntry->Type, EfiEntry->PhysicalStart, EfiEntry->NumberOfPages));
         RuntimeServicesDataPage = RuntimeServicesDataPage + EfiEntry->NumberOfPages;
      }else if (EfiEntry->Type == EfiConventionalMemory){
         DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiConventionalMemory  %3d %16lx pn %16lx \n", EfiEntry->Type, EfiEntry->PhysicalStart, EfiEntry->NumberOfPages));
         ConventionalMemoryPage = ConventionalMemoryPage + EfiEntry->NumberOfPages;
      }else if (EfiEntry->Type == EfiUnusableMemory){
         DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiUnusableMemory  %3d %16lx pn %16lx \n", EfiEntry->Type, EfiEntry->PhysicalStart, EfiEntry->NumberOfPages));
         UnusableMemoryPage = UnusableMemoryPage + EfiEntry->NumberOfPages;
      }else if (EfiEntry->Type == EfiACPIReclaimMemory){
         DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiACPIReclaimMemory  %3d %16lx pn %16lx \n", EfiEntry->Type, EfiEntry->PhysicalStart, EfiEntry->NumberOfPages));
         ACPIReclaimMemoryPage = ACPIReclaimMemoryPage + EfiEntry->NumberOfPages;
      }else if (EfiEntry->Type == EfiACPIMemoryNVS){
         DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiACPIMemoryNVS  %3d %16lx pn %16lx \n", EfiEntry->Type, EfiEntry->PhysicalStart, EfiEntry->NumberOfPages));
         ACPIMemoryNVSPage = ACPIMemoryNVSPage + EfiEntry->NumberOfPages;
      }else if (EfiEntry->Type == EfiMemoryMappedIO){
         DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiMemoryMappedIO  %3d %16lx pn %16lx \n", EfiEntry->Type, EfiEntry->PhysicalStart, EfiEntry->NumberOfPages));
         MemoryMappedIOPage = MemoryMappedIOPage + EfiEntry->NumberOfPages;
      }else if (EfiEntry->Type == EfiMemoryMappedIOPortSpace){
         DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiMemoryMappedIOPortSpace  %3d %16lx pn %16lx \n", EfiEntry->Type, EfiEntry->PhysicalStart, EfiEntry->NumberOfPages));
         MemoryMappedIOPortSpacePage = MemoryMappedIOPortSpacePage + EfiEntry->NumberOfPages;
      }else if (EfiEntry->Type == EfiPalCode){
         DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiPalCode  %3d %16lx pn %16lx \n", EfiEntry->Type, EfiEntry->PhysicalStart, EfiEntry->NumberOfPages));
         PalCodePage = PalCodePage + EfiEntry->NumberOfPages;
      }else if (EfiEntry->Type == EfiPersistentMemory){
         DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiPersistentMemory  %3d %16lx pn %16lx \n", EfiEntry->Type, EfiEntry->PhysicalStart, EfiEntry->NumberOfPages));
         PersistentMemoryPage = PersistentMemoryPage + EfiEntry->NumberOfPages;
      }else if (EfiEntry->Type == EfiMaxMemoryType){
         DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiMaxMemoryType  %3d %16lx pn %16lx \n", EfiEntry->Type, EfiEntry->PhysicalStart, EfiEntry->NumberOfPages));
         MaxMemoryTypePage = MaxMemoryTypePage + EfiEntry->NumberOfPages;
      }

    EfiEntry = NEXT_MEMORY_DESCRIPTOR(EfiEntry, EfiDescriptorSize);
  }
  DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiBootServicesData Page Number: %16lx  %dMB\n", BootServicesDataPage, BootServicesDataPage*4/1024));
  DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiBootServicesCode Page Number: %16lx  %dMB\n", BootServicesCodePage, BootServicesCodePage*4/1024));
  DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiACPIReclaimMemory Page Number: %16lx  %dMB\n", ACPIReclaimMemoryPage, ACPIReclaimMemoryPage*4/1024));
  DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiACPIMemoryNVS Page Number: %16lx  %dMB\n", ACPIMemoryNVSPage, ACPIMemoryNVSPage*4/1024));
  DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiReservedMemoryType Page Number: %16lx  %dMB\n", ReservedMemoryTypePage, ReservedMemoryTypePage*4/1024));
  DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiRuntimeServicesCode Page Number: %16lx  %dMB\n", RuntimeServicesCodePage, RuntimeServicesCodePage*4/1024));
  DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiRuntimeServicesData Page Number: %16lx  %dMB\n", RuntimeServicesDataPage, RuntimeServicesDataPage*4/1024));
  DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiLoaderCode Page Number: %16lx  %dMB\n", LoaderCodePage, LoaderCodePage*4/1024));
  DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiLoaderData Page Number: %16lx  %dMB\n", LoaderDataPage, LoaderDataPage*4/1024));
  DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiMaxMemoryType Page Number: %16lx  %dMB\n", MaxMemoryTypePage, MaxMemoryTypePage*4/1024));
  DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiConventionalMemory Page Number: %16lx  %dMB\n", ConventionalMemoryPage, ConventionalMemoryPage*4/1024));
  DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiUnusableMemory Page Number: %16lx  %dMB\n", UnusableMemoryPage, UnusableMemoryPage*4/1024));
  DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiMemoryMappedIO Page Number: %16lx  %dMB\n", MemoryMappedIOPage, MemoryMappedIOPage*4/1024));
  DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiMemoryMappedIOPortSpace Page Number: %16lx  %dMB\n", MemoryMappedIOPortSpacePage, MemoryMappedIOPortSpacePage*4/1024));
  DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiPalCode Page Number: %16lx  %dMB\n", PalCodePage, PalCodePage*4/1024));
  DEBUG((DEBUG_ERROR | DEBUG_PAGE, "[CSDN] EfiPersistentMemory Page Number: %16lx  %dMB\n", PersistentMemoryPage, PersistentMemoryPage*4/1024));

  DEBUG((DEBUG_ERROR | DEBUG_PAGE,"===========================%S============================== End\n", L"CSDN MemMap"));

  return Status;
}

编写inf代码,编译,运行efi文件 

部分运行结果如下:

显示内存类型                                                物理地址                         页数

这是一个memmap dump demo,使用该demo可以得出当前BIOS的mem region分配情况,在shell下同样可以使用内置的memmap 命令来查看当前memory map。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2120841.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电动车乱停放识别摄像头

电动车乱停放是城市交通管理中常见的问题&#xff0c;给道路通行和停车场管理带来了诸多困扰。为了有效解决这一问题&#xff0c;人们研发了电动车乱停放识别摄像头&#xff0c;这种设备结合了人工智能技术和监控摄像技术&#xff0c;能够实时监测并识别电动车乱停放情况&#…

python日常刷题(二)

前言&#xff1a;本文记录2024年4月9日至2024年4月13日做题时遇到的几个问题&#xff08;错题本&#xff09;&#xff1a; &#x1f3ac;个人简介&#xff1a;努力学习ing &#x1f4cb;本专栏&#xff1a;python日常刷题 &#x1f380;CSDN主页&#xff1a;愚润求学 文章目录 …

uniapp苹果端与安卓端兼容性问题的处理

目录 第一个问题&#xff0c;苹果端页面有下拉回弹的效果&#xff0c;安卓端没有。解决苹果端的问题&#xff0c;在pages.json中对需要的页面&#xff0c; 第二个问题&#xff0c;安卓端页面滚动到底部触发onReachBottom页面生命周期函数&#xff0c;而苹果端无法触发&#xf…

2024年PDF转换器大集合:哪4款是互联网人的首选?

嘿&#xff0c;朋友们&#xff0c;你们知道吗&#xff1f;那些在办公室里看起来特别能干的大佬们&#xff0c;他们好像总能很快地把各种文件变来变去&#xff0c;好像有什么特异功能似的。告诉你们吧&#xff0c;他们其实就是用了几款特别牛的PDF转换工具&#xff01;今天&…

前端打包装包——设置镜像

1、打包失败&#xff0c;因为没装包&#xff0c;装包失败&#xff0c;因为装包的源错误 npm config get registry npm config set registry https://registry.npmmirror.com/npm install npm run build还是失败&#xff0c;因为缺少了包&#xff0c;在package.json文件中没有包…

Centos7.9 安装Elasticsearch 8.15.1(图文教程)

本章教程,主要记录在Centos7.9 安装Elasticsearch 8.15.1的整个安装过程。 一、下载安装包 下载地址: https://www.elastic.co/cn/downloads/past-releases/elasticsearch-8-15-1 你可以通过手动下载然后上传到服务器,也可以直接使用在线下载的方式。 wget https://artifacts…

Docker 部署 Seata (图文并茂超详细)

部署 Seata ( Docker ) [Step 1] : 创建对应的**seata**数据库, 也就是下面的的**seata.sql**文件 seata.sql [Step 2] : 拉取 Seata 镜像 docker pull seataio/seata-server:1.5.2[Step 3] : 创建目录 ➡️ 创建容器 ➡️ 拷贝文件 ➡️ 授权文件 ➡️ 删除容器 # 创建…

热点文章轻松生成?一篇测评告诉你ChatGPT的神奇能力

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

【视频教程】遥感云大数据在灾害、水体与湿地领域典型案例实践及GPT模型应用

前期我们分别以Javascript和Python为编程语言&#xff0c;成功举办了数期关于GEE遥感大数据分析处理的基础培训课程&#xff0c;得到了来多个行业的学员的广泛参与和支持。应广大科研工作者的要求&#xff0c;本次课程将聚焦目前遥感应用最热门领域之一的灾害、水体及湿地领域&…

多线程篇(阻塞队列- LinkedTransferQueue)(持续更新迭代)

目录 一、简介 二、基本原理 三、jdk8 内部属性 4个常量值 transfer tryAppend take() awaitMatch boolean remove(Object o) 四、jdk17 主要参数 put/offer take() remove() 五、与synchronousqueue 区别 六、知识小结 一、简介 LinkedTransferQueue是一个由…

手撕Python之文件操作

1.编码 编码---encode() 解码---decode() #编码(encode):将我们能够识别的文字&#xff0c;转换为计算机能够识别的内容 print(你好.encode())#默认utf-8 #b\xe4\xbd\xa0\xe5\xa5\xbd #将你好翻成进制数#解码&#xff08;decode&#xff09;:将计算机能识别的内容&#xff0c…

兼顾身份保护和文本对齐!中山大学等提出CoRe:任意提示的文本到图像个性化生成!

文章链接&#xff1a;https://arxiv.org/pdf/2408.15914 亮点直击 CoRe只用于输出embedding和注意力图&#xff0c;不需要生成图像&#xff0c;可以用于任意提示。 在身份保护和文本对齐方面表现出优越的性能&#xff0c;特别是对于需要高度视觉可变性的提示。 除了个性化一般…

2. Python之注释及缩进以及print和input函数使用

一. Python代码中的注释及缩进 Python中注释有单行注释&#xff0c;多行注释&#xff0c;声明注释 单行注释使用符号#&#xff0c;从#开始&#xff0c;后面到本行末尾都是注释内容。多行注释可以使用’‘’ ‘’三个引号&#xff0c;三个引号内的内容都是注释声明注释&#x…

密钥加密机的定义与分类

密钥加密机&#xff0c;也称为加密机或硬件加密模块(HSM, Hardware Security Module)&#xff0c;是信息安全领域中的核心设备。它通过密码学原理和密钥管理技术&#xff0c;对敏感数据进行加密保护&#xff0c;确保数据在传输和存储过程中的安全性。以下是对密钥加密机的详细解…

开始一个WPF项目时的记忆重载入

目前在工业软件的UI开发方案选择中&#xff0c;WPF仍然是一个重要的选项。 但是其固有的复杂性&#xff0c;对于像我这样&#xff0c;并不是一直在从事界面开发的人来说&#xff0c;每次重启&#xff0c;都需要一两天的适应的时间。所以这里稍微写一个笔记。 还是老办法&…

分享一款520表白节JS代码

源码介绍 今天给大家分享一款JS表白源码 js会随 随机颜色心形跟随鼠标互动520表白节女神表白利器&#xff01; 修改的话就搜索&#xff1a;LOVEh 就能找到这个英文了。 效果预览 源码获取 分享一款520表白节JS代码 百度网盘提取码&#xff1a;2yar&#xff1a;https://pan.…

JavaScript高级——回调函数

1、回调函数的含义 ① 你定义的 ② 你没有调 ③ 但最终他执行了&#xff08;某个时刻或者某个条件下&#xff09; 2、常见的回调函数 ① dom事件回调函数 —— 发生事件的dom元素 ② 定时器回调函数 —— window ③ ajax请求回调函数 ④ 生命周期回调函数 本文分享…

【Adaptive AutoSAR 源码解析01】通信中间件技术总览

https://www.autosar.org/fileadmin/standards/R21-11/AP/AUTOSAR_EXP_ARAComAPI.pdf#page=8&zoom=100,94,473

pip install “git+https://xxx“报错error: subprocess-exited-with-error

有时候即使使用科学上网&#xff0c;可以正常访问github也会发生pip install “githttps://xxx“报错 如 解决方法&#xff1a; 我们可以将pip install “githttps://xxx“分为两步&#xff1a; 第一步&#xff1a; pip install "githttps://xxx" 第二步&#…

计算机技术专硕,三维数字地球的学习路径?

三维数字地球是一个跨学科领域&#xff0c;涉及地理信息系统&#xff08;GIS&#xff09;、计算机图形学、遥感技术、大数据处理等多个方面。作为计算机技术专硕的学生&#xff0c;可以按照以下学习路径来逐步深入&#xff1a; 1、基础理论学习&#xff1a; 地理信息系统&…