Date   

回复: [edk2-rfc] RFC: EXT4 filesystem driver

gaoliming
 

-----邮件原件-----
发件人: rfc@edk2.groups.io <rfc@edk2.groups.io> 代表 Pedro Falcato
发送时间: 2021年7月22日 7:12
收件人: devel@edk2.groups.io
抄送: rfc@edk2.groups.io
主题: [edk2-rfc] RFC: EXT4 filesystem driver

EXT4 (fourth extended filesystem) is a filesystem developed for Linux
that has been in wide use (desktops, servers, smartphones) since 2008.

The Ext4Pkg implements the Simple File System Protocol for a partition
that is formatted with the EXT4 file system. This allows UEFI Drivers,
UEFI Applications, UEFI OS Loaders, and the UEFI Shell to access files
on an EXT4 partition and supports booting a UEFI OS Loader from an
EXT4 partition.
This project is one of the TianoCore Google Summer of Code projects.

Right now, Ext4Pkg only contains a single member, Ext4Dxe, which is a
UEFI driver that consumes Block I/O, Disk I/O and (optionally) Disk
I/O 2 Protocols, and produces the Simple File System protocol. It
allows mounting ext4 filesystems exclusively.

Brief overhead of EXT4:
Layout of an EXT2/3/4 filesystem:
(note: this driver has been developed using
https://www.kernel.org/doc/html/latest/filesystems/ext4/index.html as
documentation).

An ext2/3/4 filesystem (here on out referred to as simply an ext4 filesystem,
due to the similarities) is composed of various concepts:

1) Superblock
The superblock is the structure near (1024 bytes offset from the start)
the start of the partition, and describes the filesystem in general.
Here, we get to know the size of the filesystem's blocks, which features
it supports or not, whether it's been cleanly unmounted, how many blocks
we have, etc.

2) Block groups
EXT4 filesystems are divided into block groups, and each block group covers
s_blocks_per_group(8 * Block Size) blocks. Each block group has an
associated block group descriptor; these are present directly after the
superblock. Each block group descriptor contains the location of the
inode table, and the inode and block bitmaps (note these bitmaps are only
a block long, which gets us the 8 * Block Size formula covered previously).

3) Blocks
The ext4 filesystem is divided into blocks, of size s_log_block_size ^ 1024.
Blocks can be allocated using individual block groups's bitmaps. Note
that block 0 is invalid and its presence on extents/block tables means
it's part of a file hole, and that particular location must be read as
a block full of zeros.

4) Inodes
The ext4 filesystem divides files/directories into inodes (originally
index nodes). Each file/socket/symlink/directory/etc (here on out referred
to as a file, since there is no distinction under the ext4 filesystem) is
stored as a /nameless/ inode, that is stored in some block group's inode
table. Each inode has s_inode_size size (or GOOD_OLD_INODE_SIZE if it's
an old filesystem), and holds various metadata about the file. Since the
largest inode structure right now is ~160 bytes, the rest of the inode
contains inline extended attributes. Inodes' data is stored using either
data blocks (under ext2/3) or extents (under ext4).

5) Extents
Ext4 inodes store data in extents. These let N contiguous logical blocks
that are represented by N contiguous physical blocks be represented by a
single extent structure, which minimizes filesystem metadata bloat and
speeds up block mapping (particularly due to the fact that high-quality
ext4 implementations like linux's try /really/ hard to make the file
contiguous, so it's common to have files with almost 0 fragmentation).
Inodes that use extents store them in a tree, and the top of the tree
is stored on i_data. The tree's leaves always start with an
EXT4_EXTENT_HEADER and contain EXT4_EXTENT_INDEX on eh_depth != 0
and
EXT4_EXTENT on eh_depth = 0; these entries are always sorted by logical
block.

6) Directories
Ext4 directories are files that store name -> inode mappings for the
logical directory; this is where files get their names, which means ext4
inodes do not themselves have names, since they can be linked (present)
multiple times with different names. Directories can store entries in two
different ways:
1) Classical linear directories: They store entries as a mostly-linked
mostly-list of EXT4_DIR_ENTRY.
2) Hash tree directories: These are used for larger directories, with
hundreds of entries, and are designed in a backwards-compatible way.
These are not yet implemented in the Ext4Dxe driver.

7) Journal
Ext3/4 filesystems have a journal to help protect the filesystem against
system crashes. This is not yet implemented in Ext4Dxe but is described
in detail in the Linux kernel's documentation.

The EDK2 implementation of ext4 is based only on the public documentation
available at
https://www.kernel.org/doc/html/latest/filesystems/ext4/index.html
and
the FreeBSD ext2fs driver (available at
https://github.com/freebsd/freebsd-src/tree/main/sys/fs/ext2fs,
BSD-2-Clause-FreeBSD licensed). It is licensed as
SPDX-License-Identifier: BSD-2-Clause-Patent.

After a brief discussion with the community, the proposed package
location is edk2-platform/Features/Ext4Pkg
(relevant discussion: https://edk2.groups.io/g/devel/topic/83060185).

I was the main contributor and I would like to maintain the package in
the future, if possible.

Current limitations:
1) The Ext4Dxe driver is, at the moment, read-only.
2) The Ext4Dxe driver at the moment cannot mount older (ext2/3)
filesystems. Ensuring compatibility with
those may not be a bad idea.

I intend to test the package using the UEFI SCTs present in edk2-test,
and implement any other needed unit tests myself using the already
available unit test framework. I also intend to (privately) fuzz the
UEFI driver with bad/unusual disk images, to improve the security and
reliability of the driver.

In the future, ext4 write support should be added so edk2 has a
fully-featured RW ext4 driver. There could also be a focus on
supporting the older ext4-like filesystems, as I mentioned in the
limitations, but that is open for discussion.

The driver's handling of unclean unmounting through forced shutdown is
unclear.
Is there a position in edk2 on how to handle such cases? I don't think
FAT32 has a "this filesystem is/was dirty" and even though it seems to
me that stopping a system from booting/opening the partition because
"we may find some tiny irregularities" is not the best course of
action, I can't find a clear answer.

The driver also had to add implementations of CRC32C and CRC16, and
after talking with my mentor we quickly reached the conclusion that
these may be good candidates for inclusion in MdePkg. We also
discussed moving the Ucs2 <-> Utf8 conversion library in RedfishPkg
(BaseUcs2Utf8Lib) into MdePkg as well. Any comments?
Current MdePkg BaseLib has CalculateCrc32(). So, CRC32C and CRC16 can be added into BaseLib.

If more modules need to consume Ucs2 <-> Utf8 conversion library, BaseUcs2Utf8Lib is generic enough
to be placed in MdePkg.

Thanks
Liming

Feel free to ask any questions you may find relevant.

Best Regards,

Pedro Falcato




Re: [PATCH v2] Xcode.md: Update instructions to work on modern macOS and Xcode versions

Andrew Fish
 

Reviewed-by: Andrew Fish <afish@apple.com>

On Jul 21, 2021, at 4:56 PM, Rebecca Cran <rebecca@bsdio.com> wrote:

The existing instructions no longer work on macOS Big Sur and Xcode 12.5.
Update them to include for example using lldb instead of gdb, installing
XQuartz, and using modern names such as macOS instead of Mac OS X.

Also, since MacPorts is less popular these days, remove instructions for
installing tools with it, leaving steps for using Homebrew.

Signed-off-by: Rebecca Cran <rebecca@bsdio.com>
---
Xcode.md | 172 +++++++++-----------
1 file changed, 78 insertions(+), 94 deletions(-)

