=====================================================armlinux系统启动相关文章列表:armlinux系统启动流程剖析armlinux启动复印信息Linuxkernelpanic问题解决方案=====================================================
笔试中常常碰到这种问题armlinux系统启动流程,首先我们遇见这种问题必须明白题目所要考察我们的目的是哪些:
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:breset||/127blsave_boot_params保存了当前cpu的运行状态,reset则进行跳转⑵设置svc模式131mrsr0,cpsr132bicr0,r0,#0x1f133orrr0,r0,#0xd3134msrcpsr,r0设置向量,为设置协处理器做打算167blcpu_init_cp15完成了我们对协处理器设置,⑶关闭了MMU和cache||/168blcpu_init_crit||/blowlevel_init(②board/samsung/fs4412/lowlevel_init。S)设置了reset,使能reset⑷关闭了开门狗(不须要帮我们重启,为了观察现象)⑸初始化时钟,⑹初始化显存,进行判别uboot是否运行在数学地址中TEXT_BASE(0x43e000000)进行⑺串口初始化操作,我们早已可以使用并口显示push{lr}。
。。。。pop{pc}==>movpc,lrbl_main(③arch/arm/lib/crt0。S)⑻初始化堆栈,打算启动C语言为gd结构体的形参做打算(提供gd结构体大小的空间)||/115blboard_init_f(④arch/arm/lib/board。c)⑼给gd结构体进行形参gd结构体定义(⑤include/asm/global_data。h)303for(init_fnc_ptr=init_sequence;*init_fnc_ptr;++init_fnc_ptr){304if((*init_fnc_ptr)()!=0){305hang();306}307}完成各类板子初始化操作,最重要的是初始化了DRAM控制器,我开始使用0000000化学地址第二阶段:主要是c代码回到arch/arm/lib/crt0。S进行寄存器形参r8=gd->start_addr_splr=herer0=gd->start_addr_spu-boot起始地址r2=gd->relocaddr搬动地址||/brelocate_code(⑥arch/arm/cpu/armv7/start。
S)196copy_loop:197ldmiar0!,{r9-r10}/*copyfromsourceaddress[r0]*/进行循环搬动198stmiar1!,{r9-r10}/*copytotargetaddress[r1]*/199cmpr0,r2/*untilsourceendaddress[r2]*/200blocopy_loop条件跳转创立条件是cmp不相等⑽自搬动关键代码243bxlr(链接寄存器)跳转||/arch/arm/lib/crt0。S⑾清除bss段从bss_start到bss_end(数学地址在System。map中)目的:腾出显存空间167ldrpc,=board_init_r||/arch/arm/lib/board。c⑿进行最后的初始化操作arm linux内核启动流程,开始执行uboot引导系统⒀702for(;;){703main_loop();704}||/⑦common/main。c获取用户设置的bootcmd等参数arm linux内核启动流程,执行uboot二、armlinux内核启动流程
第一阶段:内核的重定位和内核的自解压
第二阶段:执行没有压缩的内核的汇编代码部份
获取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指令,启动了异常处理机制92safe_svcmode_maskallr9使能svc模式365mrcp15,0,r9,c0,c0@getprocessorid95bl__lookup_processor_type||/r4=178行虚拟地址r5=beginr6=end②arch/arm/kernel/head-common。S进行化学地址和虚拟地址转换,判定处理器类型148*r3,r4,r6corrupted149*r5=proc_infopointerinphysicaladdressspace50*r9=cpuid(preserved)118*r1=machineno,r2=atagsordtb,119*r8=phys_offset,r9=cpuid,r10=procinfo121bl__vet_atags||/arch/arm/kernel/head-common。
S完成了对设备传参形式的验证(46-50设备树传参)123bl__fixup_smp124#endif125#ifdefCONFIG_ARM_PATCH_PHYS_VIRT126bl__fixup_pv_table127#endif进行处理器信息保存,为创建页表做打算128bl__create_page_tables创建页表(创建在数学地址)arch/arm/mm/proc-v7。S进行armv7处理器的设置1、开启了cache,tlbs2、开启clk3、设置了reset414*r0=cp#15controlregister415*r1=machineID416*r2=atagsordtbpointer417*r4=pagetable(seeARCH_PGD_SHIFTinasm/memory。h)418*r9=processorID419*r13=*virtual*addresstojumptouponcompletion使能mmu须要将页表的化学地址位置指向虚拟地址,我们保存在协处理器中444b__turn_mmu_on完成开启mmu操作使能成功mmu进行地址转换前须要进行mmu使能137ldrr13,=__mmap_switched@addresstojumptoafter138@mmuhasbeenenabled||/81adrr3,__mmap_switched_data(类似于这样的adr操作,都是从处理器或则uImage获取到的)104bstart_kernel||/③init/main。
c进行各类初始化操作setuparch()保存了uboot传递的参数linux命令行,保存在machine(arch/arm/include/asm/mach/arch。h)652rest_init();382kernel_thread(kernel_init,NULL,CLONE_FS|CLONE_SIGHAND);840kernel_init_freeable();928prepare_namespace();||/④init/do_mounts。c589mount_root();进行文件系统判定mount_nfs_root()完成了对文件系统的挂载内核启动:head。Shead-common。Sinit/main。cinit/do_mount。c三、Android启动流程:
Init进程是Linux内核启动后创建的第一个用户进程,地位十分重要免费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的文件系统,创建系统目录(adbshell系统目录),初始化属性系统(进程全局变量),启动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.
完~