2wsx 发表于 2022-10-13 15:17:49

如何将.c文件在UEFI系统中编译并且运行?

还有就是.inf是什么意思?

jackz007 发表于 2022-10-13 15:38:16

      UEFI 不是一种负责引导操作系统的协议吗,楼主玩的好高大上啊!

2wsx 发表于 2022-10-13 15:45:59

jackz007 发表于 2022-10-13 15:38
UEFI 不是一种负责引导操作系统的协议吗,楼主玩的好高大上啊!

主要我是不太懂啊。。。所以问问有没有人知道给我讲讲。。。

jackz007 发表于 2022-10-13 15:46:59

2wsx 发表于 2022-10-13 15:45
主要我是不太懂啊。。。所以问问有没有人知道给我讲讲。。。

      难道你在写属于自己的操作系统?

2wsx 发表于 2022-10-13 15:47:38

jackz007 发表于 2022-10-13 15:38
UEFI 不是一种负责引导操作系统的协议吗,楼主玩的好高大上啊!

怎么把.c文件变成.efi文件啊

jackz007 发表于 2022-10-13 16:05:20

2wsx 发表于 2022-10-13 15:47
怎么把.c文件变成.efi文件啊

       兄弟,折腾 .efi 文件可是不敢靠道听途说啊,小心你的小机机分分钟变成板砖,到那时,恐怕连哭鼻子都找不到地方啊。

2wsx 发表于 2022-10-13 16:06:41

jackz007 发表于 2022-10-13 15:46
难道你在写属于自己的操作系统?

不是啊,我是找了一个别人的代码,想运行一下,需要在UEFI里编译运行。我现在不知道该咋编译。

jackz007 发表于 2022-10-13 16:09:33

2wsx 发表于 2022-10-13 16:06
不是啊,我是找了一个别人的代码,想运行一下,需要在UEFI里编译运行。我现在不知道该咋编译。

         你说的 UEFI 居然是指一种 C 语言编译器?混了几十年江湖,头一回听说!

2wsx 发表于 2022-10-13 16:23:17

jackz007 发表于 2022-10-13 16:09
你说的 UEFI 居然是指一种 C 语言编译器?混了几十年江湖,头一回听说!

大佬 你了解SMBIOS吗?我目前是希望写代码读取SMBIOS的任意的Type,并将其Handle打印出来,读取任意一个的Type,打印出Type中的DeviceType、BusNum、DevFuncNum信息。根据读出来的Bus、Device、Function号读取相应PCI配置空间信息。所以我在四处找相关代码 想运行一下看看是什么效果

jackz007 发表于 2022-10-13 16:27:02

2wsx 发表于 2022-10-13 16:23
大佬 你了解SMBIOS吗?我目前是希望写代码读取SMBIOS的任意的Type,并将其Handle打印出来,读取任意一个 ...

          抱歉,你这个太专业了,恐怕这里没有人可以帮助到你,你应该去专业指向更加明确的论坛求助。

人造人 发表于 2022-10-13 16:46:12

先从基础开始学吧
你现在的学识和你目前的需求还有很长一段距离
你不能先学乘除法然后再学加减法
你的先学会走,然后再学跑
所以,先从基础开始学吧
先学C语言
另外,学会百度问题

2wsx 发表于 2022-10-14 08:07:45

人造人 发表于 2022-10-13 16:46
先从基础开始学吧
你现在的学识和你目前的需求还有很长一段距离
你不能先学乘除法然后再学加减法


好的 谢谢啦

人造人 发表于 2022-10-14 23:01:20

花了点时间研究了一下uefi编程
这个教程可以
https://kagurazakakotori.github.io/ubmp-cn/index.html

另外的参考资料
https://www.cnblogs.com/DirWang/p/15674148.html#03-uefi-hello-world
http://www.rodsbooks.com/efi-programming/index.html
https://uefi.org/sites/default/files/resources/UEFI_Spec_2_10_Aug29.pdf

我现在正在看这个教程,准备研究图像输出部分
我现在缺一个printf函数,我去研究这个函数了
之后再帮你研究研究smbios的部分

人造人 发表于 2022-10-14 23:12:46

jackz007 发表于 2022-10-13 16:09
你说的 UEFI 居然是指一种 C 语言编译器?混了几十年江湖,头一回听说!

他指的是这条指令
x86_64-w64-mingw32-gcc -Wall -e efi_main -nostdlib -fno-builtin -Wl,--subsystem,10 -I /usr/include/efi -o main.efi main.c

jackz007 发表于 2022-10-14 23:22:26

人造人 发表于 2022-10-14 23:12
他指的是这条指令

      谢谢,我说嘛,原来他要找的是一条编译命令。

人造人 发表于 2022-10-19 01:00:33

printf函数过于复杂,我现在依然写不出来
不浪费时间了,这个函数之后再研究吧
我再研究研究efi编程,然后就帮你研究smbios

#include <efi.h>

