aboutsummaryrefslogtreecommitdiffstats
path: root/Lessons_uncategorized/Lesson_FDF_FV/README.md
blob: 48ad44fb2e26772f00d29f965285131c62d8a896 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
Now it is time to look at Firmware Volumes (`FV`) and how they are described in the FDF file.

`Firmware Volume` is one of the region types in the `Flash Device Image (FD)`. If you declare some region as FV, you must provide its name `<FVname>` and define a separate section `[FV.<FVname>]`:
```
[FD.<FDname>]
...

0xXXXX|0xYYYY
FV = <FVname>


[FV.<FVname>]
...
```

Firmware volume is a region with a special formatting which is defined by the `UEFI Platform Initialization (PI) specification (Volume 3: Shared Architectural Elements)`.

At the start of each FV is a special header `EFI_FIRMWARE_VOLUME_HEADER` ([https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Pi/PiFirmwareVolume.h](https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Pi/PiFirmwareVolume.h)):
```
EFI_FIRMWARE_VOLUME_HEADER

Summary:
Describes the features and layout of the firmware volume.

Prototype:
typedef struct {
 UINT8 ZeroVector[16];
 EFI_GUID FileSystemGuid;
 UINT64 FvLength;
 UINT32 Signature;
 EFI_FVB_ATTRIBUTES_2 Attributes;
 UINT16 HeaderLength;
 UINT16 Checksum;
 UINT16 ExtHeaderOffset;
 UINT8 Reserved[1];
 UINT8 Revision;
 EFI_FV_BLOCK_MAP BlockMap[];
} EFI_FIRMWARE_VOLUME_HEADER

Parameters:
ZeroVector		The first 16 bytes are reserved to allow for the reset vector of processors whose reset vector is at address 0
FileSystemGuid		Declares the file system with which the firmware volume is formatted
FvLength		Length in bytes of the complete firmware volume, including the header
Signature		Set to {'_','F','V','H'}
Attributes		Declares capabilities and power-on defaults for the firmware volume
HeaderLength		Length in bytes of the complete firmware volume header
Checksum		A 16-bit checksum of the firmware volume header. A valid header sums to zero
ExtHeaderOffset		Offset, relative to the start of the header, of the extended header (EFI_FIRMWARE_VOLUME_EXT_HEADER) or zero if there is no extended header
Reserved		In this version of the specification, this field must always be set to zero
Revision		Set to 2. Future versions of this specification may define new header fields and will increment the Revision field accordingly
FvBlockMap[]		An array of run-length encoded FvBlockMapEntry structures. The array is terminated with an entry of {0,0}

FvBlockMapEntry.NumBlocks 	The number of blocks in the run.
FvBlockMapEntry.BlockLength 	The length of each block in the run

Description:
A firmware volume based on a block device begins with a header that describes the features and layout of the firmware volume. This header includes a description of the capabilities, state, and block map of the device.
```

The rest of the data in the FV region is organized via files in a filesystem. The filesystem in this case is called a `firmware file system (FFS)`. The FFS defines how files are stored in flash. The type of the FFS that is used is defined by the the header GUID field `EFI_FIRMWARE_VOLUME_HEADER.FileSystemGuid`.

Currently the UEFI Platform Initialization (PI) specification defines two filesystems:
```
#define EFI_FIRMWARE_FILE_SYSTEM2_GUID \
 { 0x8c8ce578, 0x8a3d, 0x4f1c, { 0x99, 0x35, 0x89, 0x61, 0x85, 0xc3, 0x2d, 0xd3 } }

#define EFI_FIRMWARE_FILE_SYSTEM3_GUID \
 { 0x5473c07a, 0x3dcb, 0x4dca, { 0xbd, 0x6f, 0x1e, 0x96, 0x89, 0xe7, 0x34, 0x9a } }
```

The main difference between them is that `EFI_FIRMWARE_FILE_SYSTEM3` supports files with a size `>16MB`. For the rest of the article we would describe `EFI_FIRMWARE_FILE_SYSTEM2`.

