rmodule: use program.ld for linking

Bring rmodule linking into the common linking method.
The __rmodule_entry symbol was removed while using
a more common _start symbol. The rmodtool will honor
the entry point found within the ELF header. Add
ENV_RMODULE so that one can distinguish the environment
when generating linker scripts for rmodules. Lastly,
directly use program.ld for the rmodule.ld linker script.

BUG=chrome-os-partner:44827
BRANCH=None
TEST=Built rambi and analyzed the relocatable ramstage,
     sipi_vector, and smm rmodules.

Change-Id: Iaa499eb229d8171272add9ee6d27cff75e7534ac
Signed-off-by: Aaron Durbin <adubin@chromium.org>
Reviewed-on: http://review.coreboot.org/11517
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
Aaron Durbin 2015-09-05 12:59:26 -05:00
parent e5bad5cd3d
commit dde7629e9c
14 changed files with 64 additions and 125 deletions

View File

@ -72,6 +72,9 @@ classes-y := ramstage romstage bootblock smm smmstub cpu_microcode libverstage v
# Add dynamic classes for rmodules # Add dynamic classes for rmodules
$(foreach supported_arch,$(ARCH_SUPPORTED), \ $(foreach supported_arch,$(ARCH_SUPPORTED), \
$(eval $(call define_class,rmodules_$(supported_arch),$(supported_arch)))) $(eval $(call define_class,rmodules_$(supported_arch),$(supported_arch))))
# Provide a macro to determine environment for free standing rmodules.
$(foreach supported_arch,$(ARCH_SUPPORTED), \
$(eval rmodules_$(supported_arch)-generic-ccopts += -D__RMODULE__))
####################################################################### #######################################################################
# Helper functions for math and various file placement matters. # Helper functions for math and various file placement matters.

View File

@ -17,6 +17,8 @@
* Foundation, Inc. * Foundation, Inc.
*/ */
#include <rules.h>
/* We use ELF as output format. So that we can debug the code in some form. */ /* We use ELF as output format. So that we can debug the code in some form. */
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
OUTPUT_ARCH(aarch64) OUTPUT_ARCH(aarch64)
@ -26,7 +28,13 @@ PHDRS
to_load PT_LOAD; to_load PT_LOAD;
} }
#ifdef __BOOTBLOCK__ #if ENV_BOOTBLOCK
TARGET(binary) TARGET(binary)
#endif #endif
/* secmon uses rmodules */
#if ENV_RMODULE
ENTRY(_start)
#else
ENTRY(stage_entry) ENTRY(stage_entry)
#endif

View File

@ -136,12 +136,12 @@ ENDPROC(arm64_c_environment)
2002: 2002:
.endm .endm
ENTRY(__rmodule_entry) ENTRY(_start)
split_bsp_path split_bsp_path
/* Save the arguments to secmon in x25 */ /* Save the arguments to secmon in x25 */
mov x25, x0 mov x25, x0
b arm64_c_environment b arm64_c_environment
ENDPROC(__rmodule_entry) ENDPROC(_start)
/* /*
* Setup SCTLR so that: * Setup SCTLR so that:

View File

@ -23,8 +23,6 @@ thread_stacks:
.code32 .code32
#endif #endif
.globl _start .globl _start
.globl __rmodule_entry
__rmodule_entry:
_start: _start:
cli cli
lgdt %cs:gdtaddr lgdt %cs:gdtaddr

View File

@ -24,7 +24,7 @@ PHDRS
to_load PT_LOAD; to_load PT_LOAD;
} }
#if ENV_RAMSTAGE #if ENV_RAMSTAGE || ENV_RMODULE
ENTRY(_start) ENTRY(_start)
#elif ENV_ROMSTAGE #elif ENV_ROMSTAGE
ENTRY(protected_start) ENTRY(protected_start)

View File

@ -20,9 +20,9 @@ $(SIPI_DOTO): $(dir $(SIPI_ELF))sipi_vector.rmodules_$(ARCH-ramstage-y).o
$(CC_rmodules_$(ARCH-ramstage-y)) $(CFLAGS_rmodules_$(ARCH-ramstage-y)) -nostdlib -r -o $@ $^ $(CC_rmodules_$(ARCH-ramstage-y)) $(CFLAGS_rmodules_$(ARCH-ramstage-y)) -nostdlib -r -o $@ $^
ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32),y) ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32),y)
$(eval $(call rmodule_link,$(SIPI_ELF), $(SIPI_ELF:.elf=.o), 0,x86_32)) $(eval $(call rmodule_link,$(SIPI_ELF), $(SIPI_DOTO), 0,x86_32))
else else
$(eval $(call rmodule_link,$(SIPI_ELF), $(SIPI_ELF:.elf=.o), 0,x86_64)) $(eval $(call rmodule_link,$(SIPI_ELF), $(SIPI_DOTO), 0,x86_64))
endif endif
$(SIPI_BIN): $(SIPI_RMOD) $(SIPI_BIN): $(SIPI_RMOD)

View File

@ -56,10 +56,8 @@ ap_count:
.text .text
.code16 .code16
.global ap_start .global _start
.global __rmodule_entry _start:
__rmodule_entry:
ap_start:
cli cli
xorl %eax, %eax xorl %eax, %eax
movl %eax, %cr3 /* Invalidate TLB*/ movl %eax, %cr3 /* Invalidate TLB*/
@ -74,9 +72,9 @@ ap_start:
/* The gdtaddr needs to be releative to the data segment in order /* The gdtaddr needs to be releative to the data segment in order
* to properly dereference it. The .text section comes first in an * to properly dereference it. The .text section comes first in an
* rmodule so ap_start can be used as a proxy for the load address. */ * rmodule so _start can be used as a proxy for the load address. */
movl $(gdtaddr), %ebx movl $(gdtaddr), %ebx
sub $(ap_start), %ebx sub $(_start), %ebx
data32 lgdt (%ebx) data32 lgdt (%ebx)

