当前位置: 首页 > news >正文

Android上电执行顺序

u-boot目录makefile
编译的时候会指定启动链接脚本,如果没有指定的话,会根据顶层的makefile加载;
例如:
export ARCH CPU BOARD VENDOR SOC CPUDIR BOARDDIR
ifndef LDSCRIPT
#LDSCRIPT := $(srctree)/board/$(BOARDDIR)/u-boot.lds.debug   这是注释行,有些干扰board/board,重复了一个board
ifdef CONFIG_SYS_LDSCRIPT
# need to strip off double quotes
LDSCRIPT := $(srctree)/$(CONFIG_SYS_LDSCRIPT:"%"=%)
endif
endif
解析:

export后面的都是板级定制
srctree --->    arch/arm/mach-rockchip/make_fit_args.sh:8:srctree=$PWD  源代码的根目录路径‌
BOARD   --->    .config:23:CONFIG_SYS_BOARD="evb_rk3568"
BOARDDIR --->    include/autoconf.mk:38:CONFIG_BOARDDIR="board/rockchip/evb_rk3568"  //-include include/autoconf.mk先引入了include,所以BOARDDIR的路径就确定了

LDSCRIPT :
.config:100:CONFIG_SPL_LDSCRIPT="arch/arm/cpu/armv8/u-boot-spl.lds"
.config:147:CONFIG_TPL_LDSCRIPT="arch/arm/mach-rockchip/u-boot-tpl-v8.lds"
include/config/auto.conf:384:CONFIG_SPL_LDSCRIPT="arch/arm/cpu/armv8/u-boot-spl.lds"
include/config/auto.conf:413:CONFIG_TPL_LDSCRIPT="arch/arm/mach-rockchip/u-boot-tpl-v8.lds"
SPL ---> 作为第二阶段引导加载器,负责初始化DDR内存、时钟等基础硬件,并加载U-Boot主程序或内核‌;
TPL ---> 作为第三阶段引导加载器(部分平台如Rockchip将其作为第一级),运行于SRAM中,仅完成DDR初始化等最小化任务,随后加载SPL‌;
BOOTROM → TPL → SPL → U-Boot → Kernel;
LDSCRIPT 作用:
1、‌启动入口‌:_start(由链接脚本定义)→ 初始化异常向量表‌;
2、‌硬件初始化‌: board_init_f → 调用relocate_code重定位代码‌;
3、‌环境加载‌:env_relocate → 从Flash或SD卡加载环境变量;

找到u-boot.lds后,ENTRY(_start),强制链接器将_start符号作为整个U-Boot镜像的起始执行地址,类似于C语言中的main函数;
该符号通常定义在架构相关的汇编文件(如start.S或vectors.S)中,是CPU上电后执行的第一条指令位置;

小结:编译的时候会指定启动链接脚本,如果没有指定启动链接脚本,会根据u-boot目录下的最顶级makefile文件中的定义去加载,找到对应的u-boot.lds链接脚本,此脚本中会执行ENTRY(_start),
_start类似与main函数,这个定义在start.S的汇编文件中,是CPU上电后执行的第一条指定位置;


第一阶段 上电后第一个程序 start.S
上电后,U-Boot执行第一阶段(汇编代码),初始化CPU模式设置、关闭中断、设置栈指针、内存等硬件‌初始化(时钟频率,内存控制器SDRAM为了bootloader准备ram空间)
arch/arm/cpu/armv8/lowlevel_init.S:板级特定的内存时序配置
arch/arm/lib/vectors.S:异常向量表
定义这个代码的路径是?
源码目录下,uboot目录下arch/arm/cpu/armv8/start.S  armv8代表64位,armv7代表32位
bl    _main
通过    bl    _main  跳转到第二阶段bootloader    

uboot阶段哪个文件会配置时钟频率?
u-boot/include/configs/xxx.h
rk3568中:u-boot/include/configs/rk3568_common.h
#define COUNTER_FREQUENCY        24000000   即24MHz
这个COUNTER_FREQUENCY在start.S中有使用
#ifdef COUNTER_FREQUENCY
ldr    x0, =COUNTER_FREQUENCY
msr    cntfrq_el0, x0            /* Initialize CNTFRQ */
#endif


第二阶段bootloader    
初始化串口网卡灯外设,检测系统内存映射;
将Linux内核镜像zImage和设备树加载到ram中,并通过寄存器传递地址给内核;
u-boot/arch/arm/lib/crt0_64.S   ENTRY(_main)
设置C运行时环境(如栈指针、BSS段清零)
随后调用board_init_f(重定向前初始化)和 board_init_r (重定向后初始化)
bl    board_init_f
b    board_init_r
U-Boot通过_main→board_init_f→board_init_r的调用链替代了传统ARMv8的start_armboot(),这是其平台定制化的典型体现
Linux内核镜像zImage加载:u-boot/common/image.c中,fit_image_load 函数 加载linux内核镜像;    
设备树加载:u-boot/cmd/bootz.c 中,do_bootz 函数 解析设备树地址,内核地址;


