linux head-common.s分析(转)
供head.S调用,其中__mmap_switched的b start_kernel跳转到C执行,且永不返回。
跳转到start_kernel时寄存器值:
R0 = cp#15 control register
R1 = machine id
R2 = atags/dtb pointer
R9 = processor ID
stext->__enable_mmu->__turn_mmu_on->ldr pc, __mmap_switched
->__mmap_switched(head-common.S)
->b start_kernel(init/main.c)
http://blog.chinaunix.net/uid-20451980-id-1945242.html
Linux kernel分析(二)
注:本文为Stephen Du原创,转载请注明
这里开始讲解head-common.S的内容。另,我的讲解顺序是按照源码的顺序来进行的而不是按照函数调用的顺序进行,所以读者要注意函数的入口以及返回地址。
这里定义了atag数据的存放地址
14 #define ATAG_CORE 0x54410001
15 #define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
这个部分head.S里面开启MMU后执行。此处开始准备执行C代码做准备:主要是text段,初始化数据段的定位!起始kernel本身的段结构跟普通进程大致相同,这也是为什么它被成文宏内核的原因!
__data_loc是kernel的text段的开始
__bss_start是__data_loc的结束也是bss段的开始
从上图看得出,kernel必须将text段跟初始化数据段准备好,对于未初始化数据段跟stack段,heap段都是不需要进行准备的!只需要设置stack指针以及heap起始地址就好!因此到了22行后未出现stack跟heap段的定义!
17 .type
__switch_data, %object
18 __switch_data:
19 .long
__mmap_switched
20 .long
__data_loc
@ r4
21 .long
__data_start
@ r5
22 .long
__bss_start
@ r6
23 .long _end
@ r7
该内存位置存储了处理器的id,也就是r4寄存器的内容,以防后面的代码丢弃r4的内容
24 .long
processor_id
@ r4
该内存位置存储了machine type的信息也是放置r5的内容被丢弃
25 .long
__machine_arch_type @ r5
该内存存储了atag的地址指针,同理防止r6被丢弃了
26 .long
__atags_pointer @ r6
27 .long
cr_alignment
@ r7
这个内存位置放置了kernel的stack & heap的内存位置信息以后,只要将pc pointer指向这里就能执行C代码了!
28 .long
init_thread_union + THREAD_START_SP @ sp
29
此前的代码可能在NOR flash中以XIP方式运行(其实Nand flash也可以XIP,只是有点技术障碍),但是kernel的代码不能总在flash内运行,该函数会进行kernel段的搬移以及处理!
39 .type
__mmap_switched, %function
40 __mmap_switched:
41 adr
r3, __switch_data + 4 // r3 point to __mmap_switched本处的注释错误!r3指向__data_loc!
将代码段,初始化数据段以及未初始化的数据段地址分别加载进入r4~r7
43 ldmia r3!,
{r4, r5, r6, r7} // load the function's addr into r4~r7;r3 point to
processor_id
此处比较难以理解,r4=__data_loc是物理上段的存储位置(可能在flash中而不是在RAM中);r5=_data_start是数据在内存的地址,如果二者相等说明已经在RAM中不必做copy,如果不在RAM中则执行copy使之在内存中运行!
44 cmp
r4, r5 // Copy
data segment if needed __data_start is the destination and __data_loc is the
src!
copy相关操作
45 1: cmpne r5, r6
// if
__data_start and __data_loc is not the same start the transfer session
46 ldrne fp,
[r4], #4
47 strne fp,
[r5], #4
48 bne 1b
清空未初始化数据段,为执行C代码扫清障碍
50 mov
fp, #0
@ Clear BSS (and zero fp)
51 1: cmp r6, r7
52 strcc fp, [r6],#4
53 bcc 1b
执行保存操作。此处最重要的是sp指针的加载!该语句后sp已经指向了kernel的stack上,执行C代码的条件就绪了(代码段ok,初始化数据段ok,未初始化数据段ok,stack
ok)
55 ldmia r3,
{r4, r5, r6, r7, sp}
56 str
r9, [r4]
@ Save processor ID
57 str
r1, [r5]
@ Save machine type
58 str
r2, [r6]
@ Save atags pointer
59 bic
r4, r0, #CR_A @
Clear 'A' bit
60 stmia r7,
{r0, r4} @
Save control register values
61
@Now we will enter the world of C
code and the MMU is on now!
62 b
entry_for_C_call
63 //b
start_kernel
@For ARM start_kernel is defined in the init/main.c we will never return
from start_kernel at all
144
145 /*
146 * Read processor ID register (CP#15, CR0), and
look up in the linker-built
147 * supported processor list. Note that we
can't use the absolute addresses
148 * for the __proc_info lists since we aren't
running with the MMU on
149 * (and therefore, we are not in the correct
address space). We have to
150 * calculate the offset.
151 *
152 * r9 = cpuid
153 * Returns:
154 * r3, r4, r6 corrupted
155 * r5 = proc_info pointer in
physical address space
156 * r9 = cpuid (preserved)
157 */
158 .type
__lookup_processor_type, %function
159 __lookup_processor_type:
160 adr r3, 3f
161 ldmda r3, {r5 -
r7}
162 sub r3, r3,
r7
@ get offset between virt&phys
163 add r5, r5,
r3
@ convert virt addresses to
164 add r6, r6,
r3
@ physical address space
165 1: ldmia r5, {r3, r4}
@ value,
mask
166 and r4, r4,
r9
@ mask wanted bits
167 teq r3, r4
168 beq 2f
169 add r5, r5,
#PROC_INFO_SZ @ sizeof(proc_info_list)
170 cmp r5, r6
171 blo 1b
172 mov r5, #0
@ unknown processor
173 2: mov pc, lr
174
175 /*
176 * This provides a C-API version of the above
function.
177 */
178 ENTRY(lookup_processor_type)
179 stmfd sp!, {r4 -
r7, r9, lr}
180 mov r9, r0
181 bl
__lookup_processor_type
182 mov r0, r5
183 ldmfd sp!, {r4 -
r7, r9, pc}
184
185 /*
186 * Look in and arch/arm/kernel/arch.[ch]
for
187 * more information about the __proc_info and
__arch_info structures.
188 */
189 .long
__proc_info_begin
190 .long
__proc_info_end
191 3: .long .
192 .long
__arch_info_begin
193 .long
__arch_info_end
194
195 /*
196 * Lookup machine architecture in the
linker-build list of architectures.
197 * Note that we can't use the absolute addresses
for the __arch_info
198 * lists since we aren't running with the MMU on
(and therefore, we are
199 * not in the correct address space). We
have to calculate the offset.
200 *
201 * r1 = machine architecture number
202 * Returns:
203 * r3, r4, r6 corrupted
204 * r5 = mach_info pointer in physical
address space
205 */
206 .type
__lookup_machine_type, %function
207 __lookup_machine_type:
208 adr r3, 3b
209 ldmia r3, {r4, r5,
r6}
210 sub r3, r3,
r4
@ get offset between virt&phys
211 add r5, r5,
r3
@ convert virt addresses to
212 add r6, r6,
r3
@ physical address space
213 1: ldr r3, [r5,
#MACHINFO_TYPE] @ get machine type
214 teq r3, r1
@ matches loader number?
215 beq 2f
@ found
216 add r5, r5,
#SIZEOF_MACHINE_DESC @ next machine_desc
217 cmp r5, r6
218 blo 1b
219 mov r5, #0
@ unknown machine
220 2: mov pc, lr
221
222 /*
223 * This provides a C-API version of the above
function.
224 */
225 ENTRY(lookup_machine_type)
226 stmfd sp!, {r4 -
r6, lr}
227 mov r1, r0
228 bl
__lookup_machine_type
229 mov r0, r5
230 ldmfd sp!, {r4 -
r6, pc}
231
232 /* Determine validity of the r2 atags pointer.
The heuristic requires
233 * that the pointer be aligned, in the first 16k
of physical RAM and
234 * that the ATAG_CORE marker is first and
present. Future revisions
235 * of this function may be more lenient with the
physical address and
236 * may also be able to move the ATAGS block if
necessary.
237 *
238 * r8 = machinfo
239 *
240 * Returns:
241 * r2 either valid atags pointer, or zero
242 * r5, r6 corrupted
243 */
244
245 .type __vet_atags,
%function
246 __vet_atags:
247 tst r2,
#0x3
@ aligned?
248 bne 1f
249
250 ldr r5,
[r2, #0] @
is first tag ATAG_CORE?
251 subs r5, r5,
#ATAG_CORE_SIZE
252 bne 1f
253 ldr r5,
[r2, #4]
254 ldr r6,
=ATAG_CORE
255 cmp r5, r6
256 bne 1f
257
258 mov pc, lr
@ atag pointer is ok
259
260 1: mov r2, #0
261 mov pc, lr
linux head-common.s分析(转)的更多相关文章
- linux系统web日志分析脚本
linux系统web日志分析这方面工具比较多,比如logwatch或awstats等使用perl语言开发,功能都非常强大.但这些软件都需要进行一些配置,很多朋友往往在技术方面没有投入太多力量,即便参照 ...
- 2019-2020-1 20199329《Linux内核原理与分析》第八周作业
<Linux内核原理与分析>第八周作业 一.本周内容概述: 理解编译链接的过程和ELF可执行文件格式 编程练习动态链接库的两种使用方式 使用gdb跟踪分析一个execve系统调用内核处理函 ...
- Android/Linux下CGroup框架分析及其使用
1 cgroup介绍 CGroup是control group的简称,它为Linux kernel提供一种任务聚集和划分的机制,可以限制.记录.隔离进程组(process groups)所使用的资源( ...
- Linux Kernel Oops异常分析
1.PowerPC小系统内核异常分析 1.1 异常打印 Unable to handle kernel paging request for data at address 0x36fef31eFa ...
- 20169212《Linux内核原理与分析》课程总结
20169212<Linux内核原理与分析>课程总结 每周作业链接汇总 第一周作业:完成linux基础入门实验,了解一些基础的命令操作. 第二周作业:学习MOOC课程--计算机是如何工作的 ...
- 1.linux服务器的性能分析与优化
[教程主题]:1.linux服务器的性能分析与优化 [课程录制]: 创E [主要内容] [1]影响Linux服务器性能的因素 操作系统级 CPU 目前大部分CPU在同一时间只能运行一个线程,超线程的处 ...
- 20169212《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...
- Linux系统日志及日志分析
Linux系统日志及日志分析 Linux系统拥有非常灵活和强大的日志功能,可以保存几乎所有的操作记录,并可以从中检索出我们需要的信息. 大部分Linux发行版默认的日志守护进程为 syslog,位 ...
- 高性能Linux服务器 第10章 基于Linux服务器的性能分析与优化
高性能Linux服务器 第10章 基于Linux服务器的性能分析与优化 作为一名Linux系统管理员,最主要的工作是优化系统配置,使应用在系统上以最优的状态运行.但硬件问题.软件问题.网络环境等 ...
- Linux内核源代码情景分析系列
http://blog.sina.com.cn/s/blog_6b94d5680101vfqv.html Linux内核源代码情景分析---第五章 文件系统 5.1 概述 构成一个操作系统最重要的就 ...
随机推荐
- 洛谷——P1991 无线通讯网
P1991 无线通讯网 题目描述 国防部计划用无线网络连接若干个边防哨所.2 种不同的通讯技术用来搭建无线网络: 每个边防哨所都要配备无线电收发器:有一些哨所还可以增配卫星电话. 任意两个配备了一条卫 ...
- Cookie和Session在Node.JS中的实践(三)
Cookie和Session在Node.JS中的实践(三) 前面作者写的COOKIE篇.SESSION篇,算是已经比较详细的说明了两者间的区别.机制.联系了.阅读时间可能稍长,因为作者本身作图也做了不 ...
- 使用参数化SQL
Java.C#等语言提供了参数化SQL机制,使用参数化SQL开发人员为在运行时才能确定的参数值设置占位符,在执行的时候再指定这些占位符所代表的值.示例代码如下: string user=txtUser ...
- 弱电系统标准CAD图例识图讲解
弱电系统标准CAD图例识图讲解 http://www.360doc.com/content/17/0317/16/33642774_637680009.shtml
- 【Linux】CentOS7 上使用yum安装和卸载软件【yum安装wine举例】
关于yum的相关解释,请 man yum 自行查看. 配置常用源:http://www.cnblogs.com/sxdcgaq8080/p/7516186.html yum的使用类似于在windows ...
- 推荐一款Java反编译器,比较好用
转自:http://www.blogjava.net/xmatthew/archive/2008/10/28/237203.html 推荐一款Java反编译器,也使用了挺久的了,感觉还是很好用,就拿出 ...
- IntelliJ IDEA 配合 Maven 的一些技巧:Profiles
环境 IntelliJ IDEA 2017.1 Maven 3.3.9 Nexus 3.2.1 学习前提 了解 Maven 配置的基本用法 了解私有仓库,比如 nexus 的一些概念 强烈建议把 Ma ...
- 前后台JSON传值得一个问题和异常处理net.sf.json.JSONException: Unquotted string '"name"'
项目中做导入的时候遇到个bug,用JSON.stringify()序列号json对象传给后台:然后后台通过getPatameter()获取值时,前台的英文引号变成了中文引号. 原来代码如下:(自己排查 ...
- pclint在VS2013中的配置
1.安装pclint a. 从http://download.csdn.net/detail/finewind/8426979下载破解版的pclint9i版: b. 点击pclint9setuo.ex ...
- TCP/IP协议组随笔
原文:https://my.oschina.net/xianggao/blog/654677 IP层负责网络主机的定位,数据传输的路由,由IP地址可以唯一的确定Internet上的一台主机. TCP层 ...