void swap(CHAR16 *a, CHAR16 *b) {
    CHAR16 temp = *a;
    *a = *b;
    *b = temp;
}

CHAR16 kgetc(EFI_SYSTEM_TABLE *SystemTable) {
    EFI_INPUT_KEY key;
    SystemTable->BootServices->WaitForEvent(1, &SystemTable->ConIn->WaitForKey, NULL);
    SystemTable->ConIn->ReadKeyStroke(SystemTable->ConIn, &key);
    if(key.UnicodeChar == '\r') key.UnicodeChar = '\n';
    return key.UnicodeChar;
}

void kputc(EFI_SYSTEM_TABLE *SystemTable, CHAR16 c) {
    if(c == L'\n') kputc(SystemTable, L'\r');
    CHAR16 str = {c, '\0'};
    SystemTable->ConOut->OutputString(SystemTable->ConOut, str);
}

void kputs(EFI_SYSTEM_TABLE *SystemTable, const CHAR16 *str) {
    for(UINTN i = 0; str; ++i) {
      kputc(SystemTable, str);
    }
}

void number(CHAR16 *buff, UINTN value, UINTN base) {
    static const CHAR16 table = L"0123456789abcdef";
    if(base > 16) base = 16;
    CHAR16 *p = buff;
    do {
      *p++ = table;
      value /= base;
    } while(value);
    *p = L'\0';
    UINTN count = p - buff;
    for(UINTN i = 0; i < count / 2; ++i) {
      swap(&buff, &buff);
    }
}

void print_dec(EFI_SYSTEM_TABLE *SystemTable, UINTN value) {
    CHAR16 buff; number(buff, value, 10); kputs(SystemTable, buff); kputc(SystemTable, L'\n');
}

void print_hex(EFI_SYSTEM_TABLE *SystemTable, UINTN value) {
    CHAR16 buff; number(buff, value, 16); kputs(SystemTable, buff); kputc(SystemTable, L'\n');
}

void info(EFI_SYSTEM_TABLE *SystemTable, EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput) {
    kputs(SystemTable, L"FrameBufferBase: "); print_hex(SystemTable, GraphicsOutput->Mode->FrameBufferBase);
    kputs(SystemTable, L"FrameBufferSize: "); print_dec(SystemTable, GraphicsOutput->Mode->FrameBufferSize);
    kputs(SystemTable, L"FrameBufferSize: "); print_hex(SystemTable, GraphicsOutput->Mode->FrameBufferSize);
    kputs(SystemTable, L"MaxMode: "); print_dec(SystemTable, GraphicsOutput->Mode->MaxMode);
    kputs(SystemTable, L"Mode: "); print_dec(SystemTable, GraphicsOutput->Mode->Mode);
    kputs(SystemTable, L"SizeOfInfo: "); print_dec(SystemTable, GraphicsOutput->Mode->SizeOfInfo);
    kputs(SystemTable, L"HorizontalResolution: "); print_dec(SystemTable, GraphicsOutput->Mode->Info->HorizontalResolution);
    kputs(SystemTable, L"PixelsPerScanLine: "); print_dec(SystemTable, GraphicsOutput->Mode->Info->PixelsPerScanLine);
    kputs(SystemTable, L"PixelFormat: "); print_dec(SystemTable, GraphicsOutput->Mode->Info->PixelFormat);
    kputs(SystemTable, L"Version: "); print_dec(SystemTable, GraphicsOutput->Mode->Info->Version);
    kputs(SystemTable, L"VerticalResolution: "); print_dec(SystemTable, GraphicsOutput->Mode->Info->VerticalResolution);
    kputs(SystemTable, L"BlueMask: "); print_dec(SystemTable, GraphicsOutput->Mode->Info->PixelInformation.BlueMask);
    kputs(SystemTable, L"GreenMask: "); print_dec(SystemTable, GraphicsOutput->Mode->Info->PixelInformation.GreenMask);
    kputs(SystemTable, L"RedMask: "); print_dec(SystemTable, GraphicsOutput->Mode->Info->PixelInformation.RedMask);
    kputs(SystemTable, L"ReservedMask: "); print_dec(SystemTable, GraphicsOutput->Mode->Info->PixelInformation.ReservedMask);
    for(UINTN i = 0; i < GraphicsOutput->Mode->MaxMode; ++i) {
      kputs(SystemTable, L"i: "); print_dec(SystemTable, i);
      EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *GraphicsOutputMode;
      UINTN SizeOfInfo;
      GraphicsOutput->QueryMode(GraphicsOutput, i, &SizeOfInfo, &GraphicsOutputMode);
      kputs(SystemTable, L"SizeOfInfo: "); print_dec(SystemTable, SizeOfInfo);
      kputs(SystemTable, L"HorizontalResolution: "); print_dec(SystemTable, GraphicsOutputMode->HorizontalResolution);
      kputs(SystemTable, L"PixelsPerScanLine: "); print_dec(SystemTable, GraphicsOutputMode->PixelsPerScanLine);
      kputs(SystemTable, L"PixelFormat: "); print_dec(SystemTable, GraphicsOutputMode->PixelFormat);
      kputs(SystemTable, L"Version: "); print_dec(SystemTable, GraphicsOutputMode->Version);
      kputs(SystemTable, L"VerticalResolution: "); print_dec(SystemTable, GraphicsOutputMode->VerticalResolution);
      kputs(SystemTable, L"BlueMask: "); print_dec(SystemTable, GraphicsOutputMode->PixelInformation.BlueMask);
      kputs(SystemTable, L"GreenMask: "); print_dec(SystemTable, GraphicsOutputMode->PixelInformation.GreenMask);
      kputs(SystemTable, L"RedMask: "); print_dec(SystemTable, GraphicsOutputMode->PixelInformation.RedMask);
      kputs(SystemTable, L"ReservedMask: "); print_dec(SystemTable, GraphicsOutputMode->PixelInformation.ReservedMask);
    }
}