diff --git a/Xcode.md b/Xcode.md
index 3d220a5..8af2653 100644
--- a/Xcode.md
+++ b/Xcode.md
@@ -1,43 +1,28 @@
-This page provides step-by-step instructions for setting up a [http://www.tianocore.org/edk2/ EDK II] build environment on Mac OS X systems using the Xcode development tools. These steps have been verified with macOS Sierra Version 10.12.4
+This page provides step-by-step instructions for setting up a [EDK II](https://github.com/tianocore/tianocore.github.io/wiki/EDK-II) build environment on macOS systems using the Xcode development tools. These steps have been verified with macOS Big Sur 11.3.1

-# Mac OS X Xcode
-Download the latest version of [Xcode](https://developer.apple.com/xcode) (9.4.1 as of this writing) from the Mac App Store. After installing Xcode, you will additionally need to install the extra command-line tools. To do this, at a Terminal prompt, enter:
+# macOS Xcode
+Download the latest version of [Xcode](https://developer.apple.com/xcode) (12.5 as of 2021-05-09) from the Mac App Store. After installing Xcode, you will additionally need to install the extra command-line tools. To do this, at a Terminal prompt, enter:
```
$ xcode-select --install
```
## Additional Development Tools
-While Xcode provides a full development environment as well as a suite of different utilities, it does not provide all tools required for Tianocore development. These tools can be provided in a number of ways, but the two most popular ways come from [Brew](https://brew.sh) and [MacPorts](https://www.macports.org/install.php). Installation information is provided at the previous links.
-
-### MacPorts Tips
-* If you work behind a firewall and need to pass your network traffic through a proxy, ensure you set the environment variable RSYNC_PROXY to your http proxy in the form of `proxy.dns.name:port_number`.
- * Remember that `sudo` by default drops most environment variables. Add the `-E` option to tell `sudo` to keep your environment variables.
-* When installing MacPorts packages, if you would like to build from source like traditional [FreeBSD Ports](https://en.wikipedia.org/wiki/FreeBSD_Ports) systems, add the `-s` option to the command line. Otherwise, default behavior is to pull precompiled packages.
+While Xcode provides a full development environment as well as a suite of different utilities, it does not provide all tools required for TianoCore development. These tools can be provided in a number of ways, but the most popular way comes from [Brew](https://brew.sh). Installation information is provided at the previous link.

## Install mtoc
The mtoc utility is required to convert from the macOS Mach-O image format to the PE/COFF format as required by the UEFI specification.

### Brew Instructions
```
-$ brew install mtoc
-```
-## MacPorts Instructions
-```
-$ sudo port install cctools
+$ brew install mtoc
```
-By default, this will install `mtoc` at `/opt/local/bin/mtoc`.
# Install NASM

-The assembler used for EDK II builds is Netwide Assembler (NASM). The latest version of NASM is available from http://www.nasm.us/.
+The assembler used for EDK II builds is Netwide Assembler (NASM). The latest version of NASM is available from https://nasm.us/.
## Brew Instructions
```
$ brew install nasm
$ brew upgrade nasm
```
-## MacPorts Instructions
-```
-$ sudo port install nasm
-```
-By default this installs `nasm` at `/opt/local/bin/nasm`.

# Install ACPI Compiler

@@ -47,26 +32,20 @@ In order to support EDK II firmware builds, the latest version of the ASL compil
$ brew install acpica
$ brew upgrade acpica
```
-## MacPorts Install
-```
-$ sudo port install acpica
-```
-By default this installs `iasl` at `/opt/local/bin/iasl`
+
+# Install XQuartz
+
+The EmulatorPkg requires headers from X11, which are provided by the XQuartz project. Install it from https://www.xquartz.org/.

# Install QEMU Emulator

-On order to support running the OVMF platforms from the OvmfPkg, the QEMU emulator from http://www.qemu.org/ must be installed.
+On order to support running the OVMF platforms from the OvmfPkg, the QEMU emulator from https://www.qemu.org/ must be installed.

## Brew Install
```
$ brew install qemu
$ brew upgrade qemu
```
-## MacPorts Install
-```
-$ sudo port install qemu
-```
-By default qemu is installed in `/opt/local/bin`.
## Update PATH environment variable

Tools installed using the `brew` command are placed in `/usr/local/bin`. The `PATH` environment variable must be updated so the newly installed tools are used instead of older pre-installed tools.
@@ -75,11 +54,6 @@ Tools installed using the `brew` command are placed in `/usr/local/bin`. The `P
export PATH=/usr/local/bin:$PATH
```

-Tools installed using the `port` should automatically be in your shell's PATH. If not, you can manually set it by:
-```
-export PATH=/opt/local/bin:$PATH
-```
-
# Verify tool versions

Run the following commands to verify the versions of the tools that have been installed.
@@ -97,84 +71,94 @@ Pick the location you want to down load the files to and `cd` to that directory:
```
cd ~/work
git clone https://github.com/tianocore/edk2.git
+cd edk2
+git submodule update --init
```

-# Build from Command Line/Debug with gdb
+# Build from Command Line/Debug with lldb

-Build the UnixPkg:
+Build the EmulatorPkg:

```
-cd ~/work/edk2/UnixPkg
+cd ~/work/edk2/EmulatorPkg
./build.sh
```

-Debug the UnixPkg
+Debug the EmulatorPkg

```
./build.sh run

-Building from: /Users/fish/work/edk2
+Initializing workspace
+/Users/bcran/src/edk2/BaseTools
+Loading previous configuration from /Users/bcran/src/edk2/Conf/BuildEnv.sh
+Using EDK2 in-source Basetools
+WORKSPACE: /Users/bcran/src/edk2
+EDK_TOOLS_PATH: /Users/bcran/src/edk2/BaseTools
+CONF_PATH: /Users/bcran/src/edk2/Conf
using prebuilt tools
-Reading symbols for shared libraries ...... done
-Breakpoint 1 at 0xce84: file /Users/fish/work/edk2/UnixPkg/Sec/SecMain.c, line 1070.
-(gdb)
-```
-
-Type `r` at the gdb prompt (don't forget to hit carriage return) to boot the emulator. Ctrl-c in the terminal window will break in to gdb. bt is the stack backtrace command:
-
-```
-^C
-Program received signal SIGINT, Interrupt.
-0x92423806 in __semwait_signal ()
-(gdb) bt
-#0 0x92423806 in __semwait_signal ()
-#1 0x9244f441 in nanosleep$UNIX2003 ()
-#2 0x0000b989 in msSleep (Milliseconds=0x14) at /Users/fish/work/Migration/edk2/UnixPkg/Sec/UnixThunk.c:102
-#3 0x0000acf5 in UgaCheckKey (UgaIo=0x2078d0) at /Users/fish/work/Migration/edk2/UnixPkg/Sec/UgaX11.c:380
-#4 0x0000d8b7 in _GasketUintn () at /Users/fish/work/Migration/edk2/Build/Unix/DEBUG_XCODE32/IA32/UnixPkg/Sec/SecMain/OUTPUT/Ia32/Gasket.iii:63
-#5 0x0000d801 in GasketUgaCheckKey (UgaIo=0x2078d0) at /Users/fish/work/Migration/edk2/UnixPkg/Sec/Gasket.c:406
-#6 0x454a25fb in UnixUgaSimpleTextInWaitForKey (Event=0x45603610, Context=0x45382110) at /Users/fish/work/Migration/edk2/UnixPkg/UnixUgaDxe/UnixUgaInput.c:169
-#7 0x45faad3a in CoreDispatchEventNotifies (Priority=0x10) at /Users/fish/work/Migration/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:185
-#8 0x45faa639 in CoreRestoreTpl (NewTpl=0x4) at /Users/fish/work/Migration/edk2/MdeModulePkg/Core/Dxe/Event/Tpl.c:114
-#9 0x45f9f197 in CoreReleaseLock (Lock=0x45fb1024) at /Users/fish/work/Migration/edk2/MdeModulePkg/Core/Dxe/Library/Library.c:102
-#10 0x45faabd6 in CoreReleaseEventLock () at /Users/fish/work/Migration/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:113
-#11 0x45fab26c in CoreCheckEvent (UserEvent=0x45603210) at /Users/fish/work/Migration/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:562
-#12 0x45fab2db in CoreWaitForEvent (NumberOfEvents=0x1, UserEvents=0x45f94cc4, UserIndex=0x45f94cb8) at /Users/fish/work/Migration/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:621
-#13 0x49ce9557 in ?? ()
-#14 0x49cf0344 in ?? ()
-#15 0x49ce3bc2 in ?? ()
-#16 0x49ce3ae1 in ?? ()
-#17 0x45f9e4e3 in CoreStartImage (ImageHandle=0x49e31e10, ExitDataSize=0x45f94eec, ExitData=0x45f94ee8) at /Users/fish/work/Migration/edk2/MdeModulePkg/Core/Dxe/Image/Image.c:1260
-#18 0x4550cccc in BdsLibBootViaBootOption (Option=0x49ffa110, DevicePath=0x49ffa190, ExitDataSize=0x45f94eec, ExitData=0x45f94ee8) at /Users/fish/work/Migration/edk2/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c:382
-#19 0x455252a9 in BdsBootDeviceSelect () at /Users/fish/work/Migration/edk2/IntelFrameworkModulePkg/Universal/BdsDxe/BdsEntry.c:214
-#20 0x455255bc in BdsEntry (This=0x4552d01c) at /Users/fish/work/Migration/edk2/IntelFrameworkModulePkg/Universal/BdsDxe/BdsEntry.c:356
-#21 0x45fad7e8 in DxeMain (HobStart=0x45f70010) at /Users/fish/work/Migration/edk2/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c:425
-#22 0x45fadd1d in ProcessModuleEntryPointList (HobStart=0x42020000) at /Users/fish/work/Migration/edk2/Build/Unix/DEBUG_XCODE32/IA32/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/AutoGen.c:287
-#23 0x45f97773 in _ModuleEntryPoint (HobStart=0x42020000) at /Users/fish/work/Migration/edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.c:54
-(gdb)
+(lldb) target create "./Host"
+Current executable set to '/Users/bcran/src/edk2/Build/EmulatorX64/DEBUG_XCODE5/X64/Host' (x86_64).
+(lldb) command script import /Users/bcran/src/edk2/EmulatorPkg/Unix/lldbefi.py
+Type r to run emulator. SecLldbScriptBreak armed. EFI modules should now get source level debugging in the emulator.
+(lldb) script lldb.debugger.SetAsync(True)
+(lldb) run
+Process 12155 launched: '/Users/bcran/src/edk2/Build/EmulatorX64/DEBUG_XCODE5/X64/Host' (x86_64)
+
+EDK II UNIX Host Emulation Environment from http://www.tianocore.org/edk2/
+ BootMode 0x00
+ OS Emulator passing in 128 KB of temp RAM at 0x102000000 to SEC
+ FD loaded from ../FV/FV_RECOVERY.fd at 0x102020000 contains SEC Core
+...
+```
+
+Type `process interrupt` at the lldb prompt (don't forget to hit carriage return) to pause execution. Ctrl-c in the terminal window will quit lldb. `bt` is the stack backtrace command:
+
+```
+Process 12420 stopped
+* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
+ frame #0: 0x00007fff2033cc22 libsystem_kernel.dylib:__semwait_signal() + 10
+libsystem_kernel.dylib`__semwait_signal:
+-> 0x7fff2033cc22 <+10>: jae 0x7fff2033cc2c ; <+20>
+ 0x7fff2033cc24 <+12>: movq %rax, %rdi
+ 0x7fff2033cc27 <+15>: jmp 0x7fff2033b72d ; cerror
+ 0x7fff2033cc2c <+20>: retq
+Target 0: (Host) stopped.
+(lldb) bt
+* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
+ * frame #0: 0x00007fff2033cc22 libsystem_kernel.dylib:__semwait_signal() + 10
+ frame #1: 0x00007fff202bcc2a libsystem_c.dylib:nanosleep() + 196
+ frame #2: 0x0000000100005e55 Host:SecCpuSleep() + 37 at /Users/bcran/src/edk2/EmulatorPkg/Unix/Host/EmuThunk.c:334
+ frame #3: 0x000000010000e96e Host:GasketSecCpuSleep() + 11 at /Users/bcran/src/edk2/Build/EmulatorX64/DEBUG_XCODE5/X64/EmulatorPkg/Unix/Host/Host/OUTPUT/X64/Gasket.iiii:283
+ frame #4: 0x0000000106f985e9 DxeCore.dll:CoreDispatchEventNotifies() + 264 at /Users/bcran/src/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:194
+ frame #5: 0x0000000106f97fce DxeCore.dll:CoreRestoreTpl() + 227 at /Users/bcran/src/edk2/MdeModulePkg/Core/Dxe/Event/Tpl.c:131
+ frame #6: 0x0000000106f989db DxeCore.dll:CoreSignalEvent() + 111 at /Users/bcran/src/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:566
+ frame #7: 0x0000000106f98b01 DxeCore.dll:CoreWaitForEvent() + 94 at /Users/bcran/src/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:707
+ frame #8: 0x0000000113e8e54c BdsDxe.dll:BdsWaitForSingleEvent() + 127 at /Users/bcran/src/edk2/MdeModulePkg/Universal/BdsDxe/BdsEntry.c:250
+ frame #9: 0x0000000113e8e70b BdsDxe.dll:BdsWait() + 215 at /Users/bcran/src/edk2/MdeModulePkg/Universal/BdsDxe/BdsEntry.c:328
+ frame #10: 0x0000000113e8dffb BdsDxe.dll:BdsEntry() + 2612 at /Users/bcran/src/edk2/MdeModulePkg/Universal/BdsDxe/BdsEntry.c:1012
+ frame #11: 0x0000000106f9bbd6 DxeCore.dll:DxeMain() + 2791 at /Users/bcran/src/edk2/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c:551
+ frame #12: 0x0000000106f9ed8f DxeCore.dll:_ModuleEntryPoint() + 20 at /Users/bcran/src/edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.c:48
+ frame #13: 0x0000000106fdd02f DxeIpl.dll:InternalSwitchStack() + 15
+ frame #14: 0x0000000106fdc0b6 DxeIpl.dll:HandOffToDxeCore() + 546 at /Users/bcran/src/edk2/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c:126
+ frame #15: 0x0000000106fda78a DxeIpl.dll:DxeLoadCore() + 1354 at /Users/bcran/src/edk2/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c:449
+ frame #16: 0x0000000106ff1d7c
+ frame #17: 0x00000001020255c6 PeiCore.dll:PeiCore() + 1982 at /Users/bcran/src/edk2/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c:331
+ frame #18: 0x000000010202a82c PeiCore.dll:PeiCheckAndSwitchStack() + 1171 at /Users/bcran/src/edk2/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c:842
+ frame #19: 0x000000010202b853 PeiCore.dll:PeiDispatcher() + 1206 at /Users/bcran/src/edk2/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c:1609
+(lldb)
+
```

# Build and Debug from Xcode
-To build from the Xcode GUI open ~/work/edk2/UnixPkg/Xcode/xcode_project/xcode_project.xcodeproj. You can build, clean, and source level debug from the Xcode GUI. You can hit the Build and Debug button to start the build process. You need to need to hit command-shift-B to show the output of the build. Click Pause to break into the debugger.
-
-[[File:Xcode.jpg]]
+To build from the Xcode GUI open ~/work/edk2/EmulatorPkg/Unix/Xcode/xcode_project64/xcode_project.xcodeproj. You can build, clean, and source level debug from the Xcode GUI. You can hit the Build and Debug button to start the build process. You need to need to hit command-shift-B to show the output of the build. Click Pause to break into the debugger.

The stack trace contains items that show as ?? since the default shell is checked in as a binary. `nanosleep$UNIX2003` and `__semwait_signal` are POSIX library calls and you do not get C source debug with these symbols.

-# Source Level Debug Shell
-
-It is possible to get source level debug for the EFI Shell by pulling these projects from source control and building them.
-
-Instructions for building and hooking in the shell are located in the [https://sourceforge.net/apps/mediawiki/tianocore/index.php?title=Gcc-shell gcc-shell] project.
-
-Please note the gcc-shell and UnixPkg build separately, so if you update shell code you need to build the shell to see the changes. The following screen shot shows being able to source level debug the shell:
-
-[[File:Xcode_good.jpg]]
+*Note* The Xcode project is currently (as of 2021-05-09) broken.

# See Also

-* [[Step-by-step instructions]]
-
# Continue with common instructions

-The [remaining instructions](../Common-instructions) are common for most UNIX-like systems.
+The [remaining instructions](https://github.com/tianocore/tianocore.github.io/wiki/Common-instructions-for-Unix) are common for most UNIX-like systems.
--
2.30.1 (Apple Git-130)







Re: [tianocore.github.io.wiki PATCH 1/1] Xcode.md: Update instructions to work on modern macOS and Xcode versions

Rebecca Cran
 

Thanks. I've just sent out a v2 with the MacPorts instructions removed.


--
Rebecca Cran


On 7/21/21 8:30 AM, Andrew Fish wrote:


On Jul 21, 2021, at 7:24 AM, Rebecca Cran <rebecca@...> wrote:

I think most people (including myself) use brew nowadays, which installs to /usr/local/bin so the instructions work.

I was wondering if we should remove the MacPorts instructions?


Rebecca,

Makes sense to move the instructions over to brew I guess. 

Thanks,

Andrew Fish

--

Rebecca Cran


On 7/20/21 11:37 PM, Andrew Fish wrote:
These Xcode instructions look good to me in general. Thanks for doing this I usually do things following a non public path. 

I think to make these instructions work you need to update *_XCODE5_*_MTOC_PATH

By default, this will install mtoc at /opt/local/bin/mtoc.

*_XCODE5_*_MTOC_PATH = /usr/local/bin/mtoc

We could change this to match the brew default location, I think this location is way out of date. I think the other things get fixed by the path variables. 

Thanks,

Andrew Fish



On May 25, 2021, at 5:36 AM, Rebecca Cran <rebecca@...> wrote:

On 5/25/21 6:21 AM, Laszlo Ersek wrote:

The idea is to use the wiki of any one of your projects on github.com --
most fittingly, your edk2 fork's wiki.

The URL to clone the "real" wiki repo from is:

  git://github.com/tianocore/tianocore.github.io.wiki

And the repo URL of the wiki of your edk2 fork *should be*:

  git@...:bcran/edk2.wiki.git

I'm not sure if you first need to enable the wiki function, for your
edk2 fork, on github.com. Maybe that's hidden somewhere between the
project (fork) settings. Either way, once your wiki repo exists, just
force-push to it whatever your local clone contains. And, only the
"master" branch matters for rendering, AFAICT.


Ah, got it - thanks.

The updated Xcode.md page is at https://github.com/bcran/edk2/wiki/Xcode


--
Rebecca Cran














[PATCH v2] Xcode.md: Update instructions to work on modern macOS and Xcode versions

Rebecca Cran
 

The existing instructions no longer work on macOS Big Sur and Xcode 12.5.
Update them to include for example using lldb instead of gdb, installing
XQuartz, and using modern names such as macOS instead of Mac OS X.

Also, since MacPorts is less popular these days, remove instructions for
installing tools with it, leaving steps for using Homebrew.

Signed-off-by: Rebecca Cran <rebecca@bsdio.com>
---
Xcode.md | 172 +++++++++-----------
1 file changed, 78 insertions(+), 94 deletions(-)

diff --git a/Xcode.md b/Xcode.md
index 3d220a5..8af2653 100644
--- a/Xcode.md
+++ b/Xcode.md
@@ -1,43 +1,28 @@
-This page provides step-by-step instructions for setting up a [http://www.=
tianocore.org/edk2/ EDK II] build environment on Mac OS X systems using the=
Xcode development tools. These steps have been verified with macOS Sierra=
Version 10.12.4
+This page provides step-by-step instructions for setting up a [EDK II](htt=
ps://github.com/tianocore/tianocore.github.io/wiki/EDK-II) build environmen=
t on macOS systems using the Xcode development tools. These steps have bee=
n verified with macOS Big Sur 11.3.1
=20
-# Mac OS X Xcode
-Download the latest version of [Xcode](https://developer.apple.com/xcode) =
(9.4.1 as of this writing) from the Mac App Store. After installing Xcode,=
you will additionally need to install the extra command-line tools. To do=
this, at a Terminal prompt, enter:
+# macOS Xcode
+Download the latest version of [Xcode](https://developer.apple.com/xcode) =
(12.5 as of 2021-05-09) from the Mac App Store. After installing Xcode, yo=
u will additionally need to install the extra command-line tools. To do th=
is, at a Terminal prompt, enter:
```
$ xcode-select --install
```
## Additional Development Tools
-While Xcode provides a full development environment as well as a suite of =
different utilities, it does not provide all tools required for Tianocore d=
evelopment. These tools can be provided in a number of ways, but the two m=
ost popular ways come from [Brew](https://brew.sh) and [MacPorts](https://w=
ww.macports.org/install.php). Installation information is provided at the =
previous links.
-
-### MacPorts Tips
-* If you work behind a firewall and need to pass your network traffic thro=
ugh a proxy, ensure you set the environment variable RSYNC_PROXY to your ht=
tp proxy in the form of `proxy.dns.name:port_number`.
- * Remember that `sudo` by default drops most environment variables. Ad=
d the `-E` option to tell `sudo` to keep your environment variables.
-* When installing MacPorts packages, if you would like to build from sourc=
e like traditional [FreeBSD Ports](https://en.wikipedia.org/wiki/FreeBSD_Po=
rts) systems, add the `-s` option to the command line. Otherwise, default =
behavior is to pull precompiled packages.=20
+While Xcode provides a full development environment as well as a suite of =
different utilities, it does not provide all tools required for TianoCore d=
evelopment. These tools can be provided in a number of ways, but the most =
popular way comes from [Brew](https://brew.sh). Installation information i=
s provided at the previous link.
=20
## Install mtoc
The mtoc utility is required to convert from the macOS Mach-O image format=
to the PE/COFF format as required by the UEFI specification.
=20
### Brew Instructions
```
-$ brew install mtoc=0D
-```
-## MacPorts Instructions
-```
-$ sudo port install cctools
+$ brew install mtoc
```
-By default, this will install `mtoc` at `/opt/local/bin/mtoc`.
# Install NASM
=20
-The assembler used for EDK II builds is Netwide Assembler (NASM). The late=
st version of NASM is available from http://www.nasm.us/.
+The assembler used for EDK II builds is Netwide Assembler (NASM). The late=
st version of NASM is available from https://nasm.us/.
## Brew Instructions
```
$ brew install nasm
$ brew upgrade nasm
```
-## MacPorts Instructions
-```
-$ sudo port install nasm
-```
-By default this installs `nasm` at `/opt/local/bin/nasm`.
=20
# Install ACPI Compiler
=20
@@ -47,26 +32,20 @@ In order to support EDK II firmware builds, the latest =
version of the ASL compil
$ brew install acpica
$ brew upgrade acpica
```
-## MacPorts Install
-```
-$ sudo port install acpica
-```
-By default this installs `iasl` at `/opt/local/bin/iasl`
+
+# Install XQuartz
+
+The EmulatorPkg requires headers from X11, which are provided by the XQuar=
tz project. Install it from https://www.xquartz.org/.
=20
# Install QEMU Emulator
=20
-On order to support running the OVMF platforms from the OvmfPkg, the QEMU =
emulator from http://www.qemu.org/ must be installed.
+On order to support running the OVMF platforms from the OvmfPkg, the QEMU =
emulator from https://www.qemu.org/ must be installed.
=20
## Brew Install
```
$ brew install qemu
$ brew upgrade qemu
```
-## MacPorts Install
-```
-$ sudo port install qemu
-```
-By default qemu is installed in `/opt/local/bin`.
## Update PATH environment variable
=20
Tools installed using the `brew` command are placed in `/usr/local/bin`. =
The `PATH` environment variable must be updated so the newly installed tool=
s are used instead of older pre-installed tools.
@@ -75,11 +54,6 @@ Tools installed using the `brew` command are placed in `=
/usr/local/bin`. The `P
export PATH=3D/usr/local/bin:$PATH
```
=20
-Tools installed using the `port` should automatically be in your shell's P=
ATH. If not, you can manually set it by:
-```
-export PATH=3D/opt/local/bin:$PATH
-```
-
# Verify tool versions
=20
Run the following commands to verify the versions of the tools that have b=
een installed.
@@ -97,84 +71,94 @@ Pick the location you want to down load the files to an=
d `cd` to that directory:
```
cd ~/work
git clone https://github.com/tianocore/edk2.git
+cd edk2
+git submodule update --init
```
=20
-# Build from Command Line/Debug with gdb
+# Build from Command Line/Debug with lldb
=20
-Build the UnixPkg:
+Build the EmulatorPkg:
=20
```
-cd ~/work/edk2/UnixPkg
+cd ~/work/edk2/EmulatorPkg
./build.sh
```
=20
-Debug the UnixPkg
+Debug the EmulatorPkg
=20
```
./build.sh run
=20
-Building from: /Users/fish/work/edk2
+Initializing workspace
+/Users/bcran/src/edk2/BaseTools
+Loading previous configuration from /Users/bcran/src/edk2/Conf/BuildEnv.sh
+Using EDK2 in-source Basetools
+WORKSPACE: /Users/bcran/src/edk2
+EDK_TOOLS_PATH: /Users/bcran/src/edk2/BaseTools
+CONF_PATH: /Users/bcran/src/edk2/Conf
using prebuilt tools
-Reading symbols for shared libraries ...... done
-Breakpoint 1 at 0xce84: file /Users/fish/work/edk2/UnixPkg/Sec/SecMain.c, =
line 1070.
-(gdb)=20
-```
-
-Type `r` at the gdb prompt (don't forget to hit carriage return) to boot t=
he emulator. Ctrl-c in the terminal window will break in to gdb. bt is the =
stack backtrace command:
-
-```
-^C
-Program received signal SIGINT, Interrupt.
-0x92423806 in __semwait_signal ()
-(gdb) bt
-#0 0x92423806 in __semwait_signal ()
-#1 0x9244f441 in nanosleep$UNIX2003 ()
-#2 0x0000b989 in msSleep (Milliseconds=3D0x14) at /Users/fish/work/Migrat=
ion/edk2/UnixPkg/Sec/UnixThunk.c:102
-#3 0x0000acf5 in UgaCheckKey (UgaIo=3D0x2078d0) at /Users/fish/work/Migra=
tion/edk2/UnixPkg/Sec/UgaX11.c:380
-#4 0x0000d8b7 in _GasketUintn () at /Users/fish/work/Migration/edk2/Build=
/Unix/DEBUG_XCODE32/IA32/UnixPkg/Sec/SecMain/OUTPUT/Ia32/Gasket.iii:63
-#5 0x0000d801 in GasketUgaCheckKey (UgaIo=3D0x2078d0) at /Users/fish/work=
/Migration/edk2/UnixPkg/Sec/Gasket.c:406
-#6 0x454a25fb in UnixUgaSimpleTextInWaitForKey (Event=3D0x45603610, Conte=
xt=3D0x45382110) at /Users/fish/work/Migration/edk2/UnixPkg/UnixUgaDxe/Unix=
UgaInput.c:169
-#7 0x45faad3a in CoreDispatchEventNotifies (Priority=3D0x10) at /Users/fi=
sh/work/Migration/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:185
-#8 0x45faa639 in CoreRestoreTpl (NewTpl=3D0x4) at /Users/fish/work/Migrat=
ion/edk2/MdeModulePkg/Core/Dxe/Event/Tpl.c:114
-#9 0x45f9f197 in CoreReleaseLock (Lock=3D0x45fb1024) at /Users/fish/work/=
Migration/edk2/MdeModulePkg/Core/Dxe/Library/Library.c:102
-#10 0x45faabd6 in CoreReleaseEventLock () at /Users/fish/work/Migration/ed=
k2/MdeModulePkg/Core/Dxe/Event/Event.c:113
-#11 0x45fab26c in CoreCheckEvent (UserEvent=3D0x45603210) at /Users/fish/w=
ork/Migration/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:562
-#12 0x45fab2db in CoreWaitForEvent (NumberOfEvents=3D0x1, UserEvents=3D0x4=
5f94cc4, UserIndex=3D0x45f94cb8) at /Users/fish/work/Migration/edk2/MdeModu=
lePkg/Core/Dxe/Event/Event.c:621
-#13 0x49ce9557 in ?? ()
-#14 0x49cf0344 in ?? ()
-#15 0x49ce3bc2 in ?? ()
-#16 0x49ce3ae1 in ?? ()
-#17 0x45f9e4e3 in CoreStartImage (ImageHandle=3D0x49e31e10, ExitDataSize=
=3D0x45f94eec, ExitData=3D0x45f94ee8) at /Users/fish/work/Migration/edk2/Md=
eModulePkg/Core/Dxe/Image/Image.c:1260
-#18 0x4550cccc in BdsLibBootViaBootOption (Option=3D0x49ffa110, DevicePath=
=3D0x49ffa190, ExitDataSize=3D0x45f94eec, ExitData=3D0x45f94ee8) at /Users/=
fish/work/Migration/edk2/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsB=
oot.c:382
-#19 0x455252a9 in BdsBootDeviceSelect () at /Users/fish/work/Migration/edk=
2/IntelFrameworkModulePkg/Universal/BdsDxe/BdsEntry.c:214
-#20 0x455255bc in BdsEntry (This=3D0x4552d01c) at /Users/fish/work/Migrati=
on/edk2/IntelFrameworkModulePkg/Universal/BdsDxe/BdsEntry.c:356
-#21 0x45fad7e8 in DxeMain (HobStart=3D0x45f70010) at /Users/fish/work/Migr=
ation/edk2/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c:425
-#22 0x45fadd1d in ProcessModuleEntryPointList (HobStart=3D0x42020000) at /=
Users/fish/work/Migration/edk2/Build/Unix/DEBUG_XCODE32/IA32/MdeModulePkg/C=
ore/Dxe/DxeMain/DEBUG/AutoGen.c:287
-#23 0x45f97773 in _ModuleEntryPoint (HobStart=3D0x42020000) at /Users/fish=
/work/Migration/edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.c:54
-(gdb)=20
+(lldb) target create "./Host"
+Current executable set to '/Users/bcran/src/edk2/Build/EmulatorX64/DEBUG_X=
CODE5/X64/Host' (x86_64).
+(lldb) command script import /Users/bcran/src/edk2/EmulatorPkg/Unix/lldbef=
i.py
+Type r to run emulator. SecLldbScriptBreak armed. EFI modules should now g=
et source level debugging in the emulator.
+(lldb) script lldb.debugger.SetAsync(True)
+(lldb) run
+Process 12155 launched: '/Users/bcran/src/edk2/Build/EmulatorX64/DEBUG_XCO=
DE5/X64/Host' (x86_64)
+
+EDK II UNIX Host Emulation Environment from http://www.tianocore.org/edk2/
+ BootMode 0x00
+ OS Emulator passing in 128 KB of temp RAM at 0x102000000 to SEC
+ FD loaded from ../FV/FV_RECOVERY.fd at 0x102020000 contains SEC Core
+...
+```
+
+Type `process interrupt` at the lldb prompt (don't forget to hit carriage =
return) to pause execution. Ctrl-c in the terminal window will quit lldb. `=
bt` is the stack backtrace command:
+
+```
+Process 12420 stopped
+* thread #1, queue =3D 'com.apple.main-thread', stop reason =3D signal SIG=
STOP
+ frame #0: 0x00007fff2033cc22 libsystem_kernel.dylib:__semwait_signal()=
+ 10
+libsystem_kernel.dylib`__semwait_signal:
+-> 0x7fff2033cc22 <+10>: jae 0x7fff2033cc2c ; <+20>
+ 0x7fff2033cc24 <+12>: movq %rax, %rdi
+ 0x7fff2033cc27 <+15>: jmp 0x7fff2033b72d ; cerror
+ 0x7fff2033cc2c <+20>: retq
+Target 0: (Host) stopped.
+(lldb) bt
+* thread #1, queue =3D 'com.apple.main-thread', stop reason =3D signal SIG=
STOP
+ * frame #0: 0x00007fff2033cc22 libsystem_kernel.dylib:__semwait_signal()=
+ 10
+ frame #1: 0x00007fff202bcc2a libsystem_c.dylib:nanosleep() + 196
+ frame #2: 0x0000000100005e55 Host:SecCpuSleep() + 37 at /Users/bcran/s=
rc/edk2/EmulatorPkg/Unix/Host/EmuThunk.c:334
+ frame #3: 0x000000010000e96e Host:GasketSecCpuSleep() + 11 at /Users/b=
cran/src/edk2/Build/EmulatorX64/DEBUG_XCODE5/X64/EmulatorPkg/Unix/Host/Host=
/OUTPUT/X64/Gasket.iiii:283
+ frame #4: 0x0000000106f985e9 DxeCore.dll:CoreDispatchEventNotifies() +=
264 at /Users/bcran/src/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:194
+ frame #5: 0x0000000106f97fce DxeCore.dll:CoreRestoreTpl() + 227 at /Us=
ers/bcran/src/edk2/MdeModulePkg/Core/Dxe/Event/Tpl.c:131
+ frame #6: 0x0000000106f989db DxeCore.dll:CoreSignalEvent() + 111 at /U=
sers/bcran/src/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:566
+ frame #7: 0x0000000106f98b01 DxeCore.dll:CoreWaitForEvent() + 94 at /U=
sers/bcran/src/edk2/MdeModulePkg/Core/Dxe/Event/Event.c:707
+ frame #8: 0x0000000113e8e54c BdsDxe.dll:BdsWaitForSingleEvent() + 127 =
at /Users/bcran/src/edk2/MdeModulePkg/Universal/BdsDxe/BdsEntry.c:250
+ frame #9: 0x0000000113e8e70b BdsDxe.dll:BdsWait() + 215 at /Users/bcra=
n/src/edk2/MdeModulePkg/Universal/BdsDxe/BdsEntry.c:328
+ frame #10: 0x0000000113e8dffb BdsDxe.dll:BdsEntry() + 2612 at /Users/b=
cran/src/edk2/MdeModulePkg/Universal/BdsDxe/BdsEntry.c:1012
+ frame #11: 0x0000000106f9bbd6 DxeCore.dll:DxeMain() + 2791 at /Users/b=
cran/src/edk2/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c:551
+ frame #12: 0x0000000106f9ed8f DxeCore.dll:_ModuleEntryPoint() + 20 at =
/Users/bcran/src/edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.c:=
48
+ frame #13: 0x0000000106fdd02f DxeIpl.dll:InternalSwitchStack() + 15
+ frame #14: 0x0000000106fdc0b6 DxeIpl.dll:HandOffToDxeCore() + 546 at /=
Users/bcran/src/edk2/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c:126
+ frame #15: 0x0000000106fda78a DxeIpl.dll:DxeLoadCore() + 1354 at /User=
s/bcran/src/edk2/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c:449
+ frame #16: 0x0000000106ff1d7c
+ frame #17: 0x00000001020255c6 PeiCore.dll:PeiCore() + 1982 at /Users/b=
cran/src/edk2/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c:331
+ frame #18: 0x000000010202a82c PeiCore.dll:PeiCheckAndSwitchStack() + 1=
171 at /Users/bcran/src/edk2/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c:=
842
+ frame #19: 0x000000010202b853 PeiCore.dll:PeiDispatcher() + 1206 at /U=
sers/bcran/src/edk2/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c:1609
+(lldb)
+
```
=20
# Build and Debug from Xcode
-To build from the Xcode GUI open ~/work/edk2/UnixPkg/Xcode/xcode_project/x=
code_project.xcodeproj. You can build, clean, and source level debug from=
the Xcode GUI. You can hit the Build and Debug button to start the build p=
rocess. You need to need to hit command-shift-B to show the output of the b=
uild. Click Pause to break into the debugger.
-
-[[File:Xcode.jpg]]
+To build from the Xcode GUI open ~/work/edk2/EmulatorPkg/Unix/Xcode/xcode_=
project64/xcode_project.xcodeproj. You can build, clean, and source level d=
ebug from the Xcode GUI. You can hit the Build and Debug button to start th=
e build process. You need to need to hit command-shift-B to show the output=
of the build. Click Pause to break into the debugger.
=20
The stack trace contains items that show as ?? since the default shell is =
checked in as a binary. `nanosleep$UNIX2003` and `__semwait_signal` are POS=
IX library calls and you do not get C source debug with these symbols.
=20
-# Source Level Debug Shell=20
-
-It is possible to get source level debug for the EFI Shell by pulling thes=
e projects from source control and building them.
-
-Instructions for building and hooking in the shell are located in the [htt=
ps://sourceforge.net/apps/mediawiki/tianocore/index.php?title=3DGcc-shell g=
cc-shell] project.
-
-Please note the gcc-shell and UnixPkg build separately, so if you update s=
hell code you need to build the shell to see the changes. The following scr=
een shot shows being able to source level debug the shell:
-
-[[File:Xcode_good.jpg]]
+*Note* The Xcode project is currently (as of 2021-05-09) broken.
=20
# See Also
=20
-* [[Step-by-step instructions]]
-
# Continue with common instructions
=20
-The [remaining instructions](../Common-instructions) are common for most U=
NIX-like systems.
+The [remaining instructions](https://github.com/tianocore/tianocore.github=
.io/wiki/Common-instructions-for-Unix) are common for most UNIX-like system=
s.
--=20
2.30.1 (Apple Git-130)


RFC: EXT4 filesystem driver

Pedro Falcato
 

EXT4 (fourth extended filesystem) is a filesystem developed for Linux
that has been in wide use (desktops, servers, smartphones) since 2008.

The Ext4Pkg implements the Simple File System Protocol for a partition
that is formatted with the EXT4 file system. This allows UEFI Drivers,
UEFI Applications, UEFI OS Loaders, and the UEFI Shell to access files
on an EXT4 partition and supports booting a UEFI OS Loader from an
EXT4 partition.
This project is one of the TianoCore Google Summer of Code projects.

Right now, Ext4Pkg only contains a single member, Ext4Dxe, which is a
UEFI driver that consumes Block I/O, Disk I/O and (optionally) Disk
I/O 2 Protocols, and produces the Simple File System protocol. It
allows mounting ext4 filesystems exclusively.

Brief overhead of EXT4:
Layout of an EXT2/3/4 filesystem:
(note: this driver has been developed using
https://www.kernel.org/doc/html/latest/filesystems/ext4/index.html as
documentation).

An ext2/3/4 filesystem (here on out referred to as simply an ext4 filesystem,
due to the similarities) is composed of various concepts:

1) Superblock
The superblock is the structure near (1024 bytes offset from the start)
the start of the partition, and describes the filesystem in general.
Here, we get to know the size of the filesystem's blocks, which features
it supports or not, whether it's been cleanly unmounted, how many blocks
we have, etc.

2) Block groups
EXT4 filesystems are divided into block groups, and each block group covers
s_blocks_per_group(8 * Block Size) blocks. Each block group has an
associated block group descriptor; these are present directly after the
superblock. Each block group descriptor contains the location of the
inode table, and the inode and block bitmaps (note these bitmaps are only
a block long, which gets us the 8 * Block Size formula covered previously).

3) Blocks
The ext4 filesystem is divided into blocks, of size s_log_block_size ^ 1024.
Blocks can be allocated using individual block groups's bitmaps. Note
that block 0 is invalid and its presence on extents/block tables means
it's part of a file hole, and that particular location must be read as
a block full of zeros.

4) Inodes
The ext4 filesystem divides files/directories into inodes (originally
index nodes). Each file/socket/symlink/directory/etc (here on out referred
to as a file, since there is no distinction under the ext4 filesystem) is
stored as a /nameless/ inode, that is stored in some block group's inode
table. Each inode has s_inode_size size (or GOOD_OLD_INODE_SIZE if it's
an old filesystem), and holds various metadata about the file. Since the
largest inode structure right now is ~160 bytes, the rest of the inode
contains inline extended attributes. Inodes' data is stored using either
data blocks (under ext2/3) or extents (under ext4).

5) Extents
Ext4 inodes store data in extents. These let N contiguous logical blocks
that are represented by N contiguous physical blocks be represented by a
single extent structure, which minimizes filesystem metadata bloat and
speeds up block mapping (particularly due to the fact that high-quality
ext4 implementations like linux's try /really/ hard to make the file
contiguous, so it's common to have files with almost 0 fragmentation).
Inodes that use extents store them in a tree, and the top of the tree
is stored on i_data. The tree's leaves always start with an
EXT4_EXTENT_HEADER and contain EXT4_EXTENT_INDEX on eh_depth != 0 and
EXT4_EXTENT on eh_depth = 0; these entries are always sorted by logical
block.

6) Directories
Ext4 directories are files that store name -> inode mappings for the
logical directory; this is where files get their names, which means ext4
inodes do not themselves have names, since they can be linked (present)
multiple times with different names. Directories can store entries in two
different ways:
1) Classical linear directories: They store entries as a mostly-linked
mostly-list of EXT4_DIR_ENTRY.
2) Hash tree directories: These are used for larger directories, with
hundreds of entries, and are designed in a backwards-compatible way.
These are not yet implemented in the Ext4Dxe driver.

7) Journal
Ext3/4 filesystems have a journal to help protect the filesystem against
system crashes. This is not yet implemented in Ext4Dxe but is described
in detail in the Linux kernel's documentation.

The EDK2 implementation of ext4 is based only on the public documentation
available at https://www.kernel.org/doc/html/latest/filesystems/ext4/index.html
and
the FreeBSD ext2fs driver (available at
https://github.com/freebsd/freebsd-src/tree/main/sys/fs/ext2fs,
BSD-2-Clause-FreeBSD licensed). It is licensed as
SPDX-License-Identifier: BSD-2-Clause-Patent.

After a brief discussion with the community, the proposed package
location is edk2-platform/Features/Ext4Pkg
(relevant discussion: https://edk2.groups.io/g/devel/topic/83060185).

I was the main contributor and I would like to maintain the package in
the future, if possible.

Current limitations:
1) The Ext4Dxe driver is, at the moment, read-only.
2) The Ext4Dxe driver at the moment cannot mount older (ext2/3)
filesystems. Ensuring compatibility with
those may not be a bad idea.