View File

@ -59,10 +59,8 @@ fallback_stack_top:
.text .text
.code16 .code16
.global smm_handler_start .global _start
.global __rmodule_entry _start:
__rmodule_entry:
smm_handler_start:
movl $(smm_relocate_gdt), %ebx movl $(smm_relocate_gdt), %ebx
data32 lgdt (%ebx) data32 lgdt (%ebx)

View File

@ -43,9 +43,9 @@
#define ARCH_STAGE_HAS_BSS_SECTION 1 #define ARCH_STAGE_HAS_BSS_SECTION 1
#endif #endif
/* Default is that currently ramstage and smm only has a heap. */ /* Default is that currently ramstage, smm, and rmodules have a heap. */
#ifndef ARCH_STAGE_HAS_HEAP_SECTION #ifndef ARCH_STAGE_HAS_HEAP_SECTION
#define ARCH_STAGE_HAS_HEAP_SECTION (ENV_RAMSTAGE || ENV_SMM) #define ARCH_STAGE_HAS_HEAP_SECTION (ENV_RAMSTAGE || ENV_SMM || ENV_RMODULE)
#endif #endif
#define STR(x) #x #define STR(x) #x

View File

@ -73,9 +73,9 @@ struct rmodule {
}; };
#if IS_ENABLED(CONFIG_RELOCATABLE_MODULES) #if IS_ENABLED(CONFIG_RELOCATABLE_MODULES)
/* Rmodules have an entry point of named __rmodule_entry. */ /* Rmodules have an entry point of named _start. */
#define RMODULE_ENTRY(entry_) \ #define RMODULE_ENTRY(entry_) \
void __rmodule_entry(void *) __attribute__((alias (STRINGIFY(entry_)))) void _start(void *) __attribute__((alias (STRINGIFY(entry_))))
#else #else
#define RMODULE_ENTRY(entry_) #define RMODULE_ENTRY(entry_)
#endif #endif

View File

