1/*
2 * Copyright 2014, General Dynamics C4 Systems
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7#define __ASSEMBLER__
8#include <config.h>
9#include <hardware.h>
10
11ENTRY(_start)
12
13KLOAD_PADDR = KERNEL_ELF_PADDR_BASE;
14KLOAD_VADDR = KERNEL_ELF_BASE;
15
16/* WARNING: constants also defined in plat/machine/hardware.h */
17#if defined(CONFIG_ARCH_IA32)
18#undef i386
19OUTPUT_ARCH(i386)
20OUTPUT_FORMAT(elf32-i386)
21#elif defined(CONFIG_ARCH_X86_64)
22OUTPUT_FORMAT(elf64-x86-64)
23#if defined(ENABLE_SMP_SUPPORT) && defined(CONFIG_KERNEL_SKIM_WINDOW)
24nodeSkimScratchOffset = nodeSkimScratch - node_info;
25#endif
26#endif
27
28KERNEL_OFFSET = KLOAD_VADDR - KLOAD_PADDR;
29
30PHDRS {
31    phys PT_LOAD FILEHDR PHDRS ;
32    boot PT_LOAD ;
33    virt PT_LOAD ;
34}
35
36SECTIONS
37{
38    /* load kernel to 1M to avoid the famous IA-32 memory holes below */
39    . = KLOAD_PADDR + SIZEOF_HEADERS;
40
41    /* code/data only needed during bootstrapping, linked to physical addresses */
42
43    .phys . :
44    {
45        *(.mbh)
46        *(.phys.text)
47        *(.phys.data)
48        . = . + 1;
49    } :phys
50
51    .phys.bss ADDR(.phys) + SIZEOF(.phys) + 4K (NOLOAD) :
52    {
53        . = ALIGN(16);
54        boot_stack_bottom = .;
55        . = . + 2K;
56        boot_stack_top = .;
57        *(.phys.bss)
58    } :phys
59
60    . = ALIGN(4K) + KERNEL_OFFSET;
61    . = . + ((ADDR(.phys) + SIZEOF(.phys)) & (4K - 1));
62    .boot . : AT(ADDR(.boot) - KERNEL_OFFSET)
63    {
64        *(.boot.text)
65        *(.boot.data)
66    } :boot
67
68    .boot.bss . (NOLOAD) : AT(ADDR(.boot.bss) - KERNEL_OFFSET)
69    {
70        *(.boot.bss)
71    } :boot
72#ifdef CONFIG_KERNEL_SKIM_WINDOW
73    /* Align up so that the SKIM portion of the kernel is by itself
74       on large pages */
75#ifdef CONFIG_ARCH_IA32
76    . = ALIGN(4M);
77#else
78    . = ALIGN(2M);
79#endif
80#else
81    . = ALIGN(8K);
82#endif
83
84    ki_boot_end = .;
85    ki_skim_start = .;
86
87    . = . + ((ADDR(.boot) + SIZEOF(.boot)) & (8K - 1));
88
89
90
91    .text . : AT(ADDR(.text) - KERNEL_OFFSET)
92    {
93        *(.text)
94    } :virt
95
96    .rodata . : AT(ADDR(.rodata) - KERNEL_OFFSET)
97    {
98        *(.rodata)
99        *(.rodata.*)
100    } :virt
101
102    .skim_data . : AT(ADDR(.skim_data) - KERNEL_OFFSET)
103    {
104        *(.skim.data)
105        *(.skim.data.*)
106    } :virt
107
108
109    .skim_bss . (NOLOAD) : AT(ADDR(.skim_bss) - KERNEL_OFFSET)
110    {
111        *(.skim.bss)
112        *(.skim.bss.*)
113    } :virt
114
115#ifdef CONFIG_KERNEL_SKIM_WINDOW
116    /* Align up so that the SKIM portion of the kernel is by itself
117       on large pages */
118#ifdef CONFIG_ARCH_IA32
119    . = ALIGN(4M);
120#else
121    . = ALIGN(2M);
122#endif
123#endif
124    ki_skim_end = .;
125
126    .data . : AT(ADDR(.data) - KERNEL_OFFSET)
127    {
128        *(.data)
129    } :virt
130
131    .bss . (NOLOAD) : AT(ADDR(.bss) - KERNEL_OFFSET)
132    {
133        *(.bss)
134        *(COMMON) /* fallback in case '-fno-common' is not used */
135    } :virt
136
137    . = ALIGN(4K);
138
139    ._idle_thread . (NOLOAD): AT(ADDR(._idle_thread) - KERNEL_OFFSET)
140    {
141	__idle_thread_start = .;
142        *(._idle_thread)
143	__idle_thread_end = .;
144    } :virt
145
146    . = ALIGN(4K);
147    ki_end = .;
148
149    /DISCARD/ :
150    {
151        *(.eh_frame)
152        *(.note.gnu.build-id)
153        *(.comment)
154    }
155}
156