coreboot: introduce CONFIG_RELOCATABLE_RAMSTAGE
This patch adds an option to build the ramstage as a reloctable binary. It uses the rmodule library for the relocation. The main changes consist of the following: 1. The ramstage is loaded just under the cmbem space. 2. Payloads cannot be loaded over where ramstage is loaded. If a payload is attempted to load where the relocatable ramstage resides the load is aborted. 3. The memory occupied by the ramstage is reserved from the OS's usage using the romstage_handoff structure stored in cbmem. This region is communicated to ramstage by an CBMEM_ID_ROMSTAGE_INFO entry in cbmem. 4. There is no need to reserve cbmem space for the OS controlled memory for the resume path because the ramsage region has been reserved in #3. 5. Since no memory needs to be preserved in the wake path, the loading and begin of execution of a elf payload is straight forward. Change-Id: Ia66cf1be65c29fa25ca7bd9ea6c8f11d7eee05f5 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/2792 Reviewed-by: Ronald G. Minnich <rminnich@gmail.com> Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@google.com>
This commit is contained in:
committed by
Stefan Reinauer
parent
43e4a80a92
commit
8e4a355773
@@ -157,6 +157,12 @@ $(objcbfs)/%.elf: $(objcbfs)/%.debug
|
||||
################################################################################
|
||||
# Build the coreboot_ram (stage 2)
|
||||
|
||||
ifeq ($(CONFIG_RELOCATABLE_RAMSTAGE),y)
|
||||
|
||||
$(eval $(call rmodule_link,$(objcbfs)/coreboot_ram.debug, $(obj)/arch/x86/boot/ramstage_module_header.ramstage.o $(objgenerated)/coreboot_ram.o, $(CONFIG_HEAP_SIZE)))
|
||||
|
||||
else
|
||||
|
||||
$(objcbfs)/coreboot_ram.debug: $(objgenerated)/coreboot_ram.o $(src)/arch/x86/coreboot_ram.ld
|
||||
@printf " CC $(subst $(obj)/,,$(@))\n"
|
||||
ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
|
||||
@@ -165,6 +171,8 @@ else
|
||||
$(CC) -nostdlib -nostartfiles -static -o $@ -L$(obj) -T $(src)/arch/x86/coreboot_ram.ld $<
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
$(objgenerated)/coreboot_ram.o: $$(ramstage-objs) $(LIBGCC_FILE_NAME)
|
||||
@printf " CC $(subst $(obj)/,,$(@))\n"
|
||||
ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
|
||||
|
@@ -9,6 +9,7 @@ ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += acpi.c
|
||||
ramstage-$(CONFIG_GENERATE_SMBIOS_TABLES) += smbios.c
|
||||
ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += acpigen.c
|
||||
ramstage-$(CONFIG_HAVE_ACPI_RESUME) += wakeup.S
|
||||
ramstage-$(CONFIG_RELOCATABLE_RAMSTAGE) += ramstage_module_header.c
|
||||
|
||||
$(obj)/arch/x86/boot/coreboot_table.ramstage.o : $(OPTION_TABLE_H)
|
||||
$(obj)/arch/x86/boot/smbios.ramstage.o: $(obj)/build.h
|
||||
|
@@ -759,6 +759,9 @@ extern unsigned int __wakeup_size;
|
||||
|
||||
void acpi_jump_to_wakeup(void *vector)
|
||||
{
|
||||
#if CONFIG_RELOCATABLE_RAMSTAGE
|
||||
u32 acpi_backup_memory = 0;
|
||||
#else
|
||||
u32 acpi_backup_memory = (u32)cbmem_find(CBMEM_ID_RESUME);
|
||||
|
||||
if (!acpi_backup_memory) {
|
||||
@@ -766,6 +769,7 @@ void acpi_jump_to_wakeup(void *vector)
|
||||
"No S3 resume.\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_SMP
|
||||
// FIXME: This should go into the ACPI backup memory, too. No pork saussages.
|
||||
|
@@ -68,6 +68,34 @@ int elf_check_arch(Elf_ehdr *ehdr)
|
||||
|
||||
}
|
||||
|
||||
#if CONFIG_RELOCATABLE_RAMSTAGE
|
||||
/* When the ramstage is relocatable the elf loading ensures an elf image cannot
|
||||
* be loaded over the ramstage code. */
|
||||
void jmp_to_elf_entry(void *entry, unsigned long unused1, unsigned long unused2)
|
||||
{
|
||||
elf_boot_notes.hdr.b_checksum =
|
||||
compute_ip_checksum(&elf_boot_notes, sizeof(elf_boot_notes));
|
||||
|
||||
/* Jump to kernel */
|
||||
__asm__ __volatile__(
|
||||
" cld \n\t"
|
||||
/* Now jump to the loaded image */
|
||||
" call *%0\n\t"
|
||||
|
||||
/* The loaded image returned? */
|
||||
" cli \n\t"
|
||||
" cld \n\t"
|
||||
|
||||
::
|
||||
"r" (entry),
|
||||
#if CONFIG_MULTIBOOT
|
||||
"b"(mbi), "a" (MB_MAGIC2)
|
||||
#else
|
||||
"b"(&elf_boot_notes), "a" (0x0E1FB007)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
#else
|
||||
void jmp_to_elf_entry(void *entry, unsigned long buffer, unsigned long size)
|
||||
{
|
||||
extern unsigned char _ram_seg, _eram_seg;
|
||||
@@ -182,5 +210,6 @@ void jmp_to_elf_entry(void *entry, unsigned long buffer, unsigned long size)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
#endif /* CONFIG_RELOCATABLE_RAMSTAGE */
|
||||
|
||||
|
||||
|
24
src/arch/x86/boot/ramstage_module_header.c
Normal file
24
src/arch/x86/boot/ramstage_module_header.c
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2013 ChromeOS Authors
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <rmodule.h>
|
||||
|
||||
extern char _start[];
|
||||
|
||||
DEFINE_RMODULE_HEADER(ramstage_module, _start, RMODULE_TYPE_STAGE);
|
@@ -232,11 +232,14 @@ struct lb_memory *write_tables(void)
|
||||
post_code(0x9e);
|
||||
|
||||
#if CONFIG_HAVE_ACPI_RESUME
|
||||
/* Only add CBMEM_ID_RESUME when the ramstage isn't relocatable. */
|
||||
#if !CONFIG_RELOCATABLE_RAMSTAGE
|
||||
/* Let's prepare the ACPI S3 Resume area now already, so we can rely on
|
||||
* it begin there during reboot time. We don't need the pointer, nor
|
||||
* the result right now. If it fails, ACPI resume will be disabled.
|
||||
*/
|
||||
cbmem_add(CBMEM_ID_RESUME, HIGH_MEMORY_SAVE);
|
||||
#endif
|
||||
#if CONFIG_NORTHBRIDGE_AMD_AGESA_FAMILY14 || CONFIG_NORTHBRIDGE_AMD_AGESA_FAMILY15_TN
|
||||
cbmem_add(CBMEM_ID_RESUME_SCRATCH, CONFIG_HIGH_SCRATCH_MEMORY_SIZE);
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user