arm linux 启动之一:汇编启动到start_kernel
描述arm linux启动的概要过程,以S5PV210(Cortex A8)为例,本文描述第一个阶段。
一、arm linux的引导
uboot在引导arm linux(uImage镜像)到SDRAM之后,通过bootm命令对uImage镜像的64个字节头进行解释,获取linux的entry入口地址,并赋值给theKernel函数指针(一般该值是0x30008000),并将uboot的环境变量参数(如平台的内存块区域信息、linux启动命令信息bootargs等)按linux要求的tags形式放置在0x30000100起始的地方。接着关掉MMU,清除icache,dcache,最后通过该函数将控制权交给arm linux:
theKernel (0, machid, bd->bi_boot_params);
其中,machid是平台的id,其需要与arch/arm/tools/mach_types 中定义的机器ID一致,否则无法启动。 bd->bi_boot_params即0x30000100,描述了linux启动所需要的信息。
二、arm linux启动的第一部分
该部分是体系相关的汇编部分,代码位于arch\arm\kernel\head.S,入口是ENTRY(stext),其主要完成的工作包括:
1) 设置当前arm工作模式是svc mode,关中断
2)__lookup_processor_type 获取对应的CPU信息数据结构地址,主要是arm v7架构相关的信息,如MMU,cache标志值等,数据结构如下:
struct proc_info_list {
unsigned int cpu_val;
unsigned int cpu_mask;
unsigned long __cpu_mm_mmu_flags; /* used by head.S */
unsigned long __cpu_io_mmu_flags; /* used by head.S */
unsigned long __cpu_flush; /* used by head.S */
const char *arch_name;
const char *elf_name;
unsigned int elf_hwcap;
const char *cpu_name;
struct processor *proc;
struct cpu_tlb_fns *tlb;
struct cpu_user_fns *user;
struct cpu_cache_fns *cache;
};
arm linux支持各种CPU体系架构,其描述在.proc.info.init 段,对应S5PV210即arch\arm\mm\proc-v7.S, lookup_processor_type先通过协处理器CP15读出CPU ID并跟cpu_val比较,匹配即可得到数据结构地址。该地址是链接到虚拟地址,而此时MMU是关闭的,需要将该地址转为物理地址访问。
3)__lookup_machine_type获取对应平台机器的数据结构地址,主要是平台板子相关的数据信息,如内存起始地址和大小,中断和timer初始化函数等,如下:
struct machine_desc {
unsigned int nr; /* architecture number */
unsigned int phys_io; /* start of physicalio */
unsigned int io_pg_offst; /* byte offsetfor io * page tabe entry */
const char *name; /* architecture name */
unsigned long boot_params; /*tagged list */
unsigned int video_start; /* start of videoRAM */
unsigned int video_end; /* end ofvideo RAM */
unsigned int reserve_lp0 :1; /* never haslp0 */
unsigned int reserve_lp1 :1; /* never haslp1 */
unsigned int reserve_lp2 :1; /* never haslp2 */
unsigned int soft_reboot :1; /* softreboot */
void (*fixup)(struct machine_desc *, struct tag *, char **, struct meminfo *);
void (*map_io)(void);/* IO mapping function */
void (*init_irq)(void);
struct sys_timer *timer; /* system tick timer */
void (*init_machine)(void);
};
arm linux支持各种平台板子,其描述在.arch.info.init 段,对应S5PV210即\arch\arm\mach-s5pv210\mach-smdkv210.c。UBOOT的machid即用于搜索匹配nr,以取到机器信息。
4)检查uboot传递过来的tags是否符合标准,并检测machine数据结构的boot_params的值是否等于theKernel传递过来的第三个参数(0x30000100)
5)create_page_tables 创建临时页表,均是以1M为单位进行映射,所以4G空间需要16K,从0x30004000到0X30008000。共映射三个部分:
i. linux内核镜像空间的映射(0xc0008***开始的内核空间映射到0x30008***)
ii. 创建页表到开启mmu之间还有一段代码需要运行,因为还需要为linux启动的初始1M空间创建一段直接映射,此时还是0X30008000+的地址运行,所以映射是0X30008000+映射到0X30008000+
iii. uboot传递过来的tags参数也需要进行映射(虚拟0XC**映射到0X3**),以进行访问。
6)ldr r13, __switch_data,将 __switch_data数据结构的地址入栈。
7)add pc,r10, #PROCINFO_INITFUNC,即将PC改到arch\arm\mm\proc-v7.S的 __v7_setup去执行,跳转前将__enable_mmu放到lr,即 __v7_setup执行完就返回到__enable_mmu。 __v7_setup主要是CPU体系相关的初始化,如icache,dcache等。
8)__enable_mmu打开MMU,cache等,最后将r13出栈,取出arch/arm/kernel/head-common.S的__switch_data的第一个内容__mmap_switched函数,并赋给PC:
__switch_data:
.long __mmap_switched
.long__data_loc @ r4
.long_data @ r5
.long __bss_start @r6
.long_end @ r7
.long processor_id @ r4
.long __machine_arch_type @ r5
.long __atags_pointer @r6
.long cr_alignment @ r7
.long init_thread_union + THREAD_START_SP @ sp
9)__mmap_switched初始化data,bss等相关段,保存相关的数据结构地址到相关变量。设置以后系统启动init进程的栈空间。
10)b start_kernel 跳转到linux启动的第二部分,为C语言编写。
转载于:https://www.cnblogs.com/yueqian-scut/p/arm-linux-boot-1st.html
arm linux 启动之一:汇编启动到start_kernel相关推荐
- arm linux中添加开机启动
微处理器:S5PV210 操作系统:linux3.0.8 前言: 在产品中,基本上都要屏蔽arm开发板中linux系统的对外通信,只应该通过产品的相关APP做相关操作. 因此需要把该A ...
- ARM linux的启动部分源代码简略分析
ARM linux的启动部分源代码简略分析 以友善之臂的mini2440开发板为平台,以较新的内核linux-2.6.32.7版本为例,仅作说明之用. 当内核映像被加载到RAM之后,Bootloade ...
- ARM linux的启动部分源代码简略分析【转】
转自:http://www.cnblogs.com/armlinux/archive/2011/11/07/2396784.html ARM linux的启动部分源代码简略分析 以友善之臂的mini2 ...
- ARM linux内核启动时几个关键地址【转】
转自:http://www.cnblogs.com/armlinux/archive/2011/11/06/2396787.html 1. 内核启动地址 1.1. 名词解释 ZTEXT ...
- Linux 进内核,arm linux 启动流程之 进入内核
原标题:arm linux 启动流程之 进入内核 还是从编译链接生成vm 的过程来看吧,由一大堆.o文件链接而成,第一个就是 kernel/arch//kernel/head-armv.o ,而且我们 ...
- linux指定内核位置,ARM linux内核启动时几个关键地址
1. 内核启动地址 ZTEXTADDR 解压代码运行的开始地址.没有物理地址和虚拟地址之分,因为此时MMU处于关闭状态.这个地址不一定时RAM的地址,可以是支持读写寻址的flash等存储中 ...
- 分析arm linux启动打印信息
===================================================== arm linux系统启动相关文章列表: arm linux系统启动流程 http://bl ...
- ARM linux解析之压缩内核zImage的启动过程
ARM linux解析之压缩内核zImage的启动过程 首先,我们要知道在zImage的生成过程中,是把arch/arm/boot/compressed/head.s 和解压代码misc.c,deco ...
- 嵌入式linux内核启动过程,嵌入式Linux:ARM Linux启动流程
ARM Linux启动流程大致为:bootloader---->kernel---->root filesystem.bootloader 是一上电就拿到cpu 的控制权的,而bootlo ...
最新文章
- Opencv 数学基础--范数(17)
- xmpp这一段蛋疼的 坑,
- Linux 的多线程编程的高效开发经验
- 数据库拆分过程及挑战
- CLion 生成CMakeList文件和include文件不存在问题
- 使用Spring Integration重试RabbitMQ
- MyBatis入门(二)---一对一,一对多
- 大型网站架构之系列(4)——分布式中的异步通信
- R语言机器学习:caret包使用及其黑箱模型解释(连续变量预测)
- CCF推荐-计算机网络领域顶级期刊会议,CCF推荐学术期刊及其会议计算机网络.pdf...
- 高速公路5G智能网联技术、方案和应用
- 网页全屏的代码实现要不要了解一下(最全)
- MascotCapsule手机游戏引擎简介
- 生僻字_tte_linux_ttf_提取字体_打印生僻字_uni
- MongoDB 3.0 用户创建
- HC32F460+RTthread U盘使用详解
- 使用webgl绘制一个点
- 3.6 函数作图与渐近线
- ffmpeg利用滤镜合并两个视频,一左一右---avfilter_link实现
- 基于DL的计算机视觉(5)--理解反向传播
热门文章
- python求平方根的代码_Python求平方根(附带源码)
- 7 centos 源码安装samba_在CentOS7.6里编译安装PHP7.4(最新版),很详细
- 李白打酒c语言编程,搞定了“李白打酒”,还原问题都迎刃而解
- jsp简介mysql_个人知识管理系统的设计与实现(JSP,MySQL)(含录像)
- 中jsp加载不出来layui_为何渔具厂生产不出来钓鱼人理想中的鱼竿呢,厂家说臣妾做不到啊...
- Git/Ctags/Vim/GDB基础笔记
- 企业区块链应用程序的两个关键问题
- 优达学城《DeepLearning》1-1:神经网络概论
- OpenCV Python 2 数字识别(K近邻)
- keras 的 example 文件 antirectifier.py 解析