mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-30 02:20:48 +00:00
Some platforms might expect the header of the image to be a certain
platform specific blob. This patch adds an ability to insert an
arbitrary size header in the binary blob, if so desired, the intention
is to have the platform specific tools to postprocess the image and
replace the header with sensible data.
Ideally we should be able to produce an image which is mapped to start
at an offset to the FLASH_BASE, but the macros in ec.S.lds files are
way too smart for this.
BRANCH=none
BUG=chrome-os-partner:43025
TEST=with this and other changes the latest cr50 image gets signed and
booted properly.
Change-Id: Icabf00c6b90657b0ae3370ddad3567ccedf3ff49
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/295200
Reviewed-by: Shawn N <shawnn@chromium.org>
331 lines
8.8 KiB
ArmAsm
331 lines
8.8 KiB
ArmAsm
/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
#include "config.h"
|
|
#include "rsa.h"
|
|
|
|
#define FW_MEM_OFF_(section) CONFIG_##section##_MEM_OFF
|
|
#define FW_MEM_OFF(section) (FW_MEM_OFF_(section))
|
|
#define FW_OFF(section) (CONFIG_FLASH_BASE + FW_MEM_OFF(section))
|
|
|
|
#define FW_SIZE_(section) CONFIG_##section##_SIZE
|
|
#define FW_SIZE(section) FW_SIZE_(section)
|
|
|
|
|
|
OUTPUT_FORMAT(BFD_FORMAT, BFD_FORMAT, BFD_FORMAT)
|
|
OUTPUT_ARCH(BFD_ARCH)
|
|
ENTRY(reset)
|
|
MEMORY
|
|
{
|
|
#if defined(SECTION_IS_RO) && defined(NPCX_RO_HEADER)
|
|
/*
|
|
* Header structure used by npcx booter in RO region.
|
|
* Please notice the location of header must be in front of FW
|
|
* which needs copy. But header itself won't be copied to code ram
|
|
* by booter.
|
|
*/
|
|
FLASH_HDR (rx) : ORIGIN = FW_OFF(RO_HDR), LENGTH = FW_SIZE(RO_HDR)
|
|
#endif
|
|
#ifdef CONFIG_SHAREDLIB
|
|
SHARED_LIB (rx) : ORIGIN = FW_OFF(SHAREDLIB), LENGTH = FW_SIZE_(SHAREDLIB)
|
|
#endif
|
|
FLASH (rx) : ORIGIN = FW_OFF(SECTION), LENGTH = FW_SIZE(SECTION)
|
|
IRAM (rw) : ORIGIN = CONFIG_RAM_BASE, LENGTH = CONFIG_RAM_SIZE
|
|
#ifdef CONFIG_CODERAM_ARCH
|
|
#ifdef CONFIG_FLASH_MAPPED
|
|
/* Geometry constants have non-standard meaning for npcx */
|
|
CDRAM (rx) : \
|
|
ORIGIN = CONFIG_CDRAM_BASE, \
|
|
LENGTH = CONFIG_CDRAM_SIZE
|
|
#else /* CONFIG_FLASH_MAPPED */
|
|
CDRAM (rx) : \
|
|
ORIGIN = CONFIG_CDRAM_BASE + FW_MEM_OFF(SECTION), \
|
|
LENGTH = FW_SIZE(SECTION)
|
|
#endif /* CONFIG_FLASH_MAPPED */
|
|
#endif /* CONFIG_CODERAM_ARCH */
|
|
#ifdef RSA_PUBLIC_KEY_SIZE
|
|
PSTATE(r) : \
|
|
ORIGIN = FW_OFF(SECTION) + FW_SIZE(SECTION), \
|
|
LENGTH = CONFIG_FW_PSTATE_SIZE
|
|
#endif
|
|
#ifdef CONFIG_USB_RAM_SIZE
|
|
USB_RAM (rw) : \
|
|
ORIGIN = CONFIG_USB_RAM_BASE, \
|
|
LENGTH = CONFIG_USB_RAM_SIZE * CONFIG_USB_RAM_ACCESS_SIZE / 2
|
|
#endif
|
|
}
|
|
SECTIONS
|
|
{
|
|
#if defined(SECTION_IS_RO) && defined(NPCX_RO_HEADER)
|
|
.header : {
|
|
KEEP(*(.header))
|
|
} > FLASH_HDR
|
|
#endif
|
|
#ifdef CONFIG_SHAREDLIB
|
|
.roshared : {
|
|
KEEP(*(.roshared*))
|
|
} > SHARED_LIB
|
|
#endif
|
|
.text : {
|
|
#if defined(CONFIG_RO_HEAD_ROOM)
|
|
. = . + CONFIG_RO_HEAD_ROOM;
|
|
#endif
|
|
OUTDIR/core/CORE/init.o (.text.vecttable)
|
|
. = ALIGN(4);
|
|
__version_struct_offset = .;
|
|
KEEP(*(.rodata.ver))
|
|
|
|
. = ALIGN(4);
|
|
KEEP(*(.rodata.pstate))
|
|
|
|
#ifdef SHIFT_CODE_FOR_TEST
|
|
. = ALIGN(256);
|
|
#else
|
|
. = ALIGN(4);
|
|
#endif
|
|
OUTDIR/core/CORE/init.o (.text)
|
|
*(.text*)
|
|
#ifdef CONFIG_CODERAM_ARCH
|
|
__flash_lpfw_start = .;
|
|
/* Entering deep idle FW for better power consumption */
|
|
KEEP(*(.lowpower_ram))
|
|
__flash_lpfw_end = .;
|
|
} > CDRAM AT > FLASH
|
|
#else
|
|
#ifdef COMPILE_FOR_RAM
|
|
} > IRAM
|
|
#else
|
|
} > FLASH
|
|
#endif
|
|
#endif
|
|
. = ALIGN(4);
|
|
.rodata : {
|
|
/* Symbols defined here are declared in link_defs.h */
|
|
__irqprio = .;
|
|
KEEP(*(.rodata.irqprio))
|
|
__irqprio_end = .;
|
|
|
|
. = ALIGN(4);
|
|
__cmds = .;
|
|
KEEP(*(SORT(.rodata.cmds*)))
|
|
__cmds_end = .;
|
|
|
|
. = ALIGN(4);
|
|
__hcmds = .;
|
|
KEEP(*(.rodata.hcmds))
|
|
__hcmds_end = .;
|
|
|
|
. = ALIGN(4);
|
|
__mkbp_evt_srcs = .;
|
|
KEEP(*(.rodata.evtsrcs))
|
|
__mkbp_evt_srcs_end = .;
|
|
|
|
. = ALIGN(4);
|
|
__hooks_init = .;
|
|
KEEP(*(.rodata.HOOK_INIT))
|
|
__hooks_init_end = .;
|
|
|
|
__hooks_pre_freq_change = .;
|
|
KEEP(*(.rodata.HOOK_PRE_FREQ_CHANGE))
|
|
__hooks_pre_freq_change_end = .;
|
|
|
|
__hooks_freq_change = .;
|
|
KEEP(*(.rodata.HOOK_FREQ_CHANGE))
|
|
__hooks_freq_change_end = .;
|
|
|
|
__hooks_sysjump = .;
|
|
KEEP(*(.rodata.HOOK_SYSJUMP))
|
|
__hooks_sysjump_end = .;
|
|
|
|
__hooks_chipset_pre_init = .;
|
|
KEEP(*(.rodata.HOOK_CHIPSET_PRE_INIT))
|
|
__hooks_chipset_pre_init_end = .;
|
|
|
|
__hooks_chipset_startup = .;
|
|
KEEP(*(.rodata.HOOK_CHIPSET_STARTUP))
|
|
__hooks_chipset_startup_end = .;
|
|
|
|
__hooks_chipset_resume = .;
|
|
KEEP(*(.rodata.HOOK_CHIPSET_RESUME))
|
|
__hooks_chipset_resume_end = .;
|
|
|
|
__hooks_chipset_suspend = .;
|
|
KEEP(*(.rodata.HOOK_CHIPSET_SUSPEND))
|
|
__hooks_chipset_suspend_end = .;
|
|
|
|
__hooks_chipset_shutdown = .;
|
|
KEEP(*(.rodata.HOOK_CHIPSET_SHUTDOWN))
|
|
__hooks_chipset_shutdown_end = .;
|
|
|
|
__hooks_ac_change = .;
|
|
KEEP(*(.rodata.HOOK_AC_CHANGE))
|
|
__hooks_ac_change_end = .;
|
|
|
|
__hooks_lid_change = .;
|
|
KEEP(*(.rodata.HOOK_LID_CHANGE))
|
|
__hooks_lid_change_end = .;
|
|
|
|
__hooks_pwrbtn_change = .;
|
|
KEEP(*(.rodata.HOOK_POWER_BUTTON_CHANGE))
|
|
__hooks_pwrbtn_change_end = .;
|
|
|
|
__hooks_charge_state_change = .;
|
|
KEEP(*(.rodata.HOOK_CHARGE_STATE_CHANGE))
|
|
__hooks_charge_state_change_end = .;
|
|
|
|
__hooks_battery_soc_change = .;
|
|
KEEP(*(.rodata.HOOK_BATTERY_SOC_CHANGE))
|
|
__hooks_battery_soc_change_end = .;
|
|
|
|
__hooks_tick = .;
|
|
KEEP(*(.rodata.HOOK_TICK))
|
|
__hooks_tick_end = .;
|
|
|
|
__hooks_second = .;
|
|
KEEP(*(.rodata.HOOK_SECOND))
|
|
__hooks_second_end = .;
|
|
|
|
__deferred_funcs = .;
|
|
KEEP(*(.rodata.deferred))
|
|
__deferred_funcs_end = .;
|
|
|
|
__usb_desc = .;
|
|
KEEP(*(.rodata.usb_desc_conf))
|
|
KEEP(*(SORT(.rodata.usb_desc*)))
|
|
__usb_desc_end = .;
|
|
. = ALIGN(4);
|
|
KEEP(*(.rodata.usb_ep))
|
|
|
|
. = ALIGN(4);
|
|
*(.rodata*)
|
|
|
|
#if defined(SECTION_IS_RO) && defined(CONFIG_FLASH)
|
|
. = ALIGN(64);
|
|
KEEP(*(.google))
|
|
#endif
|
|
. = ALIGN(4);
|
|
#ifdef CONFIG_CODERAM_ARCH
|
|
} > CDRAM AT > FLASH
|
|
#else
|
|
#ifdef COMPILE_FOR_RAM
|
|
} > IRAM
|
|
#else
|
|
} > FLASH
|
|
#endif
|
|
#endif
|
|
__ro_end = . ;
|
|
|
|
__deferred_funcs_count =
|
|
(__deferred_funcs_end - __deferred_funcs) / 4;
|
|
ASSERT(__deferred_funcs_count <= DEFERRABLE_MAX_COUNT,
|
|
"Increase DEFERRABLE_MAX_COUNT")
|
|
|
|
.bss : {
|
|
/*
|
|
* Align to 512 bytes. This is convenient when some memory block
|
|
* need big alignment. When COMPILE_FOR_RAM is not set, this is the
|
|
* beginning of the RAM, so there is usually no penalty on aligning
|
|
* this.
|
|
*/
|
|
. = ALIGN(512);
|
|
__bss_start = .;
|
|
*(.bss.big_align)
|
|
/* Stacks must be 64-bit aligned */
|
|
. = ALIGN(8);
|
|
*(.bss.system_stack)
|
|
/* Rest of .bss takes care of its own alignment */
|
|
*(.bss)
|
|
. = ALIGN(4);
|
|
__bss_end = .;
|
|
} > IRAM
|
|
#ifdef COMPILE_FOR_RAM
|
|
.data : {
|
|
#else
|
|
#ifdef CONFIG_CODERAM_ARCH
|
|
.data : AT(LOADADDR(.rodata) + SIZEOF(.rodata)) {
|
|
#else
|
|
.data : AT(ADDR(.rodata) + SIZEOF(.rodata)) {
|
|
#endif
|
|
#endif
|
|
. = ALIGN(4);
|
|
__data_start = .;
|
|
*(.data.tasks)
|
|
*(.data)
|
|
#ifdef CONFIG_MPU
|
|
/* It has to be aligned by 32 bytes to be a valid MPU region. */
|
|
. = ALIGN(32);
|
|
__iram_text_start = .;
|
|
#else
|
|
. = ALIGN(4);
|
|
#endif
|
|
*(.iram.text)
|
|
#ifdef CONFIG_MPU
|
|
. = ALIGN(32);
|
|
__iram_text_end = .;
|
|
#else
|
|
. = ALIGN(4);
|
|
#endif
|
|
__data_end = .;
|
|
|
|
/* Shared memory buffer must be at the end of preallocated RAM, so it
|
|
* can expand to use all the remaining RAM. */
|
|
__shared_mem_buf = .;
|
|
|
|
/* Tag at end of firmware image so that we can find the image size.
|
|
* This may be overwritten by the shared memory buffer; that's ok
|
|
* because we only use it to find the image size in flash. */
|
|
. = ALIGN(4);
|
|
BYTE(0x45);
|
|
BYTE(0x4e);
|
|
BYTE(0x44);
|
|
BYTE(0xea);
|
|
/* NOTHING MAY GO AFTER THIS! */
|
|
} > IRAM
|
|
|
|
#ifdef RSA_PUBLIC_KEY_SIZE
|
|
#ifdef SECTION_IS_RO
|
|
.flash_suffix : {
|
|
FILL(0xff);
|
|
/*
|
|
* Put the public key coefficients at the end of the partition
|
|
* after the pstate bits.
|
|
*/
|
|
. = ORIGIN(PSTATE) + LENGTH(PSTATE) - RSA_PUBLIC_KEY_SIZE;
|
|
*(.rsa_pubkey)
|
|
} > PSTATE
|
|
#else /* RW section: we don't need the RSA public key, put it anywhere */
|
|
.flash_suffix : AT(LOADADDR(.data) + SIZEOF(.data)) {
|
|
*(.rsa_pubkey)
|
|
} > FLASH
|
|
#endif
|
|
#endif
|
|
|
|
/* The linker won't notice if the .data section is too big to fit,
|
|
* apparently because we're sending it into IRAM, not FLASH. The following
|
|
* symbol isn't used by the code, but running "objdump -t *.elf | grep hey"
|
|
* will let us check how much flash space we're actually using. The
|
|
* explicit ASSERT afterwards will cause the linker to abort if we use too
|
|
* much. */
|
|
__hey_flash_used = LOADADDR(.data) + SIZEOF(.data) - FW_OFF(SECTION);
|
|
ASSERT(FW_SIZE(SECTION) >=
|
|
(LOADADDR(.data) + SIZEOF(.data) - FW_OFF(SECTION)),
|
|
"No room left in the flash")
|
|
|
|
#ifdef CONFIG_USB_RAM_SIZE
|
|
.usb_ram (NOLOAD) : {
|
|
__usb_ram_start = .;
|
|
. = ALIGN(8);
|
|
*(.usb_ram.btable)
|
|
*(.usb_ram.data)
|
|
} > USB_RAM
|
|
#endif
|
|
#if !(defined(SECTION_IS_RO) && defined(CONFIG_FLASH))
|
|
/DISCARD/ : {
|
|
*(.google)
|
|
}
|
|
#endif
|
|
|
|
/DISCARD/ : { *(.ARM.*) }
|
|
}
|