UEFI News and Commentary

Tuesday, June 19, 2012

HOW-TO: Set Up The EDK2's Windows-Hosted UEFI Environment With Visual Studio 2010.

This article shows how to set up the environment for the Windows-hosted UEFI (aka NT32) in the environment provided by EDK2.  This is similar to a previous article, but this time, we are using EDK2 and Visual Studio 2010.
This article assumes that you have Visual Studio 2010 installed and that EDKII has been downloaded  to C:\edk2


Create New Visual Studio Project
This step's goal is to set up Visual Studio so that it can build the Windows-hosted (NT32) environment


1.  Select File->New->Project 










2. Select the "General" project category and select "Makefile Project."  Enter the name as "NT32" and click "OK."








3. The Makefile Project Wizard will pop up.  Click "Finish."














4.  Your new project will appear in the Solution Explorer.
















5. Select the project with your mouse and then click Project->Properties 






6. Set the Configuration to "All Configurations" and select "NMake" on the right 














7. Select "Build Command Line" and click the drop-down arrow on the right.  Click "<Edit...>"  










8. This will pop up a separate editor box.  On three separate lines, enter the following text and click "OK."

cd /D c:\edk2
set WORKSPACE=c:\edk2
call edksetup.bat --nt32
build






9. Now, for "Rebuild All Command Line," enter

cd /D c:\edk2
set  WORKSPACE=c:\edk2
call edksetup.bat --nt32
build clean
build


10. For "Clean Command Line," enter

cd /D c:\edk2
set  WORKSPACE=c:\edk2
call edksetup.bat --nt32
build clean


11. Click "OK."


12. Edit target.txt, which is located in C:\edk2\Conf, and change TOOL_CHAIN_TAG = VS2010x86.  By default, it is set to MYTOOLS, which builds in Visual Studio 2008 and will cause build errors.


Launching the Windows-Hosted Environment
At this point, you should be able to build by selecting Build->Build Solution (or using F7).  You can run the emulated environment by going to the command prompt and typing:
cd /d c:\edk2\Build\NT32\DEBUG_VS2010x86\IA32
SecMain.exe
You will see (at least) two windows: the debug output console window and then the graphics output window.  The graphics output window will show a fake logo, a progress bar and then boot into the built-in EFI shell.















Conclusion
That gets us past the first step.  Next time, we'll show how to set up the debugger and make the code debugger-friendly in VS 2010.

UEFI Summer Summit, 16-20 July at Microsoft.

Well, the plugfests have been coming fast and furious. Taipei, Sunnyvale, Taipei again and now Redmond. The release of Microsoft Windows 8, UEFI-optimized versions of Redhat and other Linux distros, and IPv6 have put a lot of pressure on making UEFI interoperability a reality. Pile the new crowd of plug-in PCIe cards that have UEFI option ROMs, and even a USB display device, and you can see why getting everyone together in one place makes sense. More details and registration at  www.uefi.org.
I'll be there. I'm sure the usual suspects will be there also. Look me up in the Insyde rooms.
On a separate note, I've added a guest blogger, my daughter Shannon Lewis, a computer game science student at UC Irvine, and probably the youngest official UEFI adopter. You'll be seeing some updates to older articles, as well as new UEFI programming articles.

Thursday, May 24, 2012

PI 1.2.1 Specification Released

Well, UEFI has been going with smaller and smaller numbers in the revision numbers, trying to convince us all that "nothing has really changes". First, they did it with UEFI 2.3, going to UEFI 2.3.1 and now releasing UEFI 2.3.1c with small normative changes.
Now they are doing it again with the PI 1.2.1 specification. Let's dig in and take a look at what really changed:
  1. The Security Architecture Protocol was cleaned up. The SAP is used by the DXE Core to authenticate an image before allowing it to be loaded. More recently, it is being used to handle pieces of the UEFI 2.3.1 Secure Boot infrastructure and TCG measurement. The problem with SAP (which was addressed in SAP2) is that it didn't actually pass in a pointer to the image buffer, which forced SAP implementations to effectively reload the image from the storage device in order to get a good look at it. SAP2 addressed that, and with clarifications, proves faster for faster book.
  2. The SetMemorySpaceCapabilities function was added to GCD. Previously, the memory attributes (such as X and Y) were settable through SetMemorySpaceAttributes, but the capabilities were not changeable.
  3. A new event, End-of-DXE was added. Previously, there was no clear way to define the end of DXE and the beginning of the Boot Manager portion of the BDS phase. As a result, drivers were attempting to latch onto all sorts of implementation-specific behavior to make sure they were executed before BDS started. The new UEFI event, End-of-DXE, is guaranteed to be invoked before any UEFI drivers or applications are launched and before the console devices are connected.
  4. There is now a detailed Super I/O PEI and UEFI driver-model architecture to further standardize the process of adding super I/O device in a compatible way.
  5. New signed Firmware File System sections were added, using a header similar to the UEFI certificates to sign the file section contents.
  6. The new PCD Get Info Protocol and PPI add functions which return information about an individual PCD item.
  7. Added methods for reserving interrupt and exception vectors.
  8. Added support for weakly aligned Firmware Volumes. Previously a Firmware Volume's alignment was required and controlled the alignment of individual Firmware Files in the Firmware Volume. That is, if a Firmware Volume was aligned on an 8 byte boundary, it was impossible to include a Firmware File that required 64KB alignment. But this wasn't always useful or desirable, because Firmware Volumes were sometimes just used as containers of arbitrary files.

Thursday, May 17, 2012

UEFI May Plugfest Presentations

Hey, UEFI held a plugfest on May 8-10 in Taipei. This was the first time that it was hosted by Phoenix Technologies in Taiwan. The previous two had been hosted by Insyde Software. [Disclosure: these are my previous and current employers, respectively] All of the presentations are availabe on the UEFI Learning Center site. Of note this year is the heavy emphasis on security. Why? Because Windows 8 is driving adoption of and providing world-class implementation of the UEFI Secure Boot feature found in the UEFI 2.3.1c specification. Also at the plugfest were representatives from RedHat and Canonical.

