Commit Graph

69 Commits

Author SHA1 Message Date
Lionel Debroux
71c7bdfc00 WIP BROKEN NX enablement, for now only for the second page directory.
TODO:
    * selective NX enablement on pd0, pd1 and pd3.
      Unconditional NX on the whole pd3 makes memtest86+ reboot in a QEMU-emulated computer.
    * if supported on all x86_64 CPUs, simply enable long mode and NX simultaneously ? A real K8 dual-core processor didn't seem to hate it, at least.
    * startup code: NX enablement for x86, on capable computers (CPUID 0x80000001, edx bit 20).
    * set the appropriate flag in the headers.
2023-10-15 21:34:00 +02:00
Martin Whitaker
f62bbfde32 Additional fix to support use on headless EFI systems (issue #240) 2023-02-11 09:14:56 +00:00
Martin Whitaker
b01c8e4388 Avoid sbverify warning about gap in section table.
We have a .setup section in the EFI image that contains the remainder of
the Linux boot header and the real-mode setup code to support booting via
an intermediate bootloader. This sits between the PE header and the .text
section. We don't want the EFI loader to load this section, so simply
increase the SizeOfHeader field in the PE header to cover it.
2023-02-02 14:01:13 +01:00
Martin Whitaker
d088740757 Fix the bss section size in 32-bit builds.
The AP stacks section was being discarded by the linker because the
change in section name and attributes hadn't been propagated from
the startup64.S to startup32.S.
2023-02-02 14:01:13 +01:00
Martin Whitaker
9c16a0568a Fix assembler warning about incorrect type/attributes for .reloc section. 2023-02-02 14:01:13 +01:00
Martin Whitaker
040e253b54 Remove the alignment characteristics from the EFI image PE section table.
The alignment characteristics are only valid in COFF files. The section
alignment for image files is determined by the SectionAlignment field
in the image header.
2023-02-02 14:01:13 +01:00
Martin Whitaker
2fa2346ae0 Use the correct name for the relocation type in the EFI image .reloc section.
The coding is the same, but IMAGE_REL_AMD64_ABSOLUTE is used for COFF
relocations, not for base relocations.
2023-02-02 14:01:13 +01:00
Martin Whitaker
e5d7119abf White space changes to improve readability. 2023-02-02 14:01:13 +01:00
Martin Whitaker
a4c9adc445 Fix the virtual memory addresses and sizes in the EFI image headers.
When the reloc and sbat sections were added by PR #34, three bugs were
introduced:

1. The virtual address and size fields in the PE headers were set to the
same values as the raw address and size fields. This is incorrect, because
the sections in the image file are aligned on 512 byte boundaries, but when
loaded into memory they need to be aligned on 4096 byte boundaries.

2. The value programmed into the SizeOfImage field was too large, as it
double-counted the region before the start of the .text section.

3. The value programmed into the SizeOfImage field no longer included the bss
size. That potentially allowed the EFI loader to load the image immediately
before a reserved region of memory without leaving enough space for the bss
section.

This commit fixes those bugs by calculating both file and virtual memory
offsets & sizes in the ld script. Note that we can't add a bss section to the
EFI image because many EFI loaders fail to load images that have uninitialised
data sections. Instead the text region size in virtual memory is increased
to include the bss size.

This fixes issue #243. It also eliminates the gaps between sections
observed in issue #202.
2023-02-02 14:01:13 +01:00
martinwhitaker
327495ec61
Allow use on headless EFI systems. (#242)
A headless EFI system may have no GOP devices. In this case, disable
output to the physical display, but continue to write to the shadow
buffer. This allows operation via a serial console.
2023-01-23 15:50:52 +01:00
Sam Demeulemeester
d3d52b8a11 Add Memtest86+ Version String to Kernel Header (#75) 2023-01-03 01:35:51 +01:00
Peter Jones
04980dfda3 EFI: Add support for .sbat signature revocations
This patch adds a new section, ".sbat", which allows for the revocation
of signed binaries given a numeric value representing the set of bugs
which allow for arbitrary code execution, and therefore a Secure Boot
breakout, in a given family of binaries.

In this case, the class is defined as "memtest86+", and the current set
of bugs is 1.  This doesn't imply that we're aware of bugs currently,
merely that when we change it to 2, any bugs that /have/ been discovered
have been fixed.

Documentation for how SBAT works can be found at the following URLs:

  https://github.com/rhboot/shim/blob/main/SBAT.md
  https://github.com/rhboot/shim/blob/main/SBAT.example.md

Signed-off-by: Peter Jones <pjones@redhat.com>
2023-01-03 00:58:52 +01:00
Peter Jones
d1014365c1 EFI: Add a dummy relocation section
In the past, we've seen some problems with some EFI loaders refusing to
load a binary that has both a .text section with the VMA set and no
relocations, when the VMA set to load is already allocated for some
other purpose.

This patch adds a dummy absolute relocation from 0 to 0, so the loader
can always feel like it has done something useful.

Signed-off-by: Peter Jones <pjones@redhat.com>
2023-01-03 00:58:52 +01:00
Peter Jones
e022441544 Fix Pe.OptHdr.SizeOfImage and SizeOfHeaders
SizeOfImage is defined as:

  The size (in bytes) of the image, including all headers, as the image
  is loaded in memory. It must be a multiple of SectionAlignment.

SizeOfHeaders likewise is defined as:

  The combined size of an MS-DOS stub, PE header, and section headers
  rounded up to a multiple of FileAlignment.

Currently SizeOfImage represents .bss and .text, but it doesn't include
.header or .setup, nor any sections we'll add later, and there's nothing
enforcing that it matches SectionAlignment.  Additionally, since .bss is
being set up in our running code and /not/ by the loader, the current
value is dangerously high, as in the event there is an error in the
section table, it could potentially lead the loader to mark memory
allocated at runtime holding user-supplied data by any EFI binary loaded
before us as executable.

This patch adds a new symbol, _img_end, which is after .text and is
rounded up to 4kB (which is also what SectionAlignment is set to).  It
also adds a local label, anchored with ".org 512", and uses that to set
SizeOfHeaders - this will ensure the build fails without outputting and
invalid binary if the headers take too much space.

Signed-off-by: Peter Jones <pjones@redhat.com>
2023-01-03 00:58:52 +01:00
Peter Jones
3dd1fa8959 EFI: Add Data Directory space
Currently, the PE headers we create in boot/header.S do not allocate
space for any Data Directory entries, as they haven't been needed.

In order to support signatures and compatibility with some loaders, we
need the Data Directory to be populated at least enough to set
DataDirectory.Certs and DataDirectory.BaseReloc.

This patch extends that space enough to include those entries.

Signed-off-by: Peter Jones <pjones@redhat.com>
2023-01-03 00:58:52 +01:00
Peter Jones
e3c0d6df60 Make header.S use symbolic names for values
This changes header.S to use the constants defined in peimage.h to for
the values in its structure, making it a lot easier to debug.

Signed-off-by: Peter Jones <pjones@redhat.com>
2023-01-03 00:58:52 +01:00
Peter Jones
87f03f3b10 Add declarations and defines for PE images
This adds a header file to describe the PE binary we're building.  This
has constants defined for all the values we use in the PE headers, as
well as the structures for reference (guarded by #ifdef __ASSEMBLY__).

This particular peimage.h is originally from binutils-2.10.0.18, which
is GPLv2 licensed, and is copyright the Free Software Foundation.  I've
added the few additional fields we need.

Signed-off-by: Peter Jones <pjones@redhat.com>
2023-01-03 00:58:52 +01:00
a1346054
9660eead4e
Simple maintenance improvements (#145)
* Fix typos

* Add missing final newline

* Trim trailing whitespace
2022-08-15 17:51:48 +02:00
Martin Whitaker
13d9569041 By default, only enable USB keyboard detection when booted in UEFI mode.
Most legacy BIOSs will support USB legacy keyboard emulation. Using that
will avoid having to reserve memory for the USB drivers, and should
improve the chance of having a working keyboard without having to work
around various USB device quirks.
2022-07-24 13:56:41 +01:00
Martin Whitaker
c2e94527e1 Fix handling of EFI memory map when located above 4GB (issue #115)
The code which saves and restores the upper 32 bits of the address
was not being included, due to a typo in the #ifdef expression.
2022-07-13 20:57:02 +01:00
Martin Whitaker
f16be176ed Fix triple-fault when starting APs with program loaded above 16MB (issue #63).
In a .code16 section, the default coding for the lgdt instruction only loads
a 24 bit base address from the GDT descriptor. When loaded above 16MB, we
need it to load the full 32 bits.
2022-05-15 12:18:07 +01:00
Martin Whitaker
f98ceb1613 Set the kernel_alignment and min_alignment fields in the Linux setup header.
This shouldn't be needed because we don't set the relocatable_kernel flag,
but the GRUB linuxefi command pays no attention to that. Currently the
linuxefi command also ignores the alignment values, but set them now in
case that changes in the future.
2022-05-15 12:18:07 +01:00
Martin Whitaker
e8c8ef69eb Simplify allocation of memory in efisetup.c. 2022-05-09 18:41:14 +01:00
Martin Whitaker
e429abec9f Support boot options when booting directly from EFI image (issue #53). 2022-05-08 22:46:27 +01:00
Martin Whitaker
a14a6b8e65 Fix start address calculation when booting from 32-bit EFI (issue #52) 2022-04-23 13:17:59 +01:00
Martin Whitaker
32b9ce38e7 Fix early reboot on 32-bit CPUs that don't support long mode (issue #38) 2022-04-13 20:37:47 +01:00
Martin Whitaker
31f06ea7c8 Add a framebuffer test when EFI debug is enabled. 2022-04-13 14:30:52 +01:00
Martin Whitaker
6e9bdce92d Select the best mode for the EFI framebuffer.
This chooses the lowest resolution that supports our main display.
2022-04-13 14:30:23 +01:00
Martin Whitaker
06c2769abe Tabulation and white space fixes. 2022-04-13 12:13:13 +01:00
Martin Whitaker
1998ce16d1 Handle 64-bit frame buffer addresses when printing EFI debug info. 2022-04-11 20:00:59 +01:00
Sam DEMEULEMEESTER
2266151fe6 Early SMBUS functions (#2) & EFI Reset (#17) 2022-03-24 21:49:56 +01:00
Martin Whitaker
4078b7760e Faster barrier implementation.
The old barrier implementation was very slow when running on a multi-socket
machine (pcmemtest issue 16).

The new implementation provides two options:

  - when blocked, spin on a thread-local flag
  - when blocked, execute a HLT instruction and wait for a NMI

The first option might be faster, but we need to measure it to find out. A
new boot command line option is provided to select between the two, with a
third setting that uses a mixture of the two.
2022-02-28 22:05:21 +00:00
Martin Whitaker
f8b82eb0bd Exclude copyright notices from Doxygen file descriptions. 2022-02-19 19:56:55 +00:00
Martin Whitaker
d04ec9f681 Rename to Memtest86+ v6.0. 2022-02-19 19:44:58 +00:00
Martin Whitaker
76adad2fe6 Add ability to generate internal API documentation using Doxygen. 2022-02-19 16:17:40 +00:00
Martin Whitaker
f4a413cf6d Translate non-usable EFI memory regions to E820_RESERVED, not E820_NONE.
This is more correct. Using E820_NONE may have been confusing the code
in pmem.c that sanitises the memory map.
2022-02-13 20:44:58 +00:00
Martin Whitaker
99e258457b Use je/jne instead of jz/jnz when testing boolean variables in startup code.
Just for readability - they are aliases for the same instructions.
2022-02-12 09:39:18 +00:00
Martin Whitaker
39d5715224 Fix interrupt handling when long mode is enabled in a 32-bit binary (part 2).
Handle passing the processor state to the application interrupt handler.
Update the 64-bit code to match the new trap state structure definition.
2022-02-12 09:39:09 +00:00
Martin Whitaker
111e619b10 Fix interrupt handling when long mode is enabled in a 32-bit binary (part 1).
If long mode is enabled, the interrupt handler always runs in 64-bit
mode, so we need to set up the interrupt dispatch table accordingly.
2022-02-08 23:35:00 +00:00
Martin Whitaker
e96fd7b99f Fix a few minor issues in the 64-bit startup code...
- the calculation of the RSP value when an interrupt occurred was
  out by 8 bytes
- in a few places a 32-bit pointer was used instead of a 64-bit one
- incorrect tabulation (white space)
2022-02-08 23:29:24 +00:00
Martin Whitaker
9769990679 Extend the use of the startup mutex to cover the entire startup code.
There is more in the startup code that isn't thread safe than just
the use of the temporary stack. So take the mutex for the whole time.
The code isn't that long, so it's not worth trying to cover just the
critical sections.
2022-02-05 18:03:32 +00:00
Martin Whitaker
e37fbbd429 Set stack alignment to 16 bytes.
This needs to be done in the ldscripts.
2022-02-02 18:23:23 +00:00
Martin Whitaker
7acb81e302 Fix assembler warning about unsized bts instruction. 2022-02-02 12:52:44 +00:00
Martin Whitaker
dcac527068 Don't make assumptions about usable memory.
When using a legacy BIOS, the memory regions used by the BIOS are well
defined. This is not the case when using a UEFI BIOS. So include the
stack area in the BSS so the loader knows how much memory to allocate,
and check we have space to relocate the program to either low or high
memory.

There are still some assumptions in the USB driver code that need to
be fixed.
2022-02-02 12:20:39 +00:00
Martin Whitaker
16d55b7dad Remove distinction between physical and virtual CPUs.
This is no longer needed, now we can display as many CPUs as we can
physically handle.
2022-01-31 22:59:14 +00:00
Martin Whitaker
4100a44b12 Properly protect the startup stack with a mutex.
Because we start the APs sequentially, it is unlikely they will coincide
for the brief period that they use the temporary startup stack, but we
should guard against it. This allows us to remove the mutex around the
restart of each AP when relocating, which should improve test times.
2022-01-31 21:54:24 +00:00
Martin Whitaker
c5e9fa4e18 Increase maximum number of APs to 256. 2022-01-29 16:13:05 +00:00
Martin Whitaker
fe4374e818 Allocate the main program stacks after the loaded program.
After we relocate the program, we restart it. So there is no need to copy
over the old stack contents. This allows us to increase the maximum number
of APs without a run time overhead. The maximum number of APs will still
be limited by the size of low memory.
2022-01-29 15:17:00 +00:00
Martin Whitaker
0aa1b1fa97 Rearrange stack space to reduce memory footprint.
The BSP only needs extra stack space during program initialisation. The APs
aren't running at that point, so by positioning the BSP stack above the AP
stacks, it can extend down into the AP stack space without causing any
problems.
2022-01-09 21:25:16 +00:00
Martin Whitaker
a454174f3f Fis startup stack address calculations. 2022-01-09 19:26:56 +00:00