Kernel Linker Scripts Analysis (ARM Architecture)
来源:互联网 发布:数据库管理系统的应用 编辑:程序博客网 时间:2024/05/01 09:12
1. arch/arm/kernel/vmlinux.lds的生成:
顶层的vmlinux是由arch/arm/kernel/vmlinux.lds链接生成,顶层Makefile里面定义:
693 vmlinux-lds := arch/$(SRCARCH)/kernel/vmlinux.lds
arch/arm/kernel/vmlinux.lds是由arch/arm/kernel/vmlinux.lds.S生成,生成规则在scripts/Makefile.build中定义:
265 # Linker scripts preprocessor (.lds.S -> .lds)
266 # -------------------------------------------------------------------------- -
267 quiet_cmd_cpp_lds_S = LDS $@
268 cmd_cpp_lds_S = $(CPP) $(cpp_flags) -D__ASSEMBLY__ -o $@ $<
269
270 $(obj)/%.lds: $(src)/%.lds.S FORCE
271 $(call if_changed_dep,cpp_lds_S)
2.顶层vmlinux的起始地址
在arch/arm/kernel/vmlinux.lds.S文件中:
21 #ifdef CONFIG_XIP_KERNEL
22 . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
23 #else
24 . = PAGE_OFFSET + TEXT_OFFSET;
25 #endif
由于没有配置CONFIG_XIP_KERNEL(可查看顶层.config文件),后面才是起始地址。
arch/arm/kernel/vmlinux.lds.S文件包含了头文件asm/memory.h,查看include/asm/memory.h
34 #define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET)
查看.config文件,可以得到CONFIG_PAGE_OFFSET=0xC0000000
搜索arch/arm目录可以在其下的Makefile文件中找到:
96 textofs-y := 0x00008000
160 # The byte offset of the kernel image in RAM from the start of RAM.
161 TEXT_OFFSET := $(textofs-y)
3. DEVKIT8000的虚实地址
在arch/arm/boot/Makefile中:
16 ifneq ($(MACHINE),)
17 include $(srctree)/$(MACHINE)/Makefile.boot
18 endif
即在arch/arm/mach-omap2/Makefile.boot文件中定义了一个压缩内核镜像zImage的起始地址:
1 zreladdr-y := 0x80008000
2 params_phys-y := 0x80000100
3 initrd_phys-y := 0x80800000
在arch/arm/boot/Makefile中:
24 ZRELADDR := $(zreladdr-y)
25 PARAMS_PHYS := $(params_phys-y)
26 INITRD_PHYS := $(initrd_phys-y)
在plat-omap/include/mach/memory.h中:
36 /*
37 * Physical DRAM offset.
38 */
39 #if defined(CONFIG_ARCH_OMAP1)
40 #define PHYS_OFFSET UL(0x10000000)
41 #elif defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
42 #define PHYS_OFFSET UL(0x80000000)
43 #endif
我们使用0x80000000做为物理的页偏移地址,即sdram地址
这个地址在启动代码arch/arm/kernel/head.S中会用到:
4. 压缩的自引导镜像arch/arm/boot/compressed/vmlinux的起始地址
这个vmlinux是由同目录先vmlinux.lds脚本链接而成,而vmlinux.lds由vmlinux.lds.in生成,这个文件开头:
14 . = TEXT_START;
而此目录下的Makefile中:
113 $(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config
114 @sed "$(SEDFLAGS)" < $< > $@
68 SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
表示把TEXT_START改名为ZTEXTADDR。
56 # We now have a PIC decompressor implementation. Decompressors running
57 # from RAM should not define ZTEXTADDR. Decompressors running directly
58 # from ROM or Flash must define ZTEXTADDR (preferably via the config)
59 # FIXME: Previous assignment to ztextaddr-y is lost here. See SHARK
60 ifeq ($(CONFIG_ZBOOT_ROM),y)
61 ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT)
62 ZBSSADDR := $(CONFIG_ZBOOT_ROM_BSS)
63 else
64 ZTEXTADDR := 0
65 ZBSSADDR := ALIGN(4)
66 endif
从上面可以看出zImage从ram中启动ZTEXTADDR:= 0,从rom或者flash中启动ZTEXTADDR:= $(CONFIG_ZBOOT_ROM_TEXT)
5. arch/arm/kernel/vmlinux.lds.S链接文件分析
1 /* ld script to make ARM Linux kernel
2 * taken from the i386 version by Russell King
3 * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
4 */
5
6 #include <asm-generic/vmlinux.lds.h>
7 #include <asm/thread_info.h>
8 #include <asm/memory.h>
9
10 OUTPUT_ARCH(arm) /*指定目标板体系结构*/
11 ENTRY(stext) /*代码入口*/
12
13 #ifndef __ARMEB__
14 jiffies = jiffies_64; /*在kernel/timer.c的定义*/
15 #else
16 jiffies = jiffies_64 + 4;
17 #endif
18
19 SECTIONS
20 {
21 #ifdef CONFIG_XIP_KERNEL
22 . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
23 #else
24 . = PAGE_OFFSET + TEXT_OFFSET; /*代码段起始地址,.表示连接地址*/
25 #endif
26 .text.head : {
27 _stext = .; /*定义_stext为当前位置*/
28 _sinittext = .;
29 *(.text.head) /*将所有输入文件的.text.head段合并到这里*/
30 }
31
32 .init : { /*内核初始化的代码和数据*/
33 INIT_TEXT
34 _einittext = .;
35 __proc_info_begin = .;
36 *(.proc.info.init)
37 __proc_info_end = .;
38 __arch_info_begin = .;
39 *(.arch.info.init)
33 INIT_TEXT
34 _einittext = .;
35 __proc_info_begin = .;
36 *(.proc.info.init)
37 __proc_info_end = .;
38 __arch_info_begin = .;
39 *(.arch.info.init)
40 __arch_info_end = .;
41 __tagtable_begin = .;
42 *(.taglist.init)
43 __tagtable_end = .;
44 . = ALIGN(16);
45 __setup_start = .;
46 *(.init.setup)
47 __setup_end = .;
48 __early_begin = .;
49 *(.early_param.init)
50 __early_end = .;
51 __initcall_start = .;
52 INITCALLS
53 __initcall_end = .;
54 __con_initcall_start = .;
55 *(.con_initcall.init)
56 __con_initcall_end = .;
57 __security_initcall_start = .;
58 *(.security_initcall.init)
59 __security_initcall_end = .;
60 #ifdef CONFIG_BLK_DEV_INITRD
61 . = ALIGN(32);
62 __initramfs_start = .;
63 usr/built-in.o(.init.ramfs)
64 __initramfs_end = .;
65 #endif
66 . = ALIGN(4096);
67 __per_cpu_start = .;
68 *(.data.percpu)
69 *(.data.percpu.shared_aligned)
70 __per_cpu_end = .;
71 #ifndef CONFIG_XIP_KERNEL
72 __init_begin = _stext;
73 INIT_DATA
74 . = ALIGN(4096);
75 __init_end = .;
76 #endif
77 }
78
79 /DISCARD/ : { /*内核退出的代码和数据 */
80 EXIT_TEXT
81 EXIT_DATA
82 *(.exitcall.exit)
83 #ifndef CONFIG_MMU
84 *(.fixup)
85 *(__ex_table)
86 #endif
87 }
88
89 .text : { /*真正的代码段部分*/
90 _text = .; /*代码和只读数据*/
91 __exception_text_start = .;
92 *(.exception.text)
93 __exception_text_end = .;
94 TEXT_TEXT
95 SCHED_TEXT
96 LOCK_TEXT
97 KPROBES_TEXT
98 #ifdef CONFIG_MMU
99 *(.fixup)
100 #endif
101 *(.gnu.warning)
102 *(.rodata)
103 *(.rodata.*)
104 *(.glue_7)
105 *(.glue_7t)
106 *(.got) /* Global offset table */
107 }
108
109 RODATA
110
111 _etext = .; /*代码段和只读数据结束 */
112
113 #ifdef CONFIG_XIP_KERNEL
114 __data_loc = ALIGN(4); /* location in binary */
115 . = PAGE_OFFSET + TEXT_OFFSET;
116 #else
117 . = ALIGN(THREAD_SIZE);
118 __data_loc = .;
119 #endif
120
121 .data : AT(__data_loc) { /*数据段起始*/
122 _data = .; /*内存中的地址 */
123
124 /*
125 * first, the init task union, aligned
126 * to an 8192 byte boundary.
127 */
128 *(.data.init_task)
129
130 #ifdef CONFIG_XIP_KERNEL
131 . = ALIGN(4096);
132 __init_begin = .;
133 INIT_DATA
134 . = ALIGN(4096);
135 __init_end = .;
136 #endif
137
138 . = ALIGN(4096);
139 __nosave_begin = .;
140 *(.data.nosave)
141 . = ALIGN(4096);
142 __nosave_end = .;
143
144 /*
145 * then the cacheline aligned data
146 */
147 . = ALIGN(32);
148 *(.data.cacheline_aligned)
149
150 /*
151 * The exception fixup table (might need resorting at runtime)
152 */
153 . = ALIGN(32);
154 __start___ex_table = .;
155 #ifdef CONFIG_MMU
156 *(__ex_table)
157 #endif
158 __stop___ex_table = .;
159
160 /*
161 * and the usual data section
162 */
163 DATA_DATA
164 CONSTRUCTORS
165
166 _edata = .;
167 }
168 _edata_loc = __data_loc + SIZEOF(.data);
169
170 .bss : { /*未初始化的全局变量*/
171 __bss_start = .; /* BSS */
172 *(.bss)
173 *(COMMON)
174 _end = .;
175 }
176 /*调试信息和数据段 */
177 .stab 0 : { *(.stab) }
178 .stabstr 0 : { *(.stabstr) }
179 .stab.excl 0 : { *(.stab.excl) }
180 .stab.exclstr 0 : { *(.stab.exclstr) }
181 .stab.index 0 : { *(.stab.index) }
182 .stab.indexstr 0 : { *(.stab.indexstr) }
183 .comment 0 : { *(.comment) }
184 }
185
186 /*
187 * These must never be empty
188 * If you have to comment these two assert statements out, your
189 * binutils is too old (for other reasons as well)
190 */
191 ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support")
192 ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")
- Kernel Linker Scripts Analysis (ARM Architecture)
- ARM linux kernel file analysis
- How SMP schedule work in Linux kernel? (ARM architecture)
- MMORPG服务器 - Analysis Architecture
- GNU-ld连接脚本 Linker Scripts
- 《ld reference manual》— 3 Linker Scripts
- Asterisk Kernel analysis 1
- Asterisk Kernel Analysis
- Android Kernel wake_lock analysis
- kernel crash analysis
- The Linux kernel analysis
- linux kernel makefile analysis
- architecture of kernel
- Undefined symbols for architecture, error: linker
- The ARM Architecture
- ARM GCC linker 脚本介绍
- ARM------Linker Script,LMA,VMA
- Asterisk Kernel analysis 2 channel
- Golang横空出世的背景(为什么选择Go)
- 获取当前运行Java的进程标识符(PID)
- 【木头Cocos2d-x 033】我是定时器第02章—HelloWorld之scheduleUpdate
- 错误
- 深入理解Oracle索引(1):INDEX SKIP SCAN 和 INDEX RANGE SCAN
- Kernel Linker Scripts Analysis (ARM Architecture)
- 用C语言语法分析pISR_EINT8_23=(U32)key_handler
- 煞费心思
- 使用gdaldem创建彩色地形图和坡度阴影——thematicmapping.org译文(三)
- mysql优化
- java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
- 灵活使用Script Functoid 增强BizTalk Mapping功能
- 学习笔记——操作系统_Linux原子操作
- hdu 2993 MAX Average Problem(DP+斜率优化)