The emphasis on secure boot has raised a big issue for BIOS vendors, as OEMs and ODMs try to get the right set of keys into the flash part. Microsft has released certificates for signed UEFI drivers and signed Microsoft boot loaders for inclusion. And they are planning to open up a UEFI driver signing portal at sysdev.microsoft.com, the same place you go to sign Windows hardware drivers. Insyde (Kevin Davis) presented factory tools for packing up the certificates and keys needed to create a production BIOS. The idea of a BIOS engineer going into a locked room with a private key seems foreign to most OEM/ODM BIOS production processes.

Another interesting set of presentations from Phoenix (Dick Wilkins) and Microsoft (Tony Mangafeste) highlight likely security attack surfaces in UEFI BIOS, now that the boot loader has been secured using signing. They point to buffer overflow attacks, integer overflow and pointer manipulation in bad PE/COFF images as a likely attack. So both Microsoft and Phoenix have contributed fixes to the open-source sample UEFI implementation at http://www.tianocore.org to make the UEFI PE/COFF image loader more robust. They even added some of the security features previously only found in operating systems to the UEFI implementation, such as ALSR, usage of the NX bit and enabling of the Microsoft Visual Studio C/C++ compiler's stack checking and buffer overflow capabilities (the /GS option and /RTCs option).

Brian Richardson, from Intel (and formerly of AMI) went through the resources that Intel is putting out there, focused heavily on the IHV plug-in card vendors, including a nifty UEFI driver template tool and updated UEFI driver writer's guides. AMD rounded out the group with hints on writing good UEFI drivers for video cards, including one of the most common gotcha's: how to report EDID.

Finally, Andrew Sloss from ARM describes why they think UEFI is the standard of choice for firmware on ARM processors and how they are working to enable it for their many industry partners. Two up and coming tricky bits for ARM include ARMv8 (64-bits) and how TrustZone should work with UEFI.  From personal experience, most silicon vendors want to keep TrustZone locked up and tied tightly to their SoC. But at the same time, there are a number of features where an open firmware driver model would be extremely useful. This is something that x86 vendors have known for a long time with SMM, but the ARM community doesn't have its head wrapped around. So there have been proposals to load up TrustZone in SEC, even prior to PEI. Not a good idea, IMO. Part of this is also related to the fact that SEC has traditionally been in the built-in NOR flash, while the rest of the firmware was relegated to an off-chip NAND flash device, giving some trepidation about the security (even though it has always been signed in most commercial implementations). More on this later...

Monday, March 26, 2012

UEFI Plugfest In May Will Feature ARM & Secure Boot

UEFI just sent me the flyer for the May plug-fest in Taipei, hosted by Phoenix Technologies and UEFI. The last two were hosted by Insyde out at the Holiday Inn. This one is being held at the Sunworld Dynasty Hotel in Taipei. I can't remember if I've been there before, but the pictures make it look nice. Interesting will be a presentation about UEFI on ARM, presented by ARM Holdings itself. ARM has been really active this past couple years, and has dedicated resources improving the TianoCore.org sample implementation of UEFI.

Then there will be stuff on getting Secure Boot set up correctly during PC manufacturing and something about firmware security holes (which I'm guessing will be an update to what Microsoft talked about at the February plugfest, although I haven't heard). I'll be there in a supporting role.

Tuesday, March 06, 2012

UEFI Driver Writer's Guide & Wizard Released

Many times I hear the question: How do I write a UEFI driver for X? Or, as it is more commonly expressed: "UEFI is so dang complicated. In XYZ standard (where XYZ = BIOS or coreboot or OpenFirmware) I could just initialize my hardware, provide a few hooks and I'm done. Stupid UEFI." And there is some truth in that. Actually, you can write very simple drivers for UEFI that just initialize the hardware and produce the required interfaces. But, the very simple kind are hard to debug and don't play nice with others. For example, when we're trying to boot quickly, the UEFI core firmware need devices that aren't part of the boot path to not initialize their devices so that boot will be faster. How do you know if you are in the boot path? By whether the Start() function of the Driver Binding protocol gets called. And what happens if your device is configurable? How do you expose your configuration settings? By publishing a form in the HII Database. And so on. There are a lot of pieces to creating a fully-featured driver.

Fortunately, Intel has recently released a series of resources as a part of the TianoCore's "Enabling Resources" page, including a (long delayed) Driver Writer's guide and the UEFI Driver Wizard, which creates driver skeleton for various types of UEFI drivers.

Go check it out. Now if they would only port the C Library to work with drivers instead of just shell apps...

Thursday, February 09, 2012

ARM, Arium and UEFI

Just read the press release blurb from Arium about their upgraded support for UEFI on their ARM products.

Arium today announced support for ARM-based Unified Extensible Firmware Interface (UEFI). As part of the recently announced SourcePoint(TM) 6.9.1 debugger, Arium provides a seamless, easy-to-use, UEFI-aware development environment. Engineers have access to toolbar selections to discover and debug all phases of UEFI code (whole press release here)
I've used Ariums for a long time on Intel platforms (have one at my house right now) and have used their UEFI support there in tracking down hard-to-reproduce problems on real platforms. SourcePoint isn't my favorite debugger front end, but it is serviceable. But UEFI's standardization, even in portions of the debug infrastructure, give Ariums a chance to provide higher level features. I look forward to trying one out.

Friday, February 03, 2012

UEFI Article in Intel Technical Journal

I co-wrote (with a few Intel folks, including Vincent Zimmer who also co-wrote our book) one of the articles in the Intel Technical Journal ("UEFI Today: Bootstrapping the Continuum"). We wrote about how UEFI works to support silicon porting for firmware. My part starts on page 22, but the whole article is informative. My part details how we built up a full SMBus, ASF and DASH stack on top of the SMBus Host Controller protocol described in the PI Specification. Check it out and let me know what you think.