I intend to test the package using the UEFI SCTs present in edk2-test,
and implement any other needed unit tests myself using the already
available unit test framework. I also intend to (privately) fuzz the
UEFI driver with bad/unusual disk images, to improve the security and
reliability of the driver.

In the future, ext4 write support should be added so edk2 has a
fully-featured RW ext4 driver. There could also be a focus on
supporting the older ext4-like filesystems, as I mentioned in the
limitations, but that is open for discussion.

The driver's handling of unclean unmounting through forced shutdown is unclear.
Is there a position in edk2 on how to handle such cases? I don't think
FAT32 has a "this filesystem is/was dirty" and even though it seems to
me that stopping a system from booting/opening the partition because
"we may find some tiny irregularities" is not the best course of
action, I can't find a clear answer.

The driver also had to add implementations of CRC32C and CRC16, and
after talking with my mentor we quickly reached the conclusion that
these may be good candidates for inclusion in MdePkg. We also
discussed moving the Ucs2 <-> Utf8 conversion library in RedfishPkg
(BaseUcs2Utf8Lib) into MdePkg as well. Any comments?

Feel free to ask any questions you may find relevant.

Best Regards,

Pedro Falcato


Re: [edk2-platform][PATCH v1 1/1] Platform/RaspberryPi/RPi4: Fix non-standard ACPI HIDs

