不用EDK2超简单的uefi开发环境搭建(适合业余开发)包涵启动盘制作和真机运行helloworld教程

介绍:

本文将介绍一种非常简单的uefi开发环境的搭建,不同于EDK2这种搭建方式,EDK2更适用于专业人士。下面我将介绍一种简单的适用于业余人士的开发环境搭建,以及如何写一个能在真机上运行的hello world程序。如果你仅仅是想写一个uefi引导的标准程序的话看这篇就够了。
https://kagurazakakotori.github.io/ubmp-cn/index.html有一部分借鉴了这里面的内容

工具

推荐用Linux环境,我用的是Ubuntu
必须的工具:gcc编译器,一个文本编辑器
能让你更方便的工具:qemu虚拟机(QEMU默认不带有UEFI固件,我们需要手动安装OVMF(Open Virtual Machine Firmware)软件包)GNUmake

步骤

,基本步骤
1.安装gcc编译器
打开终端并输入 sudo apt install gcc-mingw-w64-x86-64

2.使用一款你喜欢的文本编辑器(其实Ubuntu自带的文本编辑器就够用了)
新建一个main.c文件并写入以下程序代码

struct EFI_SYSTEM_TABLE {
    char _buf[60];
    struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL {
        unsigned long long _buf;
        unsigned long long (*OutputString)(
            struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
            unsigned short *String);
        unsigned long long _buf2[4];
        unsigned long long (*ClearScreen)(
            struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This);
    } * ConOut;
};

void efi_main(void *ImageHandle __attribute__((unused)), struct EFI_SYSTEM_TABLE *SystemTable)
{
    SystemTable->ConOut->ClearScreen(SystemTable->ConOut);
    SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Hello world!\r\n");
    while (1)
        __asm__ __volatile__("HLT");
}

下面我来说明一下这部分代码,如果你了解UEFI开发可以跳过。
这些代码应该不难看懂,我们在这里定义了一个入口函数efi_main(),UEFI标准文档中有一个叫做“协议(Protocol)”的概念。在UEFI中,各种功能被分为一个个被称为“协议”的单元,并且它们被定义成以_PROTOCOL结尾的结构体。名如~_PROTOCOL这样的结构体包含一系列的函数指针,通过这些函数指针可以调用UEFI固件中的内置功能。UEFI中的有一些常用功能在EFI_SYSTEM_TABLE这个结构体里面,比如我们显示字符要用的OutputString()函数。在上面对结构体EFI_SYSTEM_TABLE的声明时你会看到一些数组,这些数组是用来占位的,因为有些函数我们用不上,没必要声明,但是如果不占位就无法找到正确的函数。在这个程序中我们用到了两个函数,分别是ClearScreen()和OutputString()函数,前者是用来清屏(清除开机logo)的后者是用来显示字符的,他们都需要传入一个指向自身所属protocol的指针,OutputString()函数还需要传入一个字符串。显示完字符串后,下面有一个无限循环,里面用了一个gcc内嵌汇编语句执行HLT休眠cpu。

3.将这些代码保存并用以下命令编译
x86_64-w64-mingw32-gcc -Wall -Wextra -e efi_main -nostdinc -nostdlib -fno-builtin -Wl,–subsystem,10 -o main.efi main.c
(其中-e参数是用来指定入口函数的名称的,也就是说我们的uefi程序将首先从这个函数执行,–subsystem,10是用来告诉编译器将生成的可执行文件类型设置为UEFI应用程序。得到的main.efi就是PE32+格式的UEFI可执行文件。)之后将会生成一个main.efi文件,到此为止我们就完成了一个uefi程序的编译编译完后生成.efi文件

4.下面我来讲一下如何制作启动盘以便在真机上运行。
将生成的main.efi 文件重命名成BOOTX64.EFI(注意大小写)。然后准备一个FAT格式的储存介质可以是U盘,如果不是FAT请先格式化一下,建议直接使用Ubuntu下的磁盘工具。然后在U盘中创建以下目录EFI/BOOT,并将刚才的BOOTX64.EFI文件放进BOOT文件夹下。到此为止启动盘的制作就完成了,现在你可以拔出U盘并插在支持uefi的64位电脑上运行(电脑开机时进入启动菜单的快捷键就请自行查找吧,不同的电脑不一样)。
运行效果
看到这里估计你就会发现UEFI引导的特点,UEFI识别一个盘里是否有可执行文件的方式较legacy BIOS来讲明显要高级许多,legacy BIOS是通过识别盘里第一个扇区是否有相应的标识符,而UEFI是能够认识文件系统的,操作系统启动程序被放在FAT格式的硬盘的相应目录下,启动时UEFI会进入指定目录查看是否有可执行文件。

让开发更便捷

如果你想要更方便地随时运行UEFI程序,可以按照以下命令安装qemu虚拟机和相应的OVMF软件包
sudo apt install qemu-system-x86 ovmf
同时想要让编译和运行虚拟机更加方便的话,可以使用Makefile,GNUmake这么常用的软件基本上人人电脑里都有,安装也很简单,就不多说了。你可以从以下链接中下载一套示例源代码,包含写好的makefile(由文前链接提供,非笔者所写)
https://github.com/kagurazakakotori/ubmp-cn-code
在baremetal文件夹下是每个示例代码的文件夹,随意进入一个文件夹,在该路径执行make run就可以自动编译并启动虚拟机运行。

感谢阅读

如果你想更加深入的学习UEFI开发,可以学学文前链接中的东西。本人才疏学浅,如有疏漏请指正,专家勿喷!

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值