linux kernel 从入口到start_kernel 的代码分析
| 分类: 嵌入式 |
linux kernel 从入口到start_kernel 的代码分析
本文的很多内容是参考了网上某位大侠的文章写的<<>>,有些东西是直接从他那copy过来的。
最近分析了一下u-boot的源码,并写了分文档, 为了能够衔接那篇文章,这次又把arm linux的启动代码大致分析了一下,特此写下了这篇文档。一来是大家可以看看u-boot到底是如何具体跳转到linux下跑的,二来也为自己更深入的学习linux kernel打下基础。
本文以arm 版的linux为例, 从kernel的第一条指令开始分析,一直分析到进入start_kernel()函数,也就是kernel启动的汇编部分,我们把它称之为第一部分, 以后有时间在把启动的第二部分在分析一下。我们当前以linux-2.6.18内核版本作为范例来分析,本文中所有的代码前面都会加上行号以便于讲解。
由于启动部分有一些代码是平台相关的,虽然大部分的平台所实现的功能都比较类似,但是为了更好的对code进行说明,对于平台相关的代码,我们选择smdk2410平台,
CPU是s3c2410(arm核是arm920T)进行分析。
一. 启动条件
arm linux boot的主线可以概括为以下几个步骤:
1. 确定 processor type
2. 确定 machine type
3.检查参数合法性
4. 创建页表
5. 调用平台特定的__cpu_flush函数 (在struct proc_info_list中)
6. 开启mmu
7. 切换数据
最终跳转到start_kernel (在__switch_data的结束的时候,调用了 b start_kernel
首先,我们先对几个重要的宏进行说明(我们针对有MMU的情况):
|
宏 |
位置 |
默认值 |
说明 |
|
KERNEL_RAM_ADDR |
arch/arm/kernel/head.S +26 |
0xc0008000 |
kernel在RAM中的虚拟地址 |
|
PAGE_OFFSET |
include/asm-arm/memeory.h +50 |
0xc0000000 |
内核空间的起始虚拟地址 |
|
TEXT_OFFSET |
arch/arm/Makefile +131 |
0x00008000 |
内核在RAM中起始位置相对于 RAM起始地址的偏移 |
|
TEXTADDR |
arch/arm/kernel/head.S +49 |
0xc0008000 |
kernel的起始虚拟地址 |
|
PHYS_OFFSET |
include/asm-arm/arch- *** /memory.h |
平台相关 |
RAM的起始物理地址,对于s3c2410来说在include/asm-arm/arch-s3c2410/memory.h下定义,值为0x30000000(ram接在片选6上) |
内核的入口是stext,这是在arch/arm/kernel/vmlinux.lds.S中定义的:
下面我们将arm linux boot的主要代码列出来进行一个概括的介绍,然后,我们会逐个的进行详细的讲解.
在arch/arm/kernel/head.S中 72 - 94 行,是arm linux boot的主代码:
00072: ENTRY(stext)
00073:
00074:
00075:
00076:
00077:
00078:
00079:
00080:
00081:
00082:
在进入linux kernel前要确保在管理模式下,并且IRQ,FIQ都是关闭的,因此在00073行就是要确保这几个条件成立。
1. 确定 processor type
arch/arm/kernel/head.S中:
00075:
00076:
00077:
00078:
75
76行:
跳转到__lookup_processor_type.在__lookup_processor_type中,会把找到匹配的processor type 对象存储在r5中。
77,78行:
判断r5中的processor type是否是0,如果是0,说明系统中没找到匹配当前processor type的对象, 则跳转到__error_p(出错)。系统中会预先定义本系统支持的processor type 对象集。
下面我们分析__lookup_processor_type函数。
arch/arm/kernel/head-common.S中:
00145:
00146: __lookup_processor_type:
00147:
00148:
00149:
00150:
00151:
00152: 1:
00153:
00154:
00155:
00156:
00157:
00158:
00159:
00160: 2:
00161:
00162:
00165: ENTRY(lookup_processor_type)
00166:
00167:
00168:
00169:
00170:
00171:
00172:
00176:

加载中…