=====================================================

arm linux系统启动相关文章列表:
arm linux系统启动流程 http://blog.csdn.net/u010872301/article/details/72615117
分析arm linux启动打印信息 http://blog.csdn.net/u010872301/article/details/78779503
Linux kernel panic 问题解决方案 http://blog.csdn.net/u010872301/article/details/73928935

=====================================================

面试中经常遇到此类问题arm linux系统启动流程,首先我们遇到此类问题必须明白题目所要考察我们的目的是什么:

1:考察点:在嵌入式开发中,遇到linux或Android系统启动报错时确定问题的位置,快速定位并解决问题。

2:问题所涉及到的知识点有:Bootloader、Linux和Android的系统启动流程

3:解答思路:

首先需要我们清楚整体的嵌入式移植开发流程图:

一、Boot启动流程

U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下:

(1)第一阶段主要包含依赖于CPU的体系结构硬件初始化的代码,通常都用汇编语言来实现。

硬件设备初始化(屏蔽所有的中断、设置CPU的速度和时钟频率、RAM初始化、初始化LED、关闭CPU内部指令/数据Cache等)

把Bootloader 为第二阶段准备RAM空间。

复制Bootloader的第二阶段代码到RAM空间中。

设置堆栈

跳转到第二阶段的C程序入口点

(2)第二阶段的功能

初始化本阶段使用的硬件设备

检测系统内存映射

将内核映像和根文件系统映像从Flash读到RAM

为内核设置启动参数

调用内核

代码如下:

第一阶段:主要是汇编代码
①进入arch/arm/cpu/armv7/start.S 直接在物理地址执行(uImage中)
⑴建立中断异常向量表
39 _start: b   reset
||
\/
127     bl  save_boot_params   保存了当前cpu的运行状态,reset则进行跳转
⑵设置svc模式131     mrs r0, cpsr
132     bic r0, r0, #0x1f
133     orr r0, r0, #0xd3
134     msr cpsr,r0
设置向量,为设置协处理器做准备
167     bl  cpu_init_cp15    完成了我们对协处理器设置,⑶关闭了MMU和cache ||
\/
168     bl  cpu_init_crit||\/b   lowlevel_init(②board/samsung/fs4412/lowlevel_init.S ) 设置了reset,使能reset ⑷关闭了开门狗(不需要帮我们重启,为了观察现象)⑸ 初始化时钟,⑹初始化内存,进行判断uboot是否运行在物理地址中TEXT_BASE (0x43e000000)进行⑺串口初始化操作,我们已经可以使用串口显示push {lr} ..... pop {pc} ==> mov pc,lrbl _main(③arch/arm/lib/crt0.S  ) ⑻初始化堆栈 ,准备启动C语言为gd结构体的赋值做准备(提供gd结构体大小的空间)||\/115     bl  board_init_f (④arch/arm/lib/board.c  ) ⑼ 给gd结构体进行赋值 gd结构体定义(⑤include/asm/global_data.h )303     for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {304         if ((*init_fnc_ptr)() != 0) {305             hang ();306         }307     }  完成各种板子初始化操作,最重要的是初始化了DRAM控制器,我开始使用400000000-800000000物理地址第二阶段:主要是c代码回到arch/arm/lib/crt0.S 进行寄存器赋值 r8 = gd->start_addr_splr = herer0 = gd->start_addr_sp   u-boot起始地址r2 = gd->relocaddr        搬移地址
||
\/
b relocate_code(⑥arch/arm/cpu/armv7/start.S)
196 copy_loop:
197     ldmia   r0!, {r9-r10}       /* copy from source address [r0]    */  进行循环搬移
198     stmia   r1!, {r9-r10}       /* copy to   target address [r1]    */
199     cmp r0, r2          /* until source end address [r2]    */
200     blo copy_loop    条件跳转 成立条件是cmp不相等
⑽自搬移关键代码
243     bx  lr(链接寄存器) 跳转||\/arch/arm/lib/crt0.S ⑾ 清除bss段 从bss_start到bss_end (物理地址在System.map中) 目的:腾出内存空间167     ldr pc, =board_init_r     ||\/arch/arm/lib/board.c  ⑿进行最后的初始化操作,开始执行uboot引导系统⒀702     for (;;) {703       main_loop();                                                  704     }||\/⑦ common/main.c 获取用户设置的bootcmd等参数,执行uboot