UEFI Plugfest, February 20-24

The next UEFI Plugfest rolls around this month on the AMD campus in Sunnyvale, CA.  If this is a typical event, and you have a Microsoft NDA, you might get a preview of the next Windows version. There is also usually a good version of Linux distros to test remote booting, including IPv6. It is free, but you must be at least a UEFI adopter to attend. Check out the registration info at www.uefi.org.

Thursday, September 08, 2011

Intel Developer Forum (September 13-15)

Hey, next week, stop by the UEFI sessions and say hello. I'm speaking in EFIS003, "Beyond DOS: UEFI Modern Pre-Boot Application Development Environment" with my buddy Vincent Zimmer, who was one of my co-authors on our book about the UEFI Shell.

Friday, August 05, 2011

UEFI Programming at the University of California (Santa Cruz)

I was sitting at the train station in Santa Clara and started flipping through the catalog for the UC Santa Cruz extension when I noticed, on the front cover, a computer science course with both BIOS and UEFI on the front cover. Later, when I showed this to long-time firmware engineers, they pulled out their cell-phones to take a picture. I'll post that picture later.

Here's the link to the course, which was offerend last month. I tried to contact the professor for the course to give them a free copy of the shell book, but no response. The course description says:

Every embedded system, from game consoles and cell phones to medical and networking equipment, requires boot loaders to initialize the hardware, perform initial diagnostics, setup the environment and load the target operating system. Some boot loaders, like U-BOOT, are simple. Others, such as BIOS (Basic Input/Output System) and UEFI (Unified Extensible Firmware Interface), are modular and extensible. In this course, you'll learn about BIOS and UEFI, the two most common boot loaders, and get a brief overview of U-BOOT.

The course starts with BIOS history, architecture and the evolution of BIOS over the past 20-plus years. Students learn about BIOS device enumeration and configuration. The course covers BIOS interfaces including software interrupts, option ROM interface, and boot mechanism. The BIOS section ends with option ROM limitations, and a brief introduction to ACPI and SMBIOS.

In the UEFI section of the course, students learn about UEFI history, architecture and services provided by UEFI. Students also learn the UEFI driver architecture and how to write UEFI drivers and applications. The course concludes with UEFI debugging methodologies and briefly addresses U-BOOT.


This course includes hands-on programming and homework assignments. By the end of the course, students have a broad understanding of operation and debugging techniques for various boot loaders. They are also able to identify various characteristics of the boot process and diagnose hardware issues

Thursday, August 04, 2011

UEFI Plugfest

Front of the T-Shirt. Don't know how many people asked me
if it was supposed to be an anagram for "LIFE".
Well, I failed completely to talk about the UEFI summer plugfest on July 6-9, even though I was there and presented (on emulated devices). In between presentations, Intel put on some excellent training sessions on topics like the UEFI shell. See all presentations here. This event was hosted by Microsoft (and Phoenix), but there was a good showing from other non-Microsoft ecosystems, including Linux distros and Apple. There was a cool t-shirt, and I'll add its image later.

Latest news is that there will be another plugfest October 24th-27th in Taiwan. I'm not sure, but I'm guessing it will be in Xinbei City again, which is a delightful valley just outside of Taipei, known for its local beauty and smoky tofu.
Back of the UEFI t-shirt.

Tuesday, May 25, 2010

UEFI as a BIOS Course

I see over at http://biosism.com/ that some folks are gearing up to teach a course in "BIOS" with a focus on UEFI.

Monday, April 05, 2010

UEFI HII Hacking

Interesting account of folks trying to hack the IFR in a Sony Vaio to enable hidden BIOS features. I suspect we'll see a lot more of this type of thing now that much of the setup data is exposed in a format that can easily be parsed. This reminds me of what happened once ACPI became widespread and the ACPI Machine Language (AML) could be disassembled and modiifed. Some of the early virtualization attacks used the hardware primitives built into AML to subvert OS security. This is less of a risk with HII, since IFR doesn't have hardware primitives and doesn't generally give any more rights to system resources than would already be available to an application that could run pre-OS in UEFI.

Here is the thread about hacking HII: http://forum.notebookreview.com/showthread.php?p=6104265

Monday, March 15, 2010

UEFI Testing Workshop Announced For 6/21/10.

Just received notice that there is another UEFI test workshop (see below), free for all UEFI members. I presume that means adopters, contributors and promoters. I haven't seen the note yet on the official web site yet. These workshops are really good for inter-op testing between BIOS vendors, chipset vendors, OS vendors, plug-in card vendors and UEFI software vendors. In addition, you often get to meet a lot of the folks who have put together the UEFI specification and talk directly to the self-cert test developers if you have questions. Hope to see you there!

Tim


Dear UEFI Developers,


The UEFI Testing Work Group (UTWG) and the UEFI Industry Communications Work Group (ICWG) from the Unified EFI (UEFI) Forum would like to invite you to the next UEFI testing workshop event / PlugFest.

This event will be held at the Intel Dupont Optimization Lab Facility in Dupont, Washington in the week of June 21, 2010. The Intel Dupont campus is located approximately one hour south of the Seattle area.

The event is open and free to all attendees from companies that are UEFI members. We encourage companies who are not yet on the UEFI member's list to sign up through the http://www.uefi.org and get ready to participate.

Upon receiving your participation response and interest, we will send you a logistics package to help you prepare for a successful test event. Additionally, participants are encouraged to download, run and submit the UEFI Self Certification Tests (SCT) results to the UTWG prior to the event.

Participants in the test event will include UEFI members who are Add-in Card Vendors / Independent Board Vendors (IBV), Operating System Vendors (OSV), Independent Software Vendors (ISV), Independent BIOS Vendors and Original Equipment / Design Manufacturers (OEM / ODM) and Platform Vendors.