void fill_screen(EFI_SYSTEM_TABLE *SystemTable, EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput) {
    //GraphicsOutput->SetMode(GraphicsOutput, 22);    // 1920x1080
    GraphicsOutput->SetMode(GraphicsOutput, 18);    // 1440x900
    EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)GraphicsOutput->Mode->FrameBufferBase;
    UINTN height = GraphicsOutput->Mode->Info->VerticalResolution;
    UINTN width = GraphicsOutput->Mode->Info->HorizontalResolution;
    EFI_GRAPHICS_OUTPUT_BLT_PIXEL color = {255, 255, 255};
    for(UINTN y = 0; y < height; ++y) {
      for(UINTN x = 0; x < width; ++x) {
            BltBuffer = color;
      }
    }
}

EFI_STATUS EFIAPI efi_main(EFI_HANDLE *ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
    EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
    EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
    SystemTable->BootServices->LocateProtocol(&gop_guid, NULL, (VOID **)&GraphicsOutput);
    info(SystemTable, GraphicsOutput);
    fill_screen(SystemTable, GraphicsOutput);
    kgetc(SystemTable);
    return EFI_SUCCESS;
}

2wsx 发表于 2022-10-19 08:03:46

人造人 发表于 2022-10-19 01:00
printf函数过于复杂,我现在依然写不出来
不浪费时间了,这个函数之后再研究吧
我再研究研究efi编程,然 ...

OK 感谢

人造人 发表于 2022-10-22 00:03:29

好了,uefi编程的研究到此为止,接下来帮你研究smbios
下面是我目前的研究成果,有兴趣的话你可以看看

$ cat main.c
#include <efi.h>

