x86: 32-bit: set _image_text_start properly

Strictly speaking, should bee a virtual, not physical address.

Signed-off-by: Andrew Boie <aab045b28152628be6af0e556050d0381fd0a34d@intel.com>

/*
 * Copyright (c) 2013-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief Common linker sections
 *
 * This script defines the memory location of the various sections that make up
 * a Zephyr Kernel image. This file is used by the linker.
 *
 * This script places the various sections of the image according to what
 * features are enabled by the kernel's configuration options.
 *
 * For a build that does not use the execute in place (XIP) feature, the script
 * generates an image suitable for loading into and executing from RAMABLE_REGION by
 * placing all the sections adjacent to each other.  There is also no separate
 * load address for the DATA section which means it doesn't have to be copied
 * into RAMABLE_REGION.
 *
 * For builds using XIP, there is a different load memory address (LMA) and
 * virtual memory address (VMA) for the DATA section.  In this case the DATA
 * section is copied into RAMABLE_REGION at runtime.
 *
 * When building an XIP image the data section is placed into ROMABLE_REGION.  In this
 * case, the LMA is set to __data_rom_start so the data section is concatenated
 * at the end of the RODATA section.  At runtime, the DATA section is copied
 * into the RAMABLE_REGION region so it can be accessed with read and write permission.
 *
 * Most symbols defined in the sections below are subject to be referenced in
 * the Zephyr Kernel image. If a symbol is used but not defined the linker will
 * emit an undefined symbol error.
 *
 * Please do not change the order of the section as the kernel expects this
 * order when programming the MMU.
 */

#include <linker/linker-defs.h>
#include <offsets.h>
#include <sys/util.h>

#include <linker/linker-tool.h>

#ifdef CONFIG_XIP
	#define ROMABLE_REGION ROM
	#define RAMABLE_REGION RAM
#else
	#define ROMABLE_REGION RAM
	#define RAMABLE_REGION RAM
#endif

/* Used to align areas with separate memory permission characteristics
 * so that the page permissions can be set in the MMU. Without this,
 * the kernel is just one blob with the same RWX permissions on all RAM
 */
#ifdef CONFIG_SRAM_REGION_PERMISSIONS
	#define MMU_PAGE_ALIGN	. = ALIGN(CONFIG_MMU_PAGE_SIZE);
#else
	#define MMU_PAGE_ALIGN
#endif

ENTRY(CONFIG_KERNEL_ENTRY)

/* SECTIONS definitions */
SECTIONS
	{

#include <linker/rel-sections.ld>

    /DISCARD/ :
	{
	*(.plt)
	}

    /DISCARD/ :
	{
	*(.iplt)
	}

	GROUP_START(ROMABLE_REGION)

	. = ALIGN(8);

#ifdef CONFIG_XIP
	_image_rom_start = PHYS_LOAD_ADDR;
#endif
	SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
	{
	_image_text_start = .;

/* Located in generated directory. This file is populated by calling
 * zephyr_linker_sources(ROM_START ...). This typically contains the vector
 * table and debug information.
 */
#include <snippets-rom-start.ld>

	*(.text_start)
	*(".text_start.*")
	*(.text)
	*(".text.*")
	*(.gnu.linkonce.t.*)
	*(.eh_frame_hdr)
	*(.eh_frame)
	*(.init)
	*(.fini)
	*(.eini)
	KEEP(*(.openocd_dbg))
	KEEP(*(".openocd_dbg.*"))

#include <linker/kobject-text.ld>

	MMU_PAGE_ALIGN
	} GROUP_LINK_IN(ROMABLE_REGION)

	_image_text_end = .;
	_image_text_size = _image_text_end - _image_text_start;
	_image_rodata_start = .;

#include <linker/common-rom.ld>

	SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
	{
	*(.rodata)
	*(".rodata.*")
	*(.gnu.linkonce.r.*)

#ifdef CONFIG_X86_MMU
	. = ALIGN(4);
	_mmu_region_list_start = .;
	KEEP(*("._mmu_region.static.*"))
	_mmu_region_list_end = .;
#endif /* CONFIG_X86_MMU */

#ifndef CONFIG_DYNAMIC_INTERRUPTS
	. = ALIGN(8);
	_idt_base_address = .;
#ifdef LINKER_PASS2
	KEEP(*(staticIdt))
#else
	. += CONFIG_IDT_NUM_VECTORS * 8;
#endif /* LINKER_PASS2 */

	. = ALIGN(4);
	_irq_to_interrupt_vector = .;
#ifdef LINKER_PASS2
	KEEP(*(irq_int_vector_map))
#else
	. += CONFIG_MAX_IRQ_LINES;
#endif
#endif /* CONFIG_DYNAMIC_INTERRUPTS */

/* Located in generated directory. This file is populated by the
 * zephyr_linker_sources() Cmake function.
 */
#include <snippets-rodata.ld>

#include <linker/kobject-rom.ld>
	} GROUP_LINK_IN(ROMABLE_REGION)

#include <linker/cplusplus-rom.ld>

	MMU_PAGE_ALIGN
	/* ROM ends here, position counter will now be in RAM areas */
#ifdef CONFIG_XIP
	_image_rom_end = .;
	_image_rom_size = _image_rom_end - _image_rom_start;
#endif
	_image_rodata_end = .;
	_image_rodata_size = _image_rodata_end - _image_rodata_start;
	GROUP_END(ROMABLE_REGION)
	/*
	 * Needed for dynamic linking which we do not have, do discard
	 */
	/DISCARD/ : {
		*(.got.plt)
		*(.igot.plt)
		*(.got)
		*(.igot)
	}
	/* RAMABLE_REGION */
	GROUP_START(RAMABLE_REGION)

/* Located in generated directory. This file is populated by the
 * zephyr_linker_sources() Cmake function.
 */
#include <snippets-ram-sections.ld>

#ifdef CONFIG_USERSPACE
	/* APP SHARED MEMORY REGION */
#define SMEM_PARTITION_ALIGN(size) MMU_PAGE_ALIGN
#define APP_SHARED_ALIGN  MMU_PAGE_ALIGN

#include <app_smem.ld>

	_image_ram_start = _app_smem_start;
	_app_smem_size = _app_smem_end - _app_smem_start;
	_app_smem_num_words = _app_smem_size >> 2;
	_app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME);
	_app_smem_num_words = _app_smem_size >> 2;
#endif /* CONFIG_USERSPACE */

	SECTION_PROLOGUE(_BSS_SECTION_NAME, (NOLOAD),)
	{
	MMU_PAGE_ALIGN
#if !defined(CONFIG_USERSPACE)
	_image_ram_start = .;
#endif
	/*
	 * For performance, BSS section is forced to be both 4 byte aligned and
	 * a multiple of 4 bytes.
	 */
	. = ALIGN(4);
	__kernel_ram_start = .;
	__bss_start = .;

	*(.bss)
	*(".bss.*")
	*(COMMON)
	*(".kernel_bss.*")

	/*
	 * As memory is cleared in words only, it is simpler to ensure the BSS
	 * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
	 */
	. = ALIGN(4);
	__bss_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)

	__bss_num_words	= (__bss_end - __bss_start) >> 2;

#include <linker/common-noinit.ld>

	MMU_PAGE_ALIGN

	SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
	{

	__data_ram_start = .;

	*(.data)
	*(".data.*")
	*(".kernel.*")

#ifdef CONFIG_DYNAMIC_INTERRUPTS
	. = ALIGN(4);
	_irq_to_interrupt_vector = .;
#ifdef LINKER_PASS2
	KEEP(*(irq_int_vector_map))
#else
	. += CONFIG_MAX_IRQ_LINES;
#endif /* LINKER_PASS2 */

	z_interrupt_vectors_allocated = .;
#ifdef LINKER_PASS2
	KEEP(*(irq_vectors_alloc))
#else
	. += (CONFIG_IDT_NUM_VECTORS + 7) / 8;
#endif /* LINKER_PASS2 */
#endif /* CONFIG_DYNAMIC_INTERRUPTS */

/* Located in generated directory. This file is populated by the
 * zephyr_linker_sources() Cmake function.
 */
#include <snippets-rwdata.ld>

#ifdef CONFIG_X86_KPTI
	MMU_PAGE_ALIGN
	z_shared_kernel_page_start = .;
	/* Special page containing supervisor data that is still mapped in
	 * user mode page tables. IDT, GDT, TSSes, trampoline stack, and
	 * any LDT must go here as they always must live in a page that is
	 * marked 'present'. Still not directly user accessible, but
	 * no sensitive data should be here as Meltdown exploits may read it.
	 */
#endif /* CONFIG_X86_KPTI */

#ifdef CONFIG_DYNAMIC_INTERRUPTS
	. = ALIGN(8);
	_idt_base_address = .;
#ifdef LINKER_PASS2
	KEEP(*(staticIdt))
#else
	. += CONFIG_IDT_NUM_VECTORS * 8;
#endif /* LINKER_PASS2 */
#endif /* CONFIG_DYNAMIC_INTERRUPTS */

#ifdef CONFIG_GDT_DYNAMIC
	KEEP(*(.tss))
	. = ALIGN(8);
	_gdt = .;
#ifdef LINKER_PASS2
	KEEP(*(gdt))
#else /* LINKER_PASS2 */

#ifdef CONFIG_USERSPACE
    #define GDT_NUM_ENTRIES 7
#elif defined(CONFIG_HW_STACK_PROTECTION)
    #define GDT_NUM_ENTRIES 5
#else
    #define GDT_NUM_ENTRIES 3
#endif /* CONFIG_X86_USERSPACE */
	. += GDT_NUM_ENTRIES * 8;
#endif /* LINKER_PASS2 */
#endif /* CONFIG_GDT_DYNAMIC */

#ifdef CONFIG_X86_KPTI
	z_trampoline_stack_start = .;
	MMU_PAGE_ALIGN
	z_trampoline_stack_end = .;
	z_shared_kernel_page_end = .;

	ASSERT(z_trampoline_stack_end - z_trampoline_stack_start >= 40,
		"trampoline stack too small");
	ASSERT(z_shared_kernel_page_end - z_shared_kernel_page_start == 4096,
	       "shared kernel area is not one memory page");
#endif /* CONFIG_X86_KPTI */

	. = ALIGN(4);
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	__data_rom_start = LOADADDR(_DATA_SECTION_NAME);

#include <linker/common-ram.ld>
#include <linker/cplusplus-ram.ld>
#include <arch/x86/pagetables.ld>

/* Must be last in RAM */
#include <linker/kobject.ld>

	MMU_PAGE_ALIGN
	__data_ram_end = .;

	/* All unused memory also owned by the kernel for heaps */
	__kernel_ram_end = KERNEL_BASE_ADDR + KERNEL_RAM_SIZE;
	__kernel_ram_size = __kernel_ram_end - __kernel_ram_start;

	_image_ram_end = .;
	_image_ram_all = (KERNEL_BASE_ADDR + KERNEL_RAM_SIZE) - _image_ram_start;

	_end = .; /* end of image */

	GROUP_END(RAMABLE_REGION)

#ifndef LINKER_PASS2
	/* static interrupts */
	SECTION_PROLOGUE(intList,,)
	{
	KEEP(*(.spurIsr))
	KEEP(*(.spurNoErrIsr))
	KEEP(*(.intList))
	KEEP(*(.gnu.linkonce.intList.*))
	} > IDT_LIST
#else
	/DISCARD/ :
	{
	KEEP(*(.spurIsr))
	KEEP(*(.spurNoErrIsr))
	KEEP(*(.intList))
	KEEP(*(.gnu.linkonce.intList.*))
	}
#endif

/* Located in generated directory. This file is populated by the
 * zephyr_linker_sources() Cmake function.
 */
#include <snippets-sections.ld>

#include <linker/debug-sections.ld>

	/DISCARD/ : { *(.note.GNU-stack) }

	}

#ifdef CONFIG_XIP
/*
 * Round up number of words for DATA section to ensure that XIP copies the
 * entire data section. XIP copy is done in words only, so there may be up
 * to 3 extra bytes copied in next section (BSS). At run time, the XIP copy
 * is done first followed by clearing the BSS section.
 */
__data_size = (__data_ram_end - __data_ram_start);
__data_num_words = (__data_size + 3) >> 2;
#endif