Each file in the filesystem would have a header `EFI_FFS_FILE_HEADER` ([https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Pi/PiFirmwareFile.h](https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Pi/PiFirmwareFile.h)):
```
EFI_FFS_FILE_HEADER

Summary:
Each file begins with a header that describes the state and contents of the file. The header is 8-byte aligned with respect to the beginning of the firmware volume

Prototype:
typedef struct {
 EFI_GUID Name;
 EFI_FFS_INTEGRITY_CHECK IntegrityCheck;
 EFI_FV_FILETYPE Type;
 EFI_FFS_FILE_ATTRIBUTES Attributes;
 UINT8 Size[3];
 EFI_FFS_FILE_STATE State;
} EFI_FFS_FILE_HEADER;

Parameters:
Name		This GUID is the file name. It is used to uniquely identify the file. There may be only one instance of a file with the file name GUID of Name
		in any given firmware volume, except if the file type is EFI_FV_FILETYPE_FFS_PAD
IntegrityCheck	Used to verify the integrity of the file
Type		Identifies the type of file
Attributes	Declares various file attribute bits
Size		The length of the file in bytes, including the FFS header
State		Used to track the state of the file throughout the life of the file from creation to deletion
```

The data inside the file is formatted with respect to the `EFI_FFS_FILE_HEADER.Type` field. Specification defines these file types:

| Name | Value | Description |
| ---- | ----- | ----------- |
| EFI_FV_FILETYPE_RAW | 0x01 | Binary data |
| EFI_FV_FILETYPE_FREEFORM | 0x02 | Sectioned data |
| EFI_FV_FILETYPE_SECURITY_CORE | 0x03 | Platform core code used during the SEC phase |
| EFI_FV_FILETYPE_PEI_CORE | 0x04 | PEI Foundation |
| EFI_FV_FILETYPE_DXE_CORE | 0x05 | DXE Foundation |
| EFI_FV_FILETYPE_PEIM | 0x06 | PEI module (PEIM) |
| EFI_FV_FILETYPE_DRIVER | 0x07 | DXE driver |
| EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER | 0x08 | Combined PEIM/DXE driver |
| EFI_FV_FILETYPE_APPLICATION | 0x09 | Application |
| EFI_FV_FILETYPE_MM | 0x0A | Contains a PE32+ image that will be loaded into MMRAM in MM Traditional Mode |
| EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE | 0x0B | Firmware volume image |
| EFI_FV_FILETYPE_COMBINED_MM_DXE | 0x0C | Contains PE32+ image that will be dispatched by the DXE Dispatcher and will also be loaded into MMRAM in MM Tradition Mode |
| EFI_FV_FILETYPE_MM_CORE | 0x0D | MM Foundation that support MM Traditional Mode |
| EFI_FV_FILETYPE_MM_STANDALONE | 0x0E | Contains a PE32+ image that will be loaded into MMRAM in MM Standalone Mode |
| EFI_FV_FILETYPE_MM_CORE_STANDALONE | 0x0F | MM Foundation that support MM Tradition Mode and MM Standalone Mode |
| EFI_FV_FILETYPE_OEM_MIN…EFI_FV_FILETYPE_OEM_MAX | 0xC0-0xDF | OEM File Types |
| EFI_FV_FILETYPE_DEBUG_MIN…EFI_FV_FILETYPE_DEBUG_MAX | 0xE0-0xEF | Debug/Test File Types |
| EFI_FV_FILETYPE_FFS_MIN…EFI_FV_FILETYPE_FFS_MAX | 0xF0-0xFF | Firmware File System Specific File Types |
| EFI_FV_FILETYPE_FFS_PAD | 0xF0 | Pad File For FFS |


Almost each type of file consists of sections, with each section prepended with a header `EFI_COMMON_SECTION_HEADER` ([https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Pi/PiFirmwareFile.h](https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Pi/PiFirmwareFile.h)):
```
EFI_COMMON_SECTION_HEADER

Summary:
Defines the common header for all the section types

Prototype:
typedef struct {
 UINT8 Size[3];
 EFI_SECTION_TYPE Type;
} EFI_COMMON_SECTION_HEADER;

Parameters:
Size	A 24-bit unsigned integer that contains the total size of the section in bytes, including the EFI_COMMON_SECTION_HEADER
Type	Declares the section type

Description:
The type EFI_COMMON_SECTION_HEADER defines the common header for all the section types
```