二、arm linux内核启动流程

第一阶段:内核的重定位和内核的自解压

第二阶段:执行没有压缩的内核的汇编代码部分

获取CPU信息

检查平台设备号

创建页表

打开MMU

清除BBS段

执行内核C语言部分入口函数

第三阶段:

获取uboot给内核传递的参数

控制台初始化

执行init命令

挂载文件系统

执行用户控件的第一个程序

设备传参方式
1、2.6内核之前 dev_param结构体进行传参
2、2.6内核后,使用dev_tags 结构体传参
3、3.0后,使用设备树进行传参

代码如下:

①进入arch/arm/kernel/head.S
使能thumb指令集,我们可以使用thumb指令,启动了异常处理机制92     safe_svcmode_maskall r9 使能svc模式365     mrc p15, 0, r9, c0, c0      @ get processor id   95     bl  __lookup_processor_type ||\/r4 = 178行虚拟地址 r5 = begin r6  = end②arch/arm/kernel/head-common.S 进行物理地址和虚拟地址转换,判断处理器类型148  *  r3, r4, r6 corrupted149  *  r5 = proc_info pointer in physical address space50  *  r9 = cpuid (preserved)
118      * r1 = machine no, r2 = atags or dtb,
119      * r8 = phys_offset, r9 = cpuid, r10 = procinfo   121     bl  __vet_atags  ||\/arch/arm/kernel/head-common.S 完成了对设备传参方式的验证(46-50设备树传参)
123     bl  __fixup_smp
124 #endif
125 #ifdef CONFIG_ARM_PATCH_PHYS_VIRT
126     bl  __fixup_pv_table
127 #endif
进行处理器信息保存,为创建页表做准备128     bl  __create_page_tables  创建页表(创建在物理地址)arch/arm/mm/proc-v7.S进行armv7处理器的设置
1、开启了cache,tlbs
2、开启clk
3、设置了reset414  *  r0  = cp#15 control register
415  *  r1  = machine ID
416  *  r2  = atags or dtb pointer
417  *  r4  = page table (see ARCH_PGD_SHIFT in asm/memory.h)
418  *  r9  = processor ID
419  *  r13 = *virtual* address to jump to upon completion
使能mmu需要将页表的物理地址位置指向虚拟地址,我们保存在协处理器中
444     b   __turn_mmu_on  完成开启mmu操作
使能成功mmu进行地址转换前需要进行mmu使能
137     ldr r13, =__mmap_switched       @ address to jump to after
138                         @ mmu has been enabled  ||\/81     adr r3, __mmap_switched_data(类似于这样的adr操作,都是从处理器或者uImage获取到的)104     b   start_kernel  ||\/③init/main.c  进行各种初始化操作setuparch()保存了uboot传递的参数,保存在machine(arch/arm/include/asm/mach/arch.h )652     rest_init();  382     kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);   840     kernel_init_freeable();  928         prepare_namespace(); ||\/④  init/do_mounts.c  589     mount_root();   进行文件系统判断mount_nfs_root()完成了对文件系统的挂载内核启动:head.S head-common.S init/main.c init/do_mount.c

三、Android启动流程:

Init进程是Linux内核启动后创建的第一个用户进程,地位非常重要,Init进程在初始化过程中会启动很多重要的守护进程,因此,了解Init进程的启动过程将有助于我们更好的理解Android系统。Init除了完成系统的初始化之外,本身也是一个守护进程,负担着系统部分很重要的职责。

知识点:介绍Init进程的初始化以及它作为守护进程的功能。

在介绍Init进程前,我们先简单介绍Android的启动过程。从系统角度看,Android的启动过程可分为bootloader引导,装载和启动Linux内核,启动Android系统,3个大的阶段。其中Android系统的启动还可以细分为启动Init进程,启动zygote,启动SystemService,启动serviceManager,启动Home等多个阶段

1)bootloader引导