#define print_variable(SystemTable, base, value) \
    kputs(SystemTable, L"" #value ": "); print_##base(SystemTable, value)

void swap(CHAR16 *a, CHAR16 *b) {
    CHAR16 temp = *a;
    *a = *b;
    *b = temp;
}

CHAR16 kgetc(EFI_SYSTEM_TABLE *SystemTable) {
    EFI_INPUT_KEY key;
    SystemTable->BootServices->WaitForEvent(1, &SystemTable->ConIn->WaitForKey, NULL);
    SystemTable->ConIn->ReadKeyStroke(SystemTable->ConIn, &key);
    if(key.UnicodeChar == '\r') key.UnicodeChar = '\n';
    return key.UnicodeChar;
}

void kputc(EFI_SYSTEM_TABLE *SystemTable, CHAR16 c) {
    if(c == L'\n') kputc(SystemTable, L'\r');
    CHAR16 str = {c, '\0'};
    SystemTable->ConOut->OutputString(SystemTable->ConOut, str);
}

void kputs(EFI_SYSTEM_TABLE *SystemTable, const CHAR16 *str) {
    for(UINTN i = 0; str; ++i) {
      kputc(SystemTable, str);
    }
}

void number(CHAR16 *buff, UINTN value, UINTN base) {
    static const CHAR16 table = L"0123456789abcdef";
    if(base > 16) base = 16;
    CHAR16 *p = buff;
    do {
      *p++ = table;
      value /= base;
    } while(value);
    *p = L'\0';
    UINTN count = p - buff;
    for(UINTN i = 0; i < count / 2; ++i) {
      swap(&buff, &buff);
    }
}

void print_dec(EFI_SYSTEM_TABLE *SystemTable, UINTN value) {
    CHAR16 buff; number(buff, value, 10); kputs(SystemTable, buff); kputc(SystemTable, L'\n');
}

void print_hex(EFI_SYSTEM_TABLE *SystemTable, UINTN value) {
    CHAR16 buff; number(buff, value, 16); kputs(SystemTable, buff); kputc(SystemTable, L'\n');
}

void info_graphics(EFI_SYSTEM_TABLE *SystemTable, EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput) {
    kputs(SystemTable, L"FrameBufferBase: "); print_hex(SystemTable, GraphicsOutput->Mode->FrameBufferBase);
    kputs(SystemTable, L"FrameBufferSize: "); print_dec(SystemTable, GraphicsOutput->Mode->FrameBufferSize);
    kputs(SystemTable, L"FrameBufferSize: "); print_hex(SystemTable, GraphicsOutput->Mode->FrameBufferSize);
    kputs(SystemTable, L"MaxMode: "); print_dec(SystemTable, GraphicsOutput->Mode->MaxMode);
    kputs(SystemTable, L"Mode: "); print_dec(SystemTable, GraphicsOutput->Mode->Mode);
    kputs(SystemTable, L"SizeOfInfo: "); print_dec(SystemTable, GraphicsOutput->Mode->SizeOfInfo);
    kputs(SystemTable, L"HorizontalResolution: "); print_dec(SystemTable, GraphicsOutput->Mode->Info->HorizontalResolution);
    kputs(SystemTable, L"PixelsPerScanLine: "); print_dec(SystemTable, GraphicsOutput->Mode->Info->PixelsPerScanLine);
    kputs(SystemTable, L"PixelFormat: "); print_dec(SystemTable, GraphicsOutput->Mode->Info->PixelFormat);
    kputs(SystemTable, L"Version: "); print_dec(SystemTable, GraphicsOutput->Mode->Info->Version);
    kputs(SystemTable, L"VerticalResolution: "); print_dec(SystemTable, GraphicsOutput->Mode->Info->VerticalResolution);
    kputs(SystemTable, L"BlueMask: "); print_dec(SystemTable, GraphicsOutput->Mode->Info->PixelInformation.BlueMask);
    kputs(SystemTable, L"GreenMask: "); print_dec(SystemTable, GraphicsOutput->Mode->Info->PixelInformation.GreenMask);
    kputs(SystemTable, L"RedMask: "); print_dec(SystemTable, GraphicsOutput->Mode->Info->PixelInformation.RedMask);
    kputs(SystemTable, L"ReservedMask: "); print_dec(SystemTable, GraphicsOutput->Mode->Info->PixelInformation.ReservedMask);
    kgetc(SystemTable);
    for(UINTN i = 0; i < GraphicsOutput->Mode->MaxMode; ++i) {
      kputs(SystemTable, L"i: "); print_dec(SystemTable, i);
      EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *GraphicsOutputMode;
      UINTN SizeOfInfo;
      GraphicsOutput->QueryMode(GraphicsOutput, i, &SizeOfInfo, &GraphicsOutputMode);
      kputs(SystemTable, L"SizeOfInfo: "); print_dec(SystemTable, SizeOfInfo);
      kputs(SystemTable, L"HorizontalResolution: "); print_dec(SystemTable, GraphicsOutputMode->HorizontalResolution);
      kputs(SystemTable, L"PixelsPerScanLine: "); print_dec(SystemTable, GraphicsOutputMode->PixelsPerScanLine);
      kputs(SystemTable, L"PixelFormat: "); print_dec(SystemTable, GraphicsOutputMode->PixelFormat);
      kputs(SystemTable, L"Version: "); print_dec(SystemTable, GraphicsOutputMode->Version);
      kputs(SystemTable, L"VerticalResolution: "); print_dec(SystemTable, GraphicsOutputMode->VerticalResolution);
      kputs(SystemTable, L"BlueMask: "); print_dec(SystemTable, GraphicsOutputMode->PixelInformation.BlueMask);
      kputs(SystemTable, L"GreenMask: "); print_dec(SystemTable, GraphicsOutputMode->PixelInformation.GreenMask);
      kputs(SystemTable, L"RedMask: "); print_dec(SystemTable, GraphicsOutputMode->PixelInformation.RedMask);
      kputs(SystemTable, L"ReservedMask: "); print_dec(SystemTable, GraphicsOutputMode->PixelInformation.ReservedMask);
      kgetc(SystemTable);
    }
}

void fill_screen(EFI_SYSTEM_TABLE *SystemTable, EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput) {
    //GraphicsOutput->SetMode(GraphicsOutput, 22);    // 1920x1080
    GraphicsOutput->SetMode(GraphicsOutput, 18);    // 1440x900
    EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)GraphicsOutput->Mode->FrameBufferBase;
    UINTN height = GraphicsOutput->Mode->Info->VerticalResolution;
    UINTN width = GraphicsOutput->Mode->Info->HorizontalResolution;
    EFI_GRAPHICS_OUTPUT_BLT_PIXEL color = {255, 255, 255};
    for(UINTN y = 0; y < height; ++y) {
      for(UINTN x = 0; x < width; ++x) {
            BltBuffer = color;
      }
    }
}

void graphics(EFI_SYSTEM_TABLE *SystemTable) {
    EFI_GUID guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
    EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
    SystemTable->BootServices->LocateProtocol(&guid, NULL, (VOID **)&GraphicsOutput);
    info_graphics(SystemTable, GraphicsOutput);
    kgetc(SystemTable);
    fill_screen(SystemTable, GraphicsOutput);
    kgetc(SystemTable);
}

