当前位置: 首页 > 编程日记 > 正文

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

相关文章:

Sql Server 因为触发器问题导致数据库更新报错“在触发器执行过程中引发了错误,批处理已中止”的问题处理...

在维护一个非常旧的项目时,由于该项目版本已经非常老了,而且在客户现场运行的非常稳定,更要命的是本人目前没有找到该项目的代码,为了处理一个新的需求而且还不能修改程序代码,于是决定从数据库入手,毕竟该…

1070 Mooncake

1. 一道典型的贪心题,策略是尽可能地多出售单价高的月饼。 2. 开始有一个用例没有通过,看了参考书,说是质量虽然给的都是整数,但是为了计算不出错,需要声明为浮点型。改了以后果然就通过了,但是个中原理不…

Java数组合并,完成排序,从时间复杂度,和空间复杂度考虑

2019独角兽企业重金招聘Python工程师标准>>> 提供方法,直接调用,支持任意个数组的合并成一个数组,并且完成排序,每个数组元素个数不定。需要提供两个方法,分别做到时间复杂度最低、空间复杂度最低。并说明两…

WPF中Auto与*的差别

Auto 表示自己主动适应显示内容的宽度, 如自己主动适应文本的宽度,文本有多长,控件就显示多长. * 则表示按比例来分配宽度. <ColumnDefinition Width"3*" /> <ColumnDefinition Width"7*" /> 相同,行能够这样定义 <RowDefinition Height&qu…

个人电脑优化方案

2009年4月13日 文件删除--系统默认磁盘清理--批处理清除无用文件--使用优化软件如优化大师 Codeecho off echo 正在清除系统垃圾文件&#xff0c;请稍等 del /f /s /q %systemdrive%\*.tmp del /f /s /q %systemdrive%\…

1037 Magic Coupon

1. 贪心算法题&#xff0c;贪心策略&#xff1a;两组乘子相乘&#xff0c;每个数字至多用一次&#xff0c;希望得到最大的乘积。那么让A组绝对值最大的正数和B组最绝对值最大的正数相乘&#xff0c;次大的和次大的相乘……同样的让A组绝对值最大的负数和B组绝对值最大的负数相乘…

综合布线系统入门及应用(二)

一、工程材料用量估计 1、信息模块及水晶头用量统计 信息插座与工位数量1:1&#xff0c;在增加5%的余量 跳线&#xff1a;一般需要2条&#xff0c;工位信息面板到设备&#xff0c;交换机到配线架&#xff0c;每根条线2个水晶头&#xff0c;预留10%-15%。 2、线槽用量统计 根据办…

如何查看服务器有多少网站--免费工具

一台虚拟主机上到底有多少个网站或者说同一ip下有多少个域名和网站&#xff1f;这是站长们都很关心的&#xff0c;因为这样可以知道你的站到底和谁是邻居&#xff0c;有时候如果你和百度黑名单上的垃圾站在同一空间下&#xff0c;你也会受到牵连。 那么怎 ...中间左侧广告 一台…

二分法在算法题中的4种常见应用(cont.)

目录 1.查找单调序列中是否存在满足某条件的元素 2.寻找序列中第一个(最后一个)满足某条件的元素的位置 3.给定一个定义在[L,R]上的单调函数f(x)&#xff0c;求方程f(x)0的根 4.快速幂的递归和迭代求法 1.查找单调序列中是否存在满足某条件的元素 //二分区间为左闭右闭的[l…

Minimum Path Sum

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You can only move either down or right at any point in time. 格子取数问题&#xff0c;另dp[i][j]表示走…

Thorntail 2.2.0提供从WildFly Swarm自动迁移的特性

自6月底宣布把WildFly Swarm2018.5.0改名为Thorntail2.0.0以来&#xff0c;Red Hat在8月中旬以后的三个周里发布了Thorntail 2.1.0版本和2.2.0版本。除了许多Bug修复外&#xff0c;尤其是和MicroProfile相关的&#xff0c;新特性还包括&#xff1a;\\符合MicroProfile 1.3\通过…

Depth Bias

在dx中的depth bias要以如下形式调用 inline DWORD F2DW( float f ) { return *((DWORD*)&f); } m_pD3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(1)); m_pD3DDevice->SetRenderState(D3DRS_DEPTHBIAS, F2DW(0.001)); 总之&#xff0c;奇怪的api。转载…

(C++)用upper_bound函数取代自己写的二分查找

int a[maxn];int j upper_bound(ai1,an,(long long)a[i]*p)-a; 以上代码的作用是 在a[i1]~a[n-1]找到第一个大于a[i]*p的数&#xff0c;将其下标返回给j 注意&#xff1a; 1.函数是左闭右开的 2.末尾要减去数组的坐标a 3.不加long long强制类型转换可能丢分

gsoap使用总结

WebService、soap、gsoap基本概念 WebService服务基本概念&#xff1a;就是一个应用程序&#xff0c;它向外界暴露出一个可以通过web进行调用的API&#xff0c;是分布式的服务组件。本质上就是要以标准的形式实现企业内外各个不同服务系统之间的互调和集成。 soap概念&#xff…

SQL时间相关 - SQL日期,时间比较

SQL Server 中时间比较 例子: select count(*) from table where DATEDIFF ([second], 2004-09-18 00:00:18, 2004-09-18 00:00:19) > 0 说明 select DATEDIFF(day, time1 , time2) 对应示例语句如下 select DATEDIFF(day, 2010-07-23 0:41:18, 2010-07-23 23:41:18) …

SQL Server 2008 的CDC功能