当我们按下手机的电源键,最先运行的就是bootloader.bootloader主要的作用是初始化基本的硬件设备(如CPU,内存,Flash等)并且通过建立内存空间映射,为装载Linux内核准备好合适的运行环境.一旦Linux内核装载完毕,bootloader将会从内存中清除掉.

如果用户在Bootloader运行期间,按下预定义的组合键,可以进入系统的更新模块.Android的下载可以选择进入FastBoot模式和Recovery模式.

Fastboot是Android设计的一套通过USB来更新手机分区映像的协议(绕写分区镜像),方便开发人员能快速更新制定的手机分区.但是一般的零售机往往去掉了Fastboot,Google销售的开发机则带有Fastboot模块.

Recovery模式是Android 特有的升级系统.利用Recovery模式,手机可以进行回复出厂设置,或者执行OTA,补丁和固件升级.进入Recovery模式实际上是启动了一个文本模式的Linux.

2) 装载和启动Linux内核.

Android的boot.img存放的就是Linux内核(system.img)和一个根文件系统(ramdisk.img).Bootloader会把boot.img映像装载进内存.然后Linux内核会执行整个系统的初始化,完成后装载根文件系统,最后启动Init进程.

3) 启动Init进程.

Linux内核加载完毕后,会首先启动Init进程,Init进程是系统的第一个进程.在Init进程的启动过程中,会解析Linux的配置脚本init.rc文件(脚本规则).根据init.rc文件的内容,init进程会装载Android的文件系统,创建系统目录(adb shell 系统目录),初始化属性系统(进程全局变量),启动Android系统重要的守护进程(后台进程),这些进程包括USB守护进程,adb守护进程(debug桥),vold守护进程(外部存储,检测热插拔sd卡(EXT4文件系统),检测挂载),rild守护进程(电话卡)等.

最后Init进程也会作为守护进程来执行修改属性请求,重启崩溃的进程等操作.

4) 启动serviceManager((本地层)进程)和四大组件没有关系

ServiceManager由Init进程启动.它主要的作用是管理Binder服务,负责Binder服务的注册与查找.

5)启动zygote进程.(受精卵)--------》(之后是java进程)

Init进程初始化结束时,会启动zygote进程.zygote进程负责fork出应用进程(复制整个父进程数据),是所有应用进程的父进程.zygote进程初始化时会创建Dalivik虚拟机(运行java程序),预装载系统的资源文件(Button,farmwork和库资源)和Java类.所有从Zygote进程fork出的用户进程(app应用程序)将继承和共享这些预加载的资源,不用浪费时间重新加载,加快了应用程序的启动过程.启动结束后,zygote进程也将变为守护进程,负责响应启动APK应用程序的请求(提高运行效率,预加载)

6) 启动SystemServer.

SystemServer是zygote进程fork出的第一个进程,也是整个Android系统的核心进程.在SystemServer中运行着Android系统大部分的Binder服务.SystemServer首先启动本地服务SensorService(传感器);接着启动包括 ActivityManagerService (四大组件之activity底层实现),WindowsManagerService(APP窗口),PackageManagerService(包管理)在内的所有Java服务.   (接口API通过Launcher调用)

7)启动MediaServer(摄像头,音视、频服务)

MediaServer由Init进程启动.它包含了一些多媒体相关的本地BInder服务,包括:cameraService,AudioFlingerService,MediaPlayerService和AudioPolicyService.

8) 启动Launcher(桌面)(java代码写的)

SystemServer加载完所有Java服务后,最后会调用ActivityManagerService的SystemReady()方法.在这个方法的执行中,会发出Intent "android.intent.category.HOME".凡是相应这个Intent的apk应用都会运行起来,Launcher应用是Android系统默认的桌面应用,一般只有它会相应这个Intent,因此,系统开机后,第一个运行的应用就是Launcher.

完~