Specification defines following sections:
| Name | Value | Description |
| ---- | ----- | ----------- |
| EFI_SECTION_COMPRESSION | 0x01 | Encapsulation section where other sections are compressed |
| EFI_SECTION_GUID_DEFINED | 0x02 | Encapsulation section where other sections have format defined by a GUID |
| EFI_SECTION_DISPOSABLE | 0x03 | Encapsulation section used during the build process but not required for execution |
| EFI_SECTION_PE32 | 0x10 | PE32+ Executable image |
| EFI_SECTION_PIC | 0x11 | Position-Independent Code |
| EFI_SECTION_TE | 0x12 | Terse Executable image |
| EFI_SECTION_DXE_DEPEX | 0x13 | DXE Dependency Expression |
| EFI_SECTION_VERSION | 0x14 | Version, Text and Numeric |
| EFI_SECTION_USER_INTERFACE | 0x15 | User-Friendly name of the driver |
| EFI_SECTION_COMPATIBILITY16 | 0x16 | DOS-style 16-bit EXE |
| EFI_SECTION_FIRMWARE_VOLUME_IMAGE | 0x17 | PI Firmware Volume image |
| EFI_SECTION_FREEFORM_SUBTYPE_GUID | 0x18 | Raw data with GUID in header to define format |
| EFI_SECTION_RAW | 0x19 | Raw data |
| EFI_SECTION_PEI_DEPEX | 0x1b | PEI Dependency Expression |
| EFI_SECTION_MM_DEPEX | 0x1c | Leaf section type for determining the dispatch order for an MM Traditional driver in MM Traditional Mode or MM Standaline driver in MM Standalone Mode |

# Create simple Firmware Volume

Now let's try to create the most simple firmware volume which would contain one binary file. Here is code for this structure (`UefiLessonsPkg/UefiLessonsPkg.fdf`):
```
[FD.SimpleImage]
BaseAddress   = 0x0
Size          = 0x1000
ErasePolarity = 1

0x100|0x500
FV = SimpleVolume

[FV.SimpleVolume]
FvAlignment   = 16

FILE RAW = 15c658f6-eb5c-4b8f-b232-d6bd7368a73e {
  $(WORKDIR)/hello.txt
}
```

Like in the FD case, we can set some characteristics of FV via predefined tokens.
In this example we have only one token setting `FvAlignment = 16`, which is placed rigth after the `[FV.SimpleVolume]`. It is the only mandatory token for the `Firmware Volume`. We will talk about FV tokens later.

Next we define what goes into the FFS of the FV. Here we have one FILE of type `RAW`, which means that the file type `EFI_FFS_FILE_HEADER.Type` is equal to `EFI_FV_FILETYPE_RAW`.
And specification defines this type like this:
```
EFI_FV_FILETYPE_RAW
The file type EFI_FV_FILETYPE_RAW denotes a file that does not contain sections and is treated as a raw data file
```
The GUID value `15c658f6-eb5c-4b8f-b232-d6bd7368a73e` I've generated via `uuidgen` utility. It defines a unique name for our file in the FFS and will be written to the `EFI_FFS_FILE_HEADER.Name` field.
Inside the brackets we define content for the file. In our case it is our `hello.txt` generated via `echo "hello!" > hello.txt` command.

Let's build and check our FD image:
```
$ hexdump Build/UefiLessonsPkg/RELEASE_GCC5/FV/SIMPLEIMAGE.fd -C
00000000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000100  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000110  78 e5 8c 8c 3d 8a 1c 4f  99 35 89 61 85 c3 2d d3  |x...=..O.5.a..-.|
00000120  00 05 00 00 00 00 00 00  5f 46 56 48 00 08 04 00  |........_FVH....|
00000130  48 00 cd e3 00 00 00 02  00 05 00 00 01 00 00 00  |H...............|
00000140  00 00 00 00 00 00 00 00  f6 58 c6 15 5c eb 8f 4b  |.........X..\..K|
00000150  b2 32 d6 bd 73 68 a7 3e  5f aa 01 00 1f 00 00 f8  |.2..sh.>_.......|
00000160  68 65 6c 6c 6f 21 0a ff  ff ff ff ff ff ff ff ff  |hello!..........|
00000170  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000600
```
Besides FD, EDKII build system also generates images for Firmware Volumes. We've generated our FV with `Offset|Size = 0x100|0x500`, therefore you can see how `SIMPLEIMAGE.fd` has 0x100 bytes of 0xff's at the start of an image, and how `SIMPLEVOLUME.Fv` starts right from its data.
```
$ hexdump Build/UefiLessonsPkg/RELEASE_GCC5/FV/SIMPLEVOLUME.Fv -C
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000010  78 e5 8c 8c 3d 8a 1c 4f  99 35 89 61 85 c3 2d d3  |x...=..O.5.a..-.|
00000020  00 05 00 00 00 00 00 00  5f 46 56 48 00 08 04 00  |........_FVH....|
00000030  48 00 cd e3 00 00 00 02  00 05 00 00 01 00 00 00  |H...............|
00000040  00 00 00 00 00 00 00 00  f6 58 c6 15 5c eb 8f 4b  |.........X..\..K|
00000050  b2 32 d6 bd 73 68 a7 3e  5f aa 01 00 1f 00 00 f8  |.2..sh.>_.......|
00000060  68 65 6c 6c 6f 21 0a ff  ff ff ff ff ff ff ff ff  |hello!..........|
00000070  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000500
```