Andrei Warkentin
 

Reviewed-by: Andrei Warkentin <awarkentin@...>


From: Ard Biesheuvel <ardb@...>
Sent: Tuesday, July 20, 2021 10:37 AM
To: Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@...>
Cc: edk2-devel-groups-io <devel@edk2.groups.io>; Leif Lindholm <leif@...>; Ard Biesheuvel <ardb+tianocore@...>; Pete Batard <pete@...>; Andrei Warkentin <awarkentin@...>; Mario Bălănică <mariobalanica02@...>
Subject: Re: [edk2-platform][PATCH v1 1/1] Platform/RaspberryPi/RPi4: Fix non-standard ACPI HIDs
 
On Mon, 19 Jul 2021 at 22:45, Samer El-Haj-Mahmoud
<Samer.El-Haj-Mahmoud@...> wrote:
>
> Remove non-standard RPI ACPI _CIDs that are not needed.
> This also fixes the FWTS failure reported in
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fpftf%2FRPi4%2Fissues%2F67&amp;data=04%7C01%7Cawarkentin%40vmware.com%7Cbfd9e47da54c40ef9c5408d94b51486a%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C637623634750321947%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=YO4V6pksRlNqfPlMwO0VPKNVcp4npeP%2BN%2BpigTFfZnM%3D&amp;reserved=0
>
> The windows drivers at https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fraspberrypi%2Fwindows-drivers&amp;data=04%7C01%7Cawarkentin%40vmware.com%7Cbfd9e47da54c40ef9c5408d94b51486a%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C637623634750321947%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=PMkBX%2F6vHaAoUC5tkCA7aAldaYEKFgh9w3yFYsgNrPQ%3D&amp;reserved=0
> are still able to match the ACPI objects using the HIDs which
> are supported in the drivers, with these two recent changes needed:
> 469702898789e555c6947e50216a3f79e0ddeb9
> and
> 5c5e2742b4c983b3001c473b168b0dae2fcba0c2
>
> Cc: Leif Lindholm <leif@...>
> Cc: Ard Biesheuvel <ardb+tianocore@...>
> Cc: Pete Batard <pete@...>
> Cc: Andrei Warkentin <awarkentin@...>
> Cc: Mario Bălănică <mariobalanica02@...>
> Signed-off-by: Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@...>
> Tested-by: Mario Bălănică <mariobalanica02@...>

Glad to see this getting cleaned up.

Anyone care to ack?


