Age | Commit message (Collapse) | Author | Files | Lines |
|
We could load it high if it is more than 2G when kernel support
LOAD_ABOVE_4G.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
We need to allocate boot_params early and clear it before copy
setup_header to it.
So kernel will not call sanitize_boot_params() to overwrite new
added parameter like ext_ramdisk_image, ext_ramdisk_size...
We should modify boot_params later instead of touch temp buf too early.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Thomas reports that efilinux hangs when executed via gummiboot. The
reason being that efilinux expects the executable name to be prepended
to the beginning of the LoadOptions string.
This behaviour isn't required by the UEFI spec, so make the options
parsing more robust to handle either case.
Reported-by: Thomas Bächler <thomas@archlinux.org>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
The ABI of the EFI handover protocol was changed in v3.8 with the
following upstream kernel commit,
: commit f791620fa7517e1045742c475a7f005db9a634b8
: Author: David Woodhouse <David.Woodhouse@intel.com>
: Date: Mon Jan 7 22:01:50 2013 +0000
:
: x86, efi: Fix 32-bit EFI handover protocol entry point
from a 'jmp' to a 'call'. This affects the layout of arguments on the
stack since 'call' expects the return address to be the data item at the
top of the stack.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
It's not enough to check that bzImage header supports the
'relocatable_kernel' field, we also need to make sure that the field
is set.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Linux kernel v3.6-rc1 support an "EFI handover protocol" that allows
most of the initialisation necessary for booting a kernel under EFI to
be performed by a boot stub in the kernel image itself.
Use the boot stub if it is supported by the kernel.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Allow specifying paths to files (kernel images, initrds) relative to the
boot drive instead of hard-coding a disk path / number in the efilinux.cfg.
Signed-off-by: Steve Langasek <steve.langasek@canonical.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
gcc by default outputs code using the SysV AMD64 ABI. We need to pass
-mno-red-zone to ensure compatibility with the Microsoft ABI, which is
what UEFI uses.
Matthew Garrett explains,
"The red zone is part of the AMD64 System V ABI and consists of
128 bytes at the bottom of the stack frame. This region is
guaranteed to be left untouched by any interrupt or signal
handlers, so it's available for functions to use as scratch
space. UEFI uses the Microsoft AMD64 ABI rather than the System V
one, and the Microsoft ABI doesn't define a red zone. UEFI
executables built on Linux tend to use System V because that means
we can link in static libraries built for Linux, rather than
needing an entirely separate toolchain and libraries to build UEFI
executables. The problem arises when we run one of these
executables and there's a UEFI interrupt handler still
running. Take an interrupt, Microsoft ABI interrupt handler gets
called and the red zone gets overwritten."
Signed-off-by: Steve Langasek <steve.langasek@canonical.com>
Cc: Matthew Garrett <mjg@redhat.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
There are restrictions on the addresses that we pass as arguments to
the kernel, mainly due to the way that the early page tables work. If
we allocate addresses above the first 1GB of memory the kernel will
fail to run. Cap key data structures at 0x3fffffff so that the kernel
can access them with its early page tables.
These limitations were discovered when running efilinux under Qemu
with multiple gigabytes of RAM.
Reported-by: Matthew Garrett <mjg@redhat.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Up until now we've been allocating the space for the kernel *after*
we've done all our other allocations, and it made the error paths
particularly cumbersome where we needed to free those
allocations. This is essentially a hack because of the extra space
required when the kernel decompresses itself. By placing all our other
allocations below the kernel they are not trashed during
decompression.
Linux kernels after v2.6.31 (with setup header version 2.10) include
'pref_address' and 'init_size' fields in their setup header. These
fields indicate where the kernel would prefer to be loaded in memory
and the size of the memory allocation required for the kernel,
including space for decompression. By using these fields we no longer
have to allocate space for the kernel after everything else. For
earlier kernel versions we can just make a conservative estimate of
the amount of space required.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
The only explanation of the config file syntax is in the commit log
that introduced it, commit 77148a3e4978 ("efilinux: Minimal
configuration file support"), so add a couple of lines to the README
describing it. Also, add an example config file.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
objcopy will leave the symbol table intact when creating an EFI
executable from the ELF shared object, which is unnecessary, but more
importantly the existence of the symbol table causes some EFI hashing
tools to fail when signing the executable for secure boot because the
symbol table is considered to be garbage.
Strip all symbol table and relocation information when creating the
EFI executable.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
At the moment whenever efilinux exits after displaying either the
command argument syntax, the list of devices or prints the memory map
the following message is printed,
"Error: Invalid Parameter"
Tidy up the exit path of parse_args() so that we can print these
useful bits of information without the user thinking that some kind of
error occurred.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Now that we have config file support failing to open a fail isn't
worthy of a warning. Many users won't be using a config file at all
and printing,
"Unable to open file <filename>"
everytime efilinux is executed is useless and annoying. Leave it to
the caller of file_open() to print any messages about failing to open
files.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
efilinux lacks a way of automatically booting a default
kernel. Instead, the kernel image path and kernel command line
arguments must be passed as arguments to efilinux on every invocation.
This commit allows a simple config file to specify a default kernel
and kernel arguments, which are passed to efilinux instead of
requiring them to be entered at the EFI shell. Now, when efilinux is
started it will first search for a file named 'efilinux.cfg' in the
same directory as the efilinux executable.
The syntax for a configuration file is exactly the same as the syntax
for efilinux's command line arguments. For example, to boot a linux
kernel the contents of 'efilinux.cfg' would be a single line,
"-f 0:\EFI\BOOT\vmlinux console=ttys0 initrd=0:\EFI\BOOT\initrd"
The contents of the file are passed to efilinux as though they were
typed at the EFI shell prompt. Multiple lines are not supported.
Cc: Darrent Hart <dvhart@linux.intel.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
gnuefi doesn't install crt0 and the ld script to a gnuefi directory by
default, but some distributions stick it there. Use find via a shell
command to take the last matching file for each of CRT0 and LDSCRIPT.
This avoids forcing the caller to duplicate the script generating the
ARCH variable used throughout the Makefile.
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
CC: Matt Fleming <matt.fleming@intel.com>
|
|
When crosscompiling, it's common to need to specify a different include dir
location.
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
|
|
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Different distributions have a habit of installing the gnu-efi crt0
and ldscripts in various locations on the file system. Until efilinux
gets autoconf support allow the user to override $CRT0 and $LDSCRIPT.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Add support for building ia32 efilinux on an x86-64
host. Cross-building can be turned on by specifying $ARCH when
building efilinux, e.g. (assuming an x86-64 host)
$ make ARCH=ia32
Also, delete $MACHINE from the Makefile and use $ARCH instead as ARCH
seems to be more commonly used for specifying the target architecture;
gnu-efi uses $ARCH for example.
Note that $(CFLAGS) is now passed to $(CC) when looking up the path
for libgcc.a,
$(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
This change is required because if we're cross-building $(CFLAGS) will
include -m32, which makes -print-libgcc-file-name return the filename
of the 32-bit version of libgcc.a, not the host's version.
Reported-by: Darren Hart <dvhart@linux.intel.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Previously we only parsed one initrd= argument from the command line,
but the linux kernel can handle multiple initrds.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
|
|
We leak a few chunks of memory if we take the error path in
efi_main(). Be sure to free the memory and clean up the file handles
in fs_exit().
Now that the caller of load_image() calls fs_exit() in the error path
we don't need to do it in the bzImage code (the kernel will reclaim
'fs_devices' anyway if it loads successfully), but we do need to be
sure to close any open file handles.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
We should be using sizeof() to figure out how large the buffer needs
to be because the buffer does not hold an array of bytes, rather it's
an array of CHAR16, which is actually 2 bytes. While I'm here cleanup
the error path so that we free() '*name' and '*cmdline' in case of
failure.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Currently if we have more than one handle that supports
FileSystemProtocol we'll copy junk from 'fs_devices' when passing the
arguments to handle_protocol(). This is because we're using an
incorrect data type for the buffer filled out by locate_handle() - it
returns an array of EFI_HANDLE, not an array of struct fs_device's.
Instead use a temporary buffer to store the list of EFI_HANDLE's and
copy them individually to fs_devices[].handle.
Also, this is a good opportunity to clean up the error path in
fs_init() so no longer leak open handles and 'fs_devices'.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
locate_protocol() has never been used by efilinux and results in the
following build error when compiled with gnu-efi <= 3.0i,
In file included from entry.c:38:0:
protocol.h: In function 'locate_protocol':
protocol.h:62:31: error: 'EFI_BOOT_SERVICES' has no member named 'LocateProtocol'
Reported-by: KESHAV P.R. <skodabenz@gmail.com>
Reported-by: Metatech <metatechbe@gmail.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Add an implementation of kernel_jump() for i386. This was all the
architecture specific code that was needed to get efilinux booting on
i386.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
The following warning appears when compiling for i386,
loaders/bzimage/bzimage.c: In function ‘load_kernel’:
loaders/bzimage/bzimage.c:172:4: error: passing argument 2 of ‘file_read’ from incompatible pointer type
fs/fs.h:63:1: note: expected ‘UINTN *’ but argument is of type ‘UINT64 *’
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
It doesn't make sense to set efi_systab_hi or efi_memmap_hi for i386
because the 32-bit addresses fit in efi_systab and efi_memmap. Also,
shifting the systab and memmap pointers results in the following
warnings,
loaders/bzimage/bzimage.c:324:2: error: right shift count >= width of type
loaders/bzimage/bzimage.c:325:2: error: right shift count >= width of type
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
The following warnings appear when compiling for i386,
cc1: warnings being treated as errors
loaders/bzimage/bzimage.c: In function ‘load_kernel’:
loaders/bzimage/bzimage.c:165:16: error: cast from pointer to integer of different size
loaders/bzimage/bzimage.c:167:11: error: cast from pointer to integer of different size
loaders/bzimage/bzimage.c:178:37: error: cast from pointer to integer of different size
loaders/bzimage/bzimage.c:186:34: error: cast from pointer to integer of different size
loaders/bzimage/bzimage.c:275:21: error: cast from pointer to integer of different size
loaders/bzimage/bzimage.c:276:21: error: cast from pointer to integer of different size
loaders/bzimage/bzimage.c:277:21: error: cast from pointer to integer of different size
loaders/bzimage/bzimage.c:283:31: error: cast to pointer from integer of different size
loaders/bzimage/bzimage.c:307:10: error: cast from pointer to integer of different size
loaders/bzimage/bzimage.c:319:28: error: cast from pointer to integer of different size
loaders/bzimage/bzimage.c:322:28: error: cast from pointer to integer of different size
Use UINTN which maps to unsigned long and works for i386 and x86-64.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
EFI_PHYSICAL_ADDRESS is a 64-bit data type, which when used to cast to
a 32-bit pointer leads to the following warnings,
cc1: warnings being treated as errors
malloc.c: In function ‘emalloc’:
malloc.c:60:6: error: cast from pointer to integer of different size
malloc.c:61:12: error: cast from pointer to integer of different size
malloc.c:67:10: error: cast to pointer from integer of different size
UINTN is a much more logical choice for this cast because it maps to
unsigned long, which will Do The Right Thing for both i386 and x86-64.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Before 32-bit support we were playing fast and loose with casts. The
problem was that we were casting away legimate warnings, such as the
compiler telling us that the value it was storing into a variable to
was too big to fit.
emalloc() was a prime example, in various places we passed a pointer
to a pointer as the third argument to emalloc which has type
EFI_PHYSICALL_ADDRESS *, where EFI_PHYSICAL_ADDRESS is a 64-bit type,
like so,
emalloc(UINTN size, UINTN align, EFI_PHYSICAL_ADDRESS *addr)
Then inside emalloc() we do,
*addr = aligned;
On 64-bit this is fine because,
sizeof(void *) == sizeof(EFI_PHYSICAL_ADDRESS)
but if we have a 32-bit pointer we attempt to store a 64-bit value
into a 32-bit data type. This led to stack corruption when we passed
the address of a pointer on the stack to emalloc().
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
We currently have two 'file' variables in load_kernel(), and the
outermost variable is live across the inner one. Rename the innermost
variable to 'rdfile' since it's used for initrd's.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
This seems to be required in order for i386 to boot.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Fix the memory types of EfiRuntimeServicesCode and EfiUnusableMemory
which should be E820_RESERVED and E820_UNUSABLE respectively.
Reported-by: Maarten Lankhorst <m.b.lankhorst@gmail.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
It is not safe to call Print() after ExitBootServices() because
Print() may allocate memory, which isn't allowed once the boot
services have exited. Maarten observed that calling Print() after boot
services have exited caused his machine to reboot.
Reported-by: Maarten Lankhorst <m.b.lankhorst@gmail.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Fix failure to boot because of >128 e820 entries
Signed-off-by: Maarten Lankhorst <m.b.lankhorst@gmail.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Here's a patch to accept 0:\vmlinuz initrd=0:\initrd.img and zap the
case sensitivity when looking up device paths. The device numbers
correspond to the position of the device in the efilinux -l list.
I alter 'name' in file_open, but it seems nothing else requires it
anyhow, so I didn't see a need to copy or revert it.
Signed-off-by: Maarten Lankhorst <m.b.lankhorst@gmail.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
|
Version numbers are useful for bug reports so the user knows which
version to report bugs against. Start at version 0.8 because 32-bit
support is planned for 0.9 with 1.0 being released after a thorough
round of testing.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
Cut down on the noise of 'git status' and ignore build objects.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
After we've printed the entries in the memory map we can free it.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
This function isn't used, and gnu-efi already provides
EFI_SIZE_TO_PAGES() for converting from a size in bytes to pages.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
It's all too easy to miss important warnings if they don't cause the
compiler to error. One really important warning is missing function
declarations - if the function cannot be resolved at runtime by the
EFI loader then efilinux will silently fail to load and run.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
This patch provides the necessary glue to load binary files and
transfer execution to them. Currently, we only support the Linux
kernel bzImage format but other formats should be trivial to handle
later.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
When loading a linux kernel we need to be able to allocate memory with
a strict alignment. This isn't possible with the current malloc
implementation, so provide a new emalloc() function that takes an
alignment as an argument.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
While gnu-efi provides a strlen implementation for Unicode strings, we
also need one for char *.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
Pass -D$(ARCH) to $(CFLAGS) so that we can make architecture-specific
decisions about which code fragments to include.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
efilinux expects to be called with the path of a kernel as its only
argument. If an argument is present, parse it and pass it to the
loader as the file to load and execute. If no arguments are present
display the proper syntax for calling efilinux.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
Files are managed via 'struct file', which allows us to hide the
details necessary for accessing the file via the firmware, e.g. all
the handles.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
descr_version should be UINT32, not UINTN. This obviously makes a
difference on x86-64 where UINT32 is 32-bits and UINTN is 64-bits.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
The @size argument to exit() should be the size, in bytes, of
@reason. Previously we were passing whatever value was left in 'size'
in efi_main(). We should instead be passing ERROR_STRING_LENGTH
because that is the size of the allocation holding @reason.
Also, cleanup a typo in the documentation for exit() where the
explanation of the @size argument referred to a nonexistent @data
argument.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
In the future there will be multiple call sites for this code,
e.g. whenever someone calls print_memory_map() and also when we call
exit_boot_services().
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
Being informed of all warnings is really useful, so turn this feature
on.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
Add a simple implementation of these standard library functions.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
Provide a malloc implementation with the same prototype as the
standard C library. This implementation is a wrapper around
allocate_pool() and allocates from the EfiLoaderData runtime pool.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
Explain how @memory is used when when @atype is AllocateAddress.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
We only need to allocate space for the services and system table data
structures once, so allocate space in entry.c. Currently, space will
be allocated in every object file that includes efilinux.h. What's
worse is that we only initialise the data objects allocated in entry.c
via register_table(), all other object files will operate on
uninitialised tables.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
Tell GCC that we're compiling in a freestanding environment, e.g. one
in which standard libraries do not exist and in which GCC should not
use builtin functions. This allows us to reuse some of the common
function names, such as exit(), but with our own implementation.
Turning off builtin functions also stops warnings like the following
from being emitted,
efilinux.h:187:1: warning: conflicting types for built-in function ‘exit’
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
Pass the correct member (->Hdr) of the system table to CheckCrc() and
fix the following warning,
efilinux.h: In function ‘register_table’:
efilinux.h:62:2: warning: passing argument 2 of ‘CheckCrc’ from incompatible pointer type
/usr/include/efi/efilib.h:155:1: note: expected ‘struct EFI_TABLE_HEADER *’ but argument is of type ‘struct EFI_SYSTEM_TABLE *’
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
Extract all the architecture-specific options and infer which
architecture we're building from $(CC) -dumpmachine. Currently, only
x86-64 and ia32 are supported, but it would be trivial to add ia64
support.
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|
|
This is the initial commit and we're just laying the ground work for
the project. We can produce a .efi executable for use with UEFI
firmware, but currently all that efilinux does is dump the memory map
to the console and exit.
Happy Hacking!
Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com>
|