aboutsummaryrefslogtreecommitdiffstats
path: root/Lessons/Lesson_37/README.md
blob: def13144afa729f0171cb6b86ee0196e408127fe (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
If you'll search through ShellPkg library (https://github.com/tianocore/edk2/tree/master/ShellPkg/Library) you can notice that there is a folder `UefiShellAcpiViewCommandLib` (https://github.com/tianocore/edk2/tree/master/ShellPkg/Library/UefiShellAcpiViewCommandLib).
This folder provides a library for the support of in-shell `acpiview` command. If you check the INF file, you'll see
https://github.com/tianocore/edk2/blob/master/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf:
```
# Provides Shell 'acpiview' command functions
```
But if you try to execute `acpiview` in our current OVMF build, you'll notice that this command is not recognized:
```
FS0:\> acpiview
'acpiview' is not recognized as an internal or external command, operable program, or script file.
```
We have 3 ways to use this 'acpiview' command functionality:
- compile `acpiview` as a separate app and run it as an ordinary UEFI shell application
- compile shell with 'acpiview' command in itself and run it under OVMF
- update OVMF image with a shell that actually includes 'acpiview' command in itself

# Compile `acpiview` as a separate app

I guess it is the most easy way.

It is possible to perform such thing with a help of https://github.com/tianocore/edk2/tree/master/ShellPkg/Application/AcpiViewApp

If you look at the source file, you'll see that it is pretty simple, the main function just makes a library call to `ShellCommandRunAcpiView` function:
```
EFI_STATUS
EFIAPI
AcpiViewAppMain (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  return ShellCommandRunAcpiView (gImageHandle, SystemTable);
}
```

To build this application issue:
```
build --platform=ShellPkg/ShellPkg.dsc --module=ShellPkg/Application/AcpiViewApp/AcpiViewApp.inf --arch=X64 --buildtarget=RELEASE --tagname=GCC5
```

Copy image to the QEMU shared folder:
```
cp Build/Shell/RELEASE_GCC5/X64/AcpiViewApp.efi ~/UEFI_disk/
```

You can see application help with a:
```
FS0:\> AcpiViewApp.efi -?
Display ACPI Table information.

ACPIVIEWAPP.EFI [[-?] | [[[[-l] | [-s AcpiTable [-d]]] [-q] [-h]] [-r Spec]]]


  -l - Display list of installed ACPI Tables.
  -s - Display only the specified AcpiTable type and only support single
       invocation option.
         AcpiTable    : The required ACPI Table type.
  -d - Generate a binary file dump of the specified AcpiTable.
  -q - Quiet. Suppress errors and warnings. Disables consistency checks.
  -h - Enable colour highlighting.
  -r - Validate that all required ACPI tables are installed
         Spec  : Specification to validate against.
                 For Arm, the possible values are:
                   0 - Server Base Boot Requirements v1.0
                   1 - Server Base Boot Requirements v1.1
                   2 - Server Base Boot Requirements v1.2
  -? - Show help.


  This program is provided to allow examination of ACPI table values from the
  UEFI Shell.  This can help with investigations, especially at that stage
  where the tables are not enabling an OS to boot.
  The program is not exhaustive, and only encapsulates detailed knowledge of a
  limited number of table types.

  Default behaviour is to display the content of all tables installed.
  'Known' table types (listed in NOTES below) will be parsed and displayed
  with descriptions and field values.  Where appropriate a degree of
  consistency checking is done and errors may be reported in the output.
  Other table types will be displayed as an array of Hexadecimal bytes.

  To facilitate debugging, the -s and -d options can be used to generate a
  binary file image of a table that can be copied elsewhere for investigation
  using tools such as those provided by acpica.org.  This is especially
  relevant for AML type tables like DSDT and SSDT.

NOTES:
  1. The AcpiTable parameter can match any installed table type.
     Tables without specific handling will be displayed as a raw hex dump (or
     dumped to a file if -d is used).
  2. -s option supports to display the specified AcpiTable type that is present
     in the system. For normal type AcpiTable, it would display the data of the
     AcpiTable and AcpiTable header. The following type may contain header type
     other than AcpiTable header. The actual header can refer to the ACPI spec
     6.3
     Extra A. Particular types:
       APIC  - Multiple APIC Description Table (MADT)
       BGRT  - Boot Graphics Resource Table
       DBG2  - Debug Port Table 2
       DSDT  - Differentiated System Description Table
       FACP  - Fixed ACPI Description Table (FADT)
       GTDT  - Generic Timer Description Table
       IORT  - IO Remapping Table
       MCFG  - Memory Mapped Config Space Base Address Description Table
       PPTT  - Processor Properties Topology Table
       RSDP  - Root System Description Pointer
       SLIT  - System Locality Information Table
       SPCR  - Serial Port Console Redirection Table
       SRAT  - System Resource Affinity Table
       SSDT  - Secondary SystemDescription Table
       XSDT  - Extended System Description Table



EXAMPLES:
  * To display a list of the installed table types:
    fs0:\> acpiviewapp.efi -l

  * To parse and display a specific table type:
    fs0:\> acpiviewapp.efi -s GTDT

  * To save a binary dump of the contents of a table to a file
    in the current working directory:
    fs0:\> acpiviewapp.efi -s DSDT -d

  * To display contents of all ACPI tables:
    fs0:\> acpiviewapp.efi

  * To check if all Server Base Boot Requirements (SBBR) v1.2 mandatory
    ACPI tables are installed (Arm only):
    fs0:\> acpiviewapp.efi -r 2
```

With this program you can list ACPI tables in system:
```
FS0:\> AcpiViewApp.efi -l

Installed Table(s):
           1. RSDP
           2. XSDT
           3. FACP
           4. FACS
           5. DSDT
           6. APIC
           7. HPET
           8. BGRT
```

Show the content of any table:
```
FS0:\> AcpiViewApp.efi -s BGRT


 --------------- BGRT Table ---------------

Address  : 0x7B77000
Length   : 56

00000000 : 42 47 52 54 38 00 00 00 - 01 C5 49 4E 54 45 4C 20   BGRT8.....INTEL
00000010 : 45 44 4B 32 20 20 20 20 - 02 00 00 00 20 20 20 20   EDK2    ....
00000020 : 13 00 00 01 01 00 01 00 - 18 30 8B 06 00 00 00 00   .........0......
00000030 : 2F 01 00 00 0F 01 00 00                             /.......

Table Checksum : OK

BGRT                                 :
  Signature                          : BGRT
  Length                             : 56
  Revision                           : 1
  Checksum                           : 0xC5
  Oem ID                             : INTEL
  Oem Table ID                       : EDK2
  Oem Revision                       : 0x2
  Creator ID                         :
  Creator Revision                   : 0x1000013
  Version                            : 0x1
  Status                             : 0x1
  Image Type                         : 0x0
  Image Address                      : 0x68B3018
  Image Offset X                     : 303
  Image Offset Y                     : 271

Table Statistics:
        0 Error(s)
        0 Warning(s)
```

Or dump any ACPI table:
```
FS0:\> acpiview -s APIC -d
Dumping ACPI table to : .\APIC0000.bin ... DONE.
```
You can disassemble this image with `iasl -d <file>` like we did earlier.


# Compile shell with 'acpiview' command in itself and run it under OVMF

This case is a little bit crazy, we would be running a shell applicaion inside the shell application.

I guess this is not the usual case, but it will help you to know how to compile the shell image that you can actually use in your projects.

If you'll look at the https://github.com/tianocore/edk2/blob/master/ShellPkg/ShellPkg.dsc you'll see that if you build `ShellPkg`, you'll actually build two versions of the `Shell.inf`:
- one would have general commands
- another one would have all the commands
```
ShellPkg/Application/Shell/Shell.inf {
  <PcdsFixedAtBuild>
    gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
  <LibraryClasses>
    NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
    NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
    NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
fndef $(NO_SHELL_PROFILES)
    NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
    NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
    NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
    NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
    NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
ndif #$(NO_SHELL_PROFILES)
}

#
# Build a second version of the shell with all commands integrated
#
ShellPkg/Application/Shell/Shell.inf {
 <Defines>
    FILE_GUID = EA4BB293-2D7F-4456-A681-1F22F42CD0BC
  <PcdsFixedAtBuild>
    gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
  <LibraryClasses>
    NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
    NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
    NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
    NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
    NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
    NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
    NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
    NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
    NULL|ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf         <------- acpiview is present in this Shell version
}
```

In case you wonder how `UefiShellAcpiViewCommandLib.inf` registers new command take a look at its sources:

https://github.com/tianocore/edk2/blob/master/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
```
[Defines]
  INF_VERSION                    = 0x00010019
  BASE_NAME                      = UefiShellAcpiViewCommandLib
  FILE_GUID                      = FB5B305E-84F5-461F-940D-82D345757AFA
  MODULE_TYPE                    = UEFI_APPLICATION
  VERSION_STRING                 = 1.0
  LIBRARY_CLASS                  = AcpiViewCommandLib|UEFI_APPLICATION UEFI_DRIVER
  CONSTRUCTOR                    = UefiShellAcpiViewCommandLibConstructor
  DESTRUCTOR                     = UefiShellAcpiViewCommandLibDestructor

  ...
```
https://github.com/tianocore/edk2/blob/master/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
```
EFI_STATUS
EFIAPI
UefiShellAcpiViewCommandLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
 ...
  // Install our Shell command handler
  ShellCommandRegisterCommandName (
    L"acpiview",
    ShellCommandRunAcpiView,
    ShellCommandGetManFileNameAcpiView,
    0,
    L"acpiview",
    TRUE,
    gShellAcpiViewHiiHandle,
    STRING_TOKEN (STR_GET_HELP_ACPIVIEW)
    );

  return EFI_SUCCESS;
}
```
It doesn't look too scary, so you can even try to add your command to the shell. Maybe will try that in later lessons.

Now execute this command to build the Shell application:
```
build --platform=ShellPkg/ShellPkg.dsc --module=ShellPkg/Application/Shell/Shell.inf --arch=X64 --buildtarget=RELEASE --tagname=GCC5
```

After the build there would be two files in the build folder:
```
$ ls Build/Shell/RELEASE_GCC5/X64/Shell*.efi
Build/Shell/RELEASE_GCC5/X64/Shell_7C04A583-9E3E-4f1c-AD65-E05268D0B4D1.efi
Build/Shell/RELEASE_GCC5/X64/Shell_EA4BB293-2D7F-4456-A681-1F22F42CD0BC.efi
```

If you look closely to the code from the `ShellPkg/ShellPkg.dsc` that I've pasted earlier, you can notice that the image that we need is an image with a `EA4BB293-2D7F-4456-A681-1F22F42CD0BC` guid.

Copy it to the QEMU shared folder:
```
$ cp Build/Shell/RELEASE_GCC5/X64/Shell_EA4BB293-2D7F-4456-A681-1F22F42CD0BC.efi ~/UEFI_disk/
```
In your default shell there wouldn't be any `acpiview` command, but when as you'll move to the `Shell_EA4BB293-2D7F-4456-A681-1F22F42CD0BC.efi` this `acpiview` command would became present in the shell.
```
FS0:\> acpiview -l
'acpiview' is not recognized as an internal or external command, operable program, or script file.
FS0:\> Shell_EA4BB293-2D7F-4456-A681-1F22F42CD0BC.efi
UEFI Interactive Shell v2.2
EDK II
UEFI v2.70 (EDK II, 0x00010000)
Mapping table
      FS0: Alias(s):HD0a1:;BLK1:
          PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)/HD(1,MBR,0xBE1AFDFA,0x3F,0xFBFC1)
     BLK0: Alias(s):
          PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)
     BLK2: Alias(s):
          PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)
Press ESC in 4 seconds to skip startup.nsh or any other key to continue.
FS0:\> acpiview -l

Installed Table(s):
           1. RSDP
           2. XSDT
           3. FACP
           4. FACS
           5. DSDT
           6. APIC
           7. HPET
           8. BGRT
```

# Update OVMF image with a shell that actually includes 'acpiview' command in itself

Correct `OvmfPkg/OvmfPkgX64.dsc`. You'll need to add `UefiShellAcpiViewCommandLib.inf` to the `Shell.inf` library classes:
```
[Components]
  ...
  ShellPkg/Application/Shell/Shell.inf {
    <LibraryClasses>
      ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
      NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
      NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
      NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
      NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
      NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
      NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
      NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
      NULL|ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf          <-----------
!if $(NETWORK_IP6_ENABLE) == TRUE
      NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
!endif
      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf

    <PcdsFixedAtBuild>
      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
  }
```

Rebuild OVMF:
```
build --platform=OvmfPkg/OvmfPkgX64.dsc --arch=X64 --buildtarget=RELEASE --tagname=GCC5
```

You can test that this OVMF image has a shell that includes `acpiview` command in itself:
```
FS0:\> acpiview -l

Installed Table(s):
           1. RSDP
           2. XSDT
           3. FACP
           4. FACS
           5. DSDT
           6. APIC
           7. HPET
           8. BGRT
```