/*
 * Copyright (c) 2013-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief Common linker sections
 *
 * This script defines the memory location of the various sections that make up
 * a Zephyr Kernel image. This file is used by the linker.
 *
 * This script places the various sections of the image according to what
 * features are enabled by the kernel's configuration options.
 *
 * For a build that does not use the execute in place (XIP) feature, the script
 * generates an image suitable for loading into and executing from RAMABLE_REGION by
 * placing all the sections adjacent to each other.  There is also no separate
 * load address for the DATA section which means it doesn't have to be copied
 * into RAMABLE_REGION.
 *
 * For builds using XIP, there is a different load memory address (LMA) and
 * virtual memory address (VMA) for the DATA section.  In this case the DATA
 * section is copied into RAMABLE_REGION at runtime.
 *
 * When building an XIP image the data section is placed into ROMABLE_REGION.  In this
 * case, the LMA is set to __data_rom_start so the data section is concatenated
 * at the end of the RODATA section.  At runtime, the DATA section is copied
 * into the RAMABLE_REGION region so it can be accessed with read and write permission.
 *
 * Most symbols defined in the sections below are subject to be referenced in
 * the Zephyr Kernel image. If a symbol is used but not defined the linker will
 * emit an undefined symbol error.
 *
 * Please do not change the order of the section as the kernel expects this
 * order when programming the MMU.
 */

#include <linker/linker-defs.h>
#include <offsets.h>
#include <sys/util.h>

#include <linker/linker-tool.h>

#ifdef CONFIG_XIP
	#define ROMABLE_REGION ROM
	#define RAMABLE_REGION RAM
#else
	#define ROMABLE_REGION RAM
	#define RAMABLE_REGION RAM
#endif

/* Used to align areas with separate memory permission characteristics
 * so that the page permissions can be set in the MMU. Without this,
 * the kernel is just one blob with the same RWX permissions on all RAM
 */
#ifdef CONFIG_SRAM_REGION_PERMISSIONS
	#define MMU_PAGE_ALIGN	. = ALIGN(CONFIG_MMU_PAGE_SIZE);
#else
	#define MMU_PAGE_ALIGN
#endif

ENTRY(CONFIG_KERNEL_ENTRY)

/* SECTIONS definitions */
SECTIONS
	{

#include <linker/rel-sections.ld>

    /DISCARD/ :
	{
	*(.plt)
	}

    /DISCARD/ :
	{
	*(.iplt)
	}

	GROUP_START(ROMABLE_REGION)

	. = ALIGN(8);

#ifdef CONFIG_XIP
	_image_rom_start = PHYS_LOAD_ADDR;
#endif
	_image_text_start = PHYS_LOAD_ADDR;
	SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
	{

/* Located in generated directory. This file is populated by calling
 * zephyr_linker_sources(ROM_START ...). This typically contains the vector
 * table and debug information.
 */
#include <snippets-rom-start.ld>

	*(.text_start)
	*(".text_start.*")
	*(.text)
	*(".text.*")
	*(.gnu.linkonce.t.*)
	*(.eh_frame_hdr)
	*(.eh_frame)
	*(.init)
	*(.fini)
	*(.eini)
	KEEP(*(.openocd_dbg))
	KEEP(*(".openocd_dbg.*"))

#include <linker/kobject-text.ld>

	MMU_PAGE_ALIGN
	} GROUP_LINK_IN(ROMABLE_REGION)

	_image_text_end = .;
	_image_text_size = _image_text_end - _image_text_start;
	_image_rodata_start = .;

#include <linker/common-rom.ld>

	SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
	{
	*(.rodata)
	*(".rodata.*")
	*(.gnu.linkonce.r.*)

#ifdef CONFIG_X86_MMU
	. = ALIGN(4);
	_mmu_region_list_start = .;
	KEEP(*("._mmu_region.static.*"))
	_mmu_region_list_end = .;
#endif /* CONFIG_X86_MMU */

#ifndef CONFIG_DYNAMIC_INTERRUPTS
	. = ALIGN(8);
	_idt_base_address = .;
#ifdef LINKER_PASS2
	KEEP(*(staticIdt))
#else
	. += CONFIG_IDT_NUM_VECTORS * 8;
#endif /* LINKER_PASS2 */

	. = ALIGN(4);
	_irq_to_interrupt_vector = .;
#ifdef LINKER_PASS2
	KEEP(*(irq_int_vector_map))
#else
	. += CONFIG_MAX_IRQ_LINES;
#endif
#endif /* CONFIG_DYNAMIC_INTERRUPTS */

/* Located in generated directory. This file is populated by the
 * zephyr_linker_sources() Cmake function.
 */
#include <snippets-rodata.ld>

#include <linker/kobject-rom.ld>
	} GROUP_LINK_IN(ROMABLE_REGION)

#include <linker/cplusplus-rom.ld>

	MMU_PAGE_ALIGN
	/* ROM ends here, position counter will now be in RAM areas */
#ifdef CONFIG_XIP
	_image_rom_end = .;
	_image_rom_size = _image_rom_end - _image_rom_start;
#endif
	_image_rodata_end = .;
	_image_rodata_size = _image_rodata_end - _image_rodata_start;
	GROUP_END(ROMABLE_REGION)
	/*
	 * Needed for dynamic linking which we do not have, do discard
	 */
	/DISCARD/ : {
		*(.got.plt)
		*(.igot.plt)
		*(.got)
		*(.igot)
	}
	/* RAMABLE_REGION */
	GROUP_START(RAMABLE_REGION)

/* Located in generated directory. This file is populated by the
 * zephyr_linker_sources() Cmake function.
 */
#include <snippets-ram-sections.ld>

#ifdef CONFIG_USERSPACE
	/* APP SHARED MEMORY REGION */
#define SMEM_PARTITION_ALIGN(size) MMU_PAGE_ALIGN
#define APP_SHARED_ALIGN  MMU_PAGE_ALIGN

#include <app_smem.ld>

	_image_ram_start = _app_smem_start;
	_app_smem_size = _app_smem_end - _app_smem_start;
	_app_smem_num_words = _app_smem_size >> 2;
	_app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME);
	_app_smem_num_words = _app_smem_size >> 2;
#endif /* CONFIG_USERSPACE */

	SECTION_PROLOGUE(_BSS_SECTION_NAME, (NOLOAD),)
	{
	MMU_PAGE_ALIGN
#if !defined(CONFIG_USERSPACE)
	_image_ram_start = .;
#endif
	/*
	 * For performance, BSS section is forced to be both 4 byte aligned and
	 * a multiple of 4 bytes.
	 */
	. = ALIGN(4);
	__kernel_ram_start = .;
	__bss_start = .;

	*(.bss)
	*(".bss.*")
	*(COMMON)
	*(".kernel_bss.*")

	/*
	 * As memory is cleared in words only, it is simpler to ensure the BSS
	 * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
	 */
	. = ALIGN(4);
	__bss_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)

	__bss_num_words	= (__bss_end - __bss_start) >> 2;

#include <linker/common-noinit.ld>

	MMU_PAGE_ALIGN

	SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
	{

	__data_ram_start = .;

	*(.data)
	*(".data.*")
	*(".kernel.*")

#ifdef CONFIG_DYNAMIC_INTERRUPTS
	. = ALIGN(4);
	_irq_to_interrupt_vector = .;
#ifdef LINKER_PASS2
	KEEP(*(irq_int_vector_map))
#else
	. += CONFIG_MAX_IRQ_LINES;
#endif /* LINKER_PASS2 */

	z_interrupt_vectors_allocated = .;
#ifdef LINKER_PASS2
	KEEP(*(irq_vectors_alloc))
#else
	. += (CONFIG_IDT_NUM_VECTORS + 7) / 8;
#endif /* LINKER_PASS2 */
#endif /* CONFIG_DYNAMIC_INTERRUPTS */

/* Located in generated directory. This file is populated by the
 * zephyr_linker_sources() Cmake function.
 */
#include <snippets-rwdata.ld>

#ifdef CONFIG_X86_KPTI
	MMU_PAGE_ALIGN
	z_shared_kernel_page_start = .;
	/* Special page containing supervisor data that is still mapped in
	 * user mode page tables. IDT, GDT, TSSes, trampoline stack, and
	 * any LDT must go here as they always must live in a page that is
	 * marked 'present'. Still not directly user accessible, but
	 * no sensitive data should be here as Meltdown exploits may read it.
	 */
#endif /* CONFIG_X86_KPTI */

#ifdef CONFIG_DYNAMIC_INTERRUPTS
	. = ALIGN(8);
	_idt_base_address = .;
#ifdef LINKER_PASS2
	KEEP(*(staticIdt))
#else
	. += CONFIG_IDT_NUM_VECTORS * 8;
#endif /* LINKER_PASS2 */
#endif /* CONFIG_DYNAMIC_INTERRUPTS */

#ifdef CONFIG_GDT_DYNAMIC
	KEEP(*(.tss))
	. = ALIGN(8);
	_gdt = .;
#ifdef LINKER_PASS2
	KEEP(*(gdt))
#else /* LINKER_PASS2 */

#ifdef CONFIG_USERSPACE
    #define GDT_NUM_ENTRIES 7
#elif defined(CONFIG_HW_STACK_PROTECTION)
    #define GDT_NUM_ENTRIES 5
#else
    #define GDT_NUM_ENTRIES 3
#endif /* CONFIG_X86_USERSPACE */
	. += GDT_NUM_ENTRIES * 8;
#endif /* LINKER_PASS2 */
#endif /* CONFIG_GDT_DYNAMIC */

#ifdef CONFIG_X86_KPTI
	z_trampoline_stack_start = .;
	MMU_PAGE_ALIGN
	z_trampoline_stack_end = .;
	z_shared_kernel_page_end = .;

	ASSERT(z_trampoline_stack_end - z_trampoline_stack_start >= 40,
		"trampoline stack too small");
	ASSERT(z_shared_kernel_page_end - z_shared_kernel_page_start == 4096,
	       "shared kernel area is not one memory page");
#endif /* CONFIG_X86_KPTI */

	. = ALIGN(4);
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	__data_rom_start = LOADADDR(_DATA_SECTION_NAME);

#include <linker/common-ram.ld>
#include <linker/cplusplus-ram.ld>
#include <arch/x86/pagetables.ld>

/* Must be last in RAM */
#include <linker/kobject.ld>

	MMU_PAGE_ALIGN
	__data_ram_end = .;

	/* All unused memory also owned by the kernel for heaps */
	__kernel_ram_end = KERNEL_BASE_ADDR + KERNEL_RAM_SIZE;
	__kernel_ram_size = __kernel_ram_end - __kernel_ram_start;

	_image_ram_end = .;
	_image_ram_all = (KERNEL_BASE_ADDR + KERNEL_RAM_SIZE) - _image_ram_start;

	_end = .; /* end of image */

	GROUP_END(RAMABLE_REGION)

#ifndef LINKER_PASS2
	/* static interrupts */
	SECTION_PROLOGUE(intList,,)
	{
	KEEP(*(.spurIsr))
	KEEP(*(.spurNoErrIsr))
	KEEP(*(.intList))
	KEEP(*(.gnu.linkonce.intList.*))
	} > IDT_LIST
#else
	/DISCARD/ :
	{
	KEEP(*(.spurIsr))
	KEEP(*(.spurNoErrIsr))
	KEEP(*(.intList))
	KEEP(*(.gnu.linkonce.intList.*))
	}
#endif

/* Located in generated directory. This file is populated by the
 * zephyr_linker_sources() Cmake function.
 */
#include <snippets-sections.ld>

#include <linker/debug-sections.ld>

	/DISCARD/ : { *(.note.GNU-stack) }

	}

#ifdef CONFIG_XIP
/*
 * Round up number of words for DATA section to ensure that XIP copies the
 * entire data section. XIP copy is done in words only, so there may be up
 * to 3 extra bytes copied in next section (BSS). At run time, the XIP copy
 * is done first followed by clearing the BSS section.
 */
__data_size = (__data_ram_end - __data_ram_start);
__data_num_words = (__data_size + 3) >> 2;
#endif


Add convert_opt to ldoc config.

Add convert_opt to ldoc config.

project = 'RpgPlus'
description = 'RpgPlus Scripting API'
full_description = [[
These are all available methods for RpgPlus scripts.
]]
file = {'.'}
format = 'markdown'
convert_opt = true


linker/common-ram.ld: force input section align

These special kernel sections represent arrays of kernel objects than
are iterated over at runtime to perform initialization.

The code expects all the data in these sections to be in the form of an
array of that section type, with each element sizeof(type) bytes apart.

Unfortunately, the linker sometimes has other plans and in some cases
was defaulting to aligning the data to some large power-of-two value,
such as 64 bytes. This causes any attempt to iterate over these sections
to fail as they are not a proper array.