@ -30,6 +30,7 @@
#define ENV_SMM 0 #define ENV_SMM 0
#define ENV_SECMON 0 #define ENV_SECMON 0
#define ENV_VERSTAGE 0 #define ENV_VERSTAGE 0
#define ENV_RMODULE 0
#elif defined(__ROMSTAGE__) #elif defined(__ROMSTAGE__)
#define ENV_BOOTBLOCK 0 #define ENV_BOOTBLOCK 0
@ -38,6 +39,7 @@
#define ENV_SMM 0 #define ENV_SMM 0
#define ENV_SECMON 0 #define ENV_SECMON 0
#define ENV_VERSTAGE 0 #define ENV_VERSTAGE 0
#define ENV_RMODULE 0
#elif defined(__SMM__) #elif defined(__SMM__)
#define ENV_BOOTBLOCK 0 #define ENV_BOOTBLOCK 0
@ -46,6 +48,7 @@
#define ENV_SMM 1 #define ENV_SMM 1
#define ENV_SECMON 0 #define ENV_SECMON 0
#define ENV_VERSTAGE 0 #define ENV_VERSTAGE 0
#define ENV_RMODULE 0
#elif defined(__SECMON__) #elif defined(__SECMON__)
#define ENV_BOOTBLOCK 0 #define ENV_BOOTBLOCK 0
@ -54,6 +57,7 @@
#define ENV_SMM 0 #define ENV_SMM 0
#define ENV_SECMON 1 #define ENV_SECMON 1
#define ENV_VERSTAGE 0 #define ENV_VERSTAGE 0
#define ENV_RMODULE 0
#elif defined(__VERSTAGE__) #elif defined(__VERSTAGE__)
#define ENV_BOOTBLOCK 0 #define ENV_BOOTBLOCK 0
@ -62,6 +66,7 @@
#define ENV_SMM 0 #define ENV_SMM 0
#define ENV_SECMON 0 #define ENV_SECMON 0
#define ENV_VERSTAGE 1 #define ENV_VERSTAGE 1
#define ENV_RMODULE 0
#elif defined(__RAMSTAGE__) #elif defined(__RAMSTAGE__)
#define ENV_BOOTBLOCK 0 #define ENV_BOOTBLOCK 0
@ -70,6 +75,16 @@
#define ENV_SMM 0 #define ENV_SMM 0
#define ENV_SECMON 0 #define ENV_SECMON 0
#define ENV_VERSTAGE 0 #define ENV_VERSTAGE 0
#define ENV_RMODULE 0
#elif defined(__RMODULE__)
#define ENV_BOOTBLOCK 0
#define ENV_ROMSTAGE 0
#define ENV_RAMSTAGE 0
#define ENV_SMM 0
#define ENV_SECMON 0
#define ENV_VERSTAGE 0
#define ENV_RMODULE 1
#else #else
/* /*
@ -84,6 +99,7 @@
#define ENV_SMM 0 #define ENV_SMM 0
#define ENV_SECMON 0 #define ENV_SECMON 0
#define ENV_VERSTAGE 0 #define ENV_VERSTAGE 0
#define ENV_RMODULE 0
#endif #endif
/* For romstage and ramstage always build with simple device model, ie. /* For romstage and ramstage always build with simple device model, ie.

View File

@ -38,14 +38,14 @@
*(.text); *(.text);
*(.text.*); *(.text.*);
#if ENV_RAMSTAGE || ENV_ROMSTAGE #if ENV_RAMSTAGE || ENV_ROMSTAGE || ENV_RMODULE
. = ALIGN(ARCH_POINTER_ALIGN_SIZE); . = ALIGN(ARCH_POINTER_ALIGN_SIZE);
_cbmem_init_hooks = .; _cbmem_init_hooks = .;
KEEP(*(.rodata.cbmem_init_hooks)); KEEP(*(.rodata.cbmem_init_hooks));
_ecbmem_init_hooks = .; _ecbmem_init_hooks = .;
#endif #endif
#if ENV_RAMSTAGE #if ENV_RAMSTAGE || ENV_RMODULE
. = ALIGN(ARCH_POINTER_ALIGN_SIZE); . = ALIGN(ARCH_POINTER_ALIGN_SIZE);
_pci_drivers = .; _pci_drivers = .;
KEEP(*(.rodata.pci_driver)); KEEP(*(.rodata.pci_driver));
@ -79,13 +79,20 @@
.data : { .data : {
. = ALIGN(ARCH_CACHELINE_ALIGN_SIZE); . = ALIGN(ARCH_CACHELINE_ALIGN_SIZE);
_data = .; _data = .;
#if ENV_RMODULE
_rmodule_params = .;
KEEP(*(.module_parameters));
_ermodule_params = .;
#endif
*(.data); *(.data);
*(.data.*); *(.data.*);
#ifdef __PRE_RAM__ #ifdef __PRE_RAM__
PROVIDE(_preram_cbmem_console = .); PROVIDE(_preram_cbmem_console = .);
PROVIDE(_epreram_cbmem_console = _preram_cbmem_console); PROVIDE(_epreram_cbmem_console = _preram_cbmem_console);
#elif ENV_RAMSTAGE #elif ENV_RAMSTAGE || ENV_RMODULE
. = ALIGN(ARCH_POINTER_ALIGN_SIZE); . = ALIGN(ARCH_POINTER_ALIGN_SIZE);
_bs_init_begin = .; _bs_init_begin = .;
KEEP(*(.bs_init)); KEEP(*(.bs_init));
@ -116,7 +123,7 @@
.heap : { .heap : {
. = ALIGN(ARCH_POINTER_ALIGN_SIZE); . = ALIGN(ARCH_POINTER_ALIGN_SIZE);
_heap = .; _heap = .;
. += CONFIG_HEAP_SIZE; . += (ENV_RMODULE ? __heap_size : CONFIG_HEAP_SIZE);
. = ALIGN(ARCH_POINTER_ALIGN_SIZE); . = ALIGN(ARCH_POINTER_ALIGN_SIZE);
_eheap = .; _eheap = .;
} }

View File

@ -12,103 +12,14 @@
* won't be a consistent mapping between the flat blob and the loaded program. * won't be a consistent mapping between the flat blob and the loaded program.
*/ */
BASE_ADDRESS = 0x00000; #include <memlayout.h>
#include <arch/header.ld>
ENTRY(__rmodule_entry);
SECTIONS SECTIONS
{ {
. = BASE_ADDRESS; SET_COUNTER(rmodule, 0x00000000)
.payload : { /* program.ld is directly included because there's no one particular
/* C code of the module. */ * class that rmodule is used on. */
_program = .; #include <lib/program.ld>
*(.text._start);
*(.text.stage_entry);
*(.text);
*(.text.*);
/* C read-only data. */
. = ALIGN(16);
#if IS_ENABLED(CONFIG_COVERAGE)
__CTOR_LIST__ = .;
*(.ctors);
LONG(0);
LONG(0);
__CTOR_END__ = .;
#endif
/* The driver sections are to allow linking coreboot's
* ramstage with the rmodule linker. Any changes made in
* ramstage.ld should be made here as well. */
. = ALIGN(8);
_pci_drivers = . ;
KEEP(*(.rodata.pci_driver));
_epci_drivers = . ;
. = ALIGN(8);
_cpu_drivers = . ;
KEEP(*(.rodata.cpu_driver));
_ecpu_drivers = . ;
. = ALIGN(8);
_bs_init_begin = .;
KEEP(*(.bs_init));
LONG(0);
LONG(0);
_bs_init_end = .;
_cbmem_init_hooks = .;
KEEP(*(.rodata.cbmem_init_hooks));
_ecbmem_init_hooks = .;
. = ALIGN(8);
*(.rodata);
*(.rodata.*);
. = ALIGN(8);
/* The parameters section can be used to pass parameters
* to a module, however there has to be an prior agreement
* on how to interpret the parameters. */
_module_params_begin = .;
KEEP(*(.module_parameters));
_module_params_end = .;
. = ALIGN(8);
/* Data section. */
. = ALIGN(64); /* Mirror cache line alignment from ramstage. */
_sdata = .;
*(.data);
*(.data.*);
. = ALIGN(8);
_edata = .;
. = ALIGN(8);
}
.bss (NOLOAD) : {
/* C uninitialized data of the module. */
_bss = .;
*(.bss);
*(.bss.*)
*(.sbss)
*(.sbss.*)
*(COMMON);
. = ALIGN(8);
_ebss = .;
/*
* Place the heap after BSS. The heap size is passed in by
* by way of ld --defsym=__heap_size=<>
*/
_heap = .;
. = . + __heap_size;
_eheap = .;
_eprogram = .;
}
/DISCARD/ : {
/* Drop unnecessary sections. */
*(.eh_frame);
*(.note);
*(.note.*);
}
} }