arm linux系统启动流程相关推荐

  1. Arm linux系统启动流程简介

    文章目录 介绍 一.Bootloader 1.总体流程 二.Linux内核 1.总体流程 2.具体流程 总结 介绍 Arm Linux 系统启动流程可分为四个部分: 1.引导加载程序(bootload ...

  2. linux 系统重启过程,linux 系统启动流程

    linux系统启动流程可以简单总结为以下几步 1)开机BIOS自检 2)读取MBR,进行MBR引导 3)启动bootloader 4)加载内核kernel 5)启动init进程,依据inittab文件 ...

  3. Linux 系统启动流程及其介绍

    熟悉Linux系统启动流程可以更好的排除Linux系统在启动的过程中所遇到的错误,下面介绍Linux系统在启动过程. 开机,BIOS自检:检测外置设备,目的是为了把外围设备的信息提供给操作系统使用 寻 ...

  4. Linux 进内核,arm linux 启动流程之 进入内核

    原标题:arm linux 启动流程之 进入内核 还是从编译链接生成vm 的过程来看吧,由一大堆.o文件链接而成,第一个就是 kernel/arch//kernel/head-armv.o ,而且我们 ...

  5. Linux系统启动流程(4)制作自定义linux之一

    Linux系统启动流程(4)制作自定义linux之一 平时使用的服务器类型的linux系统一般都会装载各种软件与服务,而在某些情况下,并不能一直直接使用公司管理的系统,一是可能会出现故障,二是在处理一 ...

  6. 嵌入式linux内核启动过程,嵌入式Linux:ARM Linux启动流程

    ARM Linux启动流程大致为:bootloader---->kernel---->root filesystem.bootloader 是一上电就拿到cpu 的控制权的,而bootlo ...

  7. linux 打开设备 流程,Linux系统启动流程

    1.linux系统启动流程 1.加载BIOS的硬件信息,获取第一个启动设备 Power-On-Self-Test,加电自检,是BIOS功能的一个主要部分.负责完成对CPU.主板.内存.硬盘子系统.显示 ...

  8. linux系统启动流程详解

    系统启动流程(CentOS6) Post加电自检: 开机检查cpu.内存.磁盘等是否存在 Boot Sequence: BIOS:Basic Input and Output System 按照BIO ...

  9. 图解Linux系统启动流程

    废话不多说,先上图 说明1:上图是Linux系统启动时的详细流程,其中黑色部分为主流程分支,蓝色部分为详细流程分支,绿色部分是注释部分.大家可点击查看大图. 说明2:增加了kernel和initrd间 ...

最新文章

  1. Pytorch的神经网络编程学习第一节
  2. android 锁屏应用,创建一个Android锁屏应用。
  3. oracle双机python连接_Python连接Oracle
  4. 好看的linux操作系统,Deepin 20 - 外媒称它是最漂亮的Linux操作系统
  5. ArcGIS Clip(裁剪)时出现000117错误的解决办法
  6. 内存和swap查看 内存是拿来用的 不是看的
  7. Postgresql 填充所有的时间点
  8. 《Spring实战》第一章 — Spring之旅
  9. 实战突击:PHP项目开发案例整合(第2版)
  10. 神经网络有趣案例_求解三体问题快了1亿倍,新型神经网络问世
  11. 【安装包】apache-tomcat-8.5.45-windows-x64
  12. n阶方阵的蛇形排列java_排列组合的模板算法
  13. Latex初学入门记载
  14. python可以用于工业机器人编程与操作_工业机器人用什么语言编程?
  15. 整理iOS9适配中出现的坑(图文)
  16. python实现pdf转ppt_wps中pdf转成word文档 Python转换PPT为PDF
  17. 如何在微信小程序中使用iconfont 1
  18. Apple DNS加速
  19. sprintf, snprintf, _snprintf, sprintf_s 等的区别
  20. 大数据分析就业培训课程大纲分享

热门文章

  1. uoj#267. 【清华集训2016】魔法小程序(乱搞)
  2. 办公用品管理系统VB——模块
  3. 51NOD 1185 威佐夫游戏 V2(威佐夫博弈)
  4. 第 4 章 terminal
  5. C# VS如何整个项目中查找字符串
  6. 警告 初始化默认驱动器时出错“找不到运行 Active Directory Web 服务的默认服务器。”...
  7. c:递归算法的三个demo:八皇后问题、台阶问题、汉诺塔
  8. C#中this关键字-调用本类成员
  9. SSAS : 如何编写自定义挖掘算法
  10. 用Netty实现RPC