LinuxBoot success on the Intel S2600WF

559 views
Skip to first unread message

Trammell Hudson

unread,
Dec 1, 2017, 8:14:37 PM12/1/17
to linu...@googlegroups.com
I'm declaring today a successful LinuxBoot test on the Intel S2600WF
mainboard. It does not have the idealogical purity of the Dell R630
build, but it works through the entire boot process:

https://www.flickr.com/photos/osr/38742461302/lightbox

The ROM layout and changes:

* Recovery (0xFEC00000)
- DxeCore built from edk2
- BdsDxe relocated
- TODO: remove network drivers, etc
* Empty (0xFF000000)
* Boot splash image (0xFF1A0000)
* WHEA (0xFF1C0000)
* Empty (0xFF1D000)
* Normal (0xFF500000)
- BdsDxe from recovery Fv
- Linux bzImage built as the shell EFI application
- Initrd as separate raw section
* NVRAM (0xFF900000)
- Unchanged
* SEC & PEI (0xFFA00000)
- Unchanged


SEC and PEI are unchanged, the BIOS recovery jumper is set and the DxeCore
in the recovery firmware volume is replaced with an edk2 build that
we control. The BdsDxe in the normal region is Intel's, since it does
the last setup stages that are necessary to configure the hardware. It
only looks in the current Fv for the shell, so it has to be moved to
the same Fv as the kernel.

The Linux kernel is built as an EFI application using the normal
CONFIG_EFI_STUB and the bzImage file guid is the well known "Shell"
(C57AD6B7-0515-40A8-9D21-551652854E37), which is the recovery shell
that BdsDxe is looking to jump into. All of the ACPI and other tables
are setup, so the kernel is able to boot all the way and talk to all
the devices.

The BdsDxe seems to corrupt things if the kernel and initrd cross a 4 MB
boundary, which is rather problematic. This needs to be debugged further.

If we can re-arrange the memory to boot in non-recovery mode, the kernel
and its parameters can be configured with nvram variables.

The setup application is still present and can be invoked from BdsDxe.
It is necessary since all of the PEI configuration parameters are stored
in the opaque SETUP nvram variable.

Finding the minimal set of DXE drivers is a remaining TODO.

Figuring out if there is a way to replicate the calls that the BdsDxe
makes so that we don't need to go through it is another TODO.

--
Trammell

ron minnich

unread,
Dec 2, 2017, 5:38:12 PM12/2/17
to Trammell Hudson, linu...@googlegroups.com
This is very similar to what we did in earlier days, with linux replacing the shell. We have found minimal DXEs on winterfell at this point, and it chips a full 10s off boot it seems.

We have to have a solid way to remove bdsdxe since on all our nodes, it's AMI, and that has to go away :-)

--
You received this message because you are subscribed to the Google Groups "linuxboot" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linuxboot+...@googlegroups.com.
To post to this group, send email to linu...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/linuxboot/20171202011434.GB31543%40chishio.swcp.com.
For more options, visit https://groups.google.com/d/optout.

Trammell Hudson

unread,
Dec 3, 2017, 5:17:54 PM12/3/17
to ron minnich, linu...@googlegroups.com
On Sat, Dec 02, 2017 at 10:38:01PM +0000, ron minnich wrote:
> This is very similar to what we did in earlier days, with linux replacing
> the shell. We have found minimal DXEs on winterfell at this point, and it
> chips a full 10s off boot it seems.

The debugging DxeCore is especially bad for timing since it is
doing blocking serial console writes at 115k baud. I turned off the
protocol registration printout since it was much too slow.

> We have to have a solid way to remove bdsdxe since on all our nodes, it's
> AMI, and that has to go away :-)

Ideally we can figure out how to reproduce whatever magic BdsDxe
is doing on the platforms that require it. I've tried connecting
all the handles, which is what edk2 BdsDxe does, and that loads a
few additional drivers.

Too bad the s2600 doesn't have debugging compiled in and it looks like
someone finally turned on -O3 so that compile-time dead code is being
pruned. The -O0 build on the r630 was really helpful for figuring
out what was happening.

--
Trammell

Trammell Hudson

unread,
Dec 3, 2017, 5:33:14 PM12/3/17
to ron minnich, linu...@googlegroups.com
On Sun, Dec 03, 2017 at 03:17:44PM -0700, Trammell Hudson wrote:
> On Sat, Dec 02, 2017 at 10:38:01PM +0000, ron minnich wrote:
> > We have to have a solid way to remove bdsdxe since on all our nodes, it's
> > AMI, and that has to go away :-)
>
> Ideally we can figure out how to reproduce whatever magic BdsDxe
> is doing on the platforms that require it. I've tried connecting
> all the handles, which is what edk2 BdsDxe does, and that loads a
> few additional drivers.

One hint might be to look at what the Bds on the Qemu platform is
doing in OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
PlatformBootManagerBeforeConsole():

Paraphrasing:

VisitAllInstancesOfProtocol (&gEfiPciRootBridgeIoProtocolGuid,
ConnectRootBridge, NULL);

//
// Signal the ACPI platform driver that it can download QEMU ACPI tables.
//
EfiEventGroupSignal (&gRootBridgesConnectedEventGroupGuid);

//
// We can't signal End-of-Dxe earlier than this. Namely, End-of-Dxe triggers
// the preparation of S3 system information. That logic has a hard dependency
// on the presence of the FACS ACPI table. Since our ACPI tables are only
// installed after PCI enumeration completes, we must not trigger the S3 save
// earlier, hence we can't signal End-of-Dxe earlier.
//
EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);

//
// Prevent further changes to LockBoxes or SMRAM.
//
Status = gBS->InstallProtocolInterface (&Handle,
&gEfiDxeSmmReadyToLockProtocolGuid, EFI_NATIVE_INTERFACE,
NULL);

//
// Dispatch deferred images after EndOfDxe event and ReadyToLock installation.
//
EfiBootManagerDispatchDeferredImages ();

PlatformInitializeConsole (gPlatformConsole);
PlatformRegisterOptionsAndKeys ();

This is worth trying tomorrow on the s2600 platform's Linux kernel BDS.

--
Trammell

ron minnich

unread,
Dec 3, 2017, 8:58:43 PM12/3/17
to Trammell Hudson, linu...@googlegroups.com
I'm going to start trying to put a table together on our experiences. I'm bothered that we see so much variance in all these EFI platforms, and it would not surprise me to find that the ODMs have made nasty expedient changes to "just get it working enough to ship." 

We know the ODMs frequently do nasty insecure things, see all those nasty SMM callout bugs, so it would not surprise me to find lots of other bad things were done too.

The EDKII source is nice to have, but I'm not sure how much it's got a strong resemblance to what's in the binary :-(

ron

Trammell Hudson

unread,
Dec 4, 2017, 12:54:49 PM12/4/17
to linu...@googlegroups.com
On Sun, Dec 03, 2017 at 03:33:07PM -0700, Trammell Hudson wrote:
> On Sun, Dec 03, 2017 at 03:17:44PM -0700, Trammell Hudson wrote:
> > On Sat, Dec 02, 2017 at 10:38:01PM +0000, ron minnich wrote:
> > > We have to have a solid way to remove bdsdxe since on all our nodes, it's
> > > AMI, and that has to go away :-)
> >
> > Ideally we can figure out how to reproduce whatever magic BdsDxe
> > is doing on the platforms that require it. I've tried connecting
> > all the handles, which is what edk2 BdsDxe does, and that loads a
> > few additional drivers.
>
> One hint might be to look at what the Bds on the Qemu platform is
> doing in OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> PlatformBootManagerBeforeConsole():

Good news everyone!

