/********************************************************************************************************
 * @file    boot_b91.link
 *
 * @brief   This is the link file for B91
 *
 * @author  Driver & Zigbee Group
 * @date    2021
 *
 * @par     Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
 *          All rights reserved.
 *
 *          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(_RESET_ENTRY)
SECTIONS
{
	NDS_SAG_LMA_FLASH = 0x20000000 ;
	. = (0x20000000 + __FW_OFFSET);	
	PROVIDE (BIN_BEGIN = .);
	.vectors 		: { KEEP(*(.vectors )) }
	. = 0x00000000;
	.retention_reset	: AT( ALIGN(LOADADDR (.vectors) + SIZEOF (.vectors),8)) 
	  	{ KEEP(*(.retention_reset )) }
	PROVIDE (_RETENTION_RESET_VMA_START = ADDR(.retention_reset));
	PROVIDE (_RETENTION_RESET_LMA_START = LOADADDR(.retention_reset));
	PROVIDE (_RETENTION_RESET_VMA_END = .); 
	/* By default,the aes_data section can only be used in the first 64K of IRAM, */
	/* please do not change the position of this section,unless you know the correct way to use */ 
	. = ALIGN(8);
	PROVIDE (_AES_VMA_START = .);
	.aes_data 	(NOLOAD)	: { KEEP(*(.aes_data )) }
	PROVIDE (_AES_VMA_END = .);
	/*. = ALIGN(8);*/
	/*.retention_data : AT( ALIGN(LOADADDR (.retention_reset) + SIZEOF (.retention_reset),8)) */
	/*	{ KEEP(*(.retention_data )) }*/
	/*PROVIDE (_RETENTION_DATA_VMA_START = ADDR(.retention_data));*/
	/*PROVIDE (_RETENTION_DATA_LMA_START = LOADADDR(.retention_data));*/
	/*PROVIDE (_RETENTION_DATA_VMA_END = .); */
	
	. = ALIGN(8);
	.ram_code	: AT( ALIGN(LOADADDR (.retention_reset) + SIZEOF (.retention_reset),8)) 
	  	{ KEEP(*(.ram_code )) }
	PROVIDE (_RAMCODE_VMA_END = .);
	PROVIDE (_RAMCODE_VMA_START = ADDR(.ram_code));
	PROVIDE (_RAMCODE_LMA_START = LOADADDR(.ram_code));
	PROVIDE (_RAMCODE_SIZE = SIZEOF (.ram_code)); 
	
	. = ALIGN(LOADADDR (.ram_code) + SIZEOF (.ram_code), 8);
	.text 			: AT(ALIGN(LOADADDR (.ram_code) + SIZEOF (.ram_code), 8)) 
		{ *(.text .stub .text.* .gnu.linkonce.t.* ) KEEP(*(.text.*personality* )) *(.gnu.warning )  }
	.rodata 		: AT(ALIGN(LOADADDR (.text) + SIZEOF (.text), ALIGNOF(.rodata))) 
		{ *(.rodata .rodata.* .gnu.linkonce.r.* )}
	.eh_frame_hdr 	: AT(ALIGN(LOADADDR (.rodata) + SIZEOF (.rodata), ALIGNOF(.eh_frame_hdr)))
		{ *(.eh_frame_hdr ) }
	. = ALIGN(0x20);
	.eh_frame 	: AT(ALIGN(LOADADDR (.eh_frame_hdr) + SIZEOF (.eh_frame_hdr), 32))
		{ KEEP(*(.eh_frame )) }
		
	.exec.itable 	: AT(ALIGN(LOADADDR (.eh_frame) + SIZEOF (.eh_frame), ALIGNOF(.exec.itable)))
		{ KEEP(*(.exec.itable)) }
				
	/*. = 0x00080000;*/
	. = ALIGN(ADDR (.ram_code) + SIZEOF (.ram_code), 8);
	PROVIDE( __global_pointer$ = . + (4K / 2) );
	.data	: AT(ALIGN(LOADADDR (.exec.itable) + SIZEOF (.exec.itable),  ALIGNOF(.data)))
		{ *(.data .data.* .gnu.linkonce.d.* ) KEEP(*(.gnu.linkonce.d.*personality* )) SORT(CONSTRUCTORS) 
		  *(.srodata.cst16 ) *(.srodata.cst8 ) *(.srodata.cst4 ) *(.srodata.cst2 ) *(.srodata .srodata.* ) *(.sdata .sdata.* .gnu.linkonce.s.* ) *(.sdata2 .sdata2.* .gnu.linkonce.s.* )
		}
    PROVIDE (_DATA_VMA_END = .);
    PROVIDE (_DATA_VMA_START = ADDR(.data));
	PROVIDE (_DATA_LMA_START = LOADADDR(.data));
	
	. = ALIGN(8);
	PROVIDE (_BSS_VMA_START = .);
	.sbss 	(NOLOAD)	: { *(.dynsbss ) *(.sbss .sbss.* .gnu.linkonce.sb.* ) *(.scommon .scommon.* ) }
	.bss 	(NOLOAD)	: { *(.dynbss ) *(.bss .bss.* .gnu.linkonce.b.* ) *(COMMON ) . = ALIGN(8); }
	PROVIDE (_BSS_VMA_END = .);
	
	.sdk_version  	: AT(LOADADDR (.data) + SIZEOF (.data))
		{ KEEP(*(.sdk_version )) }
	
	PROVIDE (BIN_SIZE = LOADADDR(.sdk_version) + SIZEOF(.sdk_version) - BIN_BEGIN);
	
	. = ALIGN(8);
	/* end is the starting address of the heap, the heap grows upward */
	_end = .;
	PROVIDE (end = .);		
	/*PROVIDE (_STACK_TOP = 0x00a0000);*/
	PROVIDE (_STACK_TOP = 0x0020000);
	PROVIDE (FLASH_SIZE = 0x0100000);
}

ASSERT((BIN_SIZE)<= FLASH_SIZE, "BIN FILE OVERFLOW");
