最近在 Porting 一段代码的时候有使用到 fread(),但是非常奇怪的是一直无法正常工作,得到的错误返回值一直为0。后来在网上找到Robins_Lee 的文章提到了这个问题https://blog.csdn.net/mini92/article/details/79274823。原来新的EDK2中,需要在INF [LibraryClasses] 中加入 DevShell 才行。
对于这个要求在 \StdLib\ReadMe.txt 有描述如下:
Figure 5: Package Build Options
===============================
INF Files
=========
The INF files for most modules will not require special directives in order to
support the Standard Libraries. The two sections which require attention: LibraryClasses
and BuildOptions, are described below.
[LibraryClasses]
UefiLib
LibC
LibString
LibStdio
DevShell
Figure 6: Module Library Classes
================================
Modules of type UEFI_APPLICATION that perform file I/O must include library
class DevShell. Including this library class will allow file operations to be
handled by the UEFI Shell. Without this class, only Console I/O is supported.
An application's INF file might need to include a [BuildOptions] section
specifying additional compiler and linker flags necessary to allow the
application to be built. Usually, this section is not needed. When building
code from external sources, though, it may be necessary to disable some
warnings or enable/disable some compiler features.
[BuildOptions]
INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
MSFT:*_*_*_CC_FLAGS = /Oi- /wd4018 /wd4131
GCC:*_*_IPF_SYMRENAME_FLAGS = --redefine-syms=Rename.txt
编写测试代码:
#include <uefi.h> #include <Library/UefiLib.h> #include<stdio.h> #include<string.h> #include<stdlib.h> #include <errno.h> #include<wchar.h> int main ( IN int Argc, IN char *Argv[] ) { FILE *fd; char text[100]; if (Argc<2) { printf("Please input filename\n"); exit(1); } if ((fd = fopen(Argv[1], "rb")) == NULL) { printf("open file failed. %s\n", strerror(errno)); exit(1); } memset(text,0,sizeof(text)); fread(text, sizeof(char), 100, fd); printf("%s\n", text); fclose(fd); return 0; }
[Defines] INF_VERSION = 0x00010006 BASE_NAME = fot FILE_GUID = 4ea97c46-0995-4dfd-b442-747010f3ce5f MODULE_TYPE = UEFI_APPLICATION VERSION_STRING = 0.1 ENTRY_POINT = ShellCEntryLib # # VALID_ARCHITECTURES = IA32 X64 # [Sources] fopentest.c [Packages] StdLib/StdLib.dec MdePkg/MdePkg.dec ShellPkg/ShellPkg.dec [LibraryClasses] LibC LibStdio UefiLib DevShell
运行结果:
完整代码:
fopentest
本人就是Robins_lee,
这个问题从去年10月份困扰了我近半年,
最开始在这个这里提问没人答复,
后面又问过很多有好多年UEFI开发经验的人
最后自己一点点看英文资料,得到一位台湾的做BIOS kernel的工程师的提示 才找到解决方案,
愤尔发写个博客,
鄙视那种自己知道答案,藏着捂着的人
感谢你的答案。不过这种东西只有遇到才会去研究........
我觉得应该批评一下Intel 写kernel 的人,没事瞎改.......
印象中我去年用 UDK2014 就不行了
後來就在 ReadMe.txt 找到答案
雖然它的 ReadMe.txt 很簡陋
但我覺得很有 Linux 早期 readme.txt 的 fu
只有幾頁也讓人比較想看
我也是靠它的 ReadMe.txt
成功 build 出 Python.efi
不得不說用 Python 在 UEFI 寫 application 是簡單多了
不過我沒有需要控制硬體
不然原生 Python 是不支援的