I hacked the Ovmf BdsPlatform.c file to build as part of BdsDxe and
guess what, it works! The magic sequence of events and connections
seems to correctly configure the various important tables and interrupts
so that Linux is able to find all of the devices.

So that is one less part that we need to include, which also frees
us from overloading the EFI shell GUID and faking the recovery variable.
It does remove the option to invoke BIOS setup, which means that we might
need to have a way to configure the PEI NVRAM out of band.

I'm going to try to port the ovmf changes into the Linux kernel so
that it can be invoked as BDS. This will be an extra compile time
config option, CONFIG_EFI_BDS, available if CONFIG_EFI_STUB is defined.
It will build the kernel as a DXE driver (not an application) and do the
right thing with registering the BDS protocol and, when invoked at the
end of DxeCore, do the magic to finalize the ACPI setup before jumping
into Linux's efi_main().

--
Trammell

Ron Minnich

unread,
Dec 4, 2017, 12:59:03 PM12/4/17
to Trammell Hudson, linu...@googlegroups.com
On Mon, Dec 4, 2017 at 9:54 AM Trammell Hudson <hud...@trmm.net> wrote:


I hacked the Ovmf BdsPlatform.c file to build as part of BdsDxe and
guess what, it works!  The magic sequence of events and connections
seems to correctly configure the various important tables and interrupts
so that Linux is able to find all of the devices.

That is truly wonderful. I am shocked but happy. Nice work!
 

So that is one less part that we need to include, which also frees
us from overloading the EFI shell GUID and faking the recovery variable.
It does remove the option to invoke BIOS setup, which means that we might
need to have a way to configure the PEI NVRAM out of band.

I think all that stuff should be out of band. I don't want to trust any part of EFI with anything. 
"Let Linux do it" -- the old LinuxBIOS motto -- applies here.
 

I'm going to try to port the ovmf changes into the Linux kernel so
that it can be invoked as BDS.  This will be an extra compile time
config option, CONFIG_EFI_BDS, available if CONFIG_EFI_STUB is defined.

 

That's a brilliant idea :-)
I am now confident you can make it work!

Rather than the patch set for EDKII would it make sense just to make a fork and push changes back to them? 
Would a new platform in EDKII called "LinuxBoot" ever make sense?

ron 

Trammell Hudson

unread,
Dec 4, 2017, 1:13:46 PM12/4/17
to Ron Minnich, linu...@googlegroups.com
On Mon, Dec 04, 2017 at 05:58:38PM +0000, Ron Minnich wrote:
> On Mon, Dec 4, 2017 at 9:54 AM Trammell Hudson <hud...@trmm.net> wrote:
> > It does remove the option to invoke BIOS setup, which means that we might
> > need to have a way to configure the PEI NVRAM out of band.
> >
>
> I think all that stuff should be out of band. I don't want to trust any
> part of EFI with anything.
> "Let Linux do it" -- the old LinuxBIOS motto -- applies here.

The only problem is that many of these things are done in PEI or in
opaque DXE drivers. Additionally, I don't believe there is a standard
for the SETUP variable, so each mainboard we want to support will need
some knowledge of how to set things like memory speeds, etc.

This might be a good application of Beekman's EFI runtime for Linux.

https://github.com/jethrogb/uefireverse/tree/master/efiperun

Could we wrap enough of the console drivers to be able to run the
setup.efi DXE driver as a user space Linux application?

> [...]
> Rather than the patch set for EDKII would it make sense just to make a fork
> and push changes back to them?
> Would a new platform in EDKII called "LinuxBoot" ever make sense?

I'm not certain that it would make sense. We're not building very
much of edk2 -- mostly all we want is the generic DxeCore -- and
the rest of it is cobbled together from the vendor firmware.

--
Trammell

Ron Minnich

unread,
Dec 4, 2017, 1:23:48 PM12/4/17
to Trammell Hudson, linu...@googlegroups.com
sounds like an issue to file on linuxboot, which I will now do :-)


Trammell Hudson

unread,
Dec 4, 2017, 1:58:34 PM12/4/17
to Ron Minnich, linu...@googlegroups.com
On Mon, Dec 04, 2017 at 05:58:38PM +0000, 'Ron Minnich' via linuxboot wrote:
> On Mon, Dec 4, 2017 at 9:54 AM Trammell Hudson <hud...@trmm.net> wrote:
> > I'm going to try to port the ovmf changes into the Linux kernel so
> > that it can be invoked as BDS. This will be an extra compile time
> > config option, CONFIG_EFI_BDS, available if CONFIG_EFI_STUB is defined.
>
> That's a brilliant idea :-)
> I am now confident you can make it work!

It works!

The patches are currently super ugly with lots of extra debugging.
I'm attaching them here for future reference and will have a cleaner
version committed to the osresearch/heads tree soon.


diff --recursive -u clean/linux-4.9.38/arch/x86/boot/compressed/early_serial_console.c linux-4.9.38/arch/x86/boot/compressed/early_serial_console.c
--- clean/linux-4.9.38/arch/x86/boot/compressed/early_serial_console.c 2017-07-15 06:17:55.000000000 -0400
+++ linux-4.9.38/arch/x86/boot/compressed/early_serial_console.c 2017-12-01 16:03:10.524787842 -0500
@@ -1,5 +1,5 @@
#include "misc.h"

-int early_serial_base;
+int early_serial_base = 0x3f8;

#include "../early_serial_console.c"
diff --recursive -u clean/linux-4.9.38/arch/x86/boot/compressed/eboot.c linux-4.9.38/arch/x86/boot/compressed/eboot.c
--- clean/linux-4.9.38/arch/x86/boot/compressed/eboot.c 2017-07-15 06:17:55.000000000 -0400
+++ linux-4.9.38/arch/x86/boot/compressed/eboot.c 2017-12-04 13:44:42.902439205 -0500
@@ -16,6 +16,71 @@
#include "../string.h"
#include "eboot.h"

+#define PORT 0x3f8 /* COM1 */
+
+#define DLAB 0x80
+
+#define TXR 0 /* Transmit register (WRITE) */
+#define RXR 0 /* Receive register (READ) */
+#define IER 1 /* Interrupt Enable */
+#define IIR 2 /* Interrupt ID */
+#define FCR 2 /* FIFO control */
+#define LCR 3 /* Line control */
+#define MCR 4 /* Modem control */
+#define LSR 5 /* Line Status */
+#define MSR 6 /* Modem Status */
+#define DLL 0 /* Divisor Latch Low */
+#define DLH 1 /* Divisor latch High */
+
+static void early_serial_init(int port, int baud)
+{
+ unsigned char c;
+ unsigned divisor;
+
+ outb(0x3, port + LCR); /* 8n1 */
+ outb(0, port + IER); /* no interrupt */
+ outb(0, port + FCR); /* no fifo */
+ outb(0x3, port + MCR); /* DTR + RTS */
+
+ divisor = 115200 / baud;
+ c = inb(port + LCR);
+ outb(c | DLAB, port + LCR);
+ outb(divisor & 0xff, port + DLL);
+ outb((divisor >> 8) & 0xff, port + DLH);
+ outb(c & ~DLAB, port + LCR);
+}
+
+static int is_transmit_empty() {
+ return inb(PORT + 5) & 0x20;
+}
+
+void serial_char(char a) {
+ outb(a, PORT);
+ while (is_transmit_empty() == 0);
+}
+
+void serial_string(const char * s)
+{
+ while(*s)
+ serial_char(*s++);
+}
+
+void serial_hex(unsigned long x, unsigned digits)
+{
+ while(digits-- > 0)
+ {
+ unsigned d = (x >> (digits * 4)) & 0xF;
+ if (d >= 0xA)
+ serial_char(d + 'A' - 0xA);
+ else
+ serial_char(d + '0');
+ }
+ serial_char('\r');
+ serial_char('\n');
+}
+
+
+
static efi_system_table_t *sys_table;

