aboutsummaryrefslogtreecommitdiffstats

Sometimes we might want to put to the FFS files that aren't the result of the edk2 build. Off course we can do it manually via the FILE = <...> statement, but it is also possible to do it via the INF file. As with compiled modules this keeps code more structured and clean.

The files that we want to push to the FFS need to be listed in the INF module [Binaries] section.

Let's try to create INF file for the Shell.efi image. First build the *.efi file:

build --platform=ShellPkg/ShellPkg.dsc --module=ShellPkg/Application/Shell/Shell.inf --arch=X64 --buildtarget=RELEASE --tagname=GCC5

Now create a folder BinaryModule for our new module and put newly generated file into that folder:

mkdir UefiLessonsPkg/BinaryModule/
cp Build/Shell/RELEASE_GCC5/X64/ShellPkg/Application/Shell/Shell/OUTPUT/Shell.efi UefiLessonsPkg/BinaryModule/

Create INF file:

[Defines]
  INF_VERSION                    = 1.25
  BASE_NAME                      = BinaryModule
  FILE_GUID                      = a580fb82-9d1f-480b-ba42-17273d861c95
  MODULE_TYPE                    = UEFI_APPLICATION
  VERSION_STRING                 = 1.0

[Binaries]
  PE32|Shell.efi

Here we don't need the ENTRY_POINT define that we've always used in our modules. And [Packages] and [LibraryClasses] sections are also no longer necessary. However you might need [Depex] section in a you binary module. But right now we leave things as they are.

The format of the statements inside the [Binaries] section is:

<SectionFileType>|<FilePath>[|Target]
  • <SectionFileType> - remember how there are usually two words for sections inside the rule statements? This is the second word
  • <FilePath> - path to the file to include
  • <Target> - you can use DEBUG/RELEASE/NOOPT/* as a taget, or you can omit this part alltogether

To build the binary module along with the ordinary rule section:

[Rule.<ARCH>.<MODULE_TYPE>]

You need to define another rule section:

[Rule.<ARCH>.<MODULE_TYPE>.BINARY]

So in our case we need to add [Rule.Common.UEFI_APPLICATION.BINARY] section along with the old one [Rule.Common.UEFI_APPLICATION].

UefiLessonsPkg/UefiLessonsPkg.fdf:

[FV.SimpleVolume]
FvAlignment        = 16

INF UefiLessonsPkg/BinaryModule/BinaryModule.inf

[Rule.Common.UEFI_APPLICATION]
  FILE APPLICATION = $(NAMED_GUID) {
    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
    UI       STRING="$(MODULE_NAME)"
    VERSION  STRING="$(INF_VERSION)" BUILD_NUM=$(BUILD_NUMBER)
  }

[Rule.Common.UEFI_APPLICATION.BINARY]
  FILE FREEFORM = $(NAMED_GUID) {
    PE32     PE32                    |.efi
    UI       STRING="$(MODULE_NAME)"
    VERSION  STRING="$(INF_VERSION)" BUILD_NUM=$(BUILD_NUMBER)
  }

To be certain that the correct rule is used in the BINARY rule we create FILE FREEFORM opposed to the FILE APPLICATION in the standard rule.

In the binary rule statements everything is the same except the PE32 statement. Here instead of an actual file we need to write file extension in a form |.<extension>

As we don't need to compile our module, we don't need to add it to the [Components] section of our DSC file. And there wouldn't be any folder like Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/BinaryModule/ after the compilation. Only the Ffs folder would be created:

$ find Build/UefiLessonsPkg/RELEASE_GCC5/FV/Ffs/a580fb82-9d1f-480b-ba42-17273d861c95BinaryModule/
Build/UefiLessonsPkg/RELEASE_GCC5/FV/Ffs/a580fb82-9d1f-480b-ba42-17273d861c95BinaryModule/
Build/UefiLessonsPkg/RELEASE_GCC5/FV/Ffs/a580fb82-9d1f-480b-ba42-17273d861c95BinaryModule/a580fb82-9d1f-480b-ba42-17273d861c95SEC2.ui
Build/UefiLessonsPkg/RELEASE_GCC5/FV/Ffs/a580fb82-9d1f-480b-ba42-17273d861c95BinaryModule/a580fb82-9d1f-480b-ba42-17273d861c95SEC3.ver.txt
Build/UefiLessonsPkg/RELEASE_GCC5/FV/Ffs/a580fb82-9d1f-480b-ba42-17273d861c95BinaryModule/a580fb82-9d1f-480b-ba42-17273d861c95.ffs
Build/UefiLessonsPkg/RELEASE_GCC5/FV/Ffs/a580fb82-9d1f-480b-ba42-17273d861c95BinaryModule/a580fb82-9d1f-480b-ba42-17273d861c95SEC1.1.pe32.txt
Build/UefiLessonsPkg/RELEASE_GCC5/FV/Ffs/a580fb82-9d1f-480b-ba42-17273d861c95BinaryModule/a580fb82-9d1f-480b-ba42-17273d861c95SEC3.ver
Build/UefiLessonsPkg/RELEASE_GCC5/FV/Ffs/a580fb82-9d1f-480b-ba42-17273d861c95BinaryModule/a580fb82-9d1f-480b-ba42-17273d861c95.ffs.txt
Build/UefiLessonsPkg/RELEASE_GCC5/FV/Ffs/a580fb82-9d1f-480b-ba42-17273d861c95BinaryModule/a580fb82-9d1f-480b-ba42-17273d861c95SEC1.1.pe32

And here is the output of VolInfo:

$ VolInfo Build/UefiLessonsPkg/RELEASE_GCC5/FV/SIMPLEVOLUME.Fv -x Build/UefiLessonsPkg/RELEASE_GCC5/FV/Guid.xref
VolInfo Version 1.0 Build Developer Build based on Revision: Unknown
%36s %511s
ParseGuidBaseNameFile: Build/UefiLessonsPkg/RELEASE_GCC5/FV/Guid.xref
Signature:        _FVH (4856465F)
Attributes:       40800
       EFI_FVB2_ERASE_POLARITY
       EFI_FVB2_ALIGNMENT_16
Header Length:         0x00000048
File System ID:        8c8ce578-8a3d-4f1c-9935-896185c32dd3
Revision:              0x0002
Number of Blocks:      0x000E2ED8
Block Length:          0x00000001
Total Volume Size:     0x000E2ED8
============================================================
File Name:        A580FB82-9D1F-480B-BA42-17273D861C95  BinaryModule
File Offset:      0x00000048
File Length:      0x000E2E8A
File Attributes:  0x00
File State:       0xF8
        EFI_FILE_DATA_VALID
File Type:        0x02  EFI_FV_FILETYPE_FREEFORM
------------------------------------------------------------
  Type:  EFI_SECTION_PE32
  Size:  0x000E2E44
------------------------------------------------------------
  Type:  EFI_SECTION_USER_INTERFACE
  Size:  0x0000001E
  String: BinaryModule
------------------------------------------------------------
  Type:  EFI_SECTION_VERSION
  Size:  0x0000000E
  Build Number:  0x0000
  Version String:  1.0
There are a total of 1 files in this FV

Adding other sections

Let's try to write other sections to the file. Create file "hello.txt":

echo "hello" > UefiLessonsPkg/BinaryModule/hello.txt

And add it as RAW to the [Binaries] section:

[Binaries]
  PE32|Shell.efi
  RAW|hello.txt

If we perform build right now, nothing would change.

We need to modify our rule to include .txt files:

[Rule.Common.UEFI_APPLICATION.BINARY]
  FILE FREEFORM = $(NAMED_GUID) {
    PE32     PE32                    |.efi
    UI       STRING="$(MODULE_NAME)"
    VERSION  STRING="$(INF_VERSION)" BUILD_NUM=$(BUILD_NUMBER)
    RAW RAW |.txt
  }

With this rule the new section would be added to the file:

$ VolInfo Build/UefiLessonsPkg/RELEASE_GCC5/FV/SIMPLEVOLUME.Fv -x Build/UefiLessonsPkg/RELEASE_GCC5/FV/Guid.xref
VolInfo Version 1.0 Build Developer Build based on Revision: Unknown
%36s %511s
ParseGuidBaseNameFile: Build/UefiLessonsPkg/RELEASE_GCC5/FV/Guid.xref
Signature:        _FVH (4856465F)
Attributes:       40800
       EFI_FVB2_ERASE_POLARITY
       EFI_FVB2_ALIGNMENT_16
Header Length:         0x00000048
File System ID:        8c8ce578-8a3d-4f1c-9935-896185c32dd3
Revision:              0x0002
Number of Blocks:      0x000E2EE0
Block Length:          0x00000001
Total Volume Size:     0x000E2EE0
============================================================
File Name:        A580FB82-9D1F-480B-BA42-17273D861C95  BinaryModule
File Offset:      0x00000048
File Length:      0x000E2E96
File Attributes:  0x00
File State:       0xF8
        EFI_FILE_DATA_VALID
File Type:        0x02  EFI_FV_FILETYPE_FREEFORM
------------------------------------------------------------
  Type:  EFI_SECTION_PE32
  Size:  0x000E2E44
------------------------------------------------------------
  Type:  EFI_SECTION_USER_INTERFACE
  Size:  0x0000001E
  String: BinaryModule
------------------------------------------------------------
  Type:  EFI_SECTION_VERSION
  Size:  0x0000000E
  Build Number:  0x0000
  Version String:  1.0
------------------------------------------------------------
  Type:  EFI_SECTION_RAW
  Size:  0x0000000A
There are a total of 1 files in this FV

Let's try to add another .txt file to our module. Create file:

$ echo "world!" > UefiLessonsPkg/BinaryModule/world.txt

And include it to the [Binaries] section:

[Binaries]
  PE32|Shell.efi
  RAW|hello.txt
  RAW|world.txt

In this case two RAW sections would be at the end of our file:

$ VolInfo Build/UefiLessonsPkg/RELEASE_GCC5/FV/SIMPLEVOLUME.Fv -x Build/UefiLessonsPkg/RELEASE_GCC5/FV/Guid.xref
VolInfo Version 1.0 Build Developer Build based on Revision: Unknown
%36s %511s
ParseGuidBaseNameFile: Build/UefiLessonsPkg/RELEASE_GCC5/FV/Guid.xref
Signature:        _FVH (4856465F)
Attributes:       40800
       EFI_FVB2_ERASE_POLARITY
       EFI_FVB2_ALIGNMENT_16
Header Length:         0x00000048
File System ID:        8c8ce578-8a3d-4f1c-9935-896185c32dd3
Revision:              0x0002
Number of Blocks:      0x000E2EF0
Block Length:          0x00000001
Total Volume Size:     0x000E2EF0
============================================================
File Name:        A580FB82-9D1F-480B-BA42-17273D861C95  BinaryModule
File Offset:      0x00000048
File Length:      0x000E2EA3
File Attributes:  0x00
File State:       0xF8
        EFI_FILE_DATA_VALID
File Type:        0x02  EFI_FV_FILETYPE_FREEFORM
------------------------------------------------------------
  Type:  EFI_SECTION_PE32
  Size:  0x000E2E44
------------------------------------------------------------
  Type:  EFI_SECTION_USER_INTERFACE
  Size:  0x0000001E
  String: BinaryModule
------------------------------------------------------------
  Type:  EFI_SECTION_VERSION
  Size:  0x0000000E
  Build Number:  0x0000
  Version String:  1.0
------------------------------------------------------------
  Type:  EFI_SECTION_RAW
  Size:  0x0000000A
------------------------------------------------------------
  Type:  EFI_SECTION_RAW
  Size:  0x0000000B
There are a total of 1 files in this FV

The hello section is the one that has a size 0x0000000A, and world! section is the one that has a size 0x0000000B as it is one symbol longer.

You can see both strings if you look at the ffs file with hexdump:

$ hexdump Build/UefiLessonsPkg/RELEASE_GCC5/FV/Ffs/a580fb82-9d1f-480b-ba42-17273d861c95BinaryModule/a580fb82-9d1f-480b-ba42-17273d861c95.ffs -C | tail
000e2e20  d8 ab e8 ab 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000e2e30  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000e2e50  00 00 00 00 00 00 00 00  00 00 00 00 1e 00 00 15  |................|
000e2e60  42 00 69 00 6e 00 61 00  72 00 79 00 4d 00 6f 00  |B.i.n.a.r.y.M.o.|
000e2e70  64 00 75 00 6c 00 65 00  00 00 00 00 0e 00 00 14  |d.u.l.e.........|
000e2e80  00 00 31 00 2e 00 30 00  00 00 00 00 0a 00 00 19  |..1...0.........|
000e2e90  68 65 6c 6c 6f 0a 00 00  0b 00 00 19 77 6f 72 6c  |hello.......worl|
000e2ea0  64 21 0a                                          |d!.|
000e2ea3

Many sections of the same type in one rule

What whould be if you put another RAW statement to the file?

[Rule.Common.UEFI_APPLICATION.BINARY]
  FILE FREEFORM = $(NAMED_GUID) {
    RAW RAW |.txt
    PE32     PE32                    |.efi
    UI       STRING="$(MODULE_NAME)"
    VERSION  STRING="$(INF_VERSION)" BUILD_NUM=$(BUILD_NUMBER)
    RAW RAW |.txt
  }

Each statement would generate 2 RAW sections (hello and world!) in this case:

$ VolInfo Build/UefiLessonsPkg/RELEASE_GCC5/FV/SIMPLEVOLUME.Fv -x Build/UefiLessonsPkg/RELEASE_GCC5/FV/Guid.xref
VolInfo Version 1.0 Build Developer Build based on Revision: Unknown
%36s %511s
ParseGuidBaseNameFile: Build/UefiLessonsPkg/RELEASE_GCC5/FV/Guid.xref
Signature:        _FVH (4856465F)
Attributes:       40800
       EFI_FVB2_ERASE_POLARITY
       EFI_FVB2_ALIGNMENT_16
Header Length:         0x00000048
File System ID:        8c8ce578-8a3d-4f1c-9935-896185c32dd3
Revision:              0x0002
Number of Blocks:      0x000E2F08
Block Length:          0x00000001
Total Volume Size:     0x000E2F08
============================================================
File Name:        A580FB82-9D1F-480B-BA42-17273D861C95  BinaryModule
File Offset:      0x00000048
File Length:      0x000E2EBB
File Attributes:  0x00
File State:       0xF8
        EFI_FILE_DATA_VALID
File Type:        0x02  EFI_FV_FILETYPE_FREEFORM
------------------------------------------------------------
  Type:  EFI_SECTION_RAW
  Size:  0x0000000A
------------------------------------------------------------
  Type:  EFI_SECTION_RAW
  Size:  0x0000000B
------------------------------------------------------------
  Type:  EFI_SECTION_PE32
  Size:  0x000E2E44
------------------------------------------------------------
  Type:  EFI_SECTION_USER_INTERFACE
  Size:  0x0000001E
  String: BinaryModule
------------------------------------------------------------
  Type:  EFI_SECTION_VERSION
  Size:  0x0000000E
  Build Number:  0x0000
  Version String:  1.0
------------------------------------------------------------
  Type:  EFI_SECTION_RAW
  Size:  0x0000000A
------------------------------------------------------------
  Type:  EFI_SECTION_RAW
  Size:  0x0000000B
There are a total of 1 files in this FV

SectionFileType for RAW section

Remember how I told you that RAW section can have several SectionFileType's: RAW/BIN/ASL/ACPI. You can try to use them for our files:

[Binaries]
  PE32|Shell.efi
  ASL|hello.txt
  ACPI|world.txt

Off course our *.txt aren't connected to the ACPI in any way, but let's just do it as an experiment.

Modify rule statement like this:

[Rule.Common.UEFI_APPLICATION.BINARY]
  FILE FREEFORM = $(NAMED_GUID) {
    PE32     PE32                    |.efi
    UI       STRING="$(MODULE_NAME)"
    VERSION  STRING="$(INF_VERSION)" BUILD_NUM=$(BUILD_NUMBER)
    RAW ASL |.txt
  }

Now build system would include only the file ASL|hello.txt, but not ACPI|world.txt as the rule works only with ASL SectionFileType's. For the proof look at the VolInfo output:

$ VolInfo Build/UefiLessonsPkg/RELEASE_GCC5/FV/SIMPLEVOLUME.Fv -x Build/UefiLessonsPkg/RELEASE_GCC5/FV/Guid.xref
VolInfo Version 1.0 Build Developer Build based on Revision: Unknown
%36s %511s
ParseGuidBaseNameFile: Build/UefiLessonsPkg/RELEASE_GCC5/FV/Guid.xref
Signature:        _FVH (4856465F)
Attributes:       40800
       EFI_FVB2_ERASE_POLARITY
       EFI_FVB2_ALIGNMENT_16
Header Length:         0x00000048
File System ID:        8c8ce578-8a3d-4f1c-9935-896185c32dd3
Revision:              0x0002
Number of Blocks:      0x000E2EE0
Block Length:          0x00000001
Total Volume Size:     0x000E2EE0
============================================================
File Name:        A580FB82-9D1F-480B-BA42-17273D861C95  BinaryModule
File Offset:      0x00000048
File Length:      0x000E2E96
File Attributes:  0x00
File State:       0xF8
        EFI_FILE_DATA_VALID
File Type:        0x02  EFI_FV_FILETYPE_FREEFORM
------------------------------------------------------------
  Type:  EFI_SECTION_PE32
  Size:  0x000E2E44
------------------------------------------------------------
  Type:  EFI_SECTION_USER_INTERFACE
  Size:  0x0000001E
  String: BinaryModule
------------------------------------------------------------
  Type:  EFI_SECTION_VERSION
  Size:  0x0000000E
  Build Number:  0x0000
  Version String:  1.0
------------------------------------------------------------
  Type:  EFI_SECTION_RAW
  Size:  0x0000000A
There are a total of 1 files in this FV

One final thing to note: there is no difference in a flash content from an actual SectionFileType that you use in [Binaries] section RAW/BIN/ASL/ACPI. There is no difference between ASL|hello.txt or BIN|hello.txt as long as the file is included in the rule.

FILE RAW = in the rule

BINARY rules also allow to add RAW files to the filesystem. Here is an example:

[Rule.Common.UEFI_APPLICATION.BINARY]
  FILE RAW = $(NAMED_GUID) {
                          |.efi
  }

This would produce following VolInfo output:

$ VolInfo Build/UefiLessonsPkg/RELEASE_GCC5/FV/SIMPLEVOLUME.Fv -x Build/UefiLessonsPkg/RELEASE_GCC5/FV/Guid.xref
VolInfo Version 1.0 Build Developer Build based on Revision: Unknown
%36s %511s
ParseGuidBaseNameFile: Build/UefiLessonsPkg/RELEASE_GCC5/FV/Guid.xref
Signature:        _FVH (4856465F)
Attributes:       40800
       EFI_FVB2_ERASE_POLARITY
       EFI_FVB2_ALIGNMENT_16
Header Length:         0x00000048
File System ID:        8c8ce578-8a3d-4f1c-9935-896185c32dd3
Revision:              0x0002
Number of Blocks:      0x000E2EA0
Block Length:          0x00000001
Total Volume Size:     0x000E2EA0
============================================================
File Name:        A580FB82-9D1F-480B-BA42-17273D861C95  BinaryModule
File Offset:      0x00000048
File Length:      0x000E2E58
File Attributes:  0x00
File State:       0xF8
        EFI_FILE_DATA_VALID
File Type:        0x01  EFI_FV_FILETYPE_RAW
There are a total of 1 files in this FV

Override for binary modules

In case you use override for a binary module:

INF RuleOverride=MyOverride UefiLessonsPkg/BinaryModule/BinaryModule.inf

You only need to provide one rule that matches override name, without the BINARY clause:

[Rule.Common.USER_APPLICATION.MyOverride]

USER_DEFINED module type

In the example above we've used MODULE_TYPE = UEFI_APPLICATION in our module. Often modules that should produce non-standard files in FFS use MODULE_TYPE = USER_DEFINED type.

Links