The purpose of this event is to provide the computing industry with an opportunity to conduct a variety of interoperability tests with implementers and implementations of UEFI among the UEFI community. This event will allow add-in cards to run the UEFI SCT on various UEFI system implementations and to test using a variety of Operating Systems.

If you know of any other groups/divisions in your company that would benefit from attending, please forward this letter to them.

Please respond to xxx (@intel.com) by April 2, 2010 to let us know your participant status in this event.

You can also reach Laurie at xxx.

We look forward to seeing you in Dupont!

Wednesday, March 03, 2010

IDF 2010 Beijing Features UEFI

There are a number of UEFI-related sessions at IDF this year (see http://www.intel.com/idf). Included are sessions on multi-processor, fast boot, EDK2, firmware security and cool mobile stuff for UEFI.

UEFI 2.3b Released.

The latest version of the UEFI specification (v2.3b, with updated errata) is now available here.

Sunday, February 28, 2010

UEFI HII (Part 11): Image Package Encoding

The UEFI specification describes a standard set of APIs for drawing bitmaps. The HII Image protocols (as well as the Graphics Output protocol) only deal with bitmaps as arrays of 32-bit pixels. But UEFI also describes a standard way that these bitmaps (or images, as the specification calls them) should be encoded as resources (or packages).

 
Within the packages, images are encoded in 5 different ways:
  • 1-bit per pixel with palette. Each pixel in the image is encoded as a single bit within a byte. Each row of the image is padded to a byte boundary (as with font glyphs). Both the 0 and 1 values can be translated to a full 24-bit color value if a palette entry is provided.
  • 4-bits per pixel with palette. Each pixel in the image is encoded as 4 bits within a byte. Each row of the image is padded to a byte boundary. Each of the 16 possible pixel values can be translated to a full 24-bit color value if a palette entry is provided.
  • 8-bits per pixel with palette. Each of the 256 possible pixel values can be translated to a full 24-bit color value if a palette entry is provided.
  • 24-bits per pixel. Each pixel takes up exactly 3 bytes, one each for red, green and blue.
  • JPEG. Support is required for high (1:1:1) and medium (4:1:1) quality JPEG encoding for R/G/B. There are many other sub-types of JPEG encoding, such as gray-scale encoding for medical imaging, which are not required to be supported.
Fortunately, developers normally never need to deal directly with these formats because they are all translated by the HII Image protocol into the standard 32-bit-per-pixel format used throughout the UEFI specification, including the drawing functions of the  Graphics Output protocol.  Tools are used at build time to convert bitmap files in various formats into of the UEFI encodings.

 
Image packages are very similar in concept to the string packages described before. They always start with the header:

 
typedef struct _EFI_HII_IMAGE_PACKAGE_HDR {

  EFI_HII_PACKAGE_HEADER Header;

 
  UINT32 ImageInfoOffset;
  UINT32 PaletteInfoOffset;
} EFI_HII_IMAGE_PACKAGE_HDR;

 
There are two offsets: the first is to the series of image blocks which describe the images themselves. The second is to the palette information.

The palette information consists of zero or more palettes. Each palette is an array of 32-bit color values, assigned an index between 0 and 255. Images can refer to a palettte and can share a palette. Palettes are not required to carry all 2 (1-bit), 16 (4-bit) or 256 (8-bit) colors but rather only those actually necessary for the images carried in the package.

 
The image information consists of zero or more image blocks, terminated by a special image block of type IIBT_END. Images are encoded in ascending order by their image identifier, starting with the value 1. Each image block does one of the following:
  • Associate a normal image with the current image identifier value.
  • Assocate a transparent image with the current image identifier value. Transparent images specify that the color value 0 should not be drawn.
  • Associate a previous image with the current image identifier value.
  • Skip a specified number of image identifier values.
The following diagram shows a simple 1-bit image as it is encoded and then how it is translated using a palette.

Conclusion
Images are just one of the many types of HII-related resources supported by the UEFI specification. The images are included in package lists which can be attached as part of the PE/COFF resources or loaded as separate files or file sections. Next time we will start looking at the most interesting of the HII constructs: the form, which encapsulate configuration settings.


Tuesday, February 16, 2010

WHY: Why Do I Get Unresolved Externals For __allmul?

While I was working on my project this week, I kept running into the following error:

CLibApp.lib(String.obj) : error LNK2019: unresolved external symbol __allmul referenced in function _wcssize


CLibApp.lib(Cwd.obj) : error LNK2001: unresolved external symbol __allmul
 
This function appears nowhere in my code, nor does it appear in any of the EDK's code? So what's going on? It turns out that this function is one of several compiler support functions that are invoked explicitly by the Microsoft C/C++ compiler. In this case, this function is called whenever the 32-bit compiler needs to multiply two 64-bit integers together. The EDK does not link with Microsoft's libraries and does not provide this function.
 
So why don't all the other drivers and applications in the EDK generated unresolved externals, since they obviously do 64-bit math? The EDK authors skirted this problem by creating 64-bit math routines of their own, such as MultU64x64 and MultU64x32 and using these instead of the built-in C/C++ multiply (*) operator.
 
Are there other functions like this one? Sure, several more for 64-bit division, remainder and shifting.
 
Interestingly enough, the EDK does contain some Microsoft C/C++ compiler support. See CompilerStub.c where both memcpy and memset (from the C standard library) are defined. Why? It turns out that later versions of the compiler optimize certain code sequences by calling the library routines. Want a little stranger bit of trivia? The EfiCommonLib tries to optimize the SetMem function by special-casing a set to zero (i.e. SetMem (dest, count, 0)). But it turns out that the C compile convers both branches into a call to memset.
 
Anyway, here is my implementation of the multiplication routine. The Microsoft version is available, but has their license. The other versions available on the web look an awful lot like the Microsoft version, down to the comments, so I reverse engineered the calling convention (old-style STDCALL) and wrote it from scratch in MASM 9.0.
 
Tim
 
; allmul - 64-bit signed multiplication support function.



.586
.MODEL FLAT, C
.CODE

;
; FUNCTION NAME.
; _allmul
;
; FUNCTIONAL DESCRIPTION.
; This function is called by the Microsoft Visual C/C++ compiler for 32-
; bit executables to multiply two 64-bit integers and returning a 64-bit
; result. The X86 processors have only a 32-bit multiply instruction,
; thus the necessity for a library support function.
;
; The operands are divided into two 32-bit quantities. You can imagine
; that this works like simple 2-digit x 2-digit multiplication, except
; that each digit is 32-bits wide.
;
;   AB
; x CD
; ----
;   DB
;  DA0
;  CB0
; CA00
; ----
; RRRR
;
; You notice that the 3rd and 4th columns never will be used because the
; are the part of the result that is > 64-bits.
;
; R[0:31] = DB[0:31]
; R[32:63] = DB[32:63] + DA[0:31] + CB[0:31]
;
; There is a short cut, if both A and C are 0, then we can use the simple
; 32-bit instruction.
;
;
; ENTRY PARAMETERS.
;    multiplicand - Right-hand operator (CD)
;    multiplier - Left-hand operator (AB)
;
; EXIT PARAMETERS.
;    EDX:EAX - Result.
;


_allmul PROC NEAR USES ESI, multiplicand:QWORD, multiplier:QWORD

 MA EQU DWORD PTR multiplier [4]
 MB EQU DWORD PTR multiplier
 MC EQU DWORD PTR multiplicand [4]
 MD EQU DWORD PTR multiplicand

 mov eax, MA
 mov ecx, MC
 or  ecx, eax    ; both zero?
 mov ecx, MD
 .if zero?      ; yes, use shortcut.
   mov eax, MB
   mul ecx      ; EDX:EAX = DB[0:63].
 .else
   mov eax, MA
   mul ecx      ; EDX:EAX = DA[0:63].
   mov esi, eax ; ESI = DA[0:31].

   mov eax, MB
   mul MC       ; EDX:EAX = CB[0:63]
   add esi, eax ; ESI = DA[0:31] + CB[0:31]


   mov eax, MB
   mul ecx      ; EDX:EAX = BD[0:63]
   add edx, esi ; EDX = DA[0:31] + CB[0:31] + DB[31:63]
                ; EAX = DB[0:31]
 .endif


 ret 16 ; callee clears the stack.
_allmul ENDP


 END

Friday, February 12, 2010

HOW-TO: Debug The EDK's Windows-Hosted UEFI Environment

Last time we took a quick look at how to set up the Windows-hosted (NT32) UEFI environment provided by the EDK. The NT32 environment is very useful for debugging UEFI applications which aren't tied to specific hardware devices. So this week, I'll show how to add on debugging support.

This article assumes that you have already loaded the Visual Studio project to build the EDK's NT32 platform in C:\EDK as described previously.

1. Select the NT32 project in the Solution Explorer.










2. Select Project|Properties











3. In the "NT32 Properties Pages" select "Debugging"










4. Select "Command" and enter "SecMain.exe".
5. Select "Working Directory" and enter "c:\edk\sample\platform\nt32\uefi\ia32".









6. Select "Environment" and select the ...












7. An editor will pop up. In the editor box, enter the following and the click "OK". These are environment variables which govern how the emulator works, how much memory it uses, what virtual devices it has access to, etc. We will discuss these more in the next article.

EFI_WIN_NT_PHYSICAL_DISKS=a:RW;2880;512!g:RW;262144;512

EFI_WIN_NT_VIRTUAL_DISKS=FW;40960;512
EFI_WIN_NT_SERIAL_PORT=COM1!COM2
EFI_WIN_NT_GOP=Graphics Output Window 1!Graphics Output Window 2
EFI_WIN_NT_UGA=UGA Window 1!UGA Window 2
EFI_FIRMWARE_VOLUMES=..\Fv\FvRecovery.fd
EFI_WIN_NT_FILE_SYSTEM=.!%EDK_SOURCE%\Other\Maintained\Application\UefiShell\bin\ia32\Apps
EFI_MEMORY_SIZE=64!64
EFI_BOOT_MODE=1
EFI_WIN_NT_CPU_MODEL=Intel(R) Processor Model
EFI_WIN_NT_CPU_SPEED=3000

8. Click "OK"

Debugging
Now you are ready to actually debug. Press F5 (or select Debug|Start Debugging). It will always ask you if you want to rebuild the project, since we havne't added any source files which Visual Studio can use to determine if the project source has been changed. For now, choose Yes and then you will see the program begin to execute normally.

You can halt the execution of the emulated UEFI environment at any time by selecting Debug|Break All. Then you can set some breakpoints on a specific function using Debug|New Breakpoint|Break At Function and type in the function name. You can force a breakpoint by inserting a __debugbreak() into your code.

As the code executes you will notice that the Visual Studio window talks about various DLLs being loaded. The Windows-hosted environment actually loads your UEFI drivers and applications as DLLs (look in C:\Edk\Sample\Platform\Nt32\Uefi\Ia32). The actual main program is called SecMain.exe.

Conclusion
So now we're debugging. But what else can we do with the Windows-hosted (NT32) environment? Next time we'll look at how the environment can be configured.

HOW-TO: Set Up The EDK's Windows-Hosted UEFI Environment With Visual Studio 2008.

Since I'm working on a little research project of my own using UEFI applications, I thought I'd use the Windows-hosted UEFI (aka NT32) environment provided with the EDK. From previous experience, I know that the ability to debug applications using the Visual Studio environment speeds up my development time considerably. So I thought I'd share how I set up my environment. Then next time, I'll share how I set up for debugging.

This article assumes that you have Visual Studio 2008 installed and that the EDK has been downloaded to C:\EDK.

Create New Visual Studio Project
In this step, the goal is to set up Visual Studio so that it can build the Windows-hosted (NT32) UEFI environment. The build files for this project are located in C:\EDK\SAMPLE\PLATFORM\NT32.

1. Select File|New|Project.









2. Select the "General" project category and select "Makefile Project". Then enter the Name as "NT32". Then click "OK".










3. The Makefile Project Wizard will pop up. Click "Finish"














4. Your new project will appear in the Solution Explorer.

















5. Select the NT32 project with the mouse. Select Project|Properties.
















6. On the "NT32 Property Pages", change "Configuration" to "All Configurations".

7. Select "Build Command Line" and then select the ... on the right edge.











8. This will pop up a separate editor box. On three separate lines, enter the following text and click "OK".

cd /D c:\edk\sample\platform\nt32
set EDK_SOURCE=c:\edk
call build.bat

9. Now, for "Rebuild All Command Line" enter:

cd /D c:\edk\sample\platform\nt32

set EDK_SOURCE=c:\edk
call build.bat clean
call build.bat

10. Now, for "Clean Command Line" enter:

cd /D c:\edk\sample\platform\nt32

set EDK_SOURCE=c:\edk
call build.bat clean

11. Finally, for the last step, enter:

c:\edk\sample\platform\nt32\uefi\ia32\SecMain.exe

12. Select OK.












13. Edit Config.env, which is located in C:\EDK\Sample\Platform\NT32\Build, and change USE_VC8 = YES. By default, it is set to NO, which will build with Visual Studio 2003 and a large number of build errors.

Launching The Windows-Hosted Environment.
At this point, should be able to build by selecting Build|Build (or using F7). You can run the emulated environment by going to the command prompt and typing:

cd /d c:\edk\sample\platform\nt32\uefi\ia32
SecMain.exe


You will see (at least) two windows: the debug output console window and then the graphics output window. The graphics output window will show a fake logo, a progress bar and then boot into the built-in EFI Shell.



Conclusion
Well, that gets us to the first step. Next time we'll discuss how to set up the debugger and how to make your code debugger friendly.

Sunday, January 31, 2010

UEFI HII (Part 10): Images

Before starting, you should be aware that the term 'image' has two different meanings in UEFI. First, it refers to executables (EXE), such as drivers and applications, that get loaded into memory by the LoadImage() and StartImage() services. Second, it refers to rectangular, full-color images.

Support for these images started with the UEFI 2.0 specification, with the EFI_GRAPHICS_OUTPUT_PROTOCOL. This protocol provide device-independent services for moving bitmapped images back and forth from a video device. But, it provided no standard means for finding and managing these images.

Then the UEFI 2.1 specification introduced the HII Database. Each driver can install pre-packaged images into the database. Then the driver can manipulate or display them using the EFI_HII_IMAGE_PROTOCOL.

Image Attributes
Images have the following attributes:
  • Identifier. Along with the database handle, this identifier uniquely specifies the image.
  • Width. The number of pixels per image row.
  • Height. The number of image rows.
  • Transparent. Indicates whether the pure black pixels (RGB(0,0,0)) will be drawn transparently over the background.
  • Bitmap. Image pixels are organized left-to-right and then top-to-bottom. Each image pixel consists of 32-bits. The first 8-bits in each pixel are the blue (0 = off, 255 = on), the next 8-bits are the green and the next 8-bits are the blue.


Image Services
The UEFI HII Image protocol provides two classes of services:  

  1. Get/Set. You can get an image from the HII database, change an image in the HII database and add a new image to the HII database.

  2. Draw. You can draw an image, either using an image identifier or from a raw bitmapped image. In both cases, the drawing can be done directly to the screen or into another image, with or without clipping.

Conclusion
Images are slowly being integrated into firmware as an integral part, simply because of user expectations and a desire for OEMs to stand out in a crowd. UEFI 2.1 provides built-in support for basic image manipulation services. UEFI 2.3 also added support for animations. In our next article, we will look at how UEFI stores different types of images in the HII packages.


Saturday, January 30, 2010

UEFI HII (Part 9): Font Package Encoding

Ok, now into the gory details of how font packages are encoded. In many ways, font packages are like string packages except, instead of strings, we are talking about font glyphs. There is a font header, followed by font information and then a series of font blocks.



The glyph blocks represent the glyphs in sorted order, starting with the glyph for character value 0x0001 and incrementing from there. Each glyph block increments the character value by either 1 or N. There are five basic types of glyph blocks:
  1. Glyphs. These actually contain glyph data. There are variants for a single glyph or multiple glyphs, ones which use default character cell information or their own character cell information. The current character value is incremented by either 1 (for single glyph versions) or N (for multiple glyph versions).
  2. Duplicate. This block duplicates the glyph data for a character value that has already been processed.  The current character value is incremented by 1.
  3. Skip. These blocks skip a specified number of character values. For example, there might be no glyphs for character values 0x2000-0x20FF, but then one more glyph for character value 0x2100. A Skip block leaves a gap. The current character value is incremented by the skip count specified.
  4. Defaults. This block sets up the default character cell information for the subsequent glyph blocks which use defaults. This is useful for fonts where a lot of characters share a specific set of information, such as Courier or other fixed-format fonts.
  5. End. This marks the end of the glyph block information.
The actual glyph data is packed with one bit per pixel of the glyph, but rows are rounded up to the nearest byte (8 pixel) boundary. For example, consider the letter 'A'.


In this case, the actual glyph data is 9 pixels wide and 11 pixels high. If optimally packed, this would lead to a storage size of 99 bits or 13 bytes (12 with 3 bits left over). However, when this was being discussed, some preliminary implementation data suggested that the glyphs were much easier to handle if each row was byte aligned (the blue shaded area in the diagram). Then, after testing with compression software (since we assumed that the fonts would be stored compressed) that the bit-packed data actually was larger after compression than the byte-packed data.

Conclusion
This wraps up the second on fonts. Next week, we'll dive into how HII stores and handles images.

Saturday, January 23, 2010

Harnessing The UEFI Shell

Just a quick plug to note that a book co-authored by myself and three Intel engineers (Mike Rothman, Bob Hale and Vincent Zimmer) is finally available for sale via Amazon or through Intel Press. UPS says that my personal copy arrives next Wednesday. Yeah!

UEFI HII (Part 8): Proportional Fonts

The UEFI Specification provids services and storage for manipulating bitmap fonts as part of the Human Interface Infrastructure (HII). Last week, we looked at the Simple Font, which describes a means of storing a fixed-width font for Unicode character values. Each character in the Simple Font is either in an 8 x 19 (narrow) pixel or 16 x 19 (wide) pixel character cell.

Proportional fonts extend bitmapped font support in several significant ways:
  1. There can be multiple fonts, each described by its name, height and style (bold, italics, underline, etc.).
  2. Each character cell in the font can be a different width.
Fonts
So, for UEFI, a font is a logical grouping of glyphs identified by a name, a size and a style.
  • Font Name. "The font name describes, in broad terms, the visual style of the font." How do you tell that a character is part of the Arial font? Or Times New Roman? Well, they tend to share certain visual characteristics, such as whether they have serifs, or whether they are rounded or angular or represent alphabetic characters or symbols. 
  • Font Size. "The font size describes the maximum height of the character cell, in pixels. The standard font always has the font size of 19." Rather than describing characters in terms of "points", the UEFI specification describes them in terms of the height of the character cell, in pixels. The UEFI specification does not use points, because (a) it only uses bitmapped fonts and (b) although points technically refers to 1/72nd of an inch, it actually does little to describe how much screen space a font will take up (except in comparison with another point size for the same font).
  • Font Style. "The font style describes standard visual modifies to the base visual style of a font." In other words, you can have Arial, Arial + Bold, Arial + Italic, Arial + Bold and Italic, etc. They are still an Arial font, but they have additional stylistic modifiers. The UEFI specification explicitly supports bold, italic, underline, double-underline, embossed, outline and shadowed.
Glyphs
The glyph is the image representation of the character, with each dot in the image represented by a single bit, on or off. The off pixels are either not drawn (for transparent drawing) or else drawn in the background color. The on pixels are drawn in the foreground color. For example, for the letter A, it might look like this:


But this isn't enough information to draw the glyph. For one thing, we don't know how much space to leave between this glyph and other glyphs that we have drawn. This is one of the key differences between this font and the simple font in the previous articles. Simple fonts have the empty space above, below, before and after the character image built into the glyph. Proportional fonts track this sort of information separately, using three key ideas:
  1. The character cell.
  2. The baseline.
  3. The character advance.
Character Cell

The character cell is a box that the glyph's image is positioned inside of. Each font has a character cell and each character glyph's image is placed relative to the top-left corner of that cell, or box. For example:




Baseline
The baseline (or Offset Y) allows UEFI firmware to draw text from different fonts on the same line and still have everything line up correctly. The baseline is calculated as the number of pixels above the Origin of the tallest character image.

 

In this picture, the baseline is the height of the tallest character (A). Notice that the character 'q' starts 3 pixels below the baseline, while both the 'A' and 'x' start on the baseline and the quotation mark (") starts 8 pixels above the baseline. The gap between the Origin and the left-most pixel of the glyph is known as Offset X. For the 'A' and 'q' and quotation mark, this is 1 pixel. For the 'x', this is 0 pixels.

Character Advance
The character advance is the number of pixels to move the Origin to the right. The character advance determines how much whitespace to put to the left and right of the glyph.

Conclusion
All of these details about offsets and baselines, advances and cells may seem intimidating, especially in a firmware environment. Many basic tasks become a lot more difficult when using proportional fonts: drawing text, editing a string or selecting text (with a mouse!). Fortunately, the EFI_HII_FONT_PROTOCOL provides functions which not only draw a string to a buffer or to the screen, but also report back information about the width and height of each character drawn. We will investigate these in more detail later.

Next week we will return to how the fonts are encoded.

Sunday, December 06, 2009

UEFI HII (Part 7): Character Encoding

How do you know that the character 'A' corresponds to the character value 0x0041? Or that character value 0x215d is the character '⅝'? Well, standard, such as ASCII or the Unicode standard (or, going further back EBCDIC) describe the mapping between a numeric value and a specific characer.

But how to convert those numeric values into actual bits and bytes? 7-bits, 8-bits, 16-bits, 32-bits? And if more than one byte, is it big-endian or little-endian? That conversion process is called encoding.

I have the Unicode 1.0 specification sitting on my shelf. At that time, there was some optimism that all the character values that anyone would ever need could be contained in 16-bits: 65,536 character values. But even then, there were some signs that people were inventing and had invented many more character glyphs than could be contained. For example, in some scripts, individual cities had their own glyphs. And what about the Mahjong tile characters (0x1F000-0x1F002b)? So, prior to the Unicode 2.0 specification, the predominant form of encoding (known as UCS-2) embodied this 16-bit assumption.

But prior to that point, many operating systems (such as Windows NT) and firmware specifications (such as EFI 1.10) had taken root. While most operating systems have since migrated to the preferred encoding standard (UTF-16), which can handle the full set of Unicode character values, the UEFI specification still retains UCS-2.

So what is the big difference between UCS-2 and UTF-16? They are both 16-bit encoding schemes. For all the character values we care about, they are identical. Most of these characterThe real difference comes in how they handle character values beyond 0x10000 (that is, beyond character 65,536).

For UCS-2, these characters don't exist. There is no proper way to encode charcter 0x10001.  For UTF-16, characters values more than 0x10000 are encoded by combining two adjacent 16-bit characters. No one was particularly happy about this solution, since it took everyone back into the multi-byte character encoding nightmare that had plagued so many previous standards attempts (Shift-JI1, GB5, Windows code pages, etc.). But the alternative was to require a 32-bit unsigned integer to represent the characters, which would add a lot of bloat. But the advantage of this technique was that only a limit range of character values could appear as the first half of a surrogate pair (0xD800-0xDBFF) and another limited range of character values could appear as the second half (0xDC00-0xDFFF).  To calculate a character value, you take 6 bits from each and add 0x10000 to the result. This gives you a range of possible character values between 0x0000000-0xFFFFFFF. By separating the surrogate pair values in to first-half and second-half allowed string processing functions to work no matter where in the string they started from and which direction they processed the string. For more information, you can read the FAQ at the Unicode site.

But, for the purposes of the UEFI specification, those surrogate pair character values have no special meaning and would each be treated as a separate character. That is, 0xD800 0xDC00 would be a single character in UTF-16, but two characters under UEFI and UCS-2.

The UEFI specification does use another range of characters with special meaning defined in the Unicode specification: the Private Usage Areas. The Private Usage Area, which is a range of character values from 0xE000-0xF7FF) is left open to use by an application. In UEFI, these are used for embedding font control information directly into strings. The values 0xF620-0xF62B control turning specific font styles, such as bold, italics, etc. The values 0xF700-0xF7FF are used to select a specific font. The values 0xF800-0xF8FF select a font of a specific cell height. These values will never occur in normal text.

For more information on these character values, as well as others given special treatment in UEFI, see section 28.2.6.2 of the UEFI 2.3 specification.

Next time we'll continue by looking at the characteristics of Proportional Fonts.

Saturday, November 28, 2009

UEFI HII (Part 6): Simple Fonts

Prior to to UEFI 2.10, there was only one graphics display mode: 800 x 600 x 32-bit color depth. Those numbers still show up as a required mode for external plug-in graphics adapters. But what if you want to draw text on those graphical displays? Where does the font come from? How big is it? Does the font really hold all 40K+ characters from the Unicode specification?

According to the EFI (and then UEFI), the system firmware was required to carry the ISO Latin-1 charcters (essentially characters U-0020 through U-00FF in the Unicode specification) as well as the line drawing characters. But that still leaves the question: how big are the bitmaps (or glyphs) in the font?

For a long time, prior to the UEFI 2.10 specification, the answer was 8 pixels wide and 19 pixels high. With a little math, you find that this works perfectly to put 80 columns and 25 rows of text on a 640 x 480 pixel display. That number of pixels, in turn, happens to be the highest resolution that could be produced by a standard VGA adapter. However, a character cell of 8 x 19 is not large enough to hold many of the glyphs found in other scripts, most notably Chinese, Japanese and Korean. So, in addition to the narrow 8 x 19 pixel character cells, a wide 16 x 19 pixel character cell was also supported.

One of the design goals for HII, back when UEFI 2.10 was being crafted, was the support for bitmapped, proportional fonts. But rather than throw away the previous way that font glyph encoding, the previous method was added as another package type: Simple Fonts (type 0x07).

Glyphs

Narrow glyphs consist of a header, followed by 19 bytes. Each of the bytes represents one row of the glyph. Byte 0 represents the top of the glyph and byte 18 represents the bottom of the glyph. Each bit in those bytes represents a single pixel, with a value of zero being off and a value of one being on. Bit 0 is the left-most pixel and bit 7 is the right-most pixel.

Wide glyphs consist of a header, followed by 38 bytes. Essentially they are encoded as two narrow glyphs, first the left half 8 x 19 image, followed by the right half 8 x 19 image.

Packages
The Simple Font package consists of the standard package header, a bit of housekeeping data and then an array of narrow glyph information, followed by an array of wide glyph information.
Each of the narrow glyphs has a small header, followed by the encoded glyph data.
typedef struct _EFI_HII_SIMPLE_FONT_PACKAGE_HDR {

  EFI_HII_PACKAGE_HEADER Header;
      UINT16           NumberOfNarrowGlyphs;
      UINT16           NumberOfWideGlyphs;
      EFI_NARROW_GLYPH NarrowGlyphs[];
      EFI_WIDE_GLYPH   WideGlyphs[];
    } EFI_HII_SIMPLE_FONT_PACKAGE_HDR;

Next week, we'll look at normal fonts.

typedef struct {

  CHAR16 UnicodeWeight;
  UINT8  Attributes;
  UINT8  GlyphCol1[EFI_GLYPH_HEIGHT];
} EFI_NARROW_GLYPH;

The Attributes indicate whether the glyph is narrow or wide and whether the character value is non-spacing. Normally, after drawing a character, the position of the next character would be directly to the right. For non-spacing characters, the next character would be drawn in exactly the same character cell. This allows, for example, the ` or ~ character to act as combining diacritical marks so that, when printed prior to an a or n, would display as á or ñ.
Each of the wide glyphs has a small header followed by the encoded glyph data:

typedef struct {

  CHAR16 UnicodeWeight;
  UINT8 Attributes;
  UINT8 GlyphCol1[EFI_GLYPH_HEIGHT];
  UINT8 GlyphCol2[EFI_GLYPH_HEIGHT];
  UINT8 Pad[3];
} EFI_WIDE_GLYPH;


Multiple Language Support
Let's say I'm designing a plug-in card and I want to support Chinese. But I don't know whether or not the system firmware in the platform where my card is installed supports all the Chinese characters (glyphs) that I need. What can I do? Well, with UEFI 2.10, your driver can just carry the characters you need that are in addition to those provided by the ISO Latin-1 characters that the platform is required to carry in its firmware. The HII Database will automatically combine glyphs from fonts which have the same font family, size and style.
Using The Simple Font
The simple font can be accessed, like all other fonts, through the HII Font protocol. The simple font has the name 'system' and has a height of 19 pixels.

Friday, November 13, 2009

Harnessing The UEFI Shell Book

Ok, a little promotion for the book I co-wrote, which is finally for sale. We finished writing it over 6 months ago. Not that most of you are going to run out and write UEFI Shell apps. But if you were...


http://www.intel.com/intelpress/sum_eshl.htm