CDC(Change Data Capture)通过对事务日志的异步读取&#xff0c;记录DML操作的发生时间、类型和实际影响的数据变化&#xff0c;然后将这些数据记录到启用CDC时自动创建的表中。通过cdc相关的存储过程&#xff0c;可以获取详细的数据变化情况。由于数据变化是异步读取的&#x…

1010 Radix

目录 总结 解题过程 总结 1. 短小精悍的一道二分算法题&#xff0c;总体思路是&#xff0c;将字符串1(如果tag不是1将两个字符串调换一下即可)转化为10进制&#xff0c;再用二分法看能否找到另一个进制使得两个字符串的10进制数相等。 2. 本题的三个函数关系是binarySearch…

喜闻乐见的const int *p、int* const p、const int* const p

不废话直接代码示例&#xff1a; 1 void f(const int *p) {2 3 int b 10;4 5 *p 10; // error6 7 p &b; // fine8 9 } 10 11 void f(int* const p) { 12 13 int b 10; 14 15 *p 10; // fine 16 17 p &b; // error 18 19 } 20 21 v…

Microsoft Visual Studio 2012 添加实体数据模型

Microsoft Visual Studio 2012 添加实体数据模型 1、创建一个web项目 2、添加ADO实体数据模型&#xff0c;如下图&#xff1a; 3、选择 从数据库生成&#xff0c;然后下一步 4、新建连接&#xff0c;如下图&#xff1a; 5、填写服务器名等&#xff0c;如下图&#xff1a; 6、选…

5.1软件升级的小阳春

现在正在去白山的车上&#xff0c;刚睡醒。习惯性的拿出手机上网&#xff0c;UCWEB提醒有最新版本升级&#xff0c;使用尚邮接收邮件的时候同样提醒有信版本升级。 公司产品9.0也正式完成&#xff0c;昨天整个小组的同事开始在领地咖啡馆&#xff0c;进行新需求的确认。 4月末5…

1030 完美数列(二分解法)

1. 将整型序列从小到大排序后&#xff0c;这道题的本质是&#xff0c;对于每一个元素i&#xff0c;找出最后一个满足p*A[i]>A[j]的元素j&#xff0c;可以转化为找出第一个不满足p*A[i]>A[j]也即p*A[i]<A[j]的元素j。再用j-1。 2.LL product (LL)p*A[i];这里后面两个…

javascript变量声明 及作用域

javascript变量声明提升(hoisting) http://openwares.net/js/javascript_declaration_hoisting.html 可能要FQ一下 javascript的变量声明具有hoisting机制&#xff0c;JavaScript引擎在执行的时候&#xff0c;会把所有变量的声明都提升到当前作用域的最前面。 先看一段代码 123…

【转载】全面理解javascript的caller,callee,call,apply概念(修改版)

今天写PPlayer&#xff0c;发现有段代码引起了我的兴趣&#xff1a; var Class { create: function() { return function() { this.initialize.apply(this, arguments); } } } 这是高手写的&#xff0c;实现了创建一个类&#xff08;其实就是对象&#xff0c;函数对象&#xf…

springMVC自定义全局异常

SpringMVC通过HandlerExceptionResolver处理程序异常&#xff0c;包括Handler映射&#xff0c;数据绑定以及目标方法执行时所发生的异常。 SpringMVC中默认是没有加装载HandlerExceptionResolver&#xff0c;我们需要在SpringMVC.xml中配置 <mvc:annotation-driven /> 1、…

1030 完美数列(two pointers解法)

1. 这道题出现在二分法&#xff0c;但是特殊之处在于&#xff0c;双指针是嵌套的&#xff0c;程序看上去有些像暴力枚举&#xff0c;但其实是利用了&#xff0c;如果i<j&#xff0c;a[i]*p>a[j]&#xff0c;那么一定有k在[i,j]范围内&#xff0c;a[i]*p>a[k]&#xff…

alsa声卡切换

环境 ubuntu12.04 因为桌面版的默认装了&#xff0c;而且调声音也很方便&#xff0c;这里说一下server版下的配置&#xff0c;毕竟做开发经常还是用server版的 1.安装 apt-get install alsa-base 它会把alsa-utils也一块装了&#xff0c;这是个工具包&#xff0c;如果没装的话 …

asp.net获取网站路径

网站在服务器磁盘上的物理路径: HttpRuntime.AppDomainAppPath 虚拟程序路径: HttpRuntime.AppDomainAppVirtualPath 任何于Request/HttpContext.Current等相关的方法, 都只能在有请求上下文或者页面时使用. 即在无请求上下文时,HttpContext.Current为null. 而上面提到的方法一…

iOS 绘制圆角

级别&#xff1a; ★☆☆☆☆ 标签&#xff1a;「iOS切圆角」「layer圆角」「CAShapeLayer圆角」 作者&#xff1a; XsH 审校&#xff1a; QiShare团队 项目中会常有圆角&#xff08;或圆形&#xff09;显示视图的需求&#xff08;比如用户头像的显示&#xff09;&#xff0c;也…

(C++)归并排序的递归与非递归实现

递归实现 merge函数利用的是双指针技巧降低复杂度。 mergeSort函数使用了递归&#xff0c;当中先对左右序列各调用一次mergeSort&#xff0c;再对整个序列调用merge。就按照最浅层的归并的思想去理解&#xff0c;不要大脑走到哪就step in。 另外mergeSort进入递归有个left&l…

SnackbarUtilDemo【Snackbar的封装类】

版权声明&#xff1a;本文为HaiyuKing原创文章&#xff0c;转载请注明出处&#xff01; 前言 这个工具类参考的是《没时间解释了&#xff0c;快使用Snackbar!——Android Snackbar花式使用指南》&#xff0c;代码几乎一样&#xff0c;所以想要了解具体原理或者更详细信息请阅读…