Firmware Volume data starts with a header. In our case:
```cpp
typedef struct {
  UINT8                     ZeroVector[16];			= { 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 }
  EFI_GUID                  FileSystemGuid;			= { 0x8c8ce578, 0x8a3d, 0x4f1c, { 0x99, 0x35, 0x89, 0x61, 0x85, 0xc3, 0x2d, 0xd3 } } = EFI_FIRMWARE_FILE_SYSTEM2_GUID
  UINT64                    FvLength;				= 0x0000000000000500
  UINT32                    Signature;				= "_FVH"
  EFI_FVB_ATTRIBUTES_2      Attributes;				= 0x00040800 = (EFI_FVB2_ERASE_POLARITY | EFI_FVB2_ALIGNMENT_16)
  UINT16                    HeaderLength;			= 0x0048
  UINT16                    Checksum;				= 0xe3cd
  UINT16                    ExtHeaderOffset;			= 0x0000
  UINT8                     Reserved[1];			= 0x00
  UINT8                     Revision;				= 0x02
  EFI_FV_BLOCK_MAP_ENTRY    BlockMap[1];			= [{0x00000500, 0x00000001}, {0x00000000, 0x00000000}]
} EFI_FIRMWARE_VOLUME_HEADER;
```

Right after the `EFI_FIRMWARE_VOLUME_HEADER` we have a header for our only file:
```cpp
typedef struct {
 EFI_GUID Name;							= 15c658f6-eb5c-4b8f-b232-d6bd7368a73e
 EFI_FFS_INTEGRITY_CHECK IntegrityCheck;			= 0x5faa
 EFI_FV_FILETYPE Type;						= 0x01 (=EFI_FV_FILETYPE_RAW)
 EFI_FFS_FILE_ATTRIBUTES Attributes;				= 0x00
 UINT8 Size[3];							= 0x00001f
 EFI_FFS_FILE_STATE State;					= 0xf8
} EFI_FFS_FILE_HEADER;
```

Right after that we have a content of our file `hello.txt`:
```
$ hexdump hello.txt -C
00000000  68 65 6c 6c 6f 21 0a                              |hello!.|
0000000
```

The rest of the FV is filled with `0xff`.

# VolInfo

There is an utility `BaseTools/BinWrappers/PosixLike/VolInfo` that you can use to dump information about Firmware Volumes. Here is an example how we can use it to dump information about our Formware Volume:
```
$ 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
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:      0x00000500
Block Length:          0x00000001
Total Volume Size:     0x00000500
============================================================
File Name:        15C658F6-EB5C-4B8F-B232-D6BD7368A73E  /<...>/edk2/$(WORKDIR)/hello.txt
File Offset:      0x00000048
File Length:      0x0000001F
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
```

As you can see this utility gives us the same information that we've parsed ourselves.

# Another file

Let's add another file to our FFS. For a change let's initialize our next file with binary content:
```
$ echo -n -e \\xDE\\xAD\\xBE\\xEF > DEADBEEF.txt
$ hexdump DEADBEEF.txt -C
00000000  de ad be ef                                       |....|
00000004
```
Now let's add it to our FFS:
```
[FD.SimpleImage]
BaseAddress   = 0x0
Size          = 0x1000
ErasePolarity = 1

0x100|0x500
FV = SimpleVolume

[FV.SimpleVolume]
FvAlignment   = 16

FILE RAW = 15c658f6-eb5c-4b8f-b232-d6bd7368a73e {
  $(WORKDIR)/hello.txt
}

FILE RAW = dd77425e-d338-43e7-8e94-1a755e0c217d {
  $(WORKDIR)/DEADBEEF.txt
}
```