static struct efi_config *efi_early;
@@ -710,6 +782,132 @@
}
}

+#define EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID EFI_GUID(0x220e73b6, 0x6bdb, 0x4413, 0x84, 0x5, 0xb9, 0x74, 0xb1, 0x8, 0x61, 0x9a)
+typedef struct _EFI_FIRMWARE_VOLUME2_PROTOCOL {
+ uint64_t GetVolumeAttributes;
+ uint64_t SetVolumeAttributes;
+ uint64_t ReadFile;
+ uint64_t ReadSection;
+ uint64_t WriteFile;
+ uint64_t GetNextFile;
+ uint32_t KeySize;
+ uint64_t ParentHandle;
+ uint64_t GetInfo;
+ uint64_t SetInfo;
+} efi_firmware_volume2_protocol_t;
+
+
+/*
+ * attempt to locate the ramdisk in our firmware volume.
+ * This assumes that it has a well-known GUID.
+ */
+static int nerf_find_initrd(const efi_guid_t * initrd_guid, void ** buffer, uint32_t * size)
+{
+ efi_status_t status;
+ efi_guid_t fv_proto = EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID;
+ void ** handles = NULL;
+ unsigned long handle_count;
+
+ status = efi_call_early(locate_handle_buffer,
+ EFI_LOCATE_BY_PROTOCOL,
+ &fv_proto,
+ NULL,
+ &handle_count,
+ &handles
+ );
+
+ if (status != 0)
+ {
+ serial_string("locate_handle rc=");
+ serial_hex(status, 8);
+ return -1;
+ }
+
+ for(unsigned i = 0 ; i < handle_count ; i++)
+ {
+ efi_firmware_volume2_protocol_t * fv = NULL;
+ uint32_t auth_status = 0;
+
+ serial_string("handle=");
+ serial_hex((unsigned long) handles[i], 16);
+
+ status = efi_call_early(handle_protocol,
+ handles[i],
+ &fv_proto,
+ (void**) &fv
+ );
+
+ if (status != 0)
+ {
+ serial_string("handle proto rc=");
+ serial_hex(status, 8);
+ continue;
+ }
+
+ serial_string("fv=");
+ serial_hex((unsigned long) fv, 16);
+ serial_hex((unsigned long) &fv->ReadSection, 16);
+ serial_hex((unsigned long) fv->ReadSection, 16);
+
+ status = efi_early->call(fv->ReadSection,
+ fv,
+ initrd_guid,
+ 0x19, // EFI_SECTION_RAW
+ 0,
+ buffer,
+ size,
+ &auth_status
+ );
+ if (status != 0)
+ {
+ serial_string("read section rc=");
+ serial_hex(status, 8);
+ continue;
+ }
+
+ serial_string("initrd ");
+ serial_hex((unsigned long) *buffer, 16);
+ serial_hex(*size, 8);
+ return 0;
+ }
+
+ // this leaks the handle buffer.
+ serial_string("initrd not found\r\n");
+ return -1;
+}
+
+
+static int efi_early_init(struct efi_config * c)
+{
+ if (efi_early)
+ return 0;
+
+ efi_early = c;
+ sys_table = (efi_system_table_t *)(unsigned long)efi_early->table;
+
+ if(!sys_table)
+ {
+ // We're NERFed and are the "DxeCore", so there is no system
+ // table. The efi_config argument is actually the HobStart
+ // pointer, but who cares about that stuff.
+ // TODO: actually handle this case
+ while(1)
+ outb('!', 0x3f8);
+ }
+
+ /* Check if we were booted by the EFI firmware */
+ if (!sys_table || sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
+ return -1;
+
+ if (efi_early->is64)
+ setup_boot_services64(efi_early);
+ else
+ setup_boot_services32(efi_early);
+
+ return 0;
+}
+
+
/*
* Because the x86 boot code expects to be passed a boot_params we
* need to create one ourselves (usually the bootloader would create
@@ -735,23 +933,17 @@
unsigned long ramdisk_addr;
unsigned long ramdisk_size;

- efi_early = c;
- sys_table = (efi_system_table_t *)(unsigned long)efi_early->table;
- handle = (void *)(unsigned long)efi_early->image_handle;
+serial_string("make_boot_params\r\n");

- /* Check if we were booted by the EFI firmware */
- if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
+ if (efi_early_init(c) < 0)
return NULL;

- if (efi_early->is64)
- setup_boot_services64(efi_early);
- else
- setup_boot_services32(efi_early);
+serial_string("early_init done\r\n");

+ handle = (void *)(unsigned long)efi_early->image_handle;
status = efi_call_early(handle_protocol, handle,
&proto, (void *)&image);
if (status != EFI_SUCCESS) {
- efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
return NULL;
}

@@ -814,6 +1006,21 @@

if (status != EFI_SUCCESS)
goto fail2;
+
+#if 1
+ void * initrd_ptr = NULL;
+ uint32_t initrd_size = 0;
+ if (nerf_find_initrd(
+ (const efi_guid_t*) "initrd.cpio/bios",
+ &initrd_ptr,
+ &initrd_size
+ ) == 0 )
+ {
+ ramdisk_addr = (uintptr_t) initrd_ptr;
+ ramdisk_size = initrd_size;
+ }
+#endif
+
hdr->ramdisk_image = ramdisk_addr & 0xffffffff;
hdr->ramdisk_size = ramdisk_size & 0xffffffff;
boot_params->ext_ramdisk_image = (u64)ramdisk_addr >> 32;
@@ -1068,6 +1275,7 @@
struct boot_params *efi_main(struct efi_config *c,
struct boot_params *boot_params)
{
+serial_string("efi_main\r\n");
struct desc_ptr *gdt = NULL;
efi_loaded_image_t *image;
struct setup_header *hdr = &boot_params->hdr;
@@ -1079,12 +1287,14 @@

efi_early = c;

+serial_string("efi_main "); serial_hex(__LINE__, 4);
_table = (efi_system_table_t *)(unsigned long)efi_early->table;
handle = (void *)(unsigned long)efi_early->image_handle;
is64 = efi_early->is64;

sys_table = _table;

+serial_string("efi_main "); serial_hex(__LINE__, 4);
/* Check if we were booted by the EFI firmware */
if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
goto fail;
@@ -1098,9 +1308,11 @@

setup_efi_pci(boot_params);

+serial_string("efi_main "); serial_hex(__LINE__, 4);
status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
sizeof(*gdt), (void **)&gdt);
if (status != EFI_SUCCESS) {
+serial_string("efi_main "); serial_hex(__LINE__, 4);
efi_printk(sys_table, "Failed to alloc mem for gdt structure\n");
goto fail;
}
@@ -1124,6 +1336,7 @@
hdr->pref_address,
hdr->kernel_alignment);
if (status != EFI_SUCCESS) {
+serial_string("efi_main "); serial_hex(__LINE__, 4);
efi_printk(sys_table, "efi_relocate_kernel() failed!\n");
goto fail;
}
@@ -1132,8 +1345,10 @@
hdr->code32_start = bzimage_addr;
}

+serial_string("efi_main "); serial_hex(__LINE__, 4);
status = exit_boot(boot_params, handle, is64);
if (status != EFI_SUCCESS) {
+serial_string("efi_main "); serial_hex(__LINE__, 4);
efi_printk(sys_table, "exit_boot() failed!\n");
goto fail;
}
@@ -1194,8 +1409,263 @@
asm volatile("cli");
asm volatile ("lgdt %0" : : "m" (*gdt));