View File

@ -402,11 +402,11 @@ static int populate_program_info(struct rmod_context *ctx)
break; break;
} }
if (populate_sym(ctx, "_module_params_begin", &ctx->parameters_begin, if (populate_sym(ctx, "_rmodule_params", &ctx->parameters_begin,
nsyms, strtab)) nsyms, strtab))
return -1; return -1;
if (populate_sym(ctx, "_module_params_end", &ctx->parameters_end, if (populate_sym(ctx, "_ermodule_params", &ctx->parameters_end,
nsyms, strtab)) nsyms, strtab))
return -1; return -1;
@ -416,8 +416,8 @@ static int populate_program_info(struct rmod_context *ctx)
if (populate_sym(ctx, "_ebss", &ctx->bss_end, nsyms, strtab)) if (populate_sym(ctx, "_ebss", &ctx->bss_end, nsyms, strtab))
return -1; return -1;
if (populate_sym(ctx, "__rmodule_entry", &ctx->entry, nsyms, strtab)) /* Honor the entry point within the ELF header. */
return -1; ctx->entry = ehdr->e_entry;
/* Link address is the virtual address of the program segment. */ /* Link address is the virtual address of the program segment. */
ctx->link_addr = ctx->phdr->p_vaddr; ctx->link_addr = ctx->phdr->p_vaddr;