void info_mouse(EFI_SYSTEM_TABLE *SystemTable, EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer) {
    kputs(SystemTable, L"ResolutionX: "); print_hex(SystemTable, SimplePointer->Mode->ResolutionX);
    kputs(SystemTable, L"ResolutionY: "); print_hex(SystemTable, SimplePointer->Mode->ResolutionY);
    kputs(SystemTable, L"ResolutionZ: "); print_hex(SystemTable, SimplePointer->Mode->ResolutionZ);
    kputs(SystemTable, L"LeftButton: "); print_hex(SystemTable, SimplePointer->Mode->LeftButton);
    kputs(SystemTable, L"RightButton: "); print_hex(SystemTable, SimplePointer->Mode->RightButton);
}

void mouse_input(EFI_SYSTEM_TABLE *SystemTable) {
    EFI_GUID guid = EFI_SIMPLE_POINTER_PROTOCOL_GUID;
    EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer;
    SystemTable->BootServices->LocateProtocol(&guid, NULL, (VOID **)&SimplePointer);
    info_mouse(SystemTable, SimplePointer);

    UINTN count = 100;
    EFI_SIMPLE_POINTER_STATE State;
    while(count--) {
      kputs(SystemTable, L"count: "); print_hex(SystemTable, count);
      SystemTable->BootServices->WaitForEvent(1, &SimplePointer->WaitForInput, NULL);
      SimplePointer->GetState(SimplePointer, &State);
      kputs(SystemTable, L"RelativeMovementX: "); print_hex(SystemTable, State.RelativeMovementX);
      kputs(SystemTable, L"RelativeMovementY: "); print_hex(SystemTable, State.RelativeMovementY);
      kputs(SystemTable, L"RelativeMovementZ: "); print_hex(SystemTable, State.RelativeMovementZ);
      kputs(SystemTable, L"LeftButton: "); print_hex(SystemTable, State.LeftButton);
      kputs(SystemTable, L"RightButton: "); print_hex(SystemTable, State.RightButton);
    }
}

void info_st(EFI_SYSTEM_TABLE *SystemTable) {
    kputs(SystemTable, L"FirmwareVendor: "); kputs(SystemTable, SystemTable->FirmwareVendor); kputc(SystemTable, L'\n');
    print_variable(SystemTable, hex, SystemTable->ConOut->Mode->Mode);
    print_variable(SystemTable, hex, SystemTable->ConOut->Mode->MaxMode);
    print_variable(SystemTable, hex, SystemTable->ConOut->Mode->Attribute);
    print_variable(SystemTable, hex, SystemTable->ConOut->Mode->CursorColumn);
    print_variable(SystemTable, hex, SystemTable->ConOut->Mode->CursorRow);
    print_variable(SystemTable, hex, SystemTable->ConOut->Mode->CursorVisible);
    print_variable(SystemTable, hex, SystemTable->NumberOfTableEntries);
    for(UINTN i = 0; i < SystemTable->ConOut->Mode->MaxMode; ++i) {
      print_variable(SystemTable, hex, i);
      UINTN Columns, Rows;
      SystemTable->ConOut->QueryMode(SystemTable->ConOut, i, &Columns, &Rows);
      print_variable(SystemTable, hex, Columns);
      print_variable(SystemTable, hex, Rows);
    }
    for(UINTN b = 0x00; b <= 0x70; b += 0x10) {
      for(UINTN f = 0x00; f <= 0x0f; ++f) {
            SystemTable->ConOut->SetAttribute(SystemTable->ConOut, b | f);
            kputs(SystemTable, L"hello world!\n");
            kgetc(SystemTable);
      }
    }
}

EFI_STATUS EFIAPI efi_main(EFI_HANDLE *ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
    graphics(SystemTable);
    mouse_input(SystemTable);
    info_st(SystemTable);
    kgetc(SystemTable);
    return EFI_SUCCESS;
}
$ x86_64-w64-mingw32-gcc -Wall -e efi_main -nostdlib -fno-builtin -Wl,--subsystem,10 -I /usr/include/efi -I /usr/include/efi/x86_64 -I /usr/include/efi/protocol -o main.efi main.c
$

人造人 发表于 2022-10-28 16:25:14

下面代码输出smbios中的相当一少部分信息
因为smbios里面的信息是真的非常非常的多
我使用的这个库(gnu-efi)只写了很少一部分struct
我当然可以选择自己照着标准文档写,也可以选择复制 dmidecode 中的struct定义,我想 dmidecode 里面应该有这些定义吧,不然他怎么解析smbios
不过吗,我并不是要写一个类似 dmidecode 的软件,就不这么整了,有什么就写什么吧(其实就是因为嫌麻烦,^_^)

#include <efi.h>
#include <libsmbios.h>