Build image and look at the Firmware Volume content:
```
$ hexdump /home/aladyshev/tiano/2021/edk2/Build/UefiLessonsPkg/RELEASE_GCC5/FV/SIMPLEVOLUME.Fv -C
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000010  78 e5 8c 8c 3d 8a 1c 4f  99 35 89 61 85 c3 2d d3  |x...=..O.5.a..-.|
00000020  00 05 00 00 00 00 00 00  5f 46 56 48 00 08 04 00  |........_FVH....|
00000030  48 00 cd e3 00 00 00 02  00 05 00 00 01 00 00 00  |H...............|
00000040  00 00 00 00 00 00 00 00  f6 58 c6 15 5c eb 8f 4b  |.........X..\..K|
00000050  b2 32 d6 bd 73 68 a7 3e  5f aa 01 00 1f 00 00 f8  |.2..sh.>_.......|
00000060  68 65 6c 6c 6f 21 0a ff  5e 42 77 dd 38 d3 e7 43  |hello!..^Bw.8..C|
00000070  8e 94 1a 75 5e 0c 21 7d  01 aa 01 00 1c 00 00 f8  |...u^.!}........|
00000080  de ad be ef ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000090  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000500
```
Here you can see how our files follow each other in the FFS. Each of the files has its own `EFI_FFS_FILE_HEADER` with its unique Name (=GUID). The important thing to note that the filesystem is flat, files just follow one another. Therefore to find some file by GUID, we need to traverse FFS from the start.
Also here you can see that the padding byte 0xff was inserted between the files. It was inserted because according to the specification each file must start at 8 byte boundary.

We can use `VolInfo` to see how it interprets our Firmware Volume:
```
$ 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
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:      0x00000500
Block Length:          0x00000001
Total Volume Size:     0x00000500
============================================================
File Name:        15C658F6-EB5C-4B8F-B232-D6BD7368A73E  /home/aladyshev/tiano/2021/edk2/$(WORKDIR)/hello.txt
File Offset:      0x00000048
File Length:      0x0000001F
File Attributes:  0x00
File State:       0xF8
        EFI_FILE_DATA_VALID
File Type:        0x01  EFI_FV_FILETYPE_RAW
============================================================
File Name:        DD77425E-D338-43E7-8E94-1A755E0C217D  /home/aladyshev/tiano/2021/edk2/$(WORKDIR)/DEADBEEF.txt
File Offset:      0x00000068
File Length:      0x0000001C
File Attributes:  0x00
File State:       0xF8
        EFI_FILE_DATA_VALID
File Type:        0x01  EFI_FV_FILETYPE_RAW
There are a total of 2 files in this FV
```
Indeed the FV contains 2 files of type `EFI_FV_FILETYPE_RAW`.


# Firmware Volume attributes

Currently in our `Firmware Volume` we've defined only one attribute `FvAlignment`. Along with these attributes it help to set flags in the `EFI_FIRMWARE_VOLUME_HEADER.Attributes` field.
```
FvAlignment        = <...>
ERASE_POLARITY     = 1|0
MEMORY_MAPPED      = TRUE|FALSE
STICKY_WRITE       = TRUE|FALSE
LOCK_CAP           = TRUE|FALSE
LOCK_STATUS        = TRUE|FALSE
WRITE_DISABLED_CAP = TRUE|FALSE
WRITE_ENABLED_CAP  = TRUE|FALSE
WRITE_STATUS       = TRUE|FALSE
WRITE_LOCK_CAP     = TRUE|FALSE
WRITE_LOCK_STATUS  = TRUE|FALSE
READ_DISABLED_CAP  = TRUE|FALSE
READ_ENABLED_CAP   = TRUE|FALSE
READ_STATUS        = TRUE|FALSE
READ_LOCK_CAP      = TRUE|FALSE
READ_LOCK_STATUS   = TRUE|FALSE
```
The setting of these attributes will set respective `EFI_FVB2_*` flags which are defined in the [https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Pi/PiFirmwareVolume.h](https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Pi/PiFirmwareVolume.h).
You can read the meaning of these flags in the `UEFI Platform Initialization (PI) specification (Volume 3: Shared Architectural Elements)`.
If you look to `VolInfo` output, you'll see that out FV has two attributes set:
- `EFI_FVB2_ERASE_POLARITY` (set by default, means that uninitialized data bits in volume are set to 1)
- `EFI_FVB2_ALIGNMENT_16` (set by our `FvAlignment=16` setting)

Other possible attribute fro FV that you can come across is `FvNameGuid`:
```
FvNameGuid           = <GUID>
# Example:
# FvNameGuid         = 763BED0D-DE9F-48F5-81F1-3E90E1B1A015
```
This attribute would lead to the creation of a file of type `EFI_FV_FILETYPE_FFS_PAD` (padding file) with a GUID value in its data. This file would be placed first in the FV.

And `BlockSize` attribute:
```
BlockSize          = <...>
```
This token define flash chip attribute similar to the one in FD.


# Links

- [\[FV\] Sections](https://edk2-docs.gitbook.io/edk-ii-fdf-specification/2_fdf_design_discussion/25_-fv-_sections)

- [Create the FV Image File(s)](https://edk2-docs.gitbook.io/edk-ii-build-specification/10_post-build_imagegen_stage_-_flash/104_create_the_fv_image_files)