+serial_string("efi_main done "); serial_hex(__LINE__, 4);
return boot_params;
fail:
+serial_string("efi_main failed "); serial_hex(__LINE__, 4);
efi_printk(sys_table, "efi_main() failed!\n");
return NULL;
}
+
+#ifdef CONFIG_EFI_STUB_BDS
+
+/*
+ * The LinuxBoot kernel is invoked as a DXE driver that registers
+ * the BDS (Boot Device Selector) protocol. Once all of the DXE
+ * executables have run, the DxeCore dispatcher will jump into the
+ * BDS to choose what kernel to run.
+ *
+ * In our case, it is this kernel. So we need to stash the config
+ * for when we are re-invoked.
+ */
+static void empty_function(void* unused) { (void) unused; }
+
+#define EFI_DXE_SERVICES_TABLE_GUID EFI_GUID(0x5ad34ba, 0x6f02, 0x4214, 0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9)
+#define EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID EFI_GUID(0x2f707ebb, 0x4a1a, 0x11d4, 0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+
+#define ROOT_BRIDGES_CONNECTED_EVENT_GROUP_GUID EFI_GUID(0x24a2d66f, 0xeedd, 0x4086, 0x90, 0x42, 0xf2, 0x6e, 0x47, 0x97, 0xee, 0x69)
+#define EFI_END_OF_DXE_EVENT_GROUP_GUID EFI_GUID(0x2ce967a, 0xdd7e, 0x4ffc, 0x9e, 0xe7, 0x81, 0xc, 0xf0, 0x47, 0x8, 0x80)
+#define EFI_DXE_SMM_READY_TO_LOCK_PROTOCOL_GUID EFI_GUID(0x60ff8964, 0xe906, 0x41d0, 0xaf, 0xed, 0xf2, 0x41, 0xe9, 0x74, 0xe0, 0x8e)
+
+
+
+
+static void * efi_find_table(uint32_t search_guid)
+{
+ const efi_system_table_64_t * st = (const void*) efi_early->table;
+ const efi_config_table_64_t * ct = (const void*) st->tables;
+
+serial_string("num tables=");
+serial_hex(st->nr_tables, 4);
+
+ for(int i = 0 ; i < st->nr_tables; i++)
+ {
+ const efi_guid_t * guid = &ct[i].guid;
+serial_hex(*(uint64_t*)guid, 16);
+ if (*(uint32_t*) guid == search_guid)
+ return (void*) ct[i].table;
+
+ }
+
+ return NULL;
+}
+
+
+static void efi_event_signal(efi_guid_t guid)
+{
+ efi_status_t status;
+ void * event = NULL;
+
+ status = efi_call_early(create_event_ex,
+ 0x200, // EVT_NOTIFY_SIGNAL
+ 8, // EFI_TPL_CALLBACK
+ empty_function,
+ NULL,
+ &guid,
+ &event
+ );
+ if (status)
+ serial_hex(status, 8);
+
+ status = efi_call_early(signal_event, event);
+ if (status)
+ serial_hex(status, 8);
+
+ status = efi_call_early(close_event, event);
+ if (status)
+ serial_hex(status, 8);
+}
+
+
+static efi_handle_t * handle_buffer;
+static const unsigned handle_buffer_size = 0x2000 * sizeof(*handle_buffer);
+
+
+static void efi_visit_handles(efi_guid_t * protocol, void (*callback)(efi_handle_t, void*), void* priv)
+{
+ unsigned handle_count = handle_buffer_size;
+ memset(handle_buffer, 0, handle_buffer_size);
+
+serial_string("efi_visit_handles ");
+serial_hex(protocol ? *(uint32_t*) protocol : 0, 8);
+
+ efi_status_t status = efi_call_early(locate_handle,
+ protocol ? 2 : 0, // ByProtocol vs AllHandles
+ protocol,
+ NULL,
+ &handle_count,
+ handle_buffer
+ );
+ if (status != 0)
+ {
+ serial_string("status=");
+ serial_hex(status, 8);
+ return;
+ }
+
+serial_string("handle_count=");
+serial_hex(handle_count, 8);
+
+ for(int i = 0 ; i < handle_count/sizeof(*handle_buffer) ; i++)
+ {
+ //serial_hex((uint64_t) handle_buffer[i], 16);
+ callback(handle_buffer[i], priv);
+ }
+}
+
+
+static void efi_connect_controllers(efi_handle_t handle, void * recursive_arg)
+{
+ efi_call_early(connect_controller, handle, NULL, NULL, recursive_arg ? 1 : 0);
+}
+
+
+void efi_platform_init(void)
+{
+ // setup something to be called whenever device path events are
+ // generated. Ovmf just twiddles an atapi bit; ignoring for now
+
+ // connect all the pci root bridges
+serial_string("connect pci root brdiges\n");
+ efi_guid_t pci_protocol = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
+ efi_visit_handles(&pci_protocol, efi_connect_controllers, (void*) 0);
+
+ // signal the acpi platform driver that it can download the ACPI tables
+serial_string("signal root bridges connected\n");
+ efi_event_signal(ROOT_BRIDGES_CONNECTED_EVENT_GROUP_GUID);
+
+ // signal that dxe is about to end
+serial_string("signal dxe end\n");
+ efi_event_signal(EFI_END_OF_DXE_EVENT_GROUP_GUID);
+
+ // Prevent further changes to LockBoxes or SMRAM.
+ // not necessary, but we probably want to do it for security
+ efi_handle_t handle = NULL;
+ efi_guid_t smm_ready_to_lock = EFI_DXE_SMM_READY_TO_LOCK_PROTOCOL_GUID;
+serial_string("signal smm ready to lock\n");
+ efi_call_early(install_protocol_interface,
+ &handle,
+ &smm_ready_to_lock,
+ 0, // EFI_NATIVE_INTERFACE,
+ NULL
+ );
+}
+
+
+static void efi_bds_main(void)
+{
+ efi_status_t status;
+
+serial_string("bds_main 1\r\n");
+ efi_low_alloc(sys_table, handle_buffer_size, 1,
+ (unsigned long *)&handle_buffer);
+serial_string("handle_buffer=");
+serial_hex((uint64_t) handle_buffer, 16);
+
+ // equivilant to PlatformBootManagerBeforeConsole
+ efi_platform_init();
+
+ // connect all drivers their contorllers
+ // this is copied from BmConnectAllDriversToAllControllers()
+ // the DXE services table is buried in the configuration
+ // table in the system table
+ const struct {
+ uint8_t pad[24 + 8 * 13]; // header and 13 functions
+ efi_status_t (*dispatch)(void);
+ } * dxe_services = efi_find_table(0x5ad34ba);
+
+ if (!dxe_services)
+ serial_string("No DXE system table found... will crash\n");
+ else {
+ serial_string("dispatch = ");
+ serial_hex((uint64_t) dxe_services->dispatch, 16);
+ }
+
+/**
+ Connect all the drivers to all the controllers.
+
+ This function makes sure all the current system drivers manage the correspoinding
+ controllers if have. And at the same time, makes sure all the system controllers
+ have driver to manage it if have.
+**/
+ do {
+ efi_visit_handles(NULL, efi_connect_controllers, (void*) 1);
+serial_string("bds_main dispatch\r\n");
+ } while(dxe_services->dispatch() == 0);
+
+ // free crashes, so just leak it
+ //serial_string("free\n");
+ //efi_call_early(free_pool, handle_buffer);
+
+ // signal that we're ready to boot, which will
+ // cause additional drivers to be loaded
+serial_string("bds_main 2\r\n");
+ efi_event_signal(EFI_EVENT_GROUP_READY_TO_BOOT);
+
+ // jump back into the real kernel startup routine
+ extern __attribute__((noreturn)) void (*efi_restart)(void * bp);
+serial_string("bds_main 5\r\n");
+ asm( "jmp efi_restart" : : "d"(efi_early) );
+}
+
+static struct
+{
+ void (*bds_main)(void);
+} efi_bds_arch_protocol;
+
+
+int efi_bds_entry(struct efi_config *c)
+{
+ efi_status_t status;
+ efi_guid_t bds_guid = EFI_BDS_ARCH_PROTOCOL_GUID;
+
+ efi_loaded_image_t *image;
+ efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
+ void * handle;
+
+serial_string("bds_entry\r\n");
+
+ if (efi_early_init(c) < 0)
+ return -1;
+
+/*
+ handle = (void *)(unsigned long)efi_early->image_handle;
+ status = efi_call_early(handle_protocol, handle,
+ &proto, (void *)&image);
+serial_string(status ? "ERROR\r\n" : "OK\r\n");
+
+ // tell DxeCore where to call us when it is ready
+ // for the kernel to startup for real
+ struct efi_bds_arch_protocol * bds;
+ status = efi_low_alloc(sys_table, sizeof(*bds), 1,
+ (unsigned long *)&bds);
+ bds->bds_main = efi_bds_main;
+ bds->config = c;
+*/
+
+ efi_bds_arch_protocol.bds_main = efi_bds_main;
+
+ handle = (void*)(uintptr_t) efi_early->image_handle;
+ status = efi_call_early(install_protocol_interface,
+ &handle,
+ &bds_guid,
+ 0, // EFI_NATIVE_INTERFACE
+ &efi_bds_arch_protocol
+ );
+
+serial_string(status ? "ERROR\r\n" : "OK\r\n");
+
+ return 0;
+}
+
+#endif
diff --recursive -u clean/linux-4.9.38/arch/x86/boot/compressed/head_64.S linux-4.9.38/arch/x86/boot/compressed/head_64.S
--- clean/linux-4.9.38/arch/x86/boot/compressed/head_64.S 2017-07-15 06:17:55.000000000 -0400
+++ linux-4.9.38/arch/x86/boot/compressed/head_64.S 2017-12-01 15:46:51.952803007 -0500
@@ -268,6 +268,11 @@
addq %rbp, efi64_config+32(%rip)

