Transcript EFI Drivers
UEFI与固件程序设计
Tel:69589584
Email:[email protected]
同济大学软件学院
Agenda
EFI Driver Development
EFI Application Development
EFI Drivers
EFI Driver Model
Supports complex bus hierarchies
– Follows the organization of physical/electrical architecture of
the machine
Driver Binding Protocol provides flexibility
– Function to match drivers to devices
– Driver version management
– Hot-plug and unload support
Drivers not tied to FLASH
– Can be loaded from EFI System Partition
Extensible
– Able to extend to future bus and device types
EFI Drivers
Driver Design Steps
Determine Driver Type
Identify Consumed I/O Protocols
Identify Produced I/O Protocols
Identify EFI Driver Model Protocols
Identify Additional Driver Features
Identify Target Platforms
– x86
– x64
– Itanium Processor Family
– EFI Byte Code (EBC)
EFI Drivers
What Type of Driver is
Being Designed?
EFI Images
Drivers
Service Drivers
EFI Driver Model
Initializing Drivers
Root Bridge
Drivers
Device
BusBus Hybrid Device
Drivers Drivers Drivers
Drivers
Drivers
EFI 1.02
Drivers
Applications
OS Loaders
EFI Drivers
Drivers
Service Drivers
Device Drivers
EFI Driver Model
Initializing Drivers
Root Bridge
Drivers
Manages a Controller or Peripheral Device
Start() Does Not Create Any Child Handles
Start() Produces One or More I/O Protocols
– Installed onto the Device’s Controller Handle
Examples:
PCI Video Adapters
USB Host Controllers
USB Keyboards / USB Mice
PS/2 Keyboards / PS/2 Mice
Bus
Drivers
Hybrid
Drivers
Device
Drivers
EFI Drivers
Drivers
Service Drivers
Bus Drivers
EFI Driver Model
Initializing Drivers
Root Bridge
Drivers
Manages and Enumerates a Bus Controller
Start() Creates One or More Child Handles
Start() Produces Bus Specific I/O Protocols
– Installed onto the Bus’s Child Handles
Examples:
PCI Network Interface Controllers
Serial UART Controllers
Bus
Drivers
Hybrid
Drivers
Device
Drivers
EFI Drivers
Drivers
Service Drivers
Hybrid Drivers
EFI Driver Model
Initializing Drivers
Root Bridge
Drivers
Bus
Drivers
Manages and Enumerates a Bus Controller
Start() Creates One or More Child Handles
Start() Produces Bus Specific I/O Protocols
– Installed onto the Bus’s Controller Handle
– Installed onto Bus’s Child Handles
Examples:
PCI SCSI Host Controllers
PCI Fiber Channel Controllers
Hybrid
Drivers
Device
Drivers
EFI Drivers
Drivers
Service Drivers
Service Drivers
EFI Driver Model
Initializing Drivers
Root Bridge
Drivers
Bus
Drivers
Does Not Manage Hardware
Provides Services to other Drivers
Does not support Driver Binding Protocol
Typically installs protocols in driver entry point
Creates One or More Service Handles
Produces Service Specific Protocols
– Installed onto Service Handles
Examples:
EFI Decompress Protocol
EFI Byte Code Virtual Machine
Boot Integrity Services (BIS)
Hybrid
Drivers
Device
Drivers
EFI Drivers
Drivers
Service Drivers
Initializing Drivers
Initializing Drivers
Typically Touches Hardware
Performs One Time Initialization Operations
Does Not Create Any Handles
Does Not Produce Any Protocols
Unloaded When Finished
Examples: None
EFI Driver Model
Root Bridge
Drivers
Bus
Drivers
Hybrid
Drivers
Device
Drivers
EFI Drivers
Drivers
Service Drivers
Root Bridge Drivers
Initializing Drivers
Typically Manages Part of Core Chipset
Directly Touches Hardware
Creates One or More Root Bridge Handles
Produces Root Bridge I/O Protocols
Installed onto new Root a Bridge Handles
Examples: PCI Host Bridge
EFI Driver Model
Root Bridge
Drivers
Bus
Drivers
Hybrid
Drivers
Device
Drivers
EFI Drivers
What I/O Protocols are
Consumed?
FLASH
USB Peripherals
USB I/O Protocol
Device Path Protocol
PCI Adapters
PCI I/O Protocol
Device Path Protocol
EFI Drivers
What I/O Protocols are
Produced?
FLASH
SCSI Pass Thru Protocol
and
Block I/O Protocol
SCSI
SCSI RAID
Fiber Channel
EFI Drivers
What I/O Protocols are
Produced?
FLASH
UNDI
and
Network Interface Identifier Protocol
Network
Interface
Controller
(NIC)
EFI Drivers
Driver Design Checklist
EFI Drivers
Running EFI drivers
ConnectController()
Called from Boot Manager or during load
Precedence rules are applied
Context override
Platform override
Bus override
Version number
Order of which drivers are installed into handle database is not
deterministic
DisconnectController()
Must test and implement Stop()
EFI Drivers
Implement, Test & Debug
See Backup Slides for Details
Required for IHVs
Optional for OEM/ODMs
Test Functions with EFI Shell Commands
Check for Leaks with EFI Shell Commands
Install EFI Compliant Operating System
Boot EFI Compliant Operating System
Debug Macros Identify Critical Failures
Use Same Techniques on all CPU Types
x86, x64, Itanium Processor Family, EBC
Driver Guidelines
Driver Guidelines
Don’t touch hardware in Driver Entry
Keep Supported() small and simple
Move complex I/O into Start() and Stop()
Start() / Stop() mirror each other
InstallProtocolInterface()
UninstallProtocolInterface()
OpenProtocol()
CloseProtocol
AllocatePages()
FreePages()
AllocatePool()
FreePool()
Driver Entry / Unload() mirror each other
Driver Guidelines
PCI Device Drivers
Always Call PciIo->Attributes()
Advertises Dual Address Cycle Capability
Save and Enable Attributes in Start()
Disable Attributes in Stop()
DMA – Bus Master Write Operations
Must call PciIo->Flush()
DMA – Setting Up with PciIo->Map()
Do Not Use Returned DeviceAddress
Not all chipsets have 1:1 bus/system mappings
Driver Guidelines
PCI Device Drivers – Start()
Status = PciIo->Attributes(
PciIo,
EfiPciIoAttributeOperationGet,
0,
&ControllerContext->OriginalPciIoAttributes
);
if (EFI_ERROR (Status)) {
// Error Handling
}
Status = PciIo->Attributes(
PciIo,
EfiPciIoAttributeOperationEnable,
(EFI_PCI_IO_ATTRIBUTE_IO |
EFI_PCI_IO_ATTRIBUTE_MEMORY |
EFI_PCI_IO_ATTRIBUTE_BUS_MASTER |
EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE),
0,
NULL
);
if (EFI_ERROR (Status)) {
// Error Handling
}
Save Original and Enable
Driver Guidelines
PCI Device Drivers – Stop()
Status = PciIo->Attributes(
PciIo,
EfiPciIoAttributeOperationSet,
&ControllerContext->OriginalPciIoAttributes
NULL
);
if (EFI_ERROR (Status)) {
// Error Handling
}
Restore Original
Driver Guidelines
Preventing Alignment Faults
VOID
ScsiDeviceNodeInit (
IN OUT SCSI_DEVICE_PATH *ScsiDeviceNode,
IN
UINT16
Pun,
IN
UINT16
Lun
)
{
ScsiDeviceNode->Scsi.Header.Type
= MESSAGING_DEVICE_PATH;
ScsiDeviceNode->Scsi.Header.SubType
= MSG_SCSI_DP;
SetDevicePathNodeLength (&ScsiDeviceNode->Scsi.Header,
sizeof(SCSI_DEVICE_PATH));
ScsiDeviceNode->Scsi.Pun
= Pun;
ScsiDeviceNode->Scsi.Lun
= Lun;
}
BAD
ScsiDeviceNode may not be aligned
Driver Guidelines
Preventing Alignment Faults
VOID
ScsiDeviceNodeInit (
IN OUT SCSI_DEVICE_PATH *ScsiDeviceNode,
IN
UINT16
Pun,
IN
UINT16
Lun
)
{
SCSI_DEVICE_PATH MyDeviceNode;
GOOD
MyDeviceNode.Scsi.Header.Type
= MESSAGING_DEVICE_PATH;
MyDeviceNode.Scsi.Header.SubType
= MSG_SCSI_DP;
SetDevicePathNodeLength (&MyDeviceNode.Scsi.Header,
sizeof(SCSI_DEVICE_PATH));
MyDeviceNode.Scsi.Pun
= Pun;
MyDeviceNode.Scsi.Lun
= Lun;
gBS->CopyMem (ScsiDeviceNode,
&MyDeviceNode,
sizeof(SCSI_DEVICE_PATH));
}
gBS->CopyMem() handles all alignments
MyDeviceNode is aligned
Driver Guidelines
Use EFI Driver Library Functions
CHILD_DEVICE
Child;
OK
Status = gBS->AllocatePool (
EfiBootServicesData,
sizeof (CHILD_DEVICE),
&Child
);
if (EFI_ERROR (Status)) {
return Status;
}
gBS->SetMem (Child, sizeof (CHILD_DEVICE), 0);
CHILD_DEVICE
Child;
GOOD
Child = EfiLibAllocateZeroPool (sizeof (CHILD_DEVICE));
if (Child == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Library Functions Simplify Source Code
Library Functions May Reduce Size
Driver Guidelines
EFI Device Paths
EFI_DRIVER_BINDING.Start()
Child->DevicePath = EfiAppendDevicePathNode (
ControllerDevicePath,
ChildDevicePathNode
);
if (Child->DevicePath == NULL) {
return(EFI_OUT_OF_RESOURCES);
}
EFI_DRIVER_BINDING.Stop()
gBS->FreePool (Child->DevicePath);
Parent Device Path is Opaque
Not Parsed by Bus Drivers
Driver Guidelines
Bus Walk Tips
Use LocateHandleBuffer(Bus I/O Protocol)
Do not scan PCI configuration space
Implement support for RemainingDevicePath
Highly recommended for all bus drivers
(i.e. SCSI, Fibre Channel, etc.)
Allows bus driver to bypass full enumeration.
Reduces boot time
Driver Guidelines
Component Name Protocol
Limit Lengths of Names to 40 Unicode Characters
Include Driver Name and Version Number
UNDI Driver (Network Interface Controller)
Typically the Name of the PCI Controller
MAC Node Produced by an UNDI Driver
Identify Location of Physical Connector on NIC
PCI Slots
Identify Physical Location of PCI Slots in the System
SCSI / SCSI RAID / Fiber Channel
Controller - Typically name of the PCI Controller
Channel
- Identify Physical Location of the SCSI Channel
Disk
- Use Results from INQUIRY Command
Driver Guidelines
Option ROM Size Reduction
Use EFI Compression
Compile with EFI Byte Code Compiler
Single Binary for x86, x64 and Itanium
Smaller than Itanium Binaries
Comparable to x86 Binaries
Compresses Well ~ 50%
Driver Guidelines
How To Improve Portability
Do Not Assume Max Number of Children
Do Not Use Fixed Memory Addresses
Do Not Use Assembly
Do Not Use Floating Point Arithmetic
Some Minor EBC Porting Considerations
Bus Drivers Should Support Producing 1 Child at a time if possible
(improves boot performance)
Driver Guidelines Improve Portability
Driver Writer’s Guide
EFI Driver Writer’s Guide
Captures Practical Experiences
Use as a Recipe Book
Must Read for all EFI Driver Developers
Living Document
Content Based on Industry Feedback
Updated as Techniques are Refined
Updated as New Technologies are Introduced
Driver Writer’s Guide
General Topics
Overview of EFI Concepts
EFI Services
Commonly Used by EFI Drivers
Rarely Used by EFI Drivers
Should Not Be Used by EFI Drivers
General Driver Design Guidelines
Classes of EFI Drivers
Driver Entry Point
Private Context Data Structures
EFI Driver Model Protocols
Driver Writer’s Guide
Platform Specific Topics
PCI Driver Guidelines
USB Driver Design Guidelines
SCSI Driver Design Guidelines
Size Optimizations
Speed Optimizations
Itanium Processor Family Considerations
EFI Byte Code Considerations
Building/Testing/Debugging EFI Drivers
Driver Writer’s Guide
Benefits of following EFI
Driver Guidelines
Following EFI Driver Guidelines
Improves Portability, Quality, and Interoperability
Reduces Implementation Effort
May Increase Performance
May Reduce FLASH Overhead
EFI Driver Writer’s Guide Helps
Improve EFI Drivers
Summary
Good Designs Save Time and Money
Many Tools Available to Test and Debug
Using Driver Guidelines Improves Portability
Compile in EBC to have one driver image to support x86,
x64 and Itanium.
Further Information
http://developer.intel.com/technology/EFI
EFI Web site for information, IDF presentations and EFI
Driver Writer’s Guide
http://www.uefi.org
Website for Unified EFI Forum
Back up
Required Materials for IHVs
Optional Materials for OEMs
Agenda
Introduction
EFI Shell
EFI Toolkit
3rd Party Libraries
What are EFI Applications?
EFI Applications extend firmware
No hardware dependence
No OS dependence
Portable across platforms
IA-32, Intel® 64, IA-64
Enables rapid application development
What is an EFI Application?
An EFI Loadable Image
Loaded by EFI loader just like drivers
Does not register protocols like drivers do
Consumes protocols
Typically user driven (exits when task completed)
Same set of interfaces available as drivers have
Can be used for
Platform diagnostics
Factory diagnostics
Utilities
Driver prototyping
‘Platform’ applications
EFI Shell
An EFI Application
Interactive Console Interface
Application Launch
Load EFI Drivers
Scripting Capability
Automatic execution of startup script file
Console redirection to files
Open Source located on http://efi-shell.tianocore.org project
EFI Toolkit Components
Utilities
C Library
Network Stack
Platform Management
Compression
Database
Source Included
Useful tools for EFI
application development
Open Source located on http://efi-toolkit.tianocore.org project
Programming Models
Native EFI Model
Uses only EFI constructs
Access to all EFI constructs
Smaller code size
Portability Model
Familiar programming interfaces
Easier to port ANSI/POSIX based programs
Larger binary image
A single program can use both
EFI Toolkit Integration
Database
Hardware
Management
Compress
Network
C Library
Utilities
EFI
EFI API
C Library
FreeBSD Port
ANSI/POSIX compliant
System I/O - open(), read(), write(), close(), stat()
Standard I/O - fopen(), printf(), gets(), …
String/Char - strcmp(), isascii(), atoi(), …
Memory
- malloc(), free(), realloc(), …
Time/Date
- time(), asctime(), ctime(), …
Math
- sqrt(), pow(), sin(), log(), …
EFI Library
“Lite Weight” C Library like functions
String Functions
Memory Support Functions
CRC Support Functions
Text I/O Functions
Math Functions
Spin Lock Functions
Specific EFI functions
Handle and Protocol Support Functions
Device Path Support Functions
Network Components
Port of FreeBSD TCP/IP stack
Supports standard protocols
IPv4, ICMP, ARP, UDP, TCP
Socket library interface
Implemented as an EFI protocol
Miscellaneous
SMBIOS Library
Library routines for parsing SMBIOS tables
Database
btree
Hashing
Compression
General purpose compression/decompression
Gzip functionality
Utilities
Network utilities
FTP client and server, ping
Text editor
Scripting interpreter (Python)
Sample applications
EFI Hello.c
#include "efi.h"
EFI_STATUS
InitializeHelloApplication (
IN EFI_HANDLE
ImageHandle,
IN EFI_SYSTEM_TABLE
*SystemTable
)
{
UINTN Index;
SystemTable->ConOut->OutputString(SystemTable->ConOut,
L”Hello application started\n");
SystemTable->ConOut->OutputString(SystemTable->ConOut,
L"\n\r\n\r\n\rHit any key to exit this
image\n\r");
SystemTable->BootServices->WaitForEvent(
1, &(SystemTable->ConIn->WaitForKey), &Index);
SystemTable->ConOut->OutputString(SystemTable->ConOut,
L"\n\r\n\r");
return EFI_SUCCESS;
}
EFI Library Hello.c
#include "efi.h"
#include "efilib.h"
EFI_STATUS
InitializeHelloLibApplication (
IN EFI_HANDLE
ImageHandle,
IN EFI_SYSTEM_TABLE
*SystemTable
)
{
InitializeLib (ImageHandle, SystemTable);
Print(L"\n\n\nHelloLib application started\n\n\n");
Print(L"\nHit any key to exit this image\n");
WaitForSingleEvent(ST->ConIn->WaitForKey,0);
ST->ConOut->OutputString (ST->ConOut, L"\n\r\n\r");
return EFI_SUCCESS;
}
C Library Hello.c
#include <atk_libc.h>
#include <stdio.h>
EFI_STATUS
InitializeHelloLibCApplication (
IN EFI_HANDLE
ImageHandle,
IN EFI_SYSTEM_TABLE
*SystemTable
)
{
InitializeLib(ImageHandle, SystemTable);
printf("Hello LibC application started\n\n\n");
printf("Hit C/R to exit this image\n");
return( getchar() );
}
C Library Hello.c
#include <atk_libc.h>
#include <stdio.h>
int main (int argc, char **argv )
{
printf("Hello LibC application
started\n\n\n");
printf("Hit C/R to exit this image\n");
return( getchar() );
}
C++ Support
No direct support
No Global constructors and destructors
New and Delete can be mapped to malloc/free
Portable Embedded
Graphics
Portable Embedded Graphics
Portable graphics library for EFI
Similar windowing components (widgets)
Dialog boxes
Progress bars, scroll bars
Text boxes
Window Management
Fonts
Bitmaps, JPEG, …
Contact Swell Software
http://www.swellsoftware.com
PEG Components
Summary
EFI Applications extend firmware
Provides system independence in the pre-boot space
Hardware
Operating System
Platform
IA-32, Intel® 64, and IA-64
Large library support
EFI Shell provides convenient launch point
Further Information
https://efi-toolkit.tianocore.org/
EFI Web site for EFI Toolkit download
https://www.TianoCore.org
Website for EFI open source resources
EFI Developer Kit (EDK)
Nt32 emulation environment
EFI Shell Source
http://www.swellsoftware.com
Portable Embedded Graphics toolkit
http:/uefi.org
UEFI Specification