#define print_variable(SystemTable, base, value) \
    kputs(SystemTable, L"" #value ": "); print_##base(SystemTable, value); kputc(SystemTable, L'\n')

void swap(CHAR16 *a, CHAR16 *b) {
    CHAR16 temp = *a;
    *a = *b;
    *b = temp;
}

CHAR16 kgetc(EFI_SYSTEM_TABLE *SystemTable) {
    EFI_INPUT_KEY key;
    SystemTable->BootServices->WaitForEvent(1, &SystemTable->ConIn->WaitForKey, NULL);
    SystemTable->ConIn->ReadKeyStroke(SystemTable->ConIn, &key);
    if(key.UnicodeChar == '\r') key.UnicodeChar = '\n';
    return key.UnicodeChar;
}

void kputc(EFI_SYSTEM_TABLE *SystemTable, CHAR16 c) {
    if(c == L'\n') kputc(SystemTable, L'\r');
    CHAR16 str = {c, '\0'};
    SystemTable->ConOut->OutputString(SystemTable->ConOut, str);
}

void kputs(EFI_SYSTEM_TABLE *SystemTable, const CHAR16 *str) {
    for(UINTN i = 0; str; ++i) {
      kputc(SystemTable, str);
    }
}

void number(CHAR16 *buff, UINTN value, UINTN base) {
    static const CHAR16 table = L"0123456789abcdef";
    if(base > 16) base = 16;
    CHAR16 *p = buff;
    do {
      *p++ = table;
      value /= base;
    } while(value);
    *p = L'\0';
    UINTN count = p - buff;
    for(UINTN i = 0; i < count / 2; ++i) {
      swap(&buff, &buff);
    }
}

void print_dec(EFI_SYSTEM_TABLE *SystemTable, UINTN value) {
    CHAR16 buff; number(buff, value, 10); kputs(SystemTable, buff);
}

void print_hex(EFI_SYSTEM_TABLE *SystemTable, UINTN value) {
    CHAR16 buff; number(buff, value, 16); kputs(SystemTable, buff);
}

/*
typedef struct {
    UINT32Data1;
    UINT16Data2;
    UINT16Data3;
    UINT8   Data4;
} EFI_GUID;
*/
BOOLEAN compare_guid(const EFI_GUID *a, const EFI_GUID *b) {
    if(a->Data1 != b->Data1) return FALSE;
    if(a->Data2 != b->Data2) return FALSE;
    if(a->Data3 != b->Data3) return FALSE;
    for(UINTN i = 0; i < 8; ++i) {
      if(a->Data4 != b->Data4) return FALSE;
    }
    return TRUE;
}

void print_guid(EFI_SYSTEM_TABLE *SystemTable, const EFI_GUID *guid) {
    const UINT8 *base = (const UINT8 *)guid;
    kputc(SystemTable, L'{');
    BOOLEAN flag = FALSE;
    for(UINTN i = 0; i < 16; ++i) {
      if(flag) kputs(SystemTable, L", ");
      flag = TRUE;
      print_hex(SystemTable, base);
    }
    kputc(SystemTable, L'}');
}

UINT8 *print_smbios_string(EFI_SYSTEM_TABLE *SystemTable, UINT8 *str) {
    if(!*str) ++str;
    for(UINTN i = 1; ; ++i) {
      if(!*str) break;
      print_dec(SystemTable, i);
      kputs(SystemTable, L": ");
      while(*str) kputc(SystemTable, *str++);
      kputc(SystemTable, L'\n');
      ++str;
    }
    return str + 1;
}

void print_smbios_header(EFI_SYSTEM_TABLE *SystemTable, const SMBIOS_HEADER *hdr) {
    print_variable(SystemTable, hex, hdr->Type);
    print_variable(SystemTable, hex, hdr->Length);
    print_variable(SystemTable, hex, *(UINT16 *)&hdr->Handle);
}

void *bios_information(EFI_SYSTEM_TABLE *SystemTable, void *base) {
    SMBIOS_TYPE0 *st0 = base;
    kputc(SystemTable, L'\n');
    print_smbios_header(SystemTable, &st0->Hdr);
    print_variable(SystemTable, hex, st0->Vendor);
    print_variable(SystemTable, hex, st0->BiosVersion);
    print_variable(SystemTable, hex, *(UINT16 *)&st0->BiosSegment);
    print_variable(SystemTable, hex, st0->BiosReleaseDate);
    print_variable(SystemTable, hex, st0->BiosSize);
    print_variable(SystemTable, hex, st0->BiosCharacteristics);
    print_variable(SystemTable, hex, st0->BiosCharacteristics);
    print_variable(SystemTable, hex, st0->BiosCharacteristics);
    print_variable(SystemTable, hex, st0->BiosCharacteristics);
    print_variable(SystemTable, hex, st0->BiosCharacteristics);
    print_variable(SystemTable, hex, st0->BiosCharacteristics);
    print_variable(SystemTable, hex, st0->BiosCharacteristics);
    print_variable(SystemTable, hex, st0->BiosCharacteristics);
    return print_smbios_string(SystemTable, base + st0->Hdr.Length);
}

void *system_information(EFI_SYSTEM_TABLE *SystemTable, void *base) {
    SMBIOS_TYPE1 *st1 = base;
    kputc(SystemTable, L'\n');
    print_smbios_header(SystemTable, &st1->Hdr);
    print_variable(SystemTable, hex, st1->Manufacturer);
    print_variable(SystemTable, hex, st1->ProductName);
    print_variable(SystemTable, hex, st1->Version);
    print_variable(SystemTable, hex, st1->SerialNumber);
    print_guid(SystemTable, &st1->Uuid); kputc(SystemTable, L'\n');
    print_variable(SystemTable, hex, st1->WakeUpType);
    return print_smbios_string(SystemTable, base + st1->Hdr.Length);
}

void *baseboard_information(EFI_SYSTEM_TABLE *SystemTable, void *base) {
    SMBIOS_TYPE2 *st2 = base;
    kputc(SystemTable, L'\n');
    print_smbios_header(SystemTable, &st2->Hdr);
    print_variable(SystemTable, hex, st2->Manufacturer);
    print_variable(SystemTable, hex, st2->ProductName);
    print_variable(SystemTable, hex, st2->Version);
    print_variable(SystemTable, hex, st2->SerialNumber);
    return print_smbios_string(SystemTable, base + st2->Hdr.Length);
}

void *system_enclosure(EFI_SYSTEM_TABLE *SystemTable, void *base) {
    SMBIOS_TYPE3 *st3 = base;
    kputc(SystemTable, L'\n');
    print_smbios_header(SystemTable, &st3->Hdr);
    print_variable(SystemTable, hex, st3->Manufacturer);
    print_variable(SystemTable, hex, st3->Type);
    print_variable(SystemTable, hex, st3->Version);
    print_variable(SystemTable, hex, st3->SerialNumber);
    print_variable(SystemTable, hex, st3->AssetTag);
    print_variable(SystemTable, hex, st3->BootupState);
    print_variable(SystemTable, hex, st3->PowerSupplyState);
    print_variable(SystemTable, hex, st3->ThermalState);
    print_variable(SystemTable, hex, st3->SecurityStatus);
    print_variable(SystemTable, hex, *(UINT32 *)&st3->OemDefined);
    return print_smbios_string(SystemTable, base + st3->Hdr.Length);
}

void *processor_information(EFI_SYSTEM_TABLE *SystemTable, void *base) {
    SMBIOS_TYPE4 *st4 = base;
    kputc(SystemTable, L'\n');
    print_smbios_header(SystemTable, &st4->Hdr);
    print_variable(SystemTable, hex, st4->Socket);
    print_variable(SystemTable, hex, st4->ProcessorType);
    print_variable(SystemTable, hex, st4->ProcessorFamily);
    print_variable(SystemTable, hex, st4->ProcessorId);
    print_variable(SystemTable, hex, st4->ProcessorId);
    print_variable(SystemTable, hex, st4->ProcessorId);
    print_variable(SystemTable, hex, st4->ProcessorId);
    print_variable(SystemTable, hex, st4->ProcessorId);
    print_variable(SystemTable, hex, st4->ProcessorId);
    print_variable(SystemTable, hex, st4->ProcessorId);
    print_variable(SystemTable, hex, st4->ProcessorId);
    print_variable(SystemTable, hex, st4->ProcessorVersion);
    print_variable(SystemTable, hex, st4->Voltage);
    print_variable(SystemTable, hex, *(UINT16 *)&st4->ExternalClock);
    print_variable(SystemTable, hex, *(UINT16 *)&st4->MaxSpeed);
    print_variable(SystemTable, hex, *(UINT16 *)&st4->CurrentSpeed);
    print_variable(SystemTable, hex, st4->Status);
    print_variable(SystemTable, hex, st4->ProcessorUpgrade);
    print_variable(SystemTable, hex, *(UINT16 *)&st4->L1CacheHandle);
    print_variable(SystemTable, hex, *(UINT16 *)&st4->L2CacheHandle);
    print_variable(SystemTable, hex, *(UINT16 *)&st4->L3CacheHandle);
    return print_smbios_string(SystemTable, base + st4->Hdr.Length);
}

void *unknown_type(EFI_SYSTEM_TABLE *SystemTable, void *base) {
    SMBIOS_HEADER *hdr = base;
    kputc(SystemTable, L'\n');
    print_smbios_header(SystemTable, hdr);
    return print_smbios_string(SystemTable, base + hdr->Length);
}

void info_eps(EFI_SYSTEM_TABLE *SystemTable) {
    EFI_GUID smbios_guid = SMBIOS_TABLE_GUID;
    EFI_GUID smbios3_guid = SMBIOS3_TABLE_GUID;
    EFI_GUID mps_guid = MPS_TABLE_GUID;
    EFI_GUID acpi_guid = ACPI_TABLE_GUID;
    EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID;
    EFI_GUID sal_system_guid = SAL_SYSTEM_TABLE_GUID;
    EFI_GUID dtb_guid = EFI_DTB_TABLE_GUID;
    SMBIOS_STRUCTURE_TABLE *smbios_header = NULL;
    for(UINTN i = 0; i < SystemTable->NumberOfTableEntries; ++i) {
      if(compare_guid(&SystemTable->ConfigurationTable.VendorGuid, &smbios_guid)) {
            kputs(SystemTable, L"SMBIOS_TABLE_GUID: ");
            smbios_header = SystemTable->ConfigurationTable.VendorTable;
      }
      if(compare_guid(&SystemTable->ConfigurationTable.VendorGuid, &smbios3_guid)) kputs(SystemTable, L"SMBIOS3_TABLE_GUID: ");
      if(compare_guid(&SystemTable->ConfigurationTable.VendorGuid, &mps_guid)) kputs(SystemTable, L"MPS_TABLE_GUID: ");
      if(compare_guid(&SystemTable->ConfigurationTable.VendorGuid, &acpi_guid)) kputs(SystemTable, L"ACPI_TABLE_GUID: ");
      if(compare_guid(&SystemTable->ConfigurationTable.VendorGuid, &acpi20_guid)) kputs(SystemTable, L"ACPI_20_TABLE_GUID: ");
      if(compare_guid(&SystemTable->ConfigurationTable.VendorGuid, &sal_system_guid)) kputs(SystemTable, L"SAL_SYSTEM_TABLE_GUID: ");
      if(compare_guid(&SystemTable->ConfigurationTable.VendorGuid, &dtb_guid)) kputs(SystemTable, L"EFI_DTB_TABLE_GUID: ");
      print_guid(SystemTable, &SystemTable->ConfigurationTable.VendorGuid); kputc(SystemTable, L'\n');
    }
    if(!smbios_header) return;
    kputs(SystemTable, L"AnchorString: \"");
    kputc(SystemTable, smbios_header->AnchorString);
    kputc(SystemTable, smbios_header->AnchorString);
    kputc(SystemTable, smbios_header->AnchorString);
    kputc(SystemTable, smbios_header->AnchorString);
    kputs(SystemTable, L"\"\n");
    print_variable(SystemTable, hex, smbios_header->EntryPointStructureChecksum);
    print_variable(SystemTable, hex, smbios_header->EntryPointLength);
    print_variable(SystemTable, hex, smbios_header->MajorVersion);
    print_variable(SystemTable, hex, smbios_header->MinorVersion);
    print_variable(SystemTable, hex, smbios_header->MaxStructureSize);
    print_variable(SystemTable, hex, smbios_header->EntryPointRevision);
    print_variable(SystemTable, hex, smbios_header->IntermediateChecksum);
    print_variable(SystemTable, hex, smbios_header->TableLength);
    print_variable(SystemTable, hex, smbios_header->TableAddress);
    print_variable(SystemTable, hex, smbios_header->NumberOfSmbiosStructures);
    print_variable(SystemTable, hex, smbios_header->SmbiosBcdRevision);
    kputs(SystemTable, L"IntermediateAnchorString: \"");
    kputc(SystemTable, smbios_header->IntermediateAnchorString);
    kputc(SystemTable, smbios_header->IntermediateAnchorString);
    kputc(SystemTable, smbios_header->IntermediateAnchorString);
    kputc(SystemTable, smbios_header->IntermediateAnchorString);
    kputc(SystemTable, smbios_header->IntermediateAnchorString);
    kputs(SystemTable, L"\"\n");
    print_variable(SystemTable, hex, smbios_header->FormattedArea);
    print_variable(SystemTable, hex, smbios_header->FormattedArea);
    print_variable(SystemTable, hex, smbios_header->FormattedArea);
    print_variable(SystemTable, hex, smbios_header->FormattedArea);
    print_variable(SystemTable, hex, smbios_header->FormattedArea);
    UINT8 *next = (UINT8 *)(UINT64)smbios_header->TableAddress;
    for(UINTN i = 0; i < smbios_header->NumberOfSmbiosStructures; ++i) {
      switch(*next) {
            case 0: next = bios_information(SystemTable, next); break;
            case 1: next = system_information(SystemTable, next); break;
            case 2: next = baseboard_information(SystemTable, next); break;
            case 3: next = system_enclosure(SystemTable, next); break;
            case 4: next = processor_information(SystemTable, next); break;
            default: next = unknown_type(SystemTable, next);
      }
      kgetc(SystemTable);
    }
}

EFI_STATUS EFIAPI efi_main(EFI_HANDLE *ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
    info_eps(SystemTable);
    kgetc(SystemTable);
    return EFI_SUCCESS;
}

人造人 发表于 2022-10-28 16:58:32

2wsx 发表于 2022-10-13 16:23
大佬 你了解SMBIOS吗?我目前是希望写代码读取SMBIOS的任意的Type,并将其Handle打印出来,读取任意一个 ...

接下来再帮你研究研究pci配置空间
页: [1]
查看完整版本: 如何将.c文件在UEFI系统中编译并且运行?