> ---
>  Platform/RaspberryPi/AcpiTables/GpuDevs.asl | 26 +++++++++++---------
>  Platform/RaspberryPi/AcpiTables/Sdhc.asl    |  4 +--
>  Platform/RaspberryPi/AcpiTables/Uart.asl    |  2 +-
>  3 files changed, 18 insertions(+), 14 deletions(-)
>
> diff --git a/Platform/RaspberryPi/AcpiTables/GpuDevs.asl b/Platform/RaspberryPi/AcpiTables/GpuDevs.asl
> index 966a94cdb5b5..9750dc25c07c 100644
> --- a/Platform/RaspberryPi/AcpiTables/GpuDevs.asl
> +++ b/Platform/RaspberryPi/AcpiTables/GpuDevs.asl
> @@ -13,7 +13,11 @@
>  Device (USB0)
>  {
>    Name (_HID, "BCM2848")
> -  Name (_CID, Package() { "DWC_OTG", "DWC2_OTG" })
> +#if (RPI_MODEL == 3)
> +  Name (_CID, "DWC_OTG")
> +#elif (RPI_MODEL == 4)
> +  Name (_CID, "BCM2848")
> +#endif
>    Name (_UID, 0x0)
>    Name (_CCA, 0x0)
>    Method (_STA)
> @@ -36,7 +40,7 @@ Device (USB0)
>  Device (GPU0)
>  {
>    Name (_HID, "BCM2850")
> -  Name (_CID, "VC4")
> +  Name (_CID, "BCM2850")
>    Name (_UID, 0x0)
>    Name (_CCA, 0x0)
>    Method (_STA)
> @@ -140,7 +144,7 @@ Device (GPU0)
>  Device (RPIQ)
>  {
>    Name (_HID, "BCM2849")
> -  Name (_CID, "RPIQ")
> +  Name (_CID, "BCM2849")
>    Name (_UID, 0)
>    Name (_CCA, 0x0)
>    Method (_STA)
> @@ -164,7 +168,7 @@ Device (RPIQ)
>  Device (VCIQ)
>  {
>    Name (_HID, "BCM2835")
> -  Name (_CID, "VCIQ")
> +  Name (_CID, "BCM2835")
>    Name (_UID, 0)
>    Name (_CCA, 0x0)
>    Name (_DEP, Package() { \_SB.GDV0.RPIQ })
> @@ -189,7 +193,7 @@ Device (VCIQ)
>  Device (VCSM)
>  {
>    Name (_HID, "BCM2856")
> -  Name (_CID, "VCSM")
> +  Name (_CID, "BCM2856")
>    Name (_UID, 0)
>    Name (_CCA, 0x0)
>    Name (_DEP, Package() { \_SB.GDV0.VCIQ })
> @@ -203,7 +207,7 @@ Device (VCSM)
>  Device (GPI0)
>  {
>    Name (_HID, "BCM2845")
> -  Name (_CID, "BCMGPIO")
> +  Name (_CID, "BCM2845")
>    Name (_UID, 0x0)
>    Name (_CCA, 0x0)
>    Method (_STA)
> @@ -230,7 +234,7 @@ Device (GPI0)
>  Device (I2C1)
>  {
>    Name (_HID, "BCM2841")
> -  Name (_CID, "BCMI2C")
> +  Name (_CID, "BCM2841")
>    Name (_UID, 0x1)
>    Name (_CCA, 0x0)
>    Method (_STA)
> @@ -254,7 +258,7 @@ Device (I2C1)
>  Device (I2C2)
>  {
>    Name (_HID, "BCM2841")
> -  Name (_CID, "BCMI2C")
> +  Name (_CID, "BCM2841")
>    Name (_UID, 0x2)
>    Name (_CCA, 0x0)
>    Method (_STA)
> @@ -278,7 +282,7 @@ Device (I2C2)
>  Device (SPI0)
>  {
>    Name (_HID, "BCM2838")
> -  Name (_CID, "BCMSPI0")
> +  Name (_CID, "BCM2838")
>    Name (_UID, 0x0)
>    Name (_CCA, 0x0)
>    Method (_STA)
> @@ -304,7 +308,7 @@ Device (SPI0)
>  Device (SPI1)
>  {
>    Name (_HID, "BCM2839")
> -  Name (_CID, "BCMAUXSPI")
> +  Name (_CID, "BCM2839")
>    Name (_UID, 0x1)
>    Name (_CCA, 0x0)
>    Name (_DEP, Package() { \_SB.GDV0.RPIQ })
> @@ -331,7 +335,7 @@ Device (SPI1)
>  // Device (SPI2)
>  // {
>  //   Name (_HID, "BCM2839")
> -//   Name (_CID, "BCMAUXSPI")
> +//   Name (_CID, "BCM2839")
>  //   Name (_UID, 0x2)
>  //   Name (_CCA, 0x0)
>  //   Name (_DEP, Package() { \_SB.GDV0.RPIQ })
> diff --git a/Platform/RaspberryPi/AcpiTables/Sdhc.asl b/Platform/RaspberryPi/AcpiTables/Sdhc.asl
> index 42776e33bbc6..85d5053a338c 100644
> --- a/Platform/RaspberryPi/AcpiTables/Sdhc.asl
> +++ b/Platform/RaspberryPi/AcpiTables/Sdhc.asl
> @@ -23,7 +23,7 @@
>  Device (SDC1)
>  {
>    Name (_HID, "BCM2847")
> -  Name (_CID, "ARASAN")
> +  Name (_CID, "BCM2847")
>    Name (_UID, 0x0)
>    Name (_CCA, 0x0)
>    Name (_S1D, 0x1)
> @@ -78,7 +78,7 @@ Device (SDC1)
>  Device (SDC2)
>  {
>    Name (_HID, "BCM2855")
> -  Name (_CID, "SDHST")
> +  Name (_CID, "BCM2855")
>    Name (_UID, 0x0)
>    Name (_CCA, 0x0)
>    Name (_S1D, 0x1)
> diff --git a/Platform/RaspberryPi/AcpiTables/Uart.asl b/Platform/RaspberryPi/AcpiTables/Uart.asl
> index 167f94e8892b..974f06d3bc3f 100644
> --- a/Platform/RaspberryPi/AcpiTables/Uart.asl
> +++ b/Platform/RaspberryPi/AcpiTables/Uart.asl
> @@ -59,7 +59,7 @@ Device (URT0)
>  Device (URTM)
>  {
>    Name (_HID, "BCM2836")
> -  Name (_CID, "MINIUART")
> +  Name (_CID, "BCM2836")
>    Name (_UID, 0x0)
>    Name (_CCA, 0x0)
>    Method (_STA)
> --
> 2.25.1
>


Re: [PATCH 1/1] MdePkg: add definition of LINUX_EFI_INITRD_MEDIA_GUID

Michael D Kinney
 

Hi Jeff,

 

I see.  I missed the file rename line in the git patch.

 

I think the description needs to be expanded to clearly describe the production and consumption of this device path with this GUID.

 

  1. What component creates the UEFI handle with the Device Path Protocol and the LoadFile2 Protocol with the initrd image?  Is it the platform FW or the OS Loader?  If it is the platform FW, then how does the platform FW know which initrd image to publish if there are multiple Linux OSes installed?
  2. What component locates the UEFI handle with the Device Path Protocol and the LoadFile2 Protocol with the initrd image?  It is another stage of the OS Loader or the OS Kernel?  Given that these handles are only available before ExitBootServices, I think this means that the component that locates the initrd image has to do so before ExitBootServices is called.

 

Thanks,

 

Mike

 

From: Jeff Brasen <jbrasen@...>
Sent: Wednesday, July 21, 2021 10:26 AM
To: Kinney, Michael D <michael.d.kinney@...>; Ard Biesheuvel <ardb@...>
Cc: devel@edk2.groups.io; ardb+tianocore@...; Justen, Jordan L <jordan.l.justen@...>; gaoliming@...; Liu, Zhiguang <zhiguang.liu@...>; Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@...>
Subject: Re: [edk2-devel] [PATCH 1/1] MdePkg: add definition of LINUX_EFI_INITRD_MEDIA_GUID

 

Does this look good for text to add

 

"Linux distro boot generally relies on an initial ramdisk (initrd)
which is provided by the loader, and which contains additional kernel
modules (for storage and network, for instance), and the initial user
space startup code, i.e., the code which brings up the user space side
of the entire OS.

In order to provide a standard method to locate this file,

the GUID defined in this file is used to describe the device path

for a LoadFile2 Protocol instance that is responsible for loading the initrd file"

 

 

Also, the patch does have

 {OvmfPkg => MdePkg}/Include/Guid/LinuxEfiInitrdMedia.h | 0
 3 files changed, 5 insertions(+), 1 deletion(-)
 rename {OvmfPkg => MdePkg}/Include/Guid/LinuxEfiInitrdMedia.h (100%)
[snip]
diff --git a/OvmfPkg/Include/Guid/LinuxEfiInitrdMedia.h b/MdePkg/Include/Guid/LinuxEfiInitrdMedia.h
similarity index 100%
rename from OvmfPkg/Include/Guid/LinuxEfiInitrdMedia.h
rename to MdePkg/Include/Guid/LinuxEfiInitrdMedia.h

 

 

Thanks,

Jeff


From: Kinney, Michael D <michael.d.kinney@...>
Sent: Wednesday, July 21, 2021 9:38 AM
To: Jeff Brasen <jbrasen@...>; Ard Biesheuvel <ardb@...>; Kinney, Michael D <michael.d.kinney@...>
Cc: devel@edk2.groups.io <devel@edk2.groups.io>; ardb+tianocore@... <ardb+tianocore@...>; Justen, Jordan L <jordan.l.justen@...>; gaoliming@... <gaoliming@...>; Liu, Zhiguang <zhiguang.liu@...>; Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@...>
Subject: RE: [edk2-devel] [PATCH 1/1] MdePkg: add definition of LINUX_EFI_INITRD_MEDIA_GUID

 

External email: Use caution opening links or attachments

 

Hi Ard,

 

If this device path node is considered as part of the standard interface between the Linux kernel and

firmware, then it does make sense for it to be in the MdePkg.  We usually try to reference a public

specification in the include file that defines the interface.

 

In this case, since there is no public document, but it is part of the Linux kernel assumptions,

can the include file for the GUID provide pointers to the Linux kernel that uses the GUID and

describe how the GUID is produced by the FW and consumed by the Linux kernel?

 

I also see that this patch appears to be incomplete.  There is an OvmfPkg/Include/Guid/LinuxEfiInitrdMedia.h

file in the OvmfPkg.  Shouldn’t that file also be moved to the MdePkg as part of this patch?

 

Thanks,

 

Mike

 

From: Jeff Brasen <jbrasen@...>
Sent: Tuesday, July 20, 2021 9:59 AM
To: Ard Biesheuvel <ardb@...>; Kinney, Michael D <michael.d.kinney@...>
Cc: devel@edk2.groups.io; ardb+tianocore@...; Justen, Jordan L <jordan.l.justen@...>; gaoliming@...; Liu, Zhiguang <zhiguang.liu@...>; Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@...>
Subject: Re: [edk2-devel] [PATCH 1/1] MdePkg: add definition of LINUX_EFI_INITRD_MEDIA_GUID

 

In my opinion MdePkg is where this should be as it is meant to be used by multiple software entities (linux kernel, grub, edk2, coreboot w/ uefi binding) and probably should be documented in some spec (Although, I am not sure which one would make sense)

 

I am fine with MdeModulePkg as well though.

 

Thanks,

Jeff


From: Ard Biesheuvel <ardb@...>
Sent: Friday, July 16, 2021 9:56 AM
To: Kinney, Michael D <michael.d.kinney@...>
Cc: Jeff Brasen <jbrasen@...>; devel@edk2.groups.io <devel@edk2.groups.io>; ardb+tianocore@... <ardb+tianocore@...>; Justen, Jordan L <jordan.l.justen@...>; gaoliming@... <gaoliming@...>; Liu, Zhiguang <zhiguang.liu@...>; Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@...>
Subject: Re: [edk2-devel] [PATCH 1/1] MdePkg: add definition of LINUX_EFI_INITRD_MEDIA_GUID

 

External email: Use caution opening links or attachments


On Fri, 16 Jul 2021 at 17:00, Kinney, Michael D
<michael.d.kinney@...> wrote:
>
> Hi Ard,
>
> I see you were involved in the OS side changes.
>
> Can you explain what is required for the FW <-> OS interface with respect to Load File Protocol and this media device path node.
>
> What happens if this media device path node is not present?  What breaks?
>
> Trying to figure out if this is a required interop feature (MdePkg candidate) or an EDK II specific extension (MdeModulePkg candidate).
>

Let me give some context first:

Linux distro boot generally relies on an initial ramdisk (initrd)
which is provided by the loader, and which contains additional kernel
modules (for storage and netwerk, for instance), and the initial user
space startup code, ie., the code which brings up the user space side
of the entire OS.

Before we introduced this media path, the only way for a EFI pre-OS
loader (such as GRUB) to provide this initrd was to copy it into DRAM
somewhere, and use a arch-specific method of passing the DRAM address
and size to the OS (x86 uses struct bootparam, whereas ARM uses device
tree). It also requires knowledge on the part of GRUB regarding which
parts of DRAM are suitable for holding an initrd image. For measured
boot scenarios, it may be an advantage not to have the initrd linger
in DRAM for longer that necessary, and we actually intend to measure
the initrd loaded via the new method right after it has been loaded
this way.

To avoid extending this to other architectures such as RISC-V, I
decided to introduce a special vendor media path for Linux initrd
images, which GRUB et al can implement, which provides the initrd
image when the OS loader that consumes it asks for it.

So for Linux on x86 or ARM, this is optional, given that support for
the old method is not going away any time soon. For RISC-V, I
suggested that only the new method be implemented, but I am not sure
what the status is there. Note that many embedded style systems don't
use GRUB, and may not use initrds to begin with. OTOH, U-Boot also
implements support for the Linux initrd vendor media path, and work is
ongoing to add measured boot support as well.

In any case, I don't have a strong preference where this should live,
as long as it is in a generic place where all architectures can use
it.

--
Ard.


Re: [PATCH v1 5/6] UefiPayloadPkg: Add DISABLE_MMX_SSE to avoid generating floating points operation

Cheng-Chieh Huang <chengchieh@...>
 

Yes, we can. I will drop this patch for this  uefipayload batch and send another one for support DISABLE_GCC_MMX_SSE in tools_de.txt.

--
Cheng-Chieh 


On Thu, Jul 22, 2021, 12:35 AM Kinney, Michael D <michael.d.kinney@...> wrote:
Are those flags needed for all packages that build with GCC?

Should this be moved into tools_def.txt?

Mike

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Cheng-Chieh Huang via groups.io
> Sent: Wednesday, July 21, 2021 6:23 AM
> To: devel@edk2.groups.io
> Cc: Cheng-Chieh Huang <chengchieh@...>
> Subject: [edk2-devel] [PATCH v1 5/6] UefiPayloadPkg: Add DISABLE_MMX_SSE to avoid generating floating points operation
>
> This will allow we compile payload using gcc8
>
> Signed-off-by: Cheng-Chieh Huang <chengchieh@...>
> ---
>  UefiPayloadPkg/UefiPayloadPkg.dsc | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc
> index 8aa5f18cd35c..fa41c5a24af5 100644
> --- a/UefiPayloadPkg/UefiPayloadPkg.dsc
> +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
> @@ -30,6 +30,8 @@ [Defines]
>    DEFINE PS2_KEYBOARD_ENABLE          = FALSE
>    DEFINE UNIVERSAL_PAYLOAD            = FALSE
>
> +  DEFINE DISABLE_MMX_SSE              = FALSE
> +
>    #
>    # SBL:      UEFI payload for Slim Bootloader
>    # COREBOOT: UEFI payload for coreboot
> @@ -96,6 +98,9 @@ [BuildOptions]
>    *_*_*_CC_FLAGS                 = -D DISABLE_NEW_DEPRECATED_INTERFACES
>  !if $(BOOTLOADER) == "LINUXBOOT"
>    *_*_*_CC_FLAGS                 = -D LINUXBOOT_PAYLOAD
> +!endif
> +!if $(DISABLE_MMX_SSE)
> +  *_*_*_CC_FLAGS                 = -mno-mmx -mno-sse
>  !endif
>    GCC:*_UNIXGCC_*_CC_FLAGS       = -DMDEPKG_NDEBUG
>    GCC:RELEASE_*_*_CC_FLAGS       = -DMDEPKG_NDEBUG
> --
> 2.32.0.402.g57bb445576-goog
>
>
>
>
>


Re: [PATCH 1/1] MdePkg: add definition of LINUX_EFI_INITRD_MEDIA_GUID

Jeff Brasen
 

Does this look good for text to add

"Linux distro boot generally relies on an initial ramdisk (initrd)
which is provided by the loader, and which contains additional kernel
modules (for storage and network, for instance), and the initial user
space startup code, i.e., the code which brings up the user space side
of the entire OS.

In order to provide a standard method to locate this file,
the GUID defined in this file is used to describe the device path
for a LoadFile2 Protocol instance that is responsible for loading the initrd file"


Also, the patch does have
 {OvmfPkg => MdePkg}/Include/Guid/LinuxEfiInitrdMedia.h | 0
 3 files changed, 5 insertions(+), 1 deletion(-)
 rename {OvmfPkg => MdePkg}/Include/Guid/LinuxEfiInitrdMedia.h (100%)
[snip]
diff --git a/OvmfPkg/Include/Guid/LinuxEfiInitrdMedia.h b/MdePkg/Include/Guid/LinuxEfiInitrdMedia.h
similarity index 100%
rename from OvmfPkg/Include/Guid/LinuxEfiInitrdMedia.h
rename to MdePkg/Include/Guid/LinuxEfiInitrdMedia.h


Thanks,

Jeff


From: Kinney, Michael D <michael.d.kinney@...>
Sent: Wednesday, July 21, 2021 9:38 AM
To: Jeff Brasen <jbrasen@...>; Ard Biesheuvel <ardb@...>; Kinney, Michael D <michael.d.kinney@...>
Cc: devel@edk2.groups.io <devel@edk2.groups.io>; ardb+tianocore@... <ardb+tianocore@...>; Justen, Jordan L <jordan.l.justen@...>; gaoliming@... <gaoliming@...>; Liu, Zhiguang <zhiguang.liu@...>; Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@...>
Subject: RE: [edk2-devel] [PATCH 1/1] MdePkg: add definition of LINUX_EFI_INITRD_MEDIA_GUID
 
External email: Use caution opening links or attachments

Hi Ard,

 

If this device path node is considered as part of the standard interface between the Linux kernel and

firmware, then it does make sense for it to be in the MdePkg.  We usually try to reference a public

specification in the include file that defines the interface.

 

In this case, since there is no public document, but it is part of the Linux kernel assumptions,

can the include file for the GUID provide pointers to the Linux kernel that uses the GUID and

describe how the GUID is produced by the FW and consumed by the Linux kernel?

 

I also see that this patch appears to be incomplete.  There is an OvmfPkg/Include/Guid/LinuxEfiInitrdMedia.h

file in the OvmfPkg.  Shouldn’t that file also be moved to the MdePkg as part of this patch?

 

Thanks,

 

Mike

 

From: Jeff Brasen <jbrasen@...>
Sent: Tuesday, July 20, 2021 9:59 AM
To: Ard Biesheuvel <ardb@...>; Kinney, Michael D <michael.d.kinney@...>
Cc: devel@edk2.groups.io; ardb+tianocore@...; Justen, Jordan L <jordan.l.justen@...>; gaoliming@...; Liu, Zhiguang <zhiguang.liu@...>; Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@...>
Subject: Re: [edk2-devel] [PATCH 1/1] MdePkg: add definition of LINUX_EFI_INITRD_MEDIA_GUID

 

In my opinion MdePkg is where this should be as it is meant to be used by multiple software entities (linux kernel, grub, edk2, coreboot w/ uefi binding) and probably should be documented in some spec (Although, I am not sure which one would make sense)

 

I am fine with MdeModulePkg as well though.

 

Thanks,

Jeff


From: Ard Biesheuvel <ardb@...>
Sent: Friday, July 16, 2021 9:56 AM
To: Kinney, Michael D <michael.d.kinney@...>
Cc: Jeff Brasen <jbrasen@...>; devel@edk2.groups.io <devel@edk2.groups.io>; ardb+tianocore@... <ardb+tianocore@...>; Justen, Jordan L <jordan.l.justen@...>; gaoliming@... <gaoliming@...>; Liu, Zhiguang <zhiguang.liu@...>; Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@...>
Subject: Re: [edk2-devel] [PATCH 1/1] MdePkg: add definition of LINUX_EFI_INITRD_MEDIA_GUID

 

External email: Use caution opening links or attachments


On Fri, 16 Jul 2021 at 17:00, Kinney, Michael D
<michael.d.kinney@...> wrote:
>
> Hi Ard,
>
> I see you were involved in the OS side changes.
>
> Can you explain what is required for the FW <-> OS interface with respect to Load File Protocol and this media device path node.
>
> What happens if this media device path node is not present?  What breaks?
>
> Trying to figure out if this is a required interop feature (MdePkg candidate) or an EDK II specific extension (MdeModulePkg candidate).
>

Let me give some context first:

Linux distro boot generally relies on an initial ramdisk (initrd)
which is provided by the loader, and which contains additional kernel
modules (for storage and netwerk, for instance), and the initial user
space startup code, ie., the code which brings up the user space side
of the entire OS.

Before we introduced this media path, the only way for a EFI pre-OS
loader (such as GRUB) to provide this initrd was to copy it into DRAM
somewhere, and use a arch-specific method of passing the DRAM address
and size to the OS (x86 uses struct bootparam, whereas ARM uses device
tree). It also requires knowledge on the part of GRUB regarding which
parts of DRAM are suitable for holding an initrd image. For measured
boot scenarios, it may be an advantage not to have the initrd linger
in DRAM for longer that necessary, and we actually intend to measure
the initrd loaded via the new method right after it has been loaded
this way.

To avoid extending this to other architectures such as RISC-V, I
decided to introduce a special vendor media path for Linux initrd
images, which GRUB et al can implement, which provides the initrd
image when the OS loader that consumes it asks for it.

So for Linux on x86 or ARM, this is optional, given that support for
the old method is not going away any time soon. For RISC-V, I
suggested that only the new method be implemented, but I am not sure
what the status is there. Note that many embedded style systems don't
use GRUB, and may not use initrds to begin with. OTOH, U-Boot also
implements support for the Linux initrd vendor media path, and work is
ongoing to add measured boot support as well.

In any case, I don't have a strong preference where this should live,
as long as it is in a generic place where all architectures can use
it.

--
Ard.


Re: [PATCH v1 6/6] UefiPayloadPkg: LinuxBoot: use a text format for the configuration block.

Marvin Häuser
 

On 21.07.21 15:23, Cheng-Chieh Huang via groups.io wrote:
From: Trammell Hudson <hudson@trmm.net>

This adds a text command line for the UefiPayloadPkg that uses
a textual magic number 'LnxBoot1' and a series of white-space
separated key=value[,value...] pairs for the parameters.

The v1 binary configuration structure is used if it is present instead
for backwards compatability.

Currently supported text command line arguments are are:

* `serial=baud,base,width,type,hz,pci`
(only `baud` needs to be specified, the rest have reasonable
defaults)

* `mem=start,end,type`
Types are based on `/sys/firmware/memmaps/*/types`:
1 == "System RAM"
3 == "ACPI Tables"
4 == "ACPI Non-volatile Storage"
5 == "Reserved"

* `ACPI20=base` pointer to RDSP (from `/sys/firmware/efi/systab`)

* `SMBIOS=base` pointer to the SMBIOS table (also from the EFI table)

Signed-off-by: Cheng-Chieh Huang <chengchieh@google.com>
---
UefiPayloadPkg/Include/Linuxboot.h | 17 +-
UefiPayloadPkg/Library/LbParseLib/LbParseLib.c | 252 +++++++++++++++++---
2 files changed, 230 insertions(+), 39 deletions(-)

diff --git a/UefiPayloadPkg/Include/Linuxboot.h b/UefiPayloadPkg/Include/Linuxboot.h
index 34ca18069983..56b39b5a09ff 100644
--- a/UefiPayloadPkg/Include/Linuxboot.h
+++ b/UefiPayloadPkg/Include/Linuxboot.h
@@ -24,8 +24,7 @@ typedef struct MemoryMapEntryStruct {
UINT32 Type;
} MemoryMapEntry;
-typedef struct UefiPayloadConfigStruct {
- UINT64 Version;
+typedef struct {
UINT64 AcpiBase;
UINT64 AcpiSize;
UINT64 SmbiosBase;
@@ -33,10 +32,22 @@ typedef struct UefiPayloadConfigStruct {
SerialPortConfig SerialConfig;
UINT32 NumMemoryMapEntries;
MemoryMapEntry MemoryMapEntries[0];
+} UefiPayloadConfigV1;
+
+typedef struct UefiPayloadConfigStruct {
+ UINT64 Version;
+ union {
+ UefiPayloadConfigV1 v1;
+ struct {
+ char cmdline[0]; // up to 64 KB
+ } v2;
+ } config;
} UefiPayloadConfig;
#pragma pack()
-#define UEFI_PAYLOAD_CONFIG_VERSION 1
+// magic version config is "LnxBoot1"
+#define UEFI_PAYLOAD_CONFIG_VERSION1 1
+#define UEFI_PAYLOAD_CONFIG_VERSION2 0x31746f6f42786e4cULL
#define LINUXBOOT_MEM_RAM 1
#define LINUXBOOT_MEM_DEFAULT 2
diff --git a/UefiPayloadPkg/Library/LbParseLib/LbParseLib.c b/UefiPayloadPkg/Library/LbParseLib/LbParseLib.c
index 34bfb6a1073f..5e68091cac91 100644
--- a/UefiPayloadPkg/Library/LbParseLib/LbParseLib.c
+++ b/UefiPayloadPkg/Library/LbParseLib/LbParseLib.c
@@ -1,13 +1,12 @@
/** @file
- This library will parse the linuxboot table in memory and extract those required
- information.
+ This library will parse the linuxboot table in memory and extract those
+required information.
Copyright (c) 2021, the u-root Authors. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-
#include <IndustryStandard/Acpi.h>
#include <IndustryStandard/SmBios.h>
#include <Library/BaseLib.h>
@@ -18,17 +17,42 @@
#include <Library/PcdLib.h>
#include <Linuxboot.h>
#include <Uefi/UefiBaseType.h>
+#include <stdint.h>
+#include <stdlib.h>
+//#include <string.h>
+//#include <ctype.h>
+
+#define strncmp(a, b, n) AsciiStrnCmp((a), (b), (n))
+
+static uint64_t parse_int(const char* s, char** end) {
+ UINT64 x;
+
+ if (s[0] == '0' && s[1] == 'x')
+ AsciiStrHexToUint64S(s, end, &x);
+ else
+ AsciiStrDecimalToUint64S(s, end, &x);
+
+ return x;
+}
+
+static int isspace(const char c) { return c == ' ' || c == '\t' || c == '\n'; }
// Retrieve UefiPayloadConfig from Linuxboot's uefiboot
-UefiPayloadConfig* GetUefiPayLoadConfig() {
- UefiPayloadConfig* config =
+const UefiPayloadConfig* GetUefiPayLoadConfig() {
+ const UefiPayloadConfig* config =
(UefiPayloadConfig*)(UINTN)(PcdGet32(PcdPayloadFdMemBase) - SIZE_64KB);
- if (config->Version != UEFI_PAYLOAD_CONFIG_VERSION) {
- DEBUG((DEBUG_ERROR, "Expect payload config version: %d, but get %d\n",
- UEFI_PAYLOAD_CONFIG_VERSION, config->Version));
- CpuDeadLoop ();
- }
- return config;
+
+ if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION1 ||
+ config->Version == UEFI_PAYLOAD_CONFIG_VERSION2)
+ return config;
+
+ DEBUG((DEBUG_ERROR,
+ "Expect payload config version %016lx or %016lx, but get %016lx\n",
+ UEFI_PAYLOAD_CONFIG_VERSION1, UEFI_PAYLOAD_CONFIG_VERSION2,
+ config->Version));
+ CpuDeadLoop();
+ while (1)
+ ;
}
// Align the address and add memory rang to MemInfoCallback
@@ -54,6 +78,57 @@ void AddMemoryRange(IN BL_MEM_INFO_CALLBACK MemInfoCallback, IN UINTN start,
MemInfoCallback(&MemoryMap, NULL);
}
+const char* cmdline_next(const char* cmdline, const char** option) {
+ // at the end of the string, we're done
+ if (!cmdline || *cmdline == '\0') return NULL;
+
+ // skip any leading whitespace
+ while (isspace(*cmdline)) cmdline++;
+
+ // if we've hit the end of the string, we're done
+ if (*cmdline == '\0') return NULL;
+
+ *option = cmdline;
+
+ // find the end of this option or the string
+ while (!isspace(*cmdline) && *cmdline != '\0') cmdline++;
+
+ // cmdline points to the whitespace or end of string
+ return cmdline;
+}
+
+int cmdline_ints(const char* option, uint64_t args[], int max) {
+ // skip any leading text up to an '='
+ const char* s = option;
+ while (1) {
+ const char c = *s++;
+ if (c == '=') break;
+
+ if (c == '\0' || isspace(c)) {
+ s = option;
+ break;
+ }
+ }
+
+ for (int i = 0; i < max; i++) {
+ char* end;
+ args[i] = parse_int(s, &end);
+
+ // end of string or end of the option?
+ if (*end == '\0' || isspace(*end)) return i + 1;
+
+ // not separator? signal an error if we have consumed any ints,
+ // otherwise return 0 saying that none were found
+ if (*end != ',') return i == 0 ? 0 : -1;
+
+ // skip the , and get the next value
+ s = end + 1;
+ }
+
+ // too many values!
+ return -1;
+}
+
/**
Acquire the memory information from the linuxboot table in memory.
@@ -67,20 +142,50 @@ void AddMemoryRange(IN BL_MEM_INFO_CALLBACK MemInfoCallback, IN UINTN start,
RETURN_STATUS
EFIAPI
ParseMemoryInfo(IN BL_MEM_INFO_CALLBACK MemInfoCallback, IN VOID* Params) {
- UefiPayloadConfig* config;
- int i;
+ const UefiPayloadConfig* config = GetUefiPayLoadConfig();
+ if (!config) {
+ DEBUG(
+ (DEBUG_ERROR, "ParseMemoryInfo: Could not find UEFI Payload config\n"));
+ return RETURN_SUCCESS;
+ }
+
+ if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION1) {
+ const UefiPayloadConfigV1* config1 = &config->config.v1;
+ DEBUG(
+ (DEBUG_INFO, "MemoryMap #entries: %d\n", config1->NumMemoryMapEntries));
+
+ for (int i = 0; i < config1->NumMemoryMapEntries; i++) {
+ const MemoryMapEntry* entry = &config1->MemoryMapEntries[i];
+ DEBUG((DEBUG_INFO, "Start: 0x%lx End: 0x%lx Type:%d\n", entry->Start,
+ entry->End, entry->Type));
+ AddMemoryRange(MemInfoCallback, entry->Start, entry->End, entry->Type);
+ }
+ } else
- config = GetUefiPayLoadConfig();
+ if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION2) {
+ const char* cmdline = config->config.v2.cmdline;
+ const char* option;
+ uint64_t args[3];
- DEBUG((DEBUG_INFO, "MemoryMap #entries: %d\n", config->NumMemoryMapEntries));
+ // look for the mem=start,end,type
+ while ((cmdline = cmdline_next(cmdline, &option))) {
+ if (strncmp(option, "mem=", 4) != 0) continue;
- MemoryMapEntry* entry = &config->MemoryMapEntries[0];
- for (i = 0; i < config->NumMemoryMapEntries; i++) {
- DEBUG((DEBUG_INFO, "Start: 0x%lx End: 0x%lx Type:%d\n", entry->Start,
- entry->End, entry->Type));
- AddMemoryRange(MemInfoCallback, entry->Start, entry->End, entry->Type);
- entry++;
+ if (cmdline_ints(option, args, 3) != 3) {
+ DEBUG((DEBUG_ERROR, "Parse error: '%a'\n", option));
+ continue;
+ }
+
+ const uint64_t start = args[0];
+ const uint64_t end = args[1];
+ const uint64_t type = args[2];
+
+ DEBUG(
+ (DEBUG_INFO, "Start: 0x%lx End: 0x%lx Type:%d\n", start, end, type));
+ AddMemoryRange(MemInfoCallback, start, end, type);
+ }
}
+
return RETURN_SUCCESS;
}
@@ -96,14 +201,52 @@ ParseMemoryInfo(IN BL_MEM_INFO_CALLBACK MemInfoCallback, IN VOID* Params) {
RETURN_STATUS
EFIAPI
ParseSystemTable(OUT SYSTEM_TABLE_INFO* SystemTableInfo) {
- UefiPayloadConfig* config;
+ const UefiPayloadConfig* config = GetUefiPayLoadConfig();
+ if (!config) {
+ DEBUG((DEBUG_ERROR,
+ "ParseSystemTable: Could not find UEFI Payload config\n"));
+ return RETURN_SUCCESS;
+ }
- config = GetUefiPayLoadConfig();
- SystemTableInfo->AcpiTableBase = config->AcpiBase;
- SystemTableInfo->AcpiTableSize = config->AcpiSize;
+ if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION1) {
+ const UefiPayloadConfigV1* config1 = &config->config.v1;
+ SystemTableInfo->AcpiTableBase = config1->AcpiBase;
+ SystemTableInfo->AcpiTableSize = config1->AcpiSize;
- SystemTableInfo->SmbiosTableBase = config->SmbiosBase;
- SystemTableInfo->SmbiosTableSize = config->SmbiosSize;
+ SystemTableInfo->SmbiosTableBase = config1->SmbiosBase;
+ SystemTableInfo->SmbiosTableSize = config1->SmbiosSize;
+ } else
+
+ if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION2) {
+ const char* cmdline = config->config.v2.cmdline;
+ const char* option;
+ uint64_t args[2];
+
+ // look for the acpi config
+ while ((cmdline = cmdline_next(cmdline, &option))) {
+ if (strncmp(option, "ACPI20=", 7) == 0) {
+ const int count = cmdline_ints(option, args, 2);
+ if (count < 0) {
+ DEBUG((DEBUG_ERROR, "Parse error: '%a'\n", option));
+ continue;
+ }
+
+ if (count > 0) SystemTableInfo->AcpiTableBase = args[0];
+ if (count > 1) SystemTableInfo->AcpiTableSize = args[1];
+ }
+
+ if (strncmp(option, "SMBIOS=", 7) == 0) {
+ const int count = cmdline_ints(option, args, 2);
+ if (count < 0) {
+ DEBUG((DEBUG_ERROR, "Parse error: '%a'\n", option));
+ continue;
+ }
+
+ if (count > 0) SystemTableInfo->SmbiosTableBase = args[0];
+ if (count > 1) SystemTableInfo->SmbiosTableSize = args[1];
+ }
Sorry, from only a quick peak, can this not leave {Acpi,Smbios}TableBase and {Acpi,Smbios}TableSize undefined entirely, while returning RETURN_SUCCESS?
Even if not, it looks kind of odd a command-line argument can change the base address without changing the size, is there a documentation of this behaviour?
What is the structure supposed to carry if no such arguments are given at all?

Thanks for your time!

Best regards,
Marvin

+ }
+ }
return RETURN_SUCCESS;
}
@@ -120,15 +263,52 @@ ParseSystemTable(OUT SYSTEM_TABLE_INFO* SystemTableInfo) {
RETURN_STATUS
EFIAPI
ParseSerialInfo(OUT SERIAL_PORT_INFO* SerialPortInfo) {
- UefiPayloadConfig* config;
- config = GetUefiPayLoadConfig();
-
- SerialPortInfo->BaseAddr = config->SerialConfig.BaseAddr;
- SerialPortInfo->RegWidth = config->SerialConfig.RegWidth;
- SerialPortInfo->Type = config->SerialConfig.Type;
- SerialPortInfo->Baud = config->SerialConfig.Baud;
- SerialPortInfo->InputHertz = config->SerialConfig.InputHertz;
- SerialPortInfo->UartPciAddr = config->SerialConfig.UartPciAddr;
+ // fill in some reasonable defaults
+ SerialPortInfo->BaseAddr = 0x3f8;
+ SerialPortInfo->RegWidth = 1;
+ SerialPortInfo->Type = 1; // uefi.SerialPortTypeIO
+ SerialPortInfo->Baud = 115200;
+ SerialPortInfo->InputHertz = 1843200;
+ SerialPortInfo->UartPciAddr = 0;
+
+ const UefiPayloadConfig* config = GetUefiPayLoadConfig();
+ if (!config) {
+ DEBUG((DEBUG_ERROR, "ParseSerialInfo: using default config\n"));
+ return RETURN_SUCCESS;
+ }
+
+ if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION1) {
+ const UefiPayloadConfigV1* config1 = &config->config.v1;
+ SerialPortInfo->BaseAddr = config1->SerialConfig.BaseAddr;
+ SerialPortInfo->RegWidth = config1->SerialConfig.RegWidth;
+ SerialPortInfo->Type = config1->SerialConfig.Type;
+ SerialPortInfo->Baud = config1->SerialConfig.Baud;
+ SerialPortInfo->InputHertz = config1->SerialConfig.InputHertz;
+ SerialPortInfo->UartPciAddr = config1->SerialConfig.UartPciAddr;
+ } else
+
+ if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION2) {
+ const char* cmdline = config->config.v2.cmdline;
+ const char* option;
+ uint64_t args[6] = {};
+
+ while ((cmdline = cmdline_next(cmdline, &option))) {
+ if (strncmp(option, "serial=", 7) != 0) continue;
+
+ const int count = cmdline_ints(option, args, 6);
+ if (count < 0) {
+ DEBUG((DEBUG_ERROR, "Parse error: %a\n", option));
+ continue;
+ }
+
+ if (count > 0) SerialPortInfo->Baud = args[0];
+ if (count > 1) SerialPortInfo->BaseAddr = args[1];
+ if (count > 2) SerialPortInfo->RegWidth = args[2];
+ if (count > 3) SerialPortInfo->Type = args[3];
+ if (count > 4) SerialPortInfo->InputHertz = args[4];
+ if (count > 5) SerialPortInfo->UartPciAddr = args[5];
+ }
+ }
return RETURN_SUCCESS;
}


Re: [PATCH v1 5/6] UefiPayloadPkg: Add DISABLE_MMX_SSE to avoid generating floating points operation

Michael D Kinney
 

Are those flags needed for all packages that build with GCC?

Should this be moved into tools_def.txt?

Mike

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Cheng-Chieh Huang via groups.io
Sent: Wednesday, July 21, 2021 6:23 AM
To: devel@edk2.groups.io
Cc: Cheng-Chieh Huang <chengchieh@google.com>
Subject: [edk2-devel] [PATCH v1 5/6] UefiPayloadPkg: Add DISABLE_MMX_SSE to avoid generating floating points operation

This will allow we compile payload using gcc8

Signed-off-by: Cheng-Chieh Huang <chengchieh@google.com>
---
UefiPayloadPkg/UefiPayloadPkg.dsc | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc
index 8aa5f18cd35c..fa41c5a24af5 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
@@ -30,6 +30,8 @@ [Defines]
DEFINE PS2_KEYBOARD_ENABLE = FALSE
DEFINE UNIVERSAL_PAYLOAD = FALSE

+ DEFINE DISABLE_MMX_SSE = FALSE
+
#
# SBL: UEFI payload for Slim Bootloader
# COREBOOT: UEFI payload for coreboot
@@ -96,6 +98,9 @@ [BuildOptions]
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
!if $(BOOTLOADER) == "LINUXBOOT"
*_*_*_CC_FLAGS = -D LINUXBOOT_PAYLOAD
+!endif
+!if $(DISABLE_MMX_SSE)
+ *_*_*_CC_FLAGS = -mno-mmx -mno-sse
!endif
GCC:*_UNIXGCC_*_CC_FLAGS = -DMDEPKG_NDEBUG
GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
--
2.32.0.402.g57bb445576-goog





Re: [PATCH 1/1] MdePkg: add definition of LINUX_EFI_INITRD_MEDIA_GUID

Michael D Kinney
 

Hi Ard,

 

If this device path node is considered as part of the standard interface between the Linux kernel and

firmware, then it does make sense for it to be in the MdePkg.  We usually try to reference a public

specification in the include file that defines the interface.

 

In this case, since there is no public document, but it is part of the Linux kernel assumptions,

can the include file for the GUID provide pointers to the Linux kernel that uses the GUID and

describe how the GUID is produced by the FW and consumed by the Linux kernel?

 

I also see that this patch appears to be incomplete.  There is an OvmfPkg/Include/Guid/LinuxEfiInitrdMedia.h

file in the OvmfPkg.  Shouldn’t that file also be moved to the MdePkg as part of this patch?

 

Thanks,

 

Mike

 

From: Jeff Brasen <jbrasen@...>
Sent: Tuesday, July 20, 2021 9:59 AM
To: Ard Biesheuvel <ardb@...>; Kinney, Michael D <michael.d.kinney@...>
Cc: devel@edk2.groups.io; ardb+tianocore@...; Justen, Jordan L <jordan.l.justen@...>; gaoliming@...; Liu, Zhiguang <zhiguang.liu@...>; Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@...>
Subject: Re: [edk2-devel] [PATCH 1/1] MdePkg: add definition of LINUX_EFI_INITRD_MEDIA_GUID

 

In my opinion MdePkg is where this should be as it is meant to be used by multiple software entities (linux kernel, grub, edk2, coreboot w/ uefi binding) and probably should be documented in some spec (Although, I am not sure which one would make sense)

 

I am fine with MdeModulePkg as well though.

 

Thanks,

Jeff


From: Ard Biesheuvel <ardb@...>
Sent: Friday, July 16, 2021 9:56 AM
To: Kinney, Michael D <michael.d.kinney@...>
Cc: Jeff Brasen <jbrasen@...>; devel@edk2.groups.io <devel@edk2.groups.io>; ardb+tianocore@... <ardb+tianocore@...>; Justen, Jordan L <jordan.l.justen@...>; gaoliming@... <gaoliming@...>; Liu, Zhiguang <zhiguang.liu@...>; Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@...>
Subject: Re: [edk2-devel] [PATCH 1/1] MdePkg: add definition of LINUX_EFI_INITRD_MEDIA_GUID

 

External email: Use caution opening links or attachments


On Fri, 16 Jul 2021 at 17:00, Kinney, Michael D
<michael.d.kinney@...> wrote:
>
> Hi Ard,
>
> I see you were involved in the OS side changes.
>
> Can you explain what is required for the FW <-> OS interface with respect to Load File Protocol and this media device path node.
>
> What happens if this media device path node is not present?  What breaks?
>
> Trying to figure out if this is a required interop feature (MdePkg candidate) or an EDK II specific extension (MdeModulePkg candidate).
>

Let me give some context first:

Linux distro boot generally relies on an initial ramdisk (initrd)
which is provided by the loader, and which contains additional kernel
modules (for storage and netwerk, for instance), and the initial user
space startup code, ie., the code which brings up the user space side
of the entire OS.

Before we introduced this media path, the only way for a EFI pre-OS
loader (such as GRUB) to provide this initrd was to copy it into DRAM
somewhere, and use a arch-specific method of passing the DRAM address
and size to the OS (x86 uses struct bootparam, whereas ARM uses device
tree). It also requires knowledge on the part of GRUB regarding which
parts of DRAM are suitable for holding an initrd image. For measured
boot scenarios, it may be an advantage not to have the initrd linger
in DRAM for longer that necessary, and we actually intend to measure
the initrd loaded via the new method right after it has been loaded
this way.

To avoid extending this to other architectures such as RISC-V, I
decided to introduce a special vendor media path for Linux initrd
images, which GRUB et al can implement, which provides the initrd
image when the OS loader that consumes it asks for it.

So for Linux on x86 or ARM, this is optional, given that support for
the old method is not going away any time soon. For RISC-V, I
suggested that only the new method be implemented, but I am not sure
what the status is there. Note that many embedded style systems don't
use GRUB, and may not use initrds to begin with. OTOH, U-Boot also
implements support for the Linux initrd vendor media path, and work is
ongoing to add measured boot support as well.

In any case, I don't have a strong preference where this should live,
as long as it is in a generic place where all architectures can use
it.

--
Ard.


Re: [edk2-platforms][PATCH v1 1/1] KabylakeOpenBoardPkg/PeiSerialPortLibSpiFlash: Remove PPI from HOB

Benjamin Doron
 

Tested, working on my Acer Aspire VN7-572G (Skylake-U/KabylakeOpenBoardPkg) board port. Debug logs continue to be written until the end of PEI rather than stopping at temporary memory teardown.


Re: [edk2-platforms][PATCH v1 1/1] KabylakeOpenBoardPkg/PeiSerialPortLibSpiFlash: Remove PPI from HOB

Michael Kubacki
 

Reminder to review/merge this patch.

On 7/9/2021 12:08 PM, Michael Kubacki wrote:
From: Michael Kubacki <michael.kubacki@microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3486
The PPI pointer should not be cached in a HOB as it could get out
of sync with the current pointers in the PPI list.
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Benjamin Doron <benjamin.doron00@gmail.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---
Platform/Intel/KabylakeOpenBoardPkg/Library/PeiSerialPortLibSpiFlash/PeiSerialPortLibSpiFlash.c | 114 +++++++++-----------
1 file changed, 48 insertions(+), 66 deletions(-)
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Library/PeiSerialPortLibSpiFlash/PeiSerialPortLibSpiFlash.c b/Platform/Intel/KabylakeOpenBoardPkg/Library/PeiSerialPortLibSpiFlash/PeiSerialPortLibSpiFlash.c
index 0230149a38c4..fc48bdc6fccb 100644
--- a/Platform/Intel/KabylakeOpenBoardPkg/Library/PeiSerialPortLibSpiFlash/PeiSerialPortLibSpiFlash.c
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Library/PeiSerialPortLibSpiFlash/PeiSerialPortLibSpiFlash.c
@@ -2,6 +2,7 @@
Serial I/O Port library implementation for output to SPI flash
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) Microsoft Corporation.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -17,40 +18,23 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/SpiLib.h>
typedef struct {
- PCH_SPI_PPI *PchSpiPpi;
UINT32 CurrentWriteOffset;
} SPI_FLASH_DEBUG_CONTEXT;
/**
- Update reference to the most recent PCH SPI PPI installed
+ Returns a pointer to the PCH SPI PPI.
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
- @param NotifyDescriptor Address of the notification descriptor data structure.
- @param Ppi Address of the PPI that was installed.
-
- @retval EFI_SUCCESS Successfully update the PCH SPI PPI reference
- @retval EFI_NOT_FOUND An error occurred locating a required interface
- @retval EFI_NOT_SUPPORTED
+ @return Pointer to PCH_SPI_PPI If an instance of the PCH SPI PPI is found
+ @return NULL If an instance of the PCH SPI PPI is not found
**/
-EFI_STATUS
-EFIAPI
-SpiPpiNotifyCallback (
- IN EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
- IN VOID *Ppi
+PCH_SPI_PPI *
+GetSpiPpi (
+ VOID
)
{
- EFI_STATUS Status;
- EFI_HOB_GUID_TYPE *GuidHob;
- PCH_SPI_PPI *PchSpiPpi;
- SPI_FLASH_DEBUG_CONTEXT *Context;
-
- GuidHob = GetFirstGuidHob (&gSpiFlashDebugHobGuid);
- if (GuidHob == NULL) {
- return EFI_NOT_FOUND;
- }
- Context = GET_GUID_HOB_DATA (GuidHob);
+ EFI_STATUS Status;
+ PCH_SPI_PPI *PchSpiPpi;
Status = PeiServicesLocatePpi (
&gPchSpiPpiGuid,
@@ -59,27 +43,17 @@ SpiPpiNotifyCallback (
(VOID **) &PchSpiPpi
);
if (EFI_ERROR (Status)) {
- return EFI_NOT_FOUND;
+ return NULL;
}
- Context->PchSpiPpi = PchSpiPpi;
-
- return EFI_SUCCESS;
+ return PchSpiPpi;
}
-EFI_PEI_NOTIFY_DESCRIPTOR mSpiPpiNotifyList[] = {
- {
- (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
- &gPchSpiPpiGuid,
- SpiPpiNotifyCallback
- }
-};
-
/**
Common function to write trace data to a chosen debug interface like
UART Serial device, USB Serial device or Trace Hub device
- @param Buffer Point of data buffer which need to be writed.
+ @param Buffer Point of data buffer which needs to be written.
@param NumberOfBytes Number of output bytes which are cached in Buffer.
**/
@@ -93,6 +67,7 @@ SerialPortWrite (
EFI_STATUS Status;
EFI_HOB_GUID_TYPE *GuidHob;
SPI_FLASH_DEBUG_CONTEXT *Context;
+ PCH_SPI_PPI *PchSpiPpi;
UINT32 BytesWritten;
UINT32 SourceBufferOffset;
UINT32 NvMessageAreaSize;
@@ -111,18 +86,22 @@ SerialPortWrite (
return 0;
}
Context = GET_GUID_HOB_DATA (GuidHob);
- if (Context == NULL || Context->PchSpiPpi == NULL || Context->CurrentWriteOffset >= NvMessageAreaSize) {
+ if (Context == NULL || Context->CurrentWriteOffset >= NvMessageAreaSize) {
+ return 0;
+ }
+ PchSpiPpi = GetSpiPpi ();
+ if (PchSpiPpi == NULL) {
return 0;
}
if ((Context->CurrentWriteOffset + NumberOfBytes) / NvMessageAreaSize > 0) {
LinearOffset = (UINT32) (FixedPcdGet32 (PcdFlashNvDebugMessageBase) - FixedPcdGet32 (PcdFlashAreaBaseAddress));
- Status = Context->PchSpiPpi->FlashErase (
- Context->PchSpiPpi,
- FlashRegionBios,
- LinearOffset,
- NvMessageAreaSize
- );
+ Status = PchSpiPpi->FlashErase (
+ PchSpiPpi,
+ FlashRegionBios,
+ LinearOffset,
+ NvMessageAreaSize
+ );
if (!EFI_ERROR (Status)) {
Context->CurrentWriteOffset = 0;
} else {
@@ -137,13 +116,13 @@ SerialPortWrite (
LinearOffset = (FixedPcdGet32 (PcdFlashNvDebugMessageBase) + Context->CurrentWriteOffset) - FixedPcdGet32 (PcdFlashAreaBaseAddress);
- Status = Context->PchSpiPpi->FlashWrite (
- Context->PchSpiPpi,
- FlashRegionBios,
- LinearOffset,
- BytesWritten,
- (UINT8 *) &Buffer[SourceBufferOffset]
- );
+ Status = PchSpiPpi->FlashWrite (
+ PchSpiPpi,
+ FlashRegionBios,
+ LinearOffset,
+ BytesWritten,
+ (UINT8 *) &Buffer[SourceBufferOffset]
+ );
if (!EFI_ERROR (Status)) {
Context->CurrentWriteOffset += BytesWritten;
return BytesWritten;
@@ -295,26 +274,29 @@ SerialPortInitialize (
)
{
EFI_STATUS Status;
+ EFI_HOB_GUID_TYPE *GuidHob;
SPI_FLASH_DEBUG_CONTEXT *Context;
+ GuidHob = GetFirstGuidHob (&gSpiFlashDebugHobGuid);
+ if (GuidHob != NULL) {
+ // Initialization only needs to occur once
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Perform silicon specific initialization required to enable write to SPI flash.
+ //
+ Status = SpiServiceInit ();
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
Context = (SPI_FLASH_DEBUG_CONTEXT *) BuildGuidHob (&gSpiFlashDebugHobGuid, sizeof (SPI_FLASH_DEBUG_CONTEXT));
if (Context == NULL) {
return EFI_DEVICE_ERROR;
}
+
ZeroMem ((VOID *) Context, sizeof (SPI_FLASH_DEBUG_CONTEXT));
- Status = PeiServicesNotifyPpi (&mSpiPpiNotifyList[0]);
- if (EFI_ERROR (Status)) {
- return EFI_DEVICE_ERROR;
- }
-
- //
- // Perform silicon specific initialization required to enable write to SPI flash.
- //
- Status = SpiServiceInit ();
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- }
-
- return Status;
+ return EFI_SUCCESS;
}


Re: [tianocore.github.io.wiki PATCH 1/1] Xcode.md: Update instructions to work on modern macOS and Xcode versions

Andrew Fish
 



On Jul 21, 2021, at 7:24 AM, Rebecca Cran <rebecca@...> wrote:

I think most people (including myself) use brew nowadays, which installs to /usr/local/bin so the instructions work.

I was wondering if we should remove the MacPorts instructions?


Rebecca,

Makes sense to move the instructions over to brew I guess. 

Thanks,

Andrew Fish

--

Rebecca Cran


On 7/20/21 11:37 PM, Andrew Fish wrote:
These Xcode instructions look good to me in general. Thanks for doing this I usually do things following a non public path. 

I think to make these instructions work you need to update *_XCODE5_*_MTOC_PATH

By default, this will install mtoc at /opt/local/bin/mtoc.

*_XCODE5_*_MTOC_PATH = /usr/local/bin/mtoc

We could change this to match the brew default location, I think this location is way out of date. I think the other things get fixed by the path variables. 

Thanks,

Andrew Fish



On May 25, 2021, at 5:36 AM, Rebecca Cran <rebecca@...> wrote:

On 5/25/21 6:21 AM, Laszlo Ersek wrote:

The idea is to use the wiki of any one of your projects on github.com --
most fittingly, your edk2 fork's wiki.

The URL to clone the "real" wiki repo from is:

  git://github.com/tianocore/tianocore.github.io.wiki

And the repo URL of the wiki of your edk2 fork *should be*:

  git@...:bcran/edk2.wiki.git

I'm not sure if you first need to enable the wiki function, for your
edk2 fork, on github.com. Maybe that's hidden somewhere between the
project (fork) settings. Either way, once your wiki repo exists, just
force-push to it whatever your local clone contains. And, only the
"master" branch matters for rendering, AFAICT.


Ah, got it - thanks.

The updated Xcode.md page is at https://github.com/bcran/edk2/wiki/Xcode


--
Rebecca Cran












[PATCH v1 6/6] UefiPayloadPkg: LinuxBoot: use a text format for the configuration block.

Cheng-Chieh Huang <chengchieh@...>
 

From: Trammell Hudson <hudson@trmm.net>

This adds a text command line for the UefiPayloadPkg that uses
a textual magic number 'LnxBoot1' and a series of white-space
separated key=value[,value...] pairs for the parameters.

The v1 binary configuration structure is used if it is present instead
for backwards compatability.

Currently supported text command line arguments are are:

* `serial=baud,base,width,type,hz,pci`
(only `baud` needs to be specified, the rest have reasonable
defaults)

* `mem=start,end,type`
Types are based on `/sys/firmware/memmaps/*/types`:
1 == "System RAM"
3 == "ACPI Tables"
4 == "ACPI Non-volatile Storage"
5 == "Reserved"

* `ACPI20=base` pointer to RDSP (from `/sys/firmware/efi/systab`)

* `SMBIOS=base` pointer to the SMBIOS table (also from the EFI table)

Signed-off-by: Cheng-Chieh Huang <chengchieh@google.com>
---
UefiPayloadPkg/Include/Linuxboot.h | 17 +-
UefiPayloadPkg/Library/LbParseLib/LbParseLib.c | 252 +++++++++++++++++---
2 files changed, 230 insertions(+), 39 deletions(-)

diff --git a/UefiPayloadPkg/Include/Linuxboot.h b/UefiPayloadPkg/Include/Linuxboot.h
index 34ca18069983..56b39b5a09ff 100644
--- a/UefiPayloadPkg/Include/Linuxboot.h
+++ b/UefiPayloadPkg/Include/Linuxboot.h
@@ -24,8 +24,7 @@ typedef struct MemoryMapEntryStruct {
UINT32 Type;
} MemoryMapEntry;

-typedef struct UefiPayloadConfigStruct {
- UINT64 Version;
+typedef struct {
UINT64 AcpiBase;
UINT64 AcpiSize;
UINT64 SmbiosBase;
@@ -33,10 +32,22 @@ typedef struct UefiPayloadConfigStruct {
SerialPortConfig SerialConfig;
UINT32 NumMemoryMapEntries;
MemoryMapEntry MemoryMapEntries[0];
+} UefiPayloadConfigV1;
+
+typedef struct UefiPayloadConfigStruct {
+ UINT64 Version;
+ union {
+ UefiPayloadConfigV1 v1;
+ struct {
+ char cmdline[0]; // up to 64 KB
+ } v2;
+ } config;
} UefiPayloadConfig;
#pragma pack()

-#define UEFI_PAYLOAD_CONFIG_VERSION 1
+// magic version config is "LnxBoot1"
+#define UEFI_PAYLOAD_CONFIG_VERSION1 1
+#define UEFI_PAYLOAD_CONFIG_VERSION2 0x31746f6f42786e4cULL

#define LINUXBOOT_MEM_RAM 1
#define LINUXBOOT_MEM_DEFAULT 2
diff --git a/UefiPayloadPkg/Library/LbParseLib/LbParseLib.c b/UefiPayloadPkg/Library/LbParseLib/LbParseLib.c
index 34bfb6a1073f..5e68091cac91 100644
--- a/UefiPayloadPkg/Library/LbParseLib/LbParseLib.c
+++ b/UefiPayloadPkg/Library/LbParseLib/LbParseLib.c
@@ -1,13 +1,12 @@
/** @file
- This library will parse the linuxboot table in memory and extract those required
- information.
+ This library will parse the linuxboot table in memory and extract those
+required information.

Copyright (c) 2021, the u-root Authors. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

-
#include <IndustryStandard/Acpi.h>
#include <IndustryStandard/SmBios.h>
#include <Library/BaseLib.h>
@@ -18,17 +17,42 @@
#include <Library/PcdLib.h>
#include <Linuxboot.h>
#include <Uefi/UefiBaseType.h>
+#include <stdint.h>
+#include <stdlib.h>
+//#include <string.h>
+//#include <ctype.h>
+
+#define strncmp(a, b, n) AsciiStrnCmp((a), (b), (n))
+
+static uint64_t parse_int(const char* s, char** end) {
+ UINT64 x;
+
+ if (s[0] == '0' && s[1] == 'x')
+ AsciiStrHexToUint64S(s, end, &x);
+ else
+ AsciiStrDecimalToUint64S(s, end, &x);
+
+ return x;
+}
+
+static int isspace(const char c) { return c == ' ' || c == '\t' || c == '\n'; }

// Retrieve UefiPayloadConfig from Linuxboot's uefiboot
-UefiPayloadConfig* GetUefiPayLoadConfig() {
- UefiPayloadConfig* config =
+const UefiPayloadConfig* GetUefiPayLoadConfig() {
+ const UefiPayloadConfig* config =
(UefiPayloadConfig*)(UINTN)(PcdGet32(PcdPayloadFdMemBase) - SIZE_64KB);
- if (config->Version != UEFI_PAYLOAD_CONFIG_VERSION) {
- DEBUG((DEBUG_ERROR, "Expect payload config version: %d, but get %d\n",
- UEFI_PAYLOAD_CONFIG_VERSION, config->Version));
- CpuDeadLoop ();
- }
- return config;
+
+ if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION1 ||
+ config->Version == UEFI_PAYLOAD_CONFIG_VERSION2)
+ return config;
+
+ DEBUG((DEBUG_ERROR,
+ "Expect payload config version %016lx or %016lx, but get %016lx\n",
+ UEFI_PAYLOAD_CONFIG_VERSION1, UEFI_PAYLOAD_CONFIG_VERSION2,
+ config->Version));
+ CpuDeadLoop();
+ while (1)
+ ;
}

// Align the address and add memory rang to MemInfoCallback
@@ -54,6 +78,57 @@ void AddMemoryRange(IN BL_MEM_INFO_CALLBACK MemInfoCallback, IN UINTN start,
MemInfoCallback(&MemoryMap, NULL);
}

+const char* cmdline_next(const char* cmdline, const char** option) {
+ // at the end of the string, we're done
+ if (!cmdline || *cmdline == '\0') return NULL;
+
+ // skip any leading whitespace
+ while (isspace(*cmdline)) cmdline++;
+
+ // if we've hit the end of the string, we're done
+ if (*cmdline == '\0') return NULL;
+
+ *option = cmdline;
+
+ // find the end of this option or the string
+ while (!isspace(*cmdline) && *cmdline != '\0') cmdline++;
+
+ // cmdline points to the whitespace or end of string
+ return cmdline;
+}
+
+int cmdline_ints(const char* option, uint64_t args[], int max) {
+ // skip any leading text up to an '='
+ const char* s = option;
+ while (1) {
+ const char c = *s++;
+ if (c == '=') break;
+
+ if (c == '\0' || isspace(c)) {
+ s = option;
+ break;
+ }
+ }
+
+ for (int i = 0; i < max; i++) {
+ char* end;
+ args[i] = parse_int(s, &end);
+
+ // end of string or end of the option?
+ if (*end == '\0' || isspace(*end)) return i + 1;
+
+ // not separator? signal an error if we have consumed any ints,
+ // otherwise return 0 saying that none were found
+ if (*end != ',') return i == 0 ? 0 : -1;
+
+ // skip the , and get the next value
+ s = end + 1;
+ }
+
+ // too many values!
+ return -1;
+}
+
/**
Acquire the memory information from the linuxboot table in memory.

@@ -67,20 +142,50 @@ void AddMemoryRange(IN BL_MEM_INFO_CALLBACK MemInfoCallback, IN UINTN start,
RETURN_STATUS
EFIAPI
ParseMemoryInfo(IN BL_MEM_INFO_CALLBACK MemInfoCallback, IN VOID* Params) {
- UefiPayloadConfig* config;
- int i;
+ const UefiPayloadConfig* config = GetUefiPayLoadConfig();
+ if (!config) {
+ DEBUG(
+ (DEBUG_ERROR, "ParseMemoryInfo: Could not find UEFI Payload config\n"));
+ return RETURN_SUCCESS;
+ }
+
+ if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION1) {
+ const UefiPayloadConfigV1* config1 = &config->config.v1;
+ DEBUG(
+ (DEBUG_INFO, "MemoryMap #entries: %d\n", config1->NumMemoryMapEntries));
+
+ for (int i = 0; i < config1->NumMemoryMapEntries; i++) {
+ const MemoryMapEntry* entry = &config1->MemoryMapEntries[i];
+ DEBUG((DEBUG_INFO, "Start: 0x%lx End: 0x%lx Type:%d\n", entry->Start,
+ entry->End, entry->Type));
+ AddMemoryRange(MemInfoCallback, entry->Start, entry->End, entry->Type);
+ }
+ } else

- config = GetUefiPayLoadConfig();
+ if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION2) {
+ const char* cmdline = config->config.v2.cmdline;
+ const char* option;
+ uint64_t args[3];

- DEBUG((DEBUG_INFO, "MemoryMap #entries: %d\n", config->NumMemoryMapEntries));
+ // look for the mem=start,end,type
+ while ((cmdline = cmdline_next(cmdline, &option))) {
+ if (strncmp(option, "mem=", 4) != 0) continue;

- MemoryMapEntry* entry = &config->MemoryMapEntries[0];
- for (i = 0; i < config->NumMemoryMapEntries; i++) {
- DEBUG((DEBUG_INFO, "Start: 0x%lx End: 0x%lx Type:%d\n", entry->Start,
- entry->End, entry->Type));
- AddMemoryRange(MemInfoCallback, entry->Start, entry->End, entry->Type);
- entry++;
+ if (cmdline_ints(option, args, 3) != 3) {
+ DEBUG((DEBUG_ERROR, "Parse error: '%a'\n", option));
+ continue;
+ }
+
+ const uint64_t start = args[0];
+ const uint64_t end = args[1];
+ const uint64_t type = args[2];
+
+ DEBUG(
+ (DEBUG_INFO, "Start: 0x%lx End: 0x%lx Type:%d\n", start, end, type));
+ AddMemoryRange(MemInfoCallback, start, end, type);
+ }
}
+
return RETURN_SUCCESS;
}

@@ -96,14 +201,52 @@ ParseMemoryInfo(IN BL_MEM_INFO_CALLBACK MemInfoCallback, IN VOID* Params) {
RETURN_STATUS
EFIAPI
ParseSystemTable(OUT SYSTEM_TABLE_INFO* SystemTableInfo) {
- UefiPayloadConfig* config;
+ const UefiPayloadConfig* config = GetUefiPayLoadConfig();
+ if (!config) {
+ DEBUG((DEBUG_ERROR,
+ "ParseSystemTable: Could not find UEFI Payload config\n"));
+ return RETURN_SUCCESS;
+ }

- config = GetUefiPayLoadConfig();
- SystemTableInfo->AcpiTableBase = config->AcpiBase;
- SystemTableInfo->AcpiTableSize = config->AcpiSize;
+ if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION1) {
+ const UefiPayloadConfigV1* config1 = &config->config.v1;
+ SystemTableInfo->AcpiTableBase = config1->AcpiBase;
+ SystemTableInfo->AcpiTableSize = config1->AcpiSize;

- SystemTableInfo->SmbiosTableBase = config->SmbiosBase;
- SystemTableInfo->SmbiosTableSize = config->SmbiosSize;
+ SystemTableInfo->SmbiosTableBase = config1->SmbiosBase;
+ SystemTableInfo->SmbiosTableSize = config1->SmbiosSize;
+ } else
+
+ if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION2) {
+ const char* cmdline = config->config.v2.cmdline;
+ const char* option;
+ uint64_t args[2];
+
+ // look for the acpi config
+ while ((cmdline = cmdline_next(cmdline, &option))) {
+ if (strncmp(option, "ACPI20=", 7) == 0) {
+ const int count = cmdline_ints(option, args, 2);
+ if (count < 0) {
+ DEBUG((DEBUG_ERROR, "Parse error: '%a'\n", option));
+ continue;
+ }
+
+ if (count > 0) SystemTableInfo->AcpiTableBase = args[0];
+ if (count > 1) SystemTableInfo->AcpiTableSize = args[1];
+ }
+
+ if (strncmp(option, "SMBIOS=", 7) == 0) {
+ const int count = cmdline_ints(option, args, 2);
+ if (count < 0) {
+ DEBUG((DEBUG_ERROR, "Parse error: '%a'\n", option));
+ continue;
+ }
+
+ if (count > 0) SystemTableInfo->SmbiosTableBase = args[0];
+ if (count > 1) SystemTableInfo->SmbiosTableSize = args[1];
+ }
+ }
+ }

return RETURN_SUCCESS;
}
@@ -120,15 +263,52 @@ ParseSystemTable(OUT SYSTEM_TABLE_INFO* SystemTableInfo) {
RETURN_STATUS
EFIAPI
ParseSerialInfo(OUT SERIAL_PORT_INFO* SerialPortInfo) {
- UefiPayloadConfig* config;
- config = GetUefiPayLoadConfig();
-
- SerialPortInfo->BaseAddr = config->SerialConfig.BaseAddr;
- SerialPortInfo->RegWidth = config->SerialConfig.RegWidth;
- SerialPortInfo->Type = config->SerialConfig.Type;
- SerialPortInfo->Baud = config->SerialConfig.Baud;
- SerialPortInfo->InputHertz = config->SerialConfig.InputHertz;
- SerialPortInfo->UartPciAddr = config->SerialConfig.UartPciAddr;
+ // fill in some reasonable defaults
+ SerialPortInfo->BaseAddr = 0x3f8;
+ SerialPortInfo->RegWidth = 1;
+ SerialPortInfo->Type = 1; // uefi.SerialPortTypeIO
+ SerialPortInfo->Baud = 115200;
+ SerialPortInfo->InputHertz = 1843200;
+ SerialPortInfo->UartPciAddr = 0;
+
+ const UefiPayloadConfig* config = GetUefiPayLoadConfig();
+ if (!config) {
+ DEBUG((DEBUG_ERROR, "ParseSerialInfo: using default config\n"));
+ return RETURN_SUCCESS;
+ }
+
+ if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION1) {
+ const UefiPayloadConfigV1* config1 = &config->config.v1;
+ SerialPortInfo->BaseAddr = config1->SerialConfig.BaseAddr;
+ SerialPortInfo->RegWidth = config1->SerialConfig.RegWidth;
+ SerialPortInfo->Type = config1->SerialConfig.Type;
+ SerialPortInfo->Baud = config1->SerialConfig.Baud;
+ SerialPortInfo->InputHertz = config1->SerialConfig.InputHertz;
+ SerialPortInfo->UartPciAddr = config1->SerialConfig.UartPciAddr;
+ } else
+
+ if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION2) {
+ const char* cmdline = config->config.v2.cmdline;
+ const char* option;
+ uint64_t args[6] = {};
+
+ while ((cmdline = cmdline_next(cmdline, &option))) {
+ if (strncmp(option, "serial=", 7) != 0) continue;
+
+ const int count = cmdline_ints(option, args, 6);
+ if (count < 0) {
+ DEBUG((DEBUG_ERROR, "Parse error: %a\n", option));
+ continue;
+ }
+
+ if (count > 0) SerialPortInfo->Baud = args[0];
+ if (count > 1) SerialPortInfo->BaseAddr = args[1];
+ if (count > 2) SerialPortInfo->RegWidth = args[2];
+ if (count > 3) SerialPortInfo->Type = args[3];
+ if (count > 4) SerialPortInfo->InputHertz = args[4];
+ if (count > 5) SerialPortInfo->UartPciAddr = args[5];
+ }
+ }

return RETURN_SUCCESS;
}
--
2.32.0.402.g57bb445576-goog


[PATCH v1 5/6] UefiPayloadPkg: Add DISABLE_MMX_SSE to avoid generating floating points operation

Cheng-Chieh Huang <chengchieh@...>
 

This will allow we compile payload using gcc8

Signed-off-by: Cheng-Chieh Huang <chengchieh@google.com>
---
UefiPayloadPkg/UefiPayloadPkg.dsc | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc
index 8aa5f18cd35c..fa41c5a24af5 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
@@ -30,6 +30,8 @@ [Defines]
DEFINE PS2_KEYBOARD_ENABLE = FALSE
DEFINE UNIVERSAL_PAYLOAD = FALSE

+ DEFINE DISABLE_MMX_SSE = FALSE
+
#
# SBL: UEFI payload for Slim Bootloader
# COREBOOT: UEFI payload for coreboot
@@ -96,6 +98,9 @@ [BuildOptions]
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
!if $(BOOTLOADER) == "LINUXBOOT"
*_*_*_CC_FLAGS = -D LINUXBOOT_PAYLOAD
+!endif
+!if $(DISABLE_MMX_SSE)
+ *_*_*_CC_FLAGS = -mno-mmx -mno-sse
!endif
GCC:*_UNIXGCC_*_CC_FLAGS = -DMDEPKG_NDEBUG
GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
--
2.32.0.402.g57bb445576-goog


[PATCH v1 4/6] UefiPayloadPkg: Reserve Payload config in runtime services data

Cheng-Chieh Huang <chengchieh@...>
 

Signed-off-by: Cheng-Chieh Huang <chengchieh@google.com>
---
UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c
index ae16f25c7c0e..70afbf83ed4a 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c
@@ -517,6 +517,8 @@ BuildGenericHob (

// The UEFI payload FV
BuildMemoryAllocationHob (PcdGet32 (PcdPayloadFdMemBase), PcdGet32 (PcdPayloadFdMemSize), EfiBootServicesData);
+ // The UEFI payload config FV
+ BuildMemoryAllocationHob (PcdGet32 (PcdPayloadFdMemBase) - SIZE_64KB, SIZE_64KB, EfiRuntimeServicesData);

//
// Build CPU memory space and IO space hob
--
2.32.0.402.g57bb445576-goog


[PATCH v1 3/6] UefiPayloadPkg: Update maximum logic processor to 256

Cheng-Chieh Huang <chengchieh@...>
 

Signed-off-by: Cheng-Chieh Huang <chengchieh@google.com>
---
UefiPayloadPkg/UefiPayloadPkg.dsc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc
index e56e6f4a5379..8aa5f18cd35c 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
@@ -40,7 +40,7 @@ [Defines]
#
# CPU options
#
- DEFINE MAX_LOGICAL_PROCESSORS = 64
+ DEFINE MAX_LOGICAL_PROCESSORS = 256

#
# PCI options
--
2.32.0.402.g57bb445576-goog


[PATCH v1 2/6] UefiPayloadPkg: Use legacy timer in Linuxboot payload

Cheng-Chieh Huang <chengchieh@...>
 

HPET timer may fail to init after prior linux taking over.

Signed-off-by: Cheng-Chieh Huang <chengchieh@google.com>
---
UefiPayloadPkg/UefiPayloadPkg.dsc | 6 ++++++
UefiPayloadPkg/UefiPayloadPkg.fdf | 5 +++++
2 files changed, 11 insertions(+)

diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc
index 54576ba485b7..e56e6f4a5379 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
@@ -438,7 +438,13 @@ [Components.X64]
NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
}

+!if $(BOOTLOADER) == "LINUXBOOT"
+ OvmfPkg/8254TimerDxe/8254Timer.inf
+ OvmfPkg/8259InterruptControllerDxe/8259.inf
+!else
PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
+!endif
+
MdeModulePkg/Universal/Metronome/Metronome.inf
MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf
index 041fed842cd8..f57a8b4bf3d3 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.fdf
+++ b/UefiPayloadPkg/UefiPayloadPkg.fdf
@@ -101,7 +101,12 @@ [FV.DXEFV]
INF UefiCpuPkg/CpuDxe/CpuDxe.inf
INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
INF MdeModulePkg/Application/UiApp/UiApp.inf
+!if $(BOOTLOADER) != "LINUXBOOT"
INF PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
+!else
+INF OvmfPkg/8254TimerDxe/8254Timer.inf
+INF OvmfPkg/8259InterruptControllerDxe/8259.inf
+!endif
INF MdeModulePkg/Universal/Metronome/Metronome.inf
INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
--
2.32.0.402.g57bb445576-goog

6521 - 6540 of 84490