第三阶段 Linux内核加载
根文件系统镜像system.img加载到ram中;
u-boot/common/image.c中 , boot_get_ramdisk 函数负责解析环境变量 initrd_high 和 initrd_addr ,确定根文件系统在RAM中的加载地址;


第四阶段 用户空间初始化
init进程启动‌
内核启动的第一个用户进程,执行init.rc脚本挂载文件系统并启动关键服务‌
系统级配置‌:system/core/rootdir/init.rc,定义基础服务(如zygote)和核心动作(如挂载/system分区)
硬件相关配置‌:device/<vendor>/<device>/init.rc或vendor/<vendor>/<device>/init.rc,针对特定硬件平台的扩展配置

system/core/rootdir/init.rc  : mkdir创建基础目录(挂载/system分区等),chmod授权,定义基础服务zygote(zygote}.rc);
import /system/etc/init/hw/init.${ro.zygote}.rc 动态加载硬件相关的Zygote配置;
start zygote  启动zygote服务,
创建java虚拟机:art/runtime/runtime.cc 中 Runtime::Create  初始化ART虚拟机,加载核心库和JIT编译器;
预加载核心类库:Zygote进程初始化核心类预加载逻辑位于frameworks/base/core/java/com/android/internal/os/ZygoteInit.java,通过preloadClasses()方法加载/system/etc/preloaded-classes文件中定义的核心类
资源预加载(如主题、布局)通过preloadResources()方法实现,相关资源路径为/system/framework/framework-res.apk
系统服务启动阶段:SystemServer在frameworks/base/services/java/com/android/server/SystemServer.java中启动时,会进一步加载android.*框架类,依赖Zygote预加载的结果;
‌配置文件路径:预加载类列表文件:/system/etc/preloaded-classes(文本格式,每行一个类名),核心库文件目录:/system/framework/包含framework.jar、core-oj.jar等;

小结:init进程解析init.rc后启动Zygote,Zygote通过上述路径预加载类库,最终由SystemServer完成系统服务的Java环境初始化;
所有预加载操作均在ZygoteInit.main()中触发,确保后续应用进程通过fork共享已加载的类

第五阶段 SystemServer启动‌
SystemServer是通过Zygote
运行核心系统服务(如ActivityManagerService),最终启动Launcher桌面应用‌
frameworks/base/services/java/com/android/server/SystemServer 
public static void main(String[] args) {
new SystemServer().run();
}
AMS服务启动
run()  ---> startBootstrapServices --->  ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm);
PMS服务启动
run()  ---> startBootstrapServices --->  PackageManagerService.main(mSystemContext, installer,mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
WMS服务启动
run()  ---> startBootstrapServices --->  WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
创建主线程 Looper 并启动 Handler 处理服务间通信‌


第六阶段 应用启动阶段
‌冷启动流程‌
系统创建新进程,完成Application初始化、首帧渲染等操作‌

‌热启动优化‌
通过延迟加载非关键组件(如第三方SDK)提升启动速度‌

http://www.dtcms.com/a/475250.html

相关文章:

  • GRPO与GSPO算法训练对比
  • 如何制作网站板块php 企业网站模板
  • 佛山网站制作好处wordpress 扣积分
  • linux重定向中 >file 2>1,>>file 2>1 , >>file是什莫意思
  • 网站引导插件做网站最好的软件是
  • C++ 泛型
  • 网站网站建设公司企业为什么要增资
  • 第9章:两条道路的风景:技术与管理的真实世界(3)
  • Python 基础教程 | 菜鸟教程
  • 建设网站需求劳务公司简介模板
  • 解决 Vue 3 + TypeScript 中 v-for 循环类型推断问题
  • 外贸网站建站注意事项及价格宣传片拍摄脚本范本
  • Linux碎碎念:网络抓包利器:tcpdump 使用与分析入门
  • 十堰网站建设是什么塔罗牌手机网站制作
  • 北京网站制作费用wampserver安装wordpress
  • c可以做网站么公司网站域名无法解析
  • 做php网站教程视频住建部网站统计城乡建设统计信息系统登录
  • 风铃网站具体是做那方面的网站后台演示地址
  • 网站 建设 内容网站后台登录界面下载
  • 园林效果图网站兰州网站排名优化服务
  • Starting again-03
  • 探秘编译器背后的语言密码:从底层实现到技术演进的全景图
  • iis 里没有网站吗深圳的网站建设公司三把火
  • 肇庆企业建站程序evernote wordpress
  • JavaWeb学习-web开发什么是web开发
  • 专业开发网站企业net网站开发net网站开发
  • 最专业的企业营销型网站建设5分钟建站wordpress
  • JavaEE--Spring MVC
  • 建设网站简单的需要多少天网站开发技术要学什么软件
  • XCP协议在以太网上实现的配置