movq %rax, %rdi
+#ifdef CONFIG_EFI_STUB_BDS // LinuxBoot (NERF) registers BDS and returns immediately
+ jmp efi_bds_entry
+#endif
+.global efi_restart
+efi_restart:
call make_boot_params
cmpq $0,%rax
je fail
@@ -294,13 +299,18 @@
jne 2f
fail:
/* EFI init failed, so hang. */
+ mov $0x3f8, %dx /* ttyS0 */
+ mov '@', %ax
+fail_loop:
+ outb %al, (%dx)
hlt
- jmp fail
+ jmp fail_loop
2:
movl BP_code32_start(%esi), %eax
leaq preferred_addr(%rax), %rax
jmp *%rax

+.global preferred_addr
preferred_addr:
#endif

diff --recursive -u clean/linux-4.9.38/arch/x86/boot/header.S linux-4.9.38/arch/x86/boot/header.S
--- clean/linux-4.9.38/arch/x86/boot/header.S 2017-07-15 06:17:55.000000000 -0400
+++ linux-4.9.38/arch/x86/boot/header.S 2017-12-01 09:59:11.737255340 -0500
@@ -171,7 +171,11 @@

.long 0x200 # SizeOfHeaders
.long 0 # CheckSum
+#ifdef CONFIG_EFI_STUB_BDS
+ .word 0xb # Subsystem (EFI boot service)
+#else
.word 0xa # Subsystem (EFI application)
+#endif
.word 0 # DllCharacteristics
#ifdef CONFIG_X86_32
.long 0 # SizeOfStackReserve
diff --recursive -u clean/linux-4.9.38/arch/x86/Kconfig linux-4.9.38/arch/x86/Kconfig
--- clean/linux-4.9.38/arch/x86/Kconfig 2017-07-15 06:17:55.000000000 -0400
+++ linux-4.9.38/arch/x86/Kconfig 2017-12-01 09:58:28.892507523 -0500
@@ -1772,6 +1772,15 @@

See Documentation/efi-stub.txt for more information.

+config EFI_STUB_BDS
+ bool "EFI BDS support"
+ depends on EFI_STUB
+ ---help---
+ This kernel feature allows a bzImage to act as the BDS
+ (Boot Device Selector) component of the EFI firmware.
+ Unless you're building a LinuxBoot system, you want to
+ say no.
+
config EFI_MIXED
bool "EFI mixed-mode support"
depends on EFI_STUB && X86_64
diff --recursive -u clean/linux-4.9.38/arch/x86/realmode/init.c linux-4.9.38/arch/x86/realmode/init.c
--- clean/linux-4.9.38/arch/x86/realmode/init.c 2017-07-15 06:17:55.000000000 -0400
+++ linux-4.9.38/arch/x86/realmode/init.c 2017-10-11 18:38:36.027243511 -0400
@@ -35,8 +35,8 @@
/* Has to be under 1M so we can execute real-mode AP code. */
mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE);
if (!mem) {
- pr_info("No sub-1M memory is available for the trampoline\n");
- return;
+ mem = 0x4000;
+ pr_info("No sub-1M memory is available for the trampoline, guessing %p\n", mem);
}

memblock_reserve(mem, size);
@@ -138,7 +138,12 @@
static int __init init_real_mode(void)
{
if (!real_mode_header)
- panic("Real mode trampoline was not allocated");
+ {
+ // ignore for now
+ //panic("Real mode trampoline was not allocated");
+ pr_warn("Real mode trampoline was not allocated");
+ return 0;
+ }

setup_real_mode();
set_real_mode_permissions();
diff --recursive -u clean/linux-4.9.38/drivers/acpi/acpica/evxfevnt.c linux-4.9.38/drivers/acpi/acpica/evxfevnt.c
--- clean/linux-4.9.38/drivers/acpi/acpica/evxfevnt.c 2017-07-15 06:17:55.000000000 -0400
+++ linux-4.9.38/drivers/acpi/acpica/evxfevnt.c 2017-10-11 18:38:36.027243511 -0400
@@ -111,6 +111,8 @@
}

ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode"));
+printk("%s:%d faking ACPI mode\n", __func__, __LINE__);
+ return_ACPI_STATUS(AE_OK);
return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
}

diff --recursive -u clean/linux-4.9.38/drivers/acpi/acpica/hwacpi.c linux-4.9.38/drivers/acpi/acpica/hwacpi.c
--- clean/linux-4.9.38/drivers/acpi/acpica/hwacpi.c 2017-07-15 06:17:55.000000000 -0400
+++ linux-4.9.38/drivers/acpi/acpica/hwacpi.c 2017-10-11 18:38:36.027243511 -0400
@@ -168,12 +168,16 @@

status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value);
if (ACPI_FAILURE(status)) {
+printk("%s:%d faking ACPI mode\n", __func__, __LINE__);
+ return_UINT32(ACPI_SYS_MODE_ACPI);
return_UINT32(ACPI_SYS_MODE_LEGACY);
}

if (value) {
return_UINT32(ACPI_SYS_MODE_ACPI);
} else {
+//printk("%s:%d faking ACPI mode\n", __func__, __LINE__);
+// return_UINT32(ACPI_SYS_MODE_ACPI);
return_UINT32(ACPI_SYS_MODE_LEGACY);
}
}
diff --recursive -u clean/linux-4.9.38/drivers/tty/serial/8250/8250_core.c linux-4.9.38/drivers/tty/serial/8250/8250_core.c
--- clean/linux-4.9.38/drivers/tty/serial/8250/8250_core.c 2017-07-15 06:17:55.000000000 -0400
+++ linux-4.9.38/drivers/tty/serial/8250/8250_core.c 2017-12-01 12:49:29.122220689 -0500
@@ -1123,39 +1123,53 @@
if (ret)
goto out;

