一、概述
本文主要介绍UEFI下基本的文件格式内容如.dec、.inf、.dsc等,驱动的调用流程,代码规范。
二、代码规范
2.1 EFI_STATUS
EFI_STATUS 是一个返回状态码类型,用来表示函数执行结果
底层通常是 UINTN(无符号整数)
EFI_STATUS mmc_write(…)
常见返回值
| 值 | 含义 |
|---|---|
| EFI_SUCCESS | 成功 |
| EFI_INVALID_PARAMETER | 参数错误 |
| EFI_DEVICE_ERROR | 设备错误 |
| EFI_TIMEOUT | 超时 |
| EFI_MEDIA_CHANGED | 介质变化 |
2.2 IN / OUT / OPTIONAL
宏定义(通常为空)
IN EFI_BLOCK_IO_PROTOCOL *This
OUT VOID *Buffer
IN
IN UINT32 MediaId
含义:输入参数(函数只读,不修改)
实际:
#define IN
编译器完全忽略,只是给人看的
OUT
OUT VOID *Buffer
含义:输出参数(函数会写这个变量)
实际:
#define OUT
IN OUT
表示:既输入又输出(可读可写)
OPTIONAL
表示:这个参数可以为 NULL
三、DXE加载驱动流程
3.1 ENTRY_POINT
ENTRY_POINT = MmcDxeInitialize 是 UEFI 模块(INF文件)中的一个关键字段,它的含义可以一句话概括:
指定这个DXE驱动被加载时,首先执行的入口函数
一、ENTRY_POINT的本质
在 UEFI 的 .inf 文件中:
ENTRY_POINT = MmcDxeInitialize
表示:当这个 MMC DXE 驱动被 DXE Core 加载时,会调用ENTRY_POINT
二、调用流程
发生在 DXE阶段驱动加载时
完整时序:
3.2 驱动代码解析
以MMC驱动加载整体流程:
3.2.1 gMmcDriverBinding整体结构
EFI_STATUS
MmcDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
3.2.2 初始化流程
Step 1:打开 Host Controller
OpenProtocol(… gEfiSdMmcHostControllerProtocolGuid …)
获取底层控制器操作接口(类似 Linux host driver)
Step 2:初始化 MMC Host
通常会做:
Reset controller
设置时钟
配置 bus width
Power on
对应底层函数类似:
MmcHost->Reset()
MmcHost->SetClock()
MmcHost->SetBusWidth()
Step 3:卡初始化(非常关键)
调用类似:
MmcIdentification()
内部流程(标准 SD/MMC 初始化):
CMD0 -> GO_IDLE_STATE
CMD1 -> SEND_OP_COND
CMD2 -> ALL_SEND_CID
CMD3 -> SET_RELATIVE_ADDR
CMD7 -> SELECT_CARD
CMD9 -> SEND_CSD
CMD16 -> SET_BLOCKLEN
这一步完成:
卡识别
RCA 分配
工作模式确定(SD / MMC / SDHC)
Step 4:创建 Block I/O 设备
InstallProtocolInterface(
&gEfiBlockIoProtocolGuid
)
之后系统就可以:
把 MMC 当磁盘使用
FAT 文件系统访问
Step 5:安装 Device Path
gEfiDevicePathProtocolGuid
用于系统识别设备路径(fs0:, blk0 等)
3.2.3 Stop阶段(卸载)
MmcDriverBindingStop()
做的事情:
Uninstall BlockIo
关闭 Host Controller
Free资源
四、 .dec、.inf、.dsc、.uni 、 .fdf解析
三个核心文件(总览)
Package(.dec)
↓
Module(.inf)
↓
Platform(.dsc)
可以理解为:
资源定义 → 模块描述 → 平台整合
4.1 .dec 文件
DEC = Declaration File(声明文件)
作用:定义“包级资源”:
GUID / PCD / Protocol / Library 类声明
内容包括
PACKAGE_GUID(包标识)
TokenSpaceGuid(PCD命名空间)
PCD声明
Protocol / PPI GUID
LibraryClasses
类比
C语言:头文件(.h)
Linux:include/ + DTS定义
一句话总结
.dec = 资源声明中心(不包含实现)
4.2 .inf 文件
INF = Information File(模块信息文件)
作用:描述一个“模块/驱动”:
这个模块:
- 是什么类型
- 用哪些库
- 依赖哪些包
- 编译哪些源文件
关键内容
[Defines]
MODULE_TYPE = UEFI_DRIVER
[Sources]
xxx.c
[Packages]
A1000/SG2042.dec
[LibraryClasses]
DebugLib
类比
Linux:
→ Makefile + Kconfig + driver入口描述
一句话总结
.inf = 单个驱动/模块的“说明书 + 编译入口”
4.3 .dsc 文件
DSC = Description File(平台描述文件)
定义整个固件:
- 用哪些模块(.inf)
- 用哪些包(.dec)
- PCD具体取值
- 编译选项
核心内容
[Packages]
A1000/SG2042.dec
[Components]
Drivers/Uart/Uart.inf
Drivers/Sd/DwMmc.inf
[PcdsFixedAtBuild]
gTokenSpaceGuid.PcdUartBase = 0x10000000
类比(非常重要)
Linux:
→ 顶层Makefile + Kconfig + DTS(合集)
一句话总结
.dsc = 整个平台的“总控配置文件”
五、三者关系(核心理解)
4.4 .uni 文件解析(Unicode字符串资源)
1本质是什么?
.uni = UEFI字符串资源文件(多语言)
用于:
Driver 名称
设备描述
BIOS界面显示
调试字符串(部分场景)
| 关键字 | 含义 |
|---|---|
| #string | 定义字符串 |
| STR_xxx | 字符串ID |
| #language | 语言 |
| “xxx” | 实际内容 |
4.5 .fdf 文件解析(Flash Description File)
属于固件构建核心
.fdf = 定义固件镜像如何打包到Flash
它决定:
哪些模块被打进BIOS
放在哪个地址
属于哪个FV(Firmware Volume)
核心结构
一个典型 .fdf:
[FV.FVMAIN]
FvNameGuid = XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
BlockSize = 0x1000
NumBlocks = 0x100
INF MdeModulePkg/Core/Dxe/DxeMain.inf
INF MmcPkg/MmcDxe/MmcDxe.inf
(1)FV(Firmware Volume)
[FV.FVMAIN]
类似“固件分区”
常见:
FVMAIN(主DXE区)
FVB(变量区)
Recovery FV
(2)INF引用
INF MmcPkg/MmcDxe/MmcDxe.inf
表示:
把 MMC 驱动编译产物放进固件
DXE阶段会加载
(3) FD(Flash Device)
[FD.MyFlash]
BaseAddress = 0x0
Size = 0x1000000
FV = FVMAIN
定义整个Flash布局
(5)构建流程关系
.inf → 定义模块
.uni → 字符串资源
.c → 代码
↓
build system
↓
.fdf → 决定放进哪个FV
↓
生成 BIOS/UEFI 固件镜像


2135

被折叠的 条评论
为什么被折叠?