Use the ld SUBALIGN() directive to force the alignment of these input
sections to 4 bytes.

Signed-off-by: Andrew Boie <aab045b28152628be6af0e556050d0381fd0a34d@intel.com>

	SECTION_DATA_PROLOGUE(initlevel, (OPTIONAL),)
	{
		DEVICE_INIT_SECTIONS()
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	/* verify we don't have rogue .init_<something> initlevel sections */
	SECTION_DATA_PROLOGUE(initlevel_error, (OPTIONAL), )
	{
		DEVICE_INIT_UNDEFINED_SECTION()
	}
	ASSERT(SIZEOF(initlevel_error) == 0, "Undefined initialization levels used.")

	SECTION_DATA_PROLOGUE(initshell, (OPTIONAL),)
	{
		SHELL_INIT_SECTIONS()
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_static_thread_area, (OPTIONAL), SUBALIGN(4))
	{
		_static_thread_data_list_start = .;
		KEEP(*(SORT_BY_NAME("._static_thread_data.static.*")))
		_static_thread_data_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_timer_area, (OPTIONAL), SUBALIGN(4))
	{
		_k_timer_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_timer.static.*")))
		_k_timer_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_mem_slab_area, (OPTIONAL), SUBALIGN(4))
	{
		_k_mem_slab_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_mem_slab.static.*")))
		_k_mem_slab_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_mem_pool_area, (OPTIONAL), SUBALIGN(4))
	{
		KEEP(*(SORT_BY_NAME("._k_memory_pool.struct*")))
		_k_mem_pool_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_mem_pool.static.*")))
		_k_mem_pool_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_sem_area, (OPTIONAL), SUBALIGN(4))
	{
		_k_sem_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_sem.static.*")))
		_k_sem_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_mutex_area, (OPTIONAL), SUBALIGN(4))
	{
		_k_mutex_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_mutex.static.*")))
		_k_mutex_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_alert_area, (OPTIONAL), SUBALIGN(4))
	{
		_k_alert_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_alert.static.*")))
		_k_alert_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_queue_area, (OPTIONAL), SUBALIGN(4))
	{
		_k_queue_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_queue.static.*")))
		_k_queue_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_stack_area, (OPTIONAL), SUBALIGN(4))
	{
		_k_stack_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_stack.static.*")))
		_k_stack_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_msgq_area, (OPTIONAL), SUBALIGN(4))
	{
		_k_msgq_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_msgq.static.*")))
		_k_msgq_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_mbox_area, (OPTIONAL), SUBALIGN(4))
	{
		_k_mbox_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_mbox.static.*")))
		_k_mbox_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_pipe_area, (OPTIONAL), SUBALIGN(4))
	{
		_k_pipe_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_pipe.static.*")))
		_k_pipe_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_work_area, (OPTIONAL), SUBALIGN(4))
	{
		_k_work_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_work.static.*")))
		_k_work_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_task_list, (OPTIONAL), SUBALIGN(4))
	{
		_k_task_list_start = .;
		*(._k_task_list.public.*)
		*(._k_task_list.private.*)
		_k_task_list_idle_start = .;
		*(._k_task_list.idle.*)
		KEEP(*(SORT_BY_NAME("._k_task_list*")))
		_k_task_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_event_list, (OPTIONAL), SUBALIGN(4))
	{
		_k_event_list_start = .;
		*(._k_event_list.event.*)
		KEEP(*(SORT_BY_NAME("._k_event_list*")))
		_k_event_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_memory_pool, (OPTIONAL), SUBALIGN(4))
	{
		*(._k_memory_pool.struct*)
		KEEP(*(SORT_BY_NAME("._k_memory_pool.struct*")))

		_k_mem_pool_start = .;
		*(._k_memory_pool.*)
		KEEP(*(SORT_BY_NAME("._k_memory_pool*")))
		_k_mem_pool_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_net_buf_pool_area, (OPTIONAL), SUBALIGN(4))
	{
		_net_buf_pool_list = .;
		KEEP(*(SORT_BY_NAME("._net_buf_pool.static.*")))
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(net_if, (OPTIONAL), SUBALIGN(4))
	{
		__net_if_start = .;
		*(".net_if.*")
		KEEP(*(SORT_BY_NAME(".net_if.*")))
		__net_if_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(net_if_event, (OPTIONAL), SUBALIGN(4))
	{
		__net_if_event_start = .;
		*(".net_if_event.*")
		KEEP(*(SORT_BY_NAME(".net_if_event.*")))
		__net_if_event_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

#if defined(CONFIG_NET_SHELL)
	SECTION_DATA_PROLOGUE(net_stack, (OPTIONAL), SUBALIGN(4))
	{
		__net_stack_start = .;
		*(".net_stack.*")
		KEEP(*(SORT_BY_NAME(".net_stack*")))
		__net_stack_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
#endif /* CONFIG_NET_SHELL */

	SECTION_DATA_PROLOGUE(net_l2_data, (OPTIONAL), SUBALIGN(4))
	{
		__net_l2_data_start = .;
		*(".net_l2.data")
		KEEP(*(SORT_BY_NAME(".net_l2.data*")))
		__net_l2_data_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(initlevel, (OPTIONAL),)
	{
		DEVICE_INIT_SECTIONS()
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	/* verify we don't have rogue .init_<something> initlevel sections */
	SECTION_DATA_PROLOGUE(initlevel_error, (OPTIONAL), )
	{
		DEVICE_INIT_UNDEFINED_SECTION()
	}
	ASSERT(SIZEOF(initlevel_error) == 0, "Undefined initialization levels used.")

	SECTION_DATA_PROLOGUE(initshell, (OPTIONAL),)
	{
		SHELL_INIT_SECTIONS()
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_static_thread_area, (OPTIONAL),)
	{
		_static_thread_data_list_start = .;
		KEEP(*(SORT_BY_NAME("._static_thread_data.static.*")))
		_static_thread_data_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_timer_area, (OPTIONAL),)
	{
		_k_timer_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_timer.static.*")))
		_k_timer_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_mem_slab_area, (OPTIONAL),)
	{
		_k_mem_slab_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_mem_slab.static.*")))
		_k_mem_slab_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_mem_pool_area, (OPTIONAL),)
	{
		KEEP(*(SORT_BY_NAME("._k_memory_pool.struct*")))
		_k_mem_pool_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_mem_pool.static.*")))
		_k_mem_pool_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_sem_area, (OPTIONAL),)
	{
		_k_sem_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_sem.static.*")))
		_k_sem_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_mutex_area, (OPTIONAL),)
	{
		_k_mutex_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_mutex.static.*")))
		_k_mutex_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_alert_area, (OPTIONAL),)
	{
		_k_alert_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_alert.static.*")))
		_k_alert_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_queue_area, (OPTIONAL),)
	{
		_k_queue_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_queue.static.*")))
		_k_queue_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_stack_area, (OPTIONAL),)
	{
		_k_stack_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_stack.static.*")))
		_k_stack_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_msgq_area, (OPTIONAL),)
	{
		_k_msgq_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_msgq.static.*")))
		_k_msgq_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_mbox_area, (OPTIONAL),)
	{
		_k_mbox_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_mbox.static.*")))
		_k_mbox_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_pipe_area, (OPTIONAL),)
	{
		_k_pipe_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_pipe.static.*")))
		_k_pipe_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_work_area, (OPTIONAL),)
	{
		_k_work_list_start = .;
		KEEP(*(SORT_BY_NAME("._k_work.static.*")))
		_k_work_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_task_list, (OPTIONAL),)
	{
		_k_task_list_start = .;
		*(._k_task_list.public.*)
		*(._k_task_list.private.*)
		_k_task_list_idle_start = .;
		*(._k_task_list.idle.*)
		KEEP(*(SORT_BY_NAME("._k_task_list*")))
		_k_task_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_event_list, (OPTIONAL),)
	{
		_k_event_list_start = .;
		*(._k_event_list.event.*)
		KEEP(*(SORT_BY_NAME("._k_event_list*")))
		_k_event_list_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_k_memory_pool, (OPTIONAL),)
	{
		*(._k_memory_pool.struct*)
		KEEP(*(SORT_BY_NAME("._k_memory_pool.struct*")))

		_k_mem_pool_start = .;
		*(._k_memory_pool.*)
		KEEP(*(SORT_BY_NAME("._k_memory_pool*")))
		_k_mem_pool_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(_net_buf_pool_area, (OPTIONAL),)
	{
		_net_buf_pool_list = .;
		KEEP(*(SORT_BY_NAME("._net_buf_pool.static.*")))
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(net_if, (OPTIONAL),)
	{
		__net_if_start = .;
		*(".net_if.*")
		KEEP(*(SORT_BY_NAME(".net_if.*")))
		__net_if_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	SECTION_DATA_PROLOGUE(net_if_event, (OPTIONAL),)
	{
		__net_if_event_start = .;
		*(".net_if_event.*")
		KEEP(*(SORT_BY_NAME(".net_if_event.*")))
		__net_if_event_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

#if defined(CONFIG_NET_SHELL)
	SECTION_DATA_PROLOGUE(net_stack, (OPTIONAL),)
	{
		__net_stack_start = .;
		*(".net_stack.*")
		KEEP(*(SORT_BY_NAME(".net_stack*")))
		__net_stack_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
#endif /* CONFIG_NET_SHELL */

	SECTION_DATA_PROLOGUE(net_l2_data, (OPTIONAL),)
	{
		__net_l2_data_start = .;
		*(".net_l2.data")
		KEEP(*(SORT_BY_NAME(".net_l2.data*")))
		__net_l2_data_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)


updated linker script file

updated linker script file

/*******************************************************************************
@file     lm4f120h5qr.ld
@author   Rajmund Szymanski
@date     02.01.2017
@brief    Linker script for LM4F120H5QR device with 256KB FLASH and 32KB RAM
*******************************************************************************/

MEMORY
{
	ROM (rx)  : ORIGIN = 0x00000000, LENGTH = 256K
	RAM (rwx) : ORIGIN = 0x20000000, LENGTH =  32K
}

__ram_start = ORIGIN(RAM);
__ram_end   = ORIGIN(RAM) + LENGTH(RAM);

ENTRY(Reset_Handler)

SECTIONS
{
	__text_start = ORIGIN(ROM);

	.text :
	{
		KEEP (*(.vectors))

		*(.text   .text.*   .gnu.linkonce.t.*)
		*(.rodata .rodata.* .gnu.linkonce.r.*)
		*(.glue_7 .glue_7t)
	} > ROM

	.init : ALIGN(4)
	{
		__preinit_array_start = .;
		KEEP (*(.preinit_array))
		__preinit_array_end = .;

		__init_array_start = .;
		KEEP (*(SORT(.init_array.*)))
		KEEP (*(.init_array))
		__init_array_end = .;

		KEEP (*(.init))
	} > ROM

	.fini : ALIGN(4)
	{
		__fini_array_start = .;
		KEEP (*(.fini_array))
		KEEP (*(SORT(.fini_array.*)))
		__fini_array_end = .;

		KEEP (*(.fini))
	} > ROM

	.ARM.extab : ALIGN(4)
	{
		*(.ARM.extab* .gnu.linkonce.armextab.*)
		*(.gcc_except_table)
		*(.eh_frame_hdr)
		*(.eh_frame)
	} > ROM

	.ARM.exidx : ALIGN(4)
	{
		__exidx_start = .;
		*(.ARM.exidx* .gnu.linkonce.armexidx.*)
		__exidx_end = .;
	} > ROM

	__text_end  = .;
	__text_size = . - __text_start;

	.main_stack (NOLOAD): ALIGN(8)
	{
		__main_stack_start = .;
		KEEP (*(.main_stack))
		. = ALIGN(8);
		__main_stack_end = .;
	} > RAM

	__main_stack_size = SIZEOF(.main_stack);

	.data : ALIGN(4)
	{
		__data_init_start = LOADADDR(.data);

		__data_start = .;
		*(.data* .gnu.linkonce.d.*)
		. = ALIGN(4);
		__data_end = .;
	} > RAM AT > ROM

	__data_size = SIZEOF(.data);

	.bss (NOLOAD): ALIGN(4)
	{
		__bss_start = .;
		*(.bss* .gnu.linkonce.b.*)
		*(COMMON)
		. = ALIGN(4);
		__bss_end = .;
	} > RAM AT > RAM

	__bss_size = SIZEOF(.bss);

	.heap (NOLOAD): ALIGN(8)
	{
		__heap_start = .;
		. = ABSOLUTE(__ram_end - __proc_stack_size);
		__heap_end = .;
	} > RAM

	__heap_size = SIZEOF(.heap);

	.proc_stack (NOLOAD): ALIGN(8)
	{
		__proc_stack_start = .;
		KEEP (*(.proc_stack))
		. = ALIGN(8);
		__proc_stack_end = .;
	} > RAM

	__proc_stack_size = SIZEOF(.proc_stack);

	__initial_msp = __main_stack_size ? __main_stack_end : __heap_end;
	__initial_sp  = __proc_stack_size ? __proc_stack_end : __initial_msp;

	PROVIDE(__data_start__ = __data_start);
	PROVIDE(__data_end__   = __data_end);
	PROVIDE(__bss_start__  = __bss_start);
	PROVIDE(__bss_end__    = __bss_end);
	PROVIDE(__end__        = __bss_end);
	PROVIDE(__heap_base__  = __heap_start);
	PROVIDE(__heap_end__   = __heap_end);
	PROVIDE(__heap_base    = __heap_start);
	PROVIDE(__heap_limit   = __heap_end);
	PROVIDE(__stack        = __initial_sp);
	PROVIDE(__process_stack_start = __proc_stack_start);
	PROVIDE(__process_stack_size  = __proc_stack_size);
}

/*******************************************************************************
@file     lm4f120h5qr.ld
@author   Rajmund Szymanski
@date     02.01.2017
@brief    Linker script for LM4F120H5QR device with 256KB FLASH and 32KB RAM
*******************************************************************************/

MEMORY
{
	ROM (rx)  : ORIGIN = 0x00000000, LENGTH = 256K
	RAM (rwx) : ORIGIN = 0x20000000, LENGTH =  32K
}

__ram_start = ORIGIN(RAM);
__ram_end   = ORIGIN(RAM) + LENGTH(RAM);

ENTRY(Reset_Handler)

SECTIONS
{
	__text_start = ORIGIN(ROM);

	.text :
	{
		KEEP (*(.vectors))

		*(.text   .text.*   .gnu.linkonce.t.*)
		*(.rodata .rodata.* .gnu.linkonce.r.*)
		*(.glue_7 .glue_7t)
	} > ROM

	.init : ALIGN(4)
	{
		__preinit_array_start = .;
		KEEP (*(.preinit_array))
		__preinit_array_end = .;

		__init_array_start = .;
		KEEP (*(SORT(.init_array.*)))
		KEEP (*(.init_array))
		__init_array_end = .;

		KEEP (*(.init))
	} > ROM

	.fini : ALIGN(4)
	{
		__fini_array_start = .;
		KEEP (*(.fini_array))
		KEEP (*(SORT(.fini_array.*)))
		__fini_array_end = .;

		KEEP (*(.fini))
	} > ROM

	.ARM.extab : ALIGN(4)
	{
		*(.ARM.extab* .gnu.linkonce.armextab.*)
		*(.gcc_except_table)
		*(.eh_frame_hdr)
		*(.eh_frame)
	} > ROM

	.ARM.exidx : ALIGN(4)
	{
		__exidx_start = .;
		*(.ARM.exidx* .gnu.linkonce.armexidx.*)
		__exidx_end = .;
	} > ROM

	__text_end  = .;
	__text_size = . - __text_start;

	.ccm (NOLOAD):
	{
		*(.ccm)
	} > CCM

	.bkp (NOLOAD):
	{
		*(.bkp)
	} > BKP

	.main_stack (NOLOAD): ALIGN(8)
	{
		__main_stack_start = .;
		KEEP (*(.main_stack))
		. = ALIGN(8);
		__main_stack_end = .;
	} > RAM

	__main_stack_size = SIZEOF(.main_stack);

	.data : ALIGN(4)
	{
		__data_init_start = LOADADDR(.data);

		__data_start = .;
		*(.data* .gnu.linkonce.d.*)
		. = ALIGN(4);
		__data_end = .;
	} > RAM AT > ROM

	__data_size = SIZEOF(.data);

	.bss (NOLOAD): ALIGN(4)
	{
		__bss_start = .;
		*(.bss* .gnu.linkonce.b.*)
		*(COMMON)
		. = ALIGN(4);
		__bss_end = .;
	} > RAM AT > RAM

	__bss_size = SIZEOF(.bss);

	.heap (NOLOAD): ALIGN(8)
	{
		__heap_start = .;
		. = ABSOLUTE(__ram_end - __proc_stack_size);
		__heap_end = .;
	} > RAM

	__heap_size = SIZEOF(.heap);

	.proc_stack (NOLOAD): ALIGN(8)
	{
		__proc_stack_start = .;
		KEEP (*(.proc_stack))
		. = ALIGN(8);
		__proc_stack_end = .;
	} > RAM

	__proc_stack_size = SIZEOF(.proc_stack);

	__initial_msp = __main_stack_size ? __main_stack_end : __heap_end;
	__initial_sp  = __proc_stack_size ? __proc_stack_end : __initial_msp;

	PROVIDE(__data_start__ = __data_start);
	PROVIDE(__data_end__   = __data_end);
	PROVIDE(__bss_start__  = __bss_start);
	PROVIDE(__bss_end__    = __bss_end);
	PROVIDE(__end__        = __bss_end);
	PROVIDE(__heap_base__  = __heap_start);
	PROVIDE(__heap_end__   = __heap_end);
	PROVIDE(__heap_base    = __heap_start);
	PROVIDE(__heap_limit   = __heap_end);
	PROVIDE(__stack        = __initial_sp);
	PROVIDE(__process_stack_start = __proc_stack_start);
	PROVIDE(__process_stack_size  = __proc_stack_size);
}


stm32/boards/stm32f722.ld: Provide memory regions for internal FS.

/*
    GNU linker script for STM32F722, STM32F723, STM32F732, STM32F733
*/

/* Specify the memory areas */
MEMORY
{
    FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 512K
    FLASH_ISR (rx)  : ORIGIN = 0x08000000, LENGTH = 16K     /* sector 0, 16K */
    FLASH_FS (r)    : ORIGIN = 0x08004000, LENGTH = 112K    /* sectors 1-4 3*16KiB 1*64KiB*/
    FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 384K    /* sectors 5-7 3*128KiB = 384K */
    DTCM (xrw)      : ORIGIN = 0x20000000, LENGTH = 64K     /* Used for storage cache */
    RAM (xrw)       : ORIGIN = 0x20010000, LENGTH = 192K    /* SRAM1 = 176K, SRAM2 = 16K */
}

/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_heap_size = 16K;

/* Define the stack.  The stack is full descending so begins just above last byte
   of RAM.  Note that EABI requires the stack to be 8-byte aligned for a call. */
_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve;
_sstack = _estack - 32K; /* tunable */

/* RAM extents for the garbage collector */
_ram_start = ORIGIN(RAM);
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
_heap_start = _ebss; /* heap starts just after statically allocated memory */
_heap_end = _sstack;

/*
    GNU linker script for STM32F722, STM32F723, STM32F732, STM32F733
*/

/* Specify the memory areas */
MEMORY
{
    FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 512K
    FLASH_ISR (rx)  : ORIGIN = 0x08000000, LENGTH = 32K     /* sectors 0,1 */
    FLASH_APP (rx)  : ORIGIN = 0x08008000, LENGTH = 480K    /* sectors 2-7 */
    RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 256K    /* DTCM+SRAM1+SRAM2 */
}

/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_heap_size = 16K;

/* Define the stack.  The stack is full descending so begins just above last byte
   of RAM.  Note that EABI requires the stack to be 8-byte aligned for a call. */
_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve;
_sstack = _estack - 32K; /* tunable */

/* RAM extents for the garbage collector */
_ram_start = ORIGIN(RAM);
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
_heap_start = _ebss; /* heap starts just after statically allocated memory */
_heap_end = _sstack;


Add more comments to kernel.ld

Add more comments to kernel.ld

SECTIONS
{
  /**
   * Start address of the kernel.
   *
   * In QEMU, this is hardcoded to 0x100000 (64Kb).
   * On the actual device, it can be modified, but it defaults to 0x8000 (32Kb).
   */
  . = 0x10000;

  /**
   * Executable code.
   *
   * All text segments are copied here. The first file in the object file
   * is kernel.s and the first function in kernel.s is the kernel function
   * which initializes everything, so it gets placed at the start address
   * by the bootstrap code. After the text segment, padding is added in
   * order to align the next segment to a page boundary.
   */
  .text :
  {
    *(.text)
  }
  . = ALIGN(0x1000);

  /**
   * Program data, all .data segments concatenated after each other. Padding
   * is added afterwards to align the next segment to page boundary.
   */
  .data :
  {
    *(.data)
  }
  . = ALIGN(0x1000);

  /**
   * Stack spaces. These come after the data from the binary file,
   * thus they are not actually present in it. They are not loaded,
   * but the addresses are set up for them after the file. If the
   * length of the file is x, then the stack addresses are located
   * at the page boundary after x + 64Kb.
   */
  . = . + 0x800;
  stack_svc = .;
  . = . + 0x800;
  stack_und = .;
  . = . + 0x800;
  stack_abt = .;
  . = . + 0x800;
  stack_irq = .;
  . = . + 0x800;
  stack_fiq = .;
  . = . + 0x400000;
  stack_sys = .;

  /**
   * Front buffer. Since this buffer is quite large, around 2Mb in size,
   * it should not appear in the binary file since it would increase the
   * time it takes to load the kernel. Thus, the address space it requires
   * is only defined in the linker script and placed at the end of the
   * kernel, after all data that is loaded from the binary file.
   */
  . = . + 640 * 480 * 8;
  gfx_buffer = .;
}


updated linker script

updated linker script

/*******************************************************************************
@file     stm32f4xx.ld
@author   Rajmund Szymanski
@date     28.02.2017
@brief    Linker script for STM32F407VG device with 1024KB FLASH and 192KB RAM
*******************************************************************************/

MEMORY
{
	ROM (rx)  : ORIGIN = 0x08000000, LENGTH = 1024k
	CCM (rwx) : ORIGIN = 0x10000000, LENGTH =   64k
	RAM (rwx) : ORIGIN = 0x20000000, LENGTH =  128k
/*	AUX (rwx) : ORIGIN = 0x2001C000, LENGTH =   16k
*/	BKP (rwx) : ORIGIN = 0x40024000, LENGTH =    4k
}

__ccm_start = ORIGIN(CCM);
__ccm_end   = ORIGIN(CCM) + LENGTH(CCM);
__ram_start = ORIGIN(RAM);
__ram_end   = ORIGIN(RAM) + LENGTH(RAM);

ENTRY(Reset_Handler)

SECTIONS
{
	__text_start = ORIGIN(ROM);

	.text :
	{
		KEEP (*(.vectors))

		*(.text   .text.*   .gnu.linkonce.t.*)
		*(.rodata .rodata.* .gnu.linkonce.r.*)
		*(.glue_7 .glue_7t)
	} > ROM

	.init : ALIGN(4)
	{
		__preinit_array_start = .;
		KEEP (*(.preinit_array))
		__preinit_array_end = .;

		__init_array_start = .;
		KEEP (*(SORT(.init_array.*)))
		KEEP (*(.init_array))
		__init_array_end = .;

		KEEP (*(.init))
	} > ROM

	.fini : ALIGN(4)
	{
		__fini_array_start = .;
		KEEP (*(.fini_array))
		KEEP (*(SORT(.fini_array.*)))
		__fini_array_end = .;

		KEEP (*(.fini))
	} > ROM

	.ARM.extab : ALIGN(4)
	{
		*(.ARM.extab* .gnu.linkonce.armextab.*)
		*(.gcc_except_table)
		*(.eh_frame_hdr)
		*(.eh_frame)
	} > ROM

	.ARM.exidx : ALIGN(4)
	{
		__exidx_start = .;
		*(.ARM.exidx* .gnu.linkonce.armexidx.*)
		__exidx_end = .;
	} > ROM

	__text_end  = .;
	__text_size = . - __text_start;

	.ccm (NOLOAD):
	{
		*(.ccm)
	} > CCM

	.bkp (NOLOAD):
	{
		*(.bkp)
	} > BKP

	.main_stack (NOLOAD): ALIGN(8)
	{
		__main_stack_start = .;
		KEEP (*(.main_stack))
		. = ALIGN(8);
		__main_stack_end = .;
	} > RAM

	__main_stack_size = SIZEOF(.main_stack);

	.data : ALIGN(4)
	{
		__data_init_start = LOADADDR(.data);

		__data_start = .;
		*(.data* .gnu.linkonce.d.*)
		. = ALIGN(4);
		__data_end = .;
	} > RAM AT > ROM

	__data_size = SIZEOF(.data);

	.bss : ALIGN(4)
	{
		__bss_start = .;
		*(.bss* .gnu.linkonce.b.*)
		*(COMMON)
		. = ALIGN(4);
		__bss_end = .;
	} > RAM AT > RAM

	__bss_size = SIZEOF(.bss);

	.proc_stack (NOLOAD): ALIGN(8)
	{
		KEEP (*(.proc_stack))
		. = ALIGN(8);
	} > RAM

	__proc_stack_size = SIZEOF(.proc_stack);

	__heap_start = LOADADDR(.proc_stack);
	__heap_end   = __ram_end - __proc_stack_size;

	__proc_stack_start = __heap_end;
	__proc_stack_end   = __ram_end;

	__initial_msp = __main_stack_size ? __main_stack_end : __heap_end;
	__initial_sp  = __proc_stack_size ? __proc_stack_end : __initial_msp;

	PROVIDE(__data_start__ = __data_start);
	PROVIDE(__data_end__   = __data_end);
	PROVIDE(__bss_start__  = __bss_start);
	PROVIDE(__bss_end__    = __bss_end);
	PROVIDE(__end__        = __bss_end);
	PROVIDE(__heap_base__  = __heap_start);
	PROVIDE(__heap_end__   = __heap_end);
	PROVIDE(__heap_base    = __heap_start);
	PROVIDE(__heap_limit   = __heap_end);
	PROVIDE(__stack        = __initial_sp);

	PROVIDE(__process_stack_start = __proc_stack_start);
	PROVIDE(__process_stack_size  = __proc_stack_size);
	PROVIDE(__process_stack_end   = __proc_stack_end);
}

/*******************************************************************************
@file     stm32f4xx.ld
@author   Rajmund Szymanski
@date     02.01.2017
@brief    Linker script for STM32F407VG device with 1024KB FLASH and 192KB RAM
*******************************************************************************/

MEMORY
{
	ROM (rx)  : ORIGIN = 0x08000000, LENGTH = 1024k
	CCM (rwx) : ORIGIN = 0x10000000, LENGTH =   64k
	RAM (rwx) : ORIGIN = 0x20000000, LENGTH =  128k
/*	AUX (rwx) : ORIGIN = 0x2001C000, LENGTH =   16k
*/	BKP (rwx) : ORIGIN = 0x40024000, LENGTH =    4k
}

__ccm_start = ORIGIN(CCM);
__ccm_end   = ORIGIN(CCM) + LENGTH(CCM);
__ram_start = ORIGIN(RAM);
__ram_end   = ORIGIN(RAM) + LENGTH(RAM);

ENTRY(Reset_Handler)

SECTIONS
{
	__text_start = ORIGIN(ROM);

	.text :
	{
		KEEP (*(.vectors))

		*(.text   .text.*   .gnu.linkonce.t.*)
		*(.rodata .rodata.* .gnu.linkonce.r.*)
		*(.glue_7 .glue_7t)
	} > ROM

	.init : ALIGN(4)
	{
		__preinit_array_start = .;
		KEEP (*(.preinit_array))
		__preinit_array_end = .;

		__init_array_start = .;
		KEEP (*(SORT(.init_array.*)))
		KEEP (*(.init_array))
		__init_array_end = .;

		KEEP (*(.init))
	} > ROM

	.fini : ALIGN(4)
	{
		__fini_array_start = .;
		KEEP (*(.fini_array))
		KEEP (*(SORT(.fini_array.*)))
		__fini_array_end = .;

		KEEP (*(.fini))
	} > ROM

	.ARM.extab : ALIGN(4)
	{
		*(.ARM.extab* .gnu.linkonce.armextab.*)
		*(.gcc_except_table)
		*(.eh_frame_hdr)
		*(.eh_frame)
	} > ROM

	.ARM.exidx : ALIGN(4)
	{
		__exidx_start = .;
		*(.ARM.exidx* .gnu.linkonce.armexidx.*)
		__exidx_end = .;
	} > ROM

	__text_end  = .;
	__text_size = . - __text_start;

	.ccm (NOLOAD):
	{
		*(.ccm)
	} > CCM

	.bkp (NOLOAD):
	{
		*(.bkp)
	} > BKP

	.main_stack (NOLOAD): ALIGN(8)
	{
		__main_stack_start = .;
		KEEP (*(.main_stack))
		. = ALIGN(8);
		__main_stack_end = .;
	} > RAM

	__main_stack_size = SIZEOF(.main_stack);

	.data : ALIGN(4)
	{
		__data_init_start = LOADADDR(.data);

		__data_start = .;
		*(.data* .gnu.linkonce.d.*)
		. = ALIGN(4);
		__data_end = .;
	} > RAM AT > ROM

	__data_size = SIZEOF(.data);

	.bss (NOLOAD): ALIGN(4)
	{
		__bss_start = .;
		*(.bss* .gnu.linkonce.b.*)
		*(COMMON)
		. = ALIGN(4);
		__bss_end = .;
	} > RAM AT > RAM

	__bss_size = SIZEOF(.bss);

	.heap (NOLOAD): ALIGN(8)
	{
		__heap_start = .;
		. = ABSOLUTE(__ram_end - __proc_stack_size);
		__heap_end = .;
	} > RAM

	__heap_size = SIZEOF(.heap);

	.proc_stack (NOLOAD): ALIGN(8)
	{
		__proc_stack_start = .;
		KEEP (*(.proc_stack))
		. = ALIGN(8);
		__proc_stack_end = .;
	} > RAM

	__proc_stack_size = SIZEOF(.proc_stack);

	__initial_msp = __main_stack_size ? __main_stack_end : __heap_end;
	__initial_sp  = __proc_stack_size ? __proc_stack_end : __initial_msp;

	PROVIDE(__data_start__ = __data_start);
	PROVIDE(__data_end__   = __data_end);
	PROVIDE(__bss_start__  = __bss_start);
	PROVIDE(__bss_end__    = __bss_end);
	PROVIDE(__end__        = __bss_end);
	PROVIDE(__heap_base__  = __heap_start);
	PROVIDE(__heap_end__   = __heap_end);
	PROVIDE(__heap_base    = __heap_start);
	PROVIDE(__heap_limit   = __heap_end);
	PROVIDE(__stack        = __initial_sp);
	PROVIDE(__process_stack_start = __proc_stack_start);
	PROVIDE(__process_stack_size  = __proc_stack_size);
}


Align everything to 2M + add explicit offset

/*
 * Copyright 2022 The Project Oak Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

ENTRY(_start)

PHDRS
{
    /* Note that the permissions flags are currently not respected. */
    /* Keep the sections here sorted from lowest memory address to largest; crosvm
     * has a sanity check that expects the section with the lowest address to come
     * first.
     */
    /* Executable text. */
    boot    PT_LOAD FLAGS(4 + 1); /* PF_R + PF_X */
    text    PT_LOAD FLAGS(4 + 1); /* PF_R + PF_X */
    /* Read-only data. */
    rodata  PT_LOAD FLAGS(4); /* PF_R */
    /* Initialized read-write data. */
    data    PT_LOAD FLAGS(4 + 2); /* PF_R + PF_W */
    /* Uninitialized read-write data. */
    bss     PT_LOAD FLAGS(4 + 2); /* PF_R + PF_W */
    /* Special sections for SEV-SNP. */
    cpuid   PT_LOAD FLAGS(1 << 23);
    secrets PT_LOAD FLAGS(1 << 24);
}

/* To set kernel VMA to high memory, set this to 0xFFFFFFFF80000000. */
KERNEL_MEM_START = 0x0;

SECTIONS {
    /*
     * Boot code is executed with identity mapping; the main duty of the boot
     * code is to set up proper page tables before jumping to the kernel proper.
     * We place that at 2M (both virtual and physical)
     */
    .boot 0x200000 : {
        ram_min = .;
        *(.boot)
    } : boot

    /*
     * Load the rest of the kernel after KERNEL_MEM_START. The idea is that the initial
     * boot code should set map KERNEL_MEM_START to physical address 0; therefore, all
     * VMAs will be LMA + KERNEL_MEM_START.
     */
    . += KERNEL_MEM_START;

    data_start = .;
    text_start = .;

    .text ALIGN(2M) : AT(ADDR(.text) - KERNEL_MEM_START) {
        *(.text .text.*)
    } : text

    text_end = .;

    .rodata ALIGN(2M) : {
        *(.rodata .rodata.*)
    } : rodata

    .data ALIGN(2M) : {
        *(.data .data.*)
    } : data

    data_end = .;

    .bss : ALIGN(2M) {
        bss_start = .;
        *(.bss .bss.*)
        bss_size = . - bss_start;
    } : bss

    /* Stack grows down, so stack_start is the upper address in memory. */
    .stack (NOLOAD) : ALIGN(2M) {
        . += 512K;
    } : bss
    stack_start = .;

    .cpuid (NOLOAD) : ALIGN(2M) {
        . += 4K;
    } : cpuid

    .secrets (NOLOAD) : ALIGN(2M) {
        . += 4K;
    } : secrets

    /DISCARD/ : {
        *(.eh_frame*)
    }
}

/*
 * Copyright 2022 The Project Oak Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

ENTRY(_start)

PHDRS
{
    /* Note that the permissions flags are currently not respected. */
    /* Keep the sections here sorted from lowest memory address to largest; crosvm
     * has a sanity check that expects the section with the lowest address to come
     * first.
     */
    /* Executable text. */
    text    PT_LOAD FLAGS(4 + 1); /* PF_R + PF_X */
    /* Read-only data. */
    rodata  PT_LOAD FLAGS(4); /* PF_R */
    /* Initialized read-write data. */
    data    PT_LOAD FLAGS(4 + 2); /* PF_R + PF_W */
    /* Uninitialized read-write data. */
    bss     PT_LOAD FLAGS(4 + 2); /* PF_R + PF_W */
    /* Special sections for SEV-SNP. */
    cpuid   PT_LOAD FLAGS(1 << 23);
    secrets PT_LOAD FLAGS(1 << 24);
}

SECTIONS {
    .boot 0x200000 : {
        ram_min = .;
        *(.boot)
    } : text

    data_start = .;
    text_start = .;

    .text : {
        *(.text .text.*)
    } : text

    text_end = .;

    .rodata : {
        *(.rodata .rodata.*)
    } : rodata

    .data : {
        *(.data .data.*)
    } : data

    data_end = .;

    .bss : {
        bss_start = .;
        *(.bss .bss.*)
        bss_size = . - bss_start;
    } : bss

    /* Stack grows down, so stack_start is the upper address in memory. */
    .stack (NOLOAD) : ALIGN(4K) {
        . += 512K;
    } : bss
    stack_start = .;

    .cpuid (NOLOAD) : ALIGN(2M) {
        . += 4K;
    } : cpuid

    .secrets (NOLOAD) : ALIGN(2M) {
        . += 4K;
    } : secrets
}


Fix bug with linker script

Fix bug with linker script

/*
 * generic gcc linker script for LPC1549
 * Taken from Kamal Mostafa <kamal@whence.com>.
 *
 * License: Public Domain
 */

MEMORY
{
    FLASH (rx)    : ORIGIN = 0x00000000, LENGTH = 256K
    RAM (rwx)     : ORIGIN = 0x02000000, LENGTH = 16K
    RAM1 (rwx)    : ORIGIN = 0x02004000, LENGTH = 16K
    RAM2 (rwx)    : ORIGIN = 0x02008000, LENGTH = 4K
}

SECTIONS
{
    .text :
    {
        _text = .;
        KEEP(*(.isr_vector))
        KEEP(*(.after_vectors))
        *(.text*)
        *(.rodata*)
        _etext = .;
    } > FLASH

    .data :
    {
        __stack_start__ = .; /* start of the stack section */
        KEEP(*(.stack))
         . = ALIGN(4);
        __stack_end__ = .;   /* end of the stack section */

        _data = .;
        *(vtable)
        *(.data*)
        _edata = .;
    } > RAM AT > FLASH

    .bss :
    {
        _bss = .;
        *(.bss*)
        *(COMMON)
        _ebss = .;
    } > RAM

}

/*
 * generic gcc linker script for LPC1549
 * Taken from Kamal Mostafa <kamal@whence.com>.
 *
 * License: Public Domain
 */

MEMORY
{
    FLASH (rx)    : ORIGIN = 0x00000000, LENGTH = 256K
    RAM (rwx)     : ORIGIN = 0x02000000, LENGTH = 16K
    RAM1 (rwx)    : ORIGIN = 0x02004000, LENGTH = 16K
    RAM2 (rwx)    : ORIGIN = 0x02008000, LENGTH = 4K
}

SECTIONS
{
    .text :
    {
        _text = .;
        KEEP(*(.isr_vector))
        KEEP(*(.after_vectors))
        *(.text*)
        *(.rodata*)
        _etext = .;
    } > FLASH

    .data : AT (ADDR(.text) + SIZEOF(.text))
    {
        __stack_start__ = .; /* start of the stack section */
        KEEP(*(.stack))
         . = ALIGN(4);
        __stack_end__ = .;   /* end of the stack section */

        _data = .;
        *(vtable)
        *(.data*)
        _edata = .;
    } > RAM

    .bss :
    {
        _bss = .;
        *(.bss*)
        *(COMMON)
        _ebss = .;
    } > RAM

}


linker: 4k page align text segment

linker: 4k page align text segment

/**
 * This file is a part of the IncludeOS unikernel - www.includeos.org
 *
 * Copyright 2015 Oslo and Akershus University College of Applied Sciences
 * and Alfred Bratterud
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http: *www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
**/
ENTRY(_start)

SECTIONS
{
  PROVIDE ( _ELF_START_ = . + 0xA00000);
  PROVIDE ( _LOAD_START_ = _ELF_START_); /* For convenience w. multiboot */

  . = _ELF_START_;

  .multiboot : {
      PROVIDE(_MULTIBOOT_START_ = .);
      *(.multiboot)
   }

  .text ALIGN(0x1000):
  {
  PROVIDE( _TEXT_START_ = . );
    /* For solo5, although it's just used to print the mem layout. */
    _stext = .;
    *(.text)
    *(.text.*)
    *(.gnu.linkonce.t*)
    /* For solo5, although it's just used to print the mem layout. */
    _etext = .;
  }
  PROVIDE( _TEXT_END_ = . );

  .init ALIGN(0x1000) : {
    _INIT_START_ = .;
    *(.init)
    _INIT_END_ = .;
  }

  .fini ALIGN(0x10) : {
    *(.fini)
  }

  /* Global offset-table. For dynamic linking */
  .got ALIGN(0x10) : {
      *(.got*)
  }

/**
 *  .ctors, .dtors, .preinit_array, .init_array, .fini_array
 *  from GNU LD default linker script
 */

.ctors          :
  {
    _GCONSTR_START_ = .;
      /* gcc uses crtbegin.o to find the start of
       the constructors, so we make sure it is
       first.  Because this is a wildcard, it
       doesn't matter if the user does not
       actually link against crtbegin.o; the
       linker won't look for a file to match a
       wildcard.  The wildcard also means that it
       doesn't matter which directory crtbegin.o
       is in.  */
       KEEP (*crtbegin.o(.ctors))
       KEEP (*crtbegin?.o(.ctors))
       /* We don't want to include the .ctor section from
       the crtend.o file until after the sorted ctors.
       The .ctor section from the crtend file contains the
       end of ctors marker and it must be last */
       KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
       KEEP (*(SORT(.ctors.*)))
       KEEP (*(.ctors))
    _GCONSTR_END_ = .;
  }

  .dtors :
  {
    KEEP (*crtbegin.o(.dtors))
    KEEP (*crtbegin?.o(.dtors))
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
  }

  .preinit_array :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  }

  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
    KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
    PROVIDE_HIDDEN (__init_array_end = .);
  }

  .fini_array :
  {
   PROVIDE_HIDDEN (__fini_array_start = .);
   KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
   KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
   PROVIDE_HIDDEN (__fini_array_end = .);
  }

  .config ALIGN(0x8) : {
    _CONFIG_JSON_START_ = .;
    KEEP(*(.config))
    _CONFIG_JSON_END_ = .;
    BYTE(0);
  }

  .rodata :
  {
    _RODATA_START_ = .;
    *(.rodata*)
    *(.gnu.linkonce.r*)
    _RODATA_END_ = .;
    /* For solo5, although it's just used to print the mem layout. */
    _erodata = .;
  }

  /* For stack unwinding (exception handling)  */
  .eh_frame_hdr ALIGN(0x8):
  {
    KEEP(*(.eh_frame_hdr*))
  }
  .eh_frame ALIGN(0x8):
  {
    PROVIDE (__eh_frame_start = .);
    KEEP(*(.eh_frame))
    LONG (0);
  }

  .gcc_except_table :
  {
    *(.gcc_except_table)
  }

  .data :
  {
    _DATA_START_ = .;
    *(.data)
    *(.data.*)
    *(.gnu.linkonce.d*)
    _DATA_END_ = .;
  }

  .tdata ALIGN(0x10) :
  {
    _TDATA_START_ = .;
    *(.tdata .tdata.*)
    _TDATA_END_ = .;
    . = ALIGN(0x10);
  }
  .tbss :
  {
    _TBSS_START_ = .;
    *(.tbss .tbss.*)
    _TBSS_END_ = .;
    . = ALIGN(0x10);
  }

  .memdisk :
  {
    _DISK_START_ = .;
    *(.diskdata)
    _DISK_END_ = .;
  }

  .elf_symbols : {
    _ELF_SYM_START_ = .;
    LONG (0);
  }

  /** Optional memory hole between memdisk and bss **/
  . += PRE_BSS_AREA;

  .bss ALIGN(0x1000) :
  {
    _BSS_START_ = .;
    *(.bss .bss.* .gnu.linkonce.b.*)
    *(COMMON)
    _BSS_END_ = .;
  }
  . = ALIGN(0x8);

  _end = .;

  PROVIDE (end = .);
  PROVIDE (_ELF_END_ = .);
  PROVIDE (_LOAD_END_ = .);
}

/**
 * This file is a part of the IncludeOS unikernel - www.includeos.org
 *
 * Copyright 2015 Oslo and Akershus University College of Applied Sciences
 * and Alfred Bratterud
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http: *www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
**/
ENTRY(_start)

SECTIONS
{
  PROVIDE ( _ELF_START_ = . + 0xA00000);
  PROVIDE ( _LOAD_START_ = _ELF_START_); /* For convenience w. multiboot */

  . = _ELF_START_;

  .multiboot : {
      PROVIDE(_MULTIBOOT_START_ = .);
      *(.multiboot)
   }

  .text ALIGN(0x10):
  {
  PROVIDE( _TEXT_START_ = . );
    /* For solo5, although it's just used to print the mem layout. */
    _stext = .;
    *(.text)
    *(.text.*)
    *(.gnu.linkonce.t*)
    /* For solo5, although it's just used to print the mem layout. */
    _etext = .;
  }
  PROVIDE( _TEXT_END_ = . );

  .init ALIGN(0x10) : {
    _INIT_START_ = .;
    *(.init)
    _INIT_END_ = .;
  }

  .fini ALIGN(0x10) : {
    *(.fini)
  }

  /* Global offset-table. For dynamic linking */
  .got ALIGN(0x10) : {
      *(.got*)
  }

/**
 *  .ctors, .dtors, .preinit_array, .init_array, .fini_array
 *  from GNU LD default linker script
 */

.ctors          :
  {
    _GCONSTR_START_ = .;
      /* gcc uses crtbegin.o to find the start of
       the constructors, so we make sure it is
       first.  Because this is a wildcard, it
       doesn't matter if the user does not
       actually link against crtbegin.o; the
       linker won't look for a file to match a
       wildcard.  The wildcard also means that it
       doesn't matter which directory crtbegin.o
       is in.  */
       KEEP (*crtbegin.o(.ctors))
       KEEP (*crtbegin?.o(.ctors))
       /* We don't want to include the .ctor section from
       the crtend.o file until after the sorted ctors.
       The .ctor section from the crtend file contains the
       end of ctors marker and it must be last */
       KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
       KEEP (*(SORT(.ctors.*)))
       KEEP (*(.ctors))
    _GCONSTR_END_ = .;
  }

  .dtors :
  {
    KEEP (*crtbegin.o(.dtors))
    KEEP (*crtbegin?.o(.dtors))
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
  }

  .preinit_array :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  }

  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
    KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
    PROVIDE_HIDDEN (__init_array_end = .);
  }

  .fini_array :
  {
   PROVIDE_HIDDEN (__fini_array_start = .);
   KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
   KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
   PROVIDE_HIDDEN (__fini_array_end = .);
  }

  .config ALIGN(0x8) : {
    _CONFIG_JSON_START_ = .;
    KEEP(*(.config))
    _CONFIG_JSON_END_ = .;
    BYTE(0);
  }

  .rodata :
  {
    _RODATA_START_ = .;
    *(.rodata*)
    *(.gnu.linkonce.r*)
    _RODATA_END_ = .;
    /* For solo5, although it's just used to print the mem layout. */
    _erodata = .;
  }

  /* For stack unwinding (exception handling)  */
  .eh_frame_hdr ALIGN(0x8):
  {
    KEEP(*(.eh_frame_hdr*))
  }
  .eh_frame ALIGN(0x8):
  {
    PROVIDE (__eh_frame_start = .);
    KEEP(*(.eh_frame))
    LONG (0);
  }

  .gcc_except_table :
  {
    *(.gcc_except_table)
  }

  .data :
  {
    _DATA_START_ = .;
    *(.data)
    *(.data.*)
    *(.gnu.linkonce.d*)
    _DATA_END_ = .;
  }

  .tdata ALIGN(0x10) :
  {
    _TDATA_START_ = .;
    *(.tdata .tdata.*)
    _TDATA_END_ = .;
    . = ALIGN(0x10);
  }
  .tbss :
  {
    _TBSS_START_ = .;
    *(.tbss .tbss.*)
    _TBSS_END_ = .;
    . = ALIGN(0x10);
  }

  .memdisk :
  {
    _DISK_START_ = .;
    *(.diskdata)
    _DISK_END_ = .;
  }

  .elf_symbols : {
    _ELF_SYM_START_ = .;
    LONG (0);
  }

  /** Optional memory hole between memdisk and bss **/
  . += PRE_BSS_AREA;

  .bss ALIGN(0x1000) :
  {
    _BSS_START_ = .;
    *(.bss .bss.* .gnu.linkonce.b.*)
    *(COMMON)
    _BSS_END_ = .;
  }
  . = ALIGN(0x8);

  _end = .;

  PROVIDE (end = .);
  PROVIDE (_ELF_END_ = .);
  PROVIDE (_LOAD_END_ = .);
}


update ld add *(.sdk.version)

update ld add *(.sdk.version)

/* This linker script generated from xt-genldscripts.tpp for LSP . */
/* Linker Script for ld -N */

PHDRS
{
  dport0_0_phdr PT_LOAD;
  dram0_0_phdr PT_LOAD;
  dram0_0_bss_phdr PT_LOAD;
  iram1_0_phdr PT_LOAD;
  irom0_0_phdr PT_LOAD;
}

/*  Default entry point:  */
ENTRY(call_user_start)
EXTERN(_DebugExceptionVector)
EXTERN(_DoubleExceptionVector)
EXTERN(_KernelExceptionVector)
EXTERN(_NMIExceptionVector)
EXTERN(_UserExceptionVector)
PROVIDE(_memmap_vecbase_reset = 0x40000000);
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00000110;
_memmap_cacheattr_wt_base = 0x00000110;
_memmap_cacheattr_bp_base = 0x00000220;
_memmap_cacheattr_unused_mask = 0xFFFFF00F;
_memmap_cacheattr_wb_trapnull = 0x2222211F;
_memmap_cacheattr_wba_trapnull = 0x2222211F;
_memmap_cacheattr_wbna_trapnull = 0x2222211F;
_memmap_cacheattr_wt_trapnull = 0x2222211F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFFF11F;
_memmap_cacheattr_wt_strict = 0xFFFFF11F;
_memmap_cacheattr_bp_strict = 0xFFFFF22F;
_memmap_cacheattr_wb_allvalid = 0x22222112;
_memmap_cacheattr_wt_allvalid = 0x22222112;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);

SECTIONS
{

  .dport0.rodata : ALIGN(4)
  {
    _dport0_rodata_start = ABSOLUTE(.);
    *(.dport0.rodata)
    *(.dport.rodata)
    _dport0_rodata_end = ABSOLUTE(.);
  } >dport0_0_seg :dport0_0_phdr

  .dport0.literal : ALIGN(4)
  {
    _dport0_literal_start = ABSOLUTE(.);
    *(.dport0.literal)
    *(.dport.literal)
    _dport0_literal_end = ABSOLUTE(.);
  } >dport0_0_seg :dport0_0_phdr

  .dport0.data : ALIGN(4)
  {
    _dport0_data_start = ABSOLUTE(.);
    *(.dport0.data)
    *(.dport.data)
    _dport0_data_end = ABSOLUTE(.);
  } >dport0_0_seg :dport0_0_phdr

  .data : ALIGN(4)
  {
    _data_start = ABSOLUTE(.);
    *(.data)
    *(.data.*)
    *(.gnu.linkonce.d.*)
    *(.data1)
    *(.sdata)
    *(.sdata.*)
    *(.gnu.linkonce.s.*)
    *(.sdata2)
    *(.sdata2.*)
    *(.gnu.linkonce.s2.*)
    *(.jcr)
    _data_end = ABSOLUTE(.);
  } >dram0_0_seg :dram0_0_phdr

  .rodata : ALIGN(4)
  {
    _rodata_start = ABSOLUTE(.);
    *(.sdk.version)
    *(.rodata)
    *(.rodata.*)
    *(.gnu.linkonce.r.*)
    *(.rodata1)
    __XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
    *(.xt_except_table)
    *(.gcc_except_table)
    *(.gnu.linkonce.e.*)
    *(.gnu.version_r)
    *(.eh_frame)
    . = (. + 3) & ~ 3;
    /*  C++ constructor and destructor tables, properly ordered:  */
    __init_array_start = ABSOLUTE(.);
    KEEP (*crtbegin.o(.ctors))
    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
    __init_array_end = ABSOLUTE(.);
    KEEP (*crtbegin.o(.dtors))
    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
    /*  C++ exception handlers table:  */
    __XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
    *(.xt_except_desc)
    *(.gnu.linkonce.h.*)
    __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
    *(.xt_except_desc_end)
    *(.dynamic)
    *(.gnu.version_d)
    . = ALIGN(4);		/* this table MUST be 4-byte aligned */
    _bss_table_start = ABSOLUTE(.);
    LONG(_bss_start)
    LONG(_bss_end)
    _bss_table_end = ABSOLUTE(.);
    _rodata_end = ABSOLUTE(.);
  } >dram0_0_seg :dram0_0_phdr

  .bss ALIGN(8) (NOLOAD) : ALIGN(4)
  {
    . = ALIGN (8);
    _bss_start = ABSOLUTE(.);
    *(.dynsbss)
    *(.sbss)
    *(.sbss.*)
    *(.gnu.linkonce.sb.*)
    *(.scommon)
    *(.sbss2)
    *(.sbss2.*)
    *(.gnu.linkonce.sb2.*)
    *(.dynbss)
    *(.bss)
    *(.bss.*)
    *(.gnu.linkonce.b.*)
    *(COMMON)
    . = ALIGN (8);
    _bss_end = ABSOLUTE(.);
    _heap_start = ABSOLUTE(.);
/*    _stack_sentry = ALIGN(0x8); */
  } >dram0_0_seg :dram0_0_bss_phdr
/* __stack = 0x3ffc8000; */

  .irom0.text : ALIGN(4)
  {
    _irom0_text_start = ABSOLUTE(.);
    *core_esp8266_*.o(.literal*, .text*)
    *spiffs*.o(.literal*, .text*)
    *.cpp.o(.literal*, .text*)
    *libm.a:(.literal .text .literal.* .text.*)
    *libsmartconfig.a:(.literal .text .literal.* .text.*)
    *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
    _irom0_text_end = ABSOLUTE(.);
    _flash_code_end = ABSOLUTE(.);
  } >irom0_0_seg :irom0_0_phdr

  .text : ALIGN(4)
  {
    _stext = .;
    _text_start = ABSOLUTE(.);
     *(.UserEnter.text)
    . = ALIGN(16);
    *(.DebugExceptionVector.text)
    . = ALIGN(16);
    *(.NMIExceptionVector.text)
    . = ALIGN(16);
    *(.KernelExceptionVector.text)
    LONG(0)
    LONG(0)
    LONG(0)
    LONG(0)
    . = ALIGN(16);
    *(.UserExceptionVector.text)
    LONG(0)
    LONG(0)
    LONG(0)
    LONG(0)
    . = ALIGN(16);
    *(.DoubleExceptionVector.text)
    LONG(0)
    LONG(0)
    LONG(0)
    LONG(0)
    . = ALIGN (16);
    *(.entry.text)
    *(.init.literal)
    *(.init)
    *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
    *(.fini.literal)
    *(.fini)
    *(.gnu.version)
    _text_end = ABSOLUTE(.);
    _etext = .;
  } >iram1_0_seg :iram1_0_phdr

  .lit4 : ALIGN(4)
  {
    _lit4_start = ABSOLUTE(.);
    *(*.lit4)
    *(.lit4.*)
    *(.gnu.linkonce.lit4.*)
    _lit4_end = ABSOLUTE(.);
  } >iram1_0_seg :iram1_0_phdr

}

/* get ROM code address */
INCLUDE "../ld/eagle.rom.addr.v6.ld"

/* This linker script generated from xt-genldscripts.tpp for LSP . */
/* Linker Script for ld -N */

PHDRS
{
  dport0_0_phdr PT_LOAD;
  dram0_0_phdr PT_LOAD;
  dram0_0_bss_phdr PT_LOAD;
  iram1_0_phdr PT_LOAD;
  irom0_0_phdr PT_LOAD;
}

/*  Default entry point:  */
ENTRY(call_user_start)
EXTERN(_DebugExceptionVector)
EXTERN(_DoubleExceptionVector)
EXTERN(_KernelExceptionVector)
EXTERN(_NMIExceptionVector)
EXTERN(_UserExceptionVector)
PROVIDE(_memmap_vecbase_reset = 0x40000000);
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00000110;
_memmap_cacheattr_wt_base = 0x00000110;
_memmap_cacheattr_bp_base = 0x00000220;
_memmap_cacheattr_unused_mask = 0xFFFFF00F;
_memmap_cacheattr_wb_trapnull = 0x2222211F;
_memmap_cacheattr_wba_trapnull = 0x2222211F;
_memmap_cacheattr_wbna_trapnull = 0x2222211F;
_memmap_cacheattr_wt_trapnull = 0x2222211F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFFF11F;
_memmap_cacheattr_wt_strict = 0xFFFFF11F;
_memmap_cacheattr_bp_strict = 0xFFFFF22F;
_memmap_cacheattr_wb_allvalid = 0x22222112;
_memmap_cacheattr_wt_allvalid = 0x22222112;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);

SECTIONS
{

  .dport0.rodata : ALIGN(4)
  {
    _dport0_rodata_start = ABSOLUTE(.);
    *(.dport0.rodata)
    *(.dport.rodata)
    _dport0_rodata_end = ABSOLUTE(.);
  } >dport0_0_seg :dport0_0_phdr

  .dport0.literal : ALIGN(4)
  {
    _dport0_literal_start = ABSOLUTE(.);
    *(.dport0.literal)
    *(.dport.literal)
    _dport0_literal_end = ABSOLUTE(.);
  } >dport0_0_seg :dport0_0_phdr

  .dport0.data : ALIGN(4)
  {
    _dport0_data_start = ABSOLUTE(.);
    *(.dport0.data)
    *(.dport.data)
    _dport0_data_end = ABSOLUTE(.);
  } >dport0_0_seg :dport0_0_phdr

  .data : ALIGN(4)
  {
    _data_start = ABSOLUTE(.);
    *(.data)
    *(.data.*)
    *(.gnu.linkonce.d.*)
    *(.data1)
    *(.sdata)
    *(.sdata.*)
    *(.gnu.linkonce.s.*)
    *(.sdata2)
    *(.sdata2.*)
    *(.gnu.linkonce.s2.*)
    *(.jcr)
    _data_end = ABSOLUTE(.);
  } >dram0_0_seg :dram0_0_phdr

  .rodata : ALIGN(4)
  {
    _rodata_start = ABSOLUTE(.);
    *(.rodata)
    *(.rodata.*)
    *(.gnu.linkonce.r.*)
    *(.rodata1)
    __XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
    *(.xt_except_table)
    *(.gcc_except_table)
    *(.gnu.linkonce.e.*)
    *(.gnu.version_r)
    *(.eh_frame)
    . = (. + 3) & ~ 3;
    /*  C++ constructor and destructor tables, properly ordered:  */
    __init_array_start = ABSOLUTE(.);
    KEEP (*crtbegin.o(.ctors))
    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
    __init_array_end = ABSOLUTE(.);
    KEEP (*crtbegin.o(.dtors))
    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
    /*  C++ exception handlers table:  */
    __XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
    *(.xt_except_desc)
    *(.gnu.linkonce.h.*)
    __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
    *(.xt_except_desc_end)
    *(.dynamic)
    *(.gnu.version_d)
    . = ALIGN(4);		/* this table MUST be 4-byte aligned */
    _bss_table_start = ABSOLUTE(.);
    LONG(_bss_start)
    LONG(_bss_end)
    _bss_table_end = ABSOLUTE(.);
    _rodata_end = ABSOLUTE(.);
  } >dram0_0_seg :dram0_0_phdr

  .bss ALIGN(8) (NOLOAD) : ALIGN(4)
  {
    . = ALIGN (8);
    _bss_start = ABSOLUTE(.);
    *(.dynsbss)
    *(.sbss)
    *(.sbss.*)
    *(.gnu.linkonce.sb.*)
    *(.scommon)
    *(.sbss2)
    *(.sbss2.*)
    *(.gnu.linkonce.sb2.*)
    *(.dynbss)
    *(.bss)
    *(.bss.*)
    *(.gnu.linkonce.b.*)
    *(COMMON)
    . = ALIGN (8);
    _bss_end = ABSOLUTE(.);
    _heap_start = ABSOLUTE(.);
/*    _stack_sentry = ALIGN(0x8); */
  } >dram0_0_seg :dram0_0_bss_phdr
/* __stack = 0x3ffc8000; */

  .irom0.text : ALIGN(4)
  {
    _irom0_text_start = ABSOLUTE(.);
    *core_esp8266_*.o(.literal*, .text*)
    *spiffs*.o(.literal*, .text*)
    *.cpp.o(.literal*, .text*)
    *libm.a:(.literal .text .literal.* .text.*)
    *libsmartconfig.a:(.literal .text .literal.* .text.*)
    *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
    _irom0_text_end = ABSOLUTE(.);
    _flash_code_end = ABSOLUTE(.);
  } >irom0_0_seg :irom0_0_phdr

  .text : ALIGN(4)
  {
    _stext = .;
    _text_start = ABSOLUTE(.);
     *(.UserEnter.text)
    . = ALIGN(16);
    *(.DebugExceptionVector.text)
    . = ALIGN(16);
    *(.NMIExceptionVector.text)
    . = ALIGN(16);
    *(.KernelExceptionVector.text)
    LONG(0)
    LONG(0)
    LONG(0)
    LONG(0)
    . = ALIGN(16);
    *(.UserExceptionVector.text)
    LONG(0)
    LONG(0)
    LONG(0)
    LONG(0)
    . = ALIGN(16);
    *(.DoubleExceptionVector.text)
    LONG(0)
    LONG(0)
    LONG(0)
    LONG(0)
    . = ALIGN (16);
    *(.entry.text)
    *(.init.literal)
    *(.init)
    *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
    *(.fini.literal)
    *(.fini)
    *(.gnu.version)
    _text_end = ABSOLUTE(.);
    _etext = .;
  } >iram1_0_seg :iram1_0_phdr

  .lit4 : ALIGN(4)
  {
    _lit4_start = ABSOLUTE(.);
    *(*.lit4)
    *(.lit4.*)
    *(.gnu.linkonce.lit4.*)
    _lit4_end = ABSOLUTE(.);
  } >iram1_0_seg :iram1_0_phdr

}

/* get ROM code address */
INCLUDE "../ld/eagle.rom.addr.v6.ld"


Now linker script create low and high sections

OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY (loader)

SECTIONS
{
    . = 0x00100000;
    .setup ALIGN (0x1000) :
    {
        __start_setup = .;
        *(.setup)
        *(.setup.data)
        __end_setup = .;
    }

    /* Higher half */
    . += 0xc0000000;
    .text ALIGN (0x1000) :
    {
        *(.text)
    __start_cs_init = .;
        *(.init.text)
    __end_cs_init = .;
    }

    .rodata ALIGN (0x1000) :
    {
    __start_data_kernel = .;
        *(.rodata*)
    }

    .data ALIGN (0x1000) :
    {
        *(.data)
    }

    .bss :
    {
        sbss = .;
        *(COMMON)
        *(.bss)
        ebss = .;
    __end_data_kernel = .;
    }
}

OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY (loader)

SECTIONS
{
    . = 0x00100000;
    .text ALIGN (0x1000) :
    {
    __start_cs_kernel = .;
        *(.text)
    __start_cs_init = .;
        *(.init.text)
    __end_cs_init = .;
    __end_cs_kernel = .;
    }

    .rodata ALIGN (0x1000) :
    {
    __start_data_kernel = .;
        *(.rodata*)
    }

    .data ALIGN (0x1000) :
    {
        *(.data)
    }

    .bss :
    {
        sbss = .;
        *(COMMON)
        *(.bss)
        ebss = .;
    __end_data_kernel = .;
    }
}


X1000: x1000_ram.lds: 修复调试时崩溃的问题/Fix crash when debugging.

当ELF文件包含很多gnu_extab*开头的section时(>100)，会导致GDB在加载操作
时崩溃。通过创建一个section来对以该名称开头的所有section进行分组可以
解决该问题。

When ELF contains many sectios(>100) starting with name gnu_extab*,
will causing GDB to crash on load action. Solving the problem by
creating a section to group all sections which begin with that name.

Signed-off-by: Zhou Yanjie <17015b8cdc0ca77b55f0bd985068d713e2de996d@zoho.com>

/*
 * File      : x1000_ram.lds
 * COPYRIGHT (C) 2015, RT-Thread Development Team
 *
 *  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; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Change Logs:
 * 2015-12-12     bernard       first version
 */

OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradlittlemips", "elf32-tradlittlemips")
OUTPUT_ARCH(mips)

MEMORY
{
   /* 16M SDRAM */
   DRAM : ORIGIN = 0x80800000, LENGTH = 0x01800000
   /* 16K SRAM  */
   IRAM : ORIGIN = 0x80000000, LENGTH = 0x00004000
}

ENTRY(_start)
SECTIONS
{
    .start :
    {
        *(.start);
    } > DRAM

    . = ALIGN(4);

    .text :
    {
        *(.text.unlikely .text.*_unlikely .text.unlikely.*)
        *(.text.exit .text.exit.*)
        *(.text.startup .text.startup.*)
        *(.text.hot .text.hot.*)
        *(.text .stub .text.* .gnu.linkonce.t.*)
        *(.text)                        /* remaining code */
        *(.text.*)                      /* remaining code */
        *(.rodata)                      /* read-only data (constants) */
        *(.rodata*)
        *(.glue_7)
        *(.glue_7t)
        *(.gnu.linkonce.t*)

        /* section information for finsh shell */
        . = ALIGN(4);
        __fsymtab_start = .;
        KEEP(*(FSymTab))
        __fsymtab_end = .;
        . = ALIGN(4);
        __vsymtab_start = .;
        KEEP(*(VSymTab))
        __vsymtab_end = .;
        . = ALIGN(4);

        /* section information for initial. */
        . = ALIGN(4);
        __rt_init_start = .;
        KEEP(*(SORT(.rti_fn*)))
        __rt_init_end = .;
        . = ALIGN(4);

        /* section information for modules */
        . = ALIGN(4);
        __rtmsymtab_start = .;
        KEEP(*(RTMSymTab))
        __rtmsymtab_end = .;

        . = ALIGN(4);
        _etext = .;
    } > DRAM

    .eh_frame_hdr :
    {
         *(.eh_frame_hdr)
         *(.eh_frame_entry)
         *(.eh_frame_entry.*)
    } > DRAM
    .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } > DRAM

    . = ALIGN(4);
    .gnu_extab :
    {
        *(.gnu_extab.*)
    } > DRAM

    . = ALIGN(4);
    .ctors :
    {
        PROVIDE(__ctors_start__ = .);
        KEEP(*(SORT(.ctors.*)))
        KEEP(*(.ctors))
        PROVIDE(__ctors_end__ = .);
    } > DRAM

    .dtors :
    {
        PROVIDE(__dtors_start__ = .);
        KEEP(*(SORT(.dtors.*)))
        KEEP(*(.dtors))
        PROVIDE(__dtors_end__ = .);
    } > DRAM

    .data :
    {
     *(.data)
     *(.data.*)

     *(.data1)
     *(.data1.*)

     . = ALIGN(8);
     _gp = ABSOLUTE(.);     /* Base of small data */

     *(.sdata)
     *(.sdata.*)
    } > DRAM

    . = ALIGN(4);
    _iramat = .;

    .iram : AT(_iramat)
    {
        _iramstart = .;
        *(.vectors.1);
        . = 0x100;
        *(.vectors.2);
        . = 0x180;
        *(.vectors.3);
        . = 0x200;
        *(.vectors.4);
        *(.vectors);

        *(.icode);
        *(.irodata);
        *(.idata);
        KEEP(*(.vectors*))
        _iramend = .;
    } > IRAM
    _iramcopy = LOADADDR(.iram);

    .sbss :
    {
    __bss_start = .;
        *(.sbss)
        *(.sbss.*)
        *(.dynsbss)
        *(.scommon)
    } > DRAM

    .bss :
    {
        *(.bss)
        *(.bss.*)
        *(.dynbss)
        *(COMMON)
    __bss_end = .;
    } > DRAM

    _end = .;

    /* Stabs debugging sections.  */
    .stab          0 : { *(.stab) }
    .stabstr       0 : { *(.stabstr) }
    .stab.excl     0 : { *(.stab.excl) }
    .stab.exclstr  0 : { *(.stab.exclstr) }
    .stab.index    0 : { *(.stab.index) }
    .stab.indexstr 0 : { *(.stab.indexstr) }
    .comment       0 : { *(.comment) }
    /* DWARF debug sections.
     * Symbols in the DWARF debugging sections are relative to the beginning
     * of the section so we begin them at 0.  */
    /* DWARF 1 */
    .debug          0 : { *(.debug) }
    .line           0 : { *(.line) }
    /* GNU DWARF 1 extensions */
    .debug_srcinfo  0 : { *(.debug_srcinfo) }
    .debug_sfnames  0 : { *(.debug_sfnames) }
    /* DWARF 1.1 and DWARF 2 */
    .debug_aranges  0 : { *(.debug_aranges) }
    .debug_pubnames 0 : { *(.debug_pubnames) }
    /* DWARF 2 */
    .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
    .debug_abbrev   0 : { *(.debug_abbrev) }
    .debug_line     0 : { *(.debug_line) }
    .debug_frame    0 : { *(.debug_frame) }
    .debug_str      0 : { *(.debug_str) }
    .debug_loc      0 : { *(.debug_loc) }
    .debug_macinfo  0 : { *(.debug_macinfo) }
    /* SGI/MIPS DWARF 2 extensions */
    .debug_weaknames 0 : { *(.debug_weaknames) }
    .debug_funcnames 0 : { *(.debug_funcnames) }
    .debug_typenames 0 : { *(.debug_typenames) }
    .debug_varnames  0 : { *(.debug_varnames) }
}

/*
 * File      : x1000_ram.lds
 * COPYRIGHT (C) 2015, RT-Thread Development Team
 *
 *  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; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Change Logs:
 * 2015-12-12     bernard       first version
 */

OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradlittlemips", "elf32-tradlittlemips")
OUTPUT_ARCH(mips)

MEMORY
{
   /* 16M SDRAM */
   DRAM : ORIGIN = 0x80800000, LENGTH = 0x01800000
   /* 16K SRAM  */
   IRAM : ORIGIN = 0x80000000, LENGTH = 0x00004000
}

ENTRY(_start)
SECTIONS
{
    .start :
    {
        *(.start);
    } > DRAM

    . = ALIGN(4);

    .text :
    {
        *(.text)                        /* remaining code */
        *(.text.*)                      /* remaining code */
        *(.rodata)                      /* read-only data (constants) */
        *(.rodata*)
        *(.glue_7)
        *(.glue_7t)
        *(.gnu.linkonce.t*)

        /* section information for finsh shell */
        . = ALIGN(4);
        __fsymtab_start = .;
        KEEP(*(FSymTab))
        __fsymtab_end = .;
        . = ALIGN(4);
        __vsymtab_start = .;
        KEEP(*(VSymTab))
        __vsymtab_end = .;
        . = ALIGN(4);

        /* section information for initial. */
        . = ALIGN(4);
        __rt_init_start = .;
        KEEP(*(SORT(.rti_fn*)))
        __rt_init_end = .;
        . = ALIGN(4);

        /* section information for modules */
        . = ALIGN(4);
        __rtmsymtab_start = .;
        KEEP(*(RTMSymTab))
        __rtmsymtab_end = .;

        . = ALIGN(4);
        _etext = .;
    } > DRAM

    .eh_frame_hdr :
    {
         *(.eh_frame_hdr)
         *(.eh_frame_entry)
         *(.eh_frame_entry.*)
    } > DRAM
    .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } > DRAM

    . = ALIGN(4);
    .ctors :
    {
        PROVIDE(__ctors_start__ = .);
        KEEP(*(SORT(.ctors.*)))
        KEEP(*(.ctors))
        PROVIDE(__ctors_end__ = .);
    } > DRAM

    .dtors :
    {
        PROVIDE(__dtors_start__ = .);
        KEEP(*(SORT(.dtors.*)))
        KEEP(*(.dtors))
        PROVIDE(__dtors_end__ = .);
    } > DRAM

    .data :
    {
     *(.data)
     *(.data.*)

     *(.data1)
     *(.data1.*)

     . = ALIGN(8);
     _gp = ABSOLUTE(.);     /* Base of small data */

     *(.sdata)
     *(.sdata.*)
    } > DRAM

    . = ALIGN(4);
    _iramat = .;

    .iram : AT(_iramat)
    {
        _iramstart = .;
        *(.vectors.1);
        . = 0x100;
        *(.vectors.2);
        . = 0x180;
        *(.vectors.3);
        . = 0x200;
        *(.vectors.4);
        *(.vectors);

        *(.icode);
        *(.irodata);
        *(.idata);
        KEEP(*(.vectors*))
        _iramend = .;
    } > IRAM
    _iramcopy = LOADADDR(.iram);

    .sbss :
    {
    __bss_start = .;
        *(.sbss)
        *(.sbss.*)
        *(.dynsbss)
        *(.scommon)
    } > DRAM

    .bss :
    {
        *(.bss)
        *(.bss.*)
        *(.dynbss)
        *(COMMON)
    __bss_end = .;
    } > DRAM

    _end = .;

    /* Stabs debugging sections.  */
    .stab          0 : { *(.stab) }
    .stabstr       0 : { *(.stabstr) }
    .stab.excl     0 : { *(.stab.excl) }
    .stab.exclstr  0 : { *(.stab.exclstr) }
    .stab.index    0 : { *(.stab.index) }
    .stab.indexstr 0 : { *(.stab.indexstr) }
    .comment       0 : { *(.comment) }
    /* DWARF debug sections.
     * Symbols in the DWARF debugging sections are relative to the beginning
     * of the section so we begin them at 0.  */
    /* DWARF 1 */
    .debug          0 : { *(.debug) }
    .line           0 : { *(.line) }
    /* GNU DWARF 1 extensions */
    .debug_srcinfo  0 : { *(.debug_srcinfo) }
    .debug_sfnames  0 : { *(.debug_sfnames) }
    /* DWARF 1.1 and DWARF 2 */
    .debug_aranges  0 : { *(.debug_aranges) }
    .debug_pubnames 0 : { *(.debug_pubnames) }
    /* DWARF 2 */
    .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
    .debug_abbrev   0 : { *(.debug_abbrev) }
    .debug_line     0 : { *(.debug_line) }
    .debug_frame    0 : { *(.debug_frame) }
    .debug_str      0 : { *(.debug_str) }
    .debug_loc      0 : { *(.debug_loc) }
    .debug_macinfo  0 : { *(.debug_macinfo) }
    /* SGI/MIPS DWARF 2 extensions */
    .debug_weaknames 0 : { *(.debug_weaknames) }
    .debug_funcnames 0 : { *(.debug_funcnames) }
    .debug_typenames 0 : { *(.debug_typenames) }
    .debug_varnames  0 : { *(.debug_varnames) }
}