+/*
ret = serial8250_pnp_init();
if (ret)
goto unreg_uart_drv;
+*/

+printk("%s:%d\n", __func__, __LINE__);
serial8250_isa_devs = platform_device_alloc("serial8250",
PLAT8250_DEV_LEGACY);
+printk("%s:%d\n", __func__, __LINE__);
if (!serial8250_isa_devs) {
+printk("%s:%d\n", __func__, __LINE__);
ret = -ENOMEM;
- goto unreg_pnp;
+ //goto unreg_pnp;
+ goto unreg_uart_drv;
}

+printk("%s:%d\n", __func__, __LINE__);
ret = platform_device_add(serial8250_isa_devs);
if (ret)
goto put_dev;

+printk("%s:%d\n", __func__, __LINE__);
serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);

+printk("%s:%d\n", __func__, __LINE__);
ret = platform_driver_register(&serial8250_isa_driver);
if (ret == 0)
goto out;

+printk("%s:%d\n", __func__, __LINE__);
platform_device_del(serial8250_isa_devs);
put_dev:
+printk("%s:%d\n", __func__, __LINE__);
platform_device_put(serial8250_isa_devs);
unreg_pnp:
+printk("%s:%d\n", __func__, __LINE__);
serial8250_pnp_exit();
unreg_uart_drv:
+printk("%s:%d\n", __func__, __LINE__);
#ifdef CONFIG_SPARC
sunserial_unregister_minors(&serial8250_reg, UART_NR);
#else
uart_unregister_driver(&serial8250_reg);
#endif
out:
+printk("%s:%d\n", __func__, __LINE__);
return ret;
}

diff --recursive -u clean/linux-4.9.38/include/linux/efi.h linux-4.9.38/include/linux/efi.h
--- clean/linux-4.9.38/include/linux/efi.h 2017-07-15 06:17:55.000000000 -0400
+++ linux-4.9.38/include/linux/efi.h 2017-11-30 13:46:12.391653428 -0500
@@ -287,10 +287,10 @@
void *create_event;
void *set_timer;
void *wait_for_event;
- void *signal_event;
- void *close_event;
+ efi_status_t (*signal_event)(void *);
+ efi_status_t (*close_event)(void *);
void *check_event;
- void *install_protocol_interface;
+ efi_status_t (*install_protocol_interface)(efi_handle_t *, efi_guid_t *, int, void *);
void *reinstall_protocol_interface;
void *uninstall_protocol_interface;
efi_status_t (*handle_protocol)(efi_handle_t, efi_guid_t *, void **);
@@ -308,20 +308,20 @@
void *get_next_monotonic_count;
void *stall;
void *set_watchdog_timer;
- void *connect_controller;
+ efi_status_t (*connect_controller)(efi_handle_t, efi_handle_t *, void **, unsigned);
void *disconnect_controller;
void *open_protocol;
void *close_protocol;
void *open_protocol_information;
void *protocols_per_handle;
- void *locate_handle_buffer;
+ efi_status_t (*locate_handle_buffer)(unsigned, efi_guid_t *, void *, unsigned *, efi_handle_t **);
efi_status_t (*locate_protocol)(efi_guid_t *, void *, void **);
void *install_multiple_protocol_interfaces;
void *uninstall_multiple_protocol_interfaces;
void *calculate_crc32;
void *copy_mem;
void *set_mem;
- void *create_event_ex;
+ efi_status_t (*create_event_ex)(uint32_t type, unsigned tpl, void (*func)(void*), void *context, efi_guid_t *, void **event_out);
} efi_boot_services_t;

