EFI Drivers

advertisement
UEFI与固件程序设计
Tel:69589584
Email:wang.box@163.com
同济大学软件学院
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
Download