typedef enum {
@@ -592,6 +592,11 @@
#define EFI_RNG_PROTOCOL_GUID EFI_GUID(0x3152bca5, 0xeade, 0x433d, 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44)
#define EFI_MEMORY_ATTRIBUTES_TABLE_GUID EFI_GUID(0xdcfa911d, 0x26eb, 0x469f, 0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20)
#define EFI_CONSOLE_OUT_DEVICE_GUID EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+#define EFI_BDS_ARCH_PROTOCOL_GUID EFI_GUID(0x665E3FF6, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D)
+#define EFI_EVENT_GROUP_READY_TO_BOOT EFI_GUID(0x7ce88fb3, 0x4bd7, 0x4679, 0x87, 0xa8, 0xa8, 0xd8, 0xde, 0xe5, 0x0d, 0x2b)
+
+
+

/*
* This GUID is used to pass to the kernel proper the struct screen_info

Trammell Hudson

unread,
Dec 7, 2017, 1:15:12 PM12/7/17
to linu...@googlegroups.com
On Mon, Dec 4, 2017 at 9:54 AM Trammell Hudson <hud...@trmm.net> wrote:
> I'm going to try to port the ovmf changes into the Linux kernel so
> that it can be invoked as BDS. This will be an extra compile time
> config option, CONFIG_EFI_BDS, available if CONFIG_EFI_STUB is defined.

These have been pushed to the osresearch/heads tree on the nerf branch
and work well enough. I haven't tested it yet on the r630.

Here's the current problem:

If I use Intel's UEFI image, stripped down from over 400 files to
around 100 (not counting duplicates for other chipsets), everything works.
The ACPI tables look good, SMM and ACPI are setup, buses are all
enumerated, etc. I've replaced DxeCore, PciBusDxe, SmmCore and SmmIpl
with edk2 built versions so that they have debugging turned on, which
was helpful to identify the deadweight. So, yes! It works, but with
a significant compromise in moral purity.

When I try to use an entirely edk2 built image with no SMM and static
ACPI tables, the kernel hangs when it tries to initialize the serial
port. The early serial console works (via busy waiting), but turning
on initcall_debug shows that it dies when the serial port autoconfig()
and autoconfig_irq() routines are called.

If I stub those out, the TPM initialization hangs. If I make that a
module, the kernel gets all the way into user space, but the console is
screwd up and doesn't take input.

Any ideas?

--
Trammell

ron minnich

unread,
Dec 7, 2017, 1:22:01 PM12/7/17
to Trammell Hudson, linu...@googlegroups.com
I'm not all there at the moment, sorry, but you did mention static ACPI tables. 

I suspect you are getting stuck on interrupt setup, and you need the AML to run. That's what I found when porting Plan 9 to random machines, and I had to add AML support to fix the problems. If you have no SMM I wonder if you can even enable SCI and such, which sounds like a problem. 

So we'd like to go with compromised moral purity for now, as described in your first paragraph ... is that easy to get to with what's in your repo?

Trammell Hudson

unread,
Dec 7, 2017, 1:45:12 PM12/7/17
to ron minnich, linu...@googlegroups.com
On Thu, Dec 07, 2017 at 06:21:50PM +0000, ron minnich wrote:
> I suspect you are getting stuck on interrupt setup, and you need the AML to
> run. That's what I found when porting Plan 9 to random machines, and I had
> to add AML support to fix the problems. If you have no SMM I wonder if you
> can even enable SCI and such, which sounds like a problem.

That seems likely. My guess is that things that busy wait on the serial
console work fine, but things that depend on interrupts firing are getting
hung. For instance, with SMP enabled it eventually watchdogs.

> So we'd like to go with compromised moral purity for now, as described in
> your first paragraph ... is that easy to get to with what's in your repo?

Building the Linux kernel part is easy, but the Intel UEFI DxeCore volume
is hand hacked right now. Are there any decent scriptable tools for
extracting certain pieces from a UEFI volume that would make this
doable in a build script?

--
Trammell

Ron Minnich

unread,
Dec 7, 2017, 1:48:19 PM12/7/17
to Trammell Hudson, ron minnich, linu...@googlegroups.com
On Thu, Dec 7, 2017 at 10:45 AM Trammell Hudson <hud...@trmm.net> wrote:


Building the Linux kernel part is easy, but the Intel UEFI DxeCore volume
is hand hacked right now.  Are there any decent scriptable tools for
extracting certain pieces from a UEFI volume that would make this
doable in a build script?


we are planning to write Go tools that let us script this stuff. UEFITool is fine, but we want
to script it. 

Trammell Hudson

unread,
Dec 8, 2017, 2:57:05 PM12/8/17
to linu...@googlegroups.com
On Thu, Dec 07, 2017 at 06:48:07PM +0000, 'Ron Minnich' via linuxboot wrote:
> we are planning to write Go tools that let us script this stuff. UEFITool
> is fine, but we want
> to script it.

I've sent a pull request to uefitool for modifying FFSv3 firmwares,
which the s2600wf is using:

https://github.com/LongSoft/UEFITool/pull/90

However, it is still a manual process to insert filesystems, etc.
It would be great to have a programatic way to extract pieces from
vendor firmware, replace bits and insert them into ours.

Here is minimal* set of DXE and SMM modules that I needed in the recovery
ROM, which can load up the LinuxBoot kernel and runtime (up to 9 MB)
with ACPI support. Even with massive amounts of debugging going to
the serial console at 115200 baud it takes 25 seconds from power on
to busybox prompt. SEC/PEI are 11 seconds and ACPI is about 10.

The DxeCore and PiSmmCore are built from edk2 sources, so even though
the rest of the modules are vendor blobs and represent moral compromise,
at least we're in control of the dispatch and load components.

The 4 MB recovery image region can be extracted from the 64 MB ROM dump:

dd if=s2600wf.rom of=recovery-original.rom \
bs=[0x10000] skip=$[0x2c0] count=$[0x40]

The individual files can be extracted with uefi-firmware-parser -e,
which will produce a directory of directory of directory of directory
of them. There are 379 file.obj in the stock image; this set of 55
is sufficient to boot.

I'm using edk2's GenFv to make an uncompressed image, which then is
inserted into the 4 MB rom using the patched UEFItool.

GenFv \
--numberblock 0x100 \
--blocksize 0x10000 \
--FvNameGuid 4652454e-482f-6165-6473-2f4c696e7578 \
-o minimal.rom \
`awk '/^[0-9A-Fa-f]/ {print "-f file-"$1"/file.obj"}' guids.txt`


fc510ee7-ffdc-11d4-bd41-0080c73c8881 DxeApriori
d6a2cb7f-6a18-4e2f-b43b-9920a733700a DxeCore
80cf7257-87ab-47f9-a3fe-d50b76d89541 PcdDxe
56d60ee4-5ccf-485c-bbbb-fedae2b24146 RegAccessDxe
e0471a15-76dc-4203-8b27-6db4f8ba644a UbaConfigDatabaseDxe
69e6dd6d-f09e-485f-9627-eb70e9cfc82a UbaInitDxe
466a36cc-494a-4a33-bbfe-8c4416155c1d StaticSkuDataDxeWolfPass
3631014e-bdb8-4f58-ae2e-a7ee7c30c83e SmbiosDataUpdateDxeWolfPass
cbaeb5fd-e23d-499b-8930-0e66321502a2 IioCfgUpdateDxeWolfPass
788dd6a1-f1ee-4bba-a925-c0e7d66271bd SystemBoardDxe
2e6a521c-f697-402d-9774-98b2b7e140f3 PlatformType
9f7dcade-11ea-448a-a46f-76e003657dd1 VariableSmmRuntimeDxe
96fcec89-bbd9-4413-93cd-144631db7431 SmbiosPcTable
7f8d35bd-0ce3-4654-b5d3-73fc4b38aabf PlatformEarlyDxe
bae7599f-3c6b-43b7-bdf0-9ce07aa91aa6 CpuIoDxe
a19b1fe7-c1bc-49f8-875f-54a5d542443f CpuIo2Dxe
348c4d62-bfbd-4882-9ece-c80bb1c4783b HiiDatabase
79ca4208-bba1-4a9a-8456-e1e66a81484e Legacy8259
62d171cb-78cd-4480-8678-c6a2a797a8de CpuArchDxe
76a7b4fc-c8d5-462d-a4d2-6e88338a772a PlatformCpuPolicy
40beab40-cece-4909-b133-20a413ae19e9 CpuMpDxe
c8339973-a563-4561-b858-d8476f9defc4 Metronome
f099d67f-71ae-4c36-b2a3-dceb0eb2b7d8 WatchdogTimer
b601f8c4-43b7-4784-95b1-f4226cb40cee RuntimeDxe
d58ebce1-af26-488d-be66-c164417f8c13 PciHostBridge
3ffcae95-23cf-4967-94f5-16352f68e43b PpmInitialize
f80697e9-7fd6-4665-8646-88e33ef71dfc SecurityStubDxe
9622e42c-8e38-4a08-9e8f-54f784652f6b AcpiTableDxe
96b5c032-df4c-4b6e-8232-438dcf448d0e NullMemoryTestDxe
de23acee-cf55-4fb6-aa77-984ab53de823 PchInitDxe
e052d8a6-224a-4c32-8d37-2e0ae162364d PchSmbusDxe
a0bad9f7-ab78-491b-b583-c52b7f84b9e0 SmmControl
90cb75db-71fc-489d-aacf-943477ec7212 SmartTimer
bb1fbd4f-2e30-4793-9bed-74f672bc8ffe PchResetRuntime
5aab83e5-f027-4ca7-bfd0-16358cc9e453 WdtDxe
e2441b64-7ef4-41fe-b3a3-8caa7f8d3017 PciPlatform
f9d88642-0737-49bc-81b5-6889cd57d9ea SmbiosDxe
87ab821c-79b8-4ef6-a913-21d22063f55f AcpiPlatform
274f0c8f-9e57-41d8-9966-29ccd48d31c2 SmmAccess
8faad0a7-02b4-432f-8f5c-b880965d8b41 SmmCommunicationBuffer
7e374e25-8e01-4fee-87f2-390c23c606cd EfiAcpiTableStorage
06d20d84-a032-4e25-969a-346d255e46d1 CpuCsrAccess
c4eb3614-4986-42b9-8c0d-9fe118278908 CrystalRidge
63809859-f029-41c3-9f34-eeeb9ea787a5 IioInit
6ec99217-69bb-4ad6-9b4e-8f4ab9af72b9 ResetTesting
deb0ee00-18df-415c-af03-74d09b0aad87 JedecNvDimm
2fa2a6da-11d5-4dc3-999a-749648b03c56 PiSmmIpl
e94f54cd-81eb-47ed-aec3-856f5dc157a9 PiSmmCore
d96a2393-8790-4baa-9ceb-42533f016ee9 RegAccessSMM
7d94b7a4-b8d7-4371-8d12-92083adf5e47 SmiVariable
23a089b3-eed5-4ac5-b2ab-43e3298c2343 VariableSmm
a3ff0ef5-0c28-42f5-b544-8c7de1e80014 PiSmmCpuDxeSmm
b0d6ed53-b844-43f5-bd2f-61095264e77e PchSmiDispatcher
a47ee2d8-f60e-42fd-8e58-7bd65ee4c29b CpuIo2Smm
27f4917b-a707-4aad-9676-26df168cbf0d PchSpiSmm


*: I felt this was enough effort put into it... It looks like the
ACPI SMM driver is not being loaded, so we can probably dispense
with it entirely if ACPI is not required. The TPM might be borked
as well.

--
trammell

Trammell Hudson

unread,
Dec 8, 2017, 7:25:37 PM12/8/17
to linu...@googlegroups.com
With "acpi=off" on the kernel command line the S2600 goes from power
on to shell in less than 20 seconds:

https://www.youtube.com/watch?v=0HISDFXZvSI

--
Trammell
> --
> You received this message because you are subscribed to the Google Groups "linuxboot" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linuxboot+...@googlegroups.com.
> To post to this group, send email to linu...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/linuxboot/20171208195700.GE31543%40chishio.swcp.com.

Ron Minnich

unread,
Dec 8, 2017, 8:54:31 PM12/8/17
to Trammell Hudson, linu...@googlegroups.com
On Fri, Dec 8, 2017 at 4:25 PM Trammell Hudson <hud...@trmm.net> wrote:
With "acpi=off" on the kernel command line the S2600 goes from power
on to shell in less than 20 seconds:


yes, we always ran the HPC systems at LANL with acpi=off. This works as long as your _MP_ tables are good, right? Or how did you pick up all the IRQ routing? 

 

Trammell Hudson

unread,
Dec 8, 2017, 9:19:44 PM12/8/17
to linu...@googlegroups.com
With acpi=off the LinuxBoot kernel comes up with only one CPU, so
my guess is that it is not finding the legacy tables (and the build
doesn't have any of the legacy support DXE included).

That seems ok, as long as the kexec'ed kernel can pickup the ACPI
tables and bring up the CPUs. I haven't tested that yet...

--
Trammell

ron minnich

unread,
Dec 8, 2017, 10:00:08 PM12/8/17
to Trammell Hudson, linu...@googlegroups.com
yes, I agree, you don't really need more than one cpu if you're just booting the next kernel. I'm interested to hear how it works out for you ...

--
You received this message because you are subscribed to the Google Groups "linuxboot" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linuxboot+...@googlegroups.com.
To post to this group, send email to linu...@googlegroups.com.

ron minnich

unread,
Dec 11, 2017, 10:46:20 PM12/11/17
to Trammell Hudson, linu...@googlegroups.com
in your repo, currently, is there a way to build the bdsdxe? I don't see it but it's probably under my nose.

We need a bds as the dxecore we build is looking for a bunch of bogus guids. We're hoping we can at least get the tiano dxecore to call something familiar.

Chris Koch

unread,
Dec 11, 2017, 11:37:41 PM12/11/17
to ron minnich, Trammell Hudson, linu...@googlegroups.com

Re scripting, have you seen https://github.com/theopolis/uefi-firmware-parser ?

I'm hoping to use that as a basis for something that can parse + replace things at some point to automate the build process. But it's a little further down my list of tools to build right now.


On Mon, Dec 11, 2017, 19:46 ron minnich <rmin...@gmail.com> wrote:
in your repo, currently, is there a way to build the bdsdxe? I don't see it but it's probably under my nose.

We need a bds as the dxecore we build is looking for a bunch of bogus guids. We're hoping we can at least get the tiano dxecore to call something familiar.

--
You received this message because you are subscribed to the Google Groups "linuxboot" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linuxboot+...@googlegroups.com.
To post to this group, send email to linu...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
--
Christopher Koch | Software Engineer | chr...@google.com | 650-214-3546

Trammell Hudson

unread,
Dec 11, 2017, 11:52:31 PM12/11/17
to ron minnich, linu...@googlegroups.com
It's a little convoluted right now. "make CONFIG=config/winterfell.config edk2.intermediate nerf.vol" should result in a DxeCore.efi and DxeCore.ffs



-- 
Trammell (mobile)

On Dec 12, 2017, at 04:46, ron minnich <rmin...@gmail.com> wrote:

in your repo, currently, is there a way to build the bdsdxe? I don't see it but it's probably under my nose.

We need a bds as the dxecore we build is looking for a bunch of bogus guids. We're hoping we can at least get the tiano dxecore to call something familiar.

--
You received this message because you are subscribed to the Google Groups "linuxboot" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linuxboot+...@googlegroups.com.
To post to this group, send email to linu...@googlegroups.com.

Gan Shun

unread,
Dec 11, 2017, 11:54:20 PM12/11/17
to Chris Koch, ron minnich, Trammell Hudson, linu...@googlegroups.com
yeah I was actually thinking about turning uefi-firmware-parser into something that can modify the image + I actually want to do something that can resize firmware volumes. I wanna do it in Go though.

Ron Minnich

unread,
Dec 12, 2017, 1:26:12 AM12/12/17
to Gan Shun, Chris Koch, ron minnich, Trammell Hudson, linu...@googlegroups.com
trammell, what about the bdsdxe though? That's where I'm stuck. YOu had some way to build the ovmf version or something?

Trammell Hudson

unread,
Dec 12, 2017, 6:19:55 AM12/12/17
to linu...@googlegroups.com
On Tue, Dec 12, 2017 at 06:26:01AM +0000, 'Ron Minnich' via linuxboot wrote:
> trammell, what about the bdsdxe though? That's where I'm stuck. YOu had
> some way to build the ovmf version or something?

Dur. I blame jetlag for misreading your email.

BdsDxe.efi will be built as part of edk2.intermediate, but we
don't use it since Linux acts as BDS. If you want it it will
be in here:

build/edk2-UDK2017/Build/MdeModule/DEBUG_GCC5/X64/BdsDxe.efi

You'll need to enable CONFIG_EFI_STUB_BDS in the Linux kernel:

https://github.com/osresearch/heads/commit/5a188f5b46e5115a905ab759c641563c3af37b9c
> >>> <https://groups.google.com/d/msgid/linuxboot/CAP6exYJuOuROPkeqXb3RjQgRE8sUT689rRz2B72XBV2q9WNPxg%40mail.gmail.com?utm_medium=email&utm_source=footer>
> >>> .
> >>> For more options, visit https://groups.google.com/d/optout.
> >>>
> >> --
> >> Christopher Koch | Software Engineer | chr...@google.com |
> >> 650-214-3546 <(650)%20214-3546>
> >>
> >> --
> >> You received this message because you are subscribed to the Google Groups
> >> "linuxboot" group.
> >> To unsubscribe from this group and stop receiving emails from it, send an
> >> email to linuxboot+...@googlegroups.com.
> >> To post to this group, send email to linu...@googlegroups.com.
> >> To view this discussion on the web visit
> >> https://groups.google.com/d/msgid/linuxboot/CAA0N8zatHRumYjHkH0-FHZ2YS-x8iKB2Li1wi%3D5xzDBgRKrXBQ%40mail.gmail.com
> >> <https://groups.google.com/d/msgid/linuxboot/CAA0N8zatHRumYjHkH0-FHZ2YS-x8iKB2Li1wi%3D5xzDBgRKrXBQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
> >> .
> >> For more options, visit https://groups.google.com/d/optout.
> >>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "linuxboot" group.
> > To unsubscribe from this group and stop receiving emails from it, send an
> > email to linuxboot+...@googlegroups.com.
> > To post to this group, send email to linu...@googlegroups.com.
> > To view this discussion on the web visit
> > https://groups.google.com/d/msgid/linuxboot/CAOBgeHEAGzUbfYPcPk1VveN3v-8iKotm1t0jgnzKEX5RWGQzJQ%40mail.gmail.com
> > <https://groups.google.com/d/msgid/linuxboot/CAOBgeHEAGzUbfYPcPk1VveN3v-8iKotm1t0jgnzKEX5RWGQzJQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
> > .
> > For more options, visit https://groups.google.com/d/optout.
> >
>
> --
> You received this message because you are subscribed to the Google Groups "linuxboot" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linuxboot+...@googlegroups.com.
> To post to this group, send email to linu...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/linuxboot/CAPAv03MFva7hC%3D-pfC3EPXx_usJK7SY6VzVe%2BK8WDB9BQqyROg%40mail.gmail.com.
Reply all
Reply to author
Forward
0 new messages