imx8mm偶现启动内核失败问题分析报告
转载自前同事zhouyuanjie。
- 问题环境
project:ubox
openwrt:v18.06.4
kernel:4.14.98
uboot:2018.03
- 问题现象
在openwrt编译ubox镜像后,使用镜像启动偶现镜像卡在“Starting kernel ...”阶段。
ubox镜像是通过mkimage工具做的FIT镜像,配置如下:
- 问题分析
分析一:
因未打包的源文件在uboot中使用的是booti命令启动,FIT镜像需要使用bootm命令启动,所以将有问题的FIT镜像采用booti的命令启动,发现能够正常启动,判断FIT打包前的源文件是没有问题的,排除因去掉了不该去掉的配置造成不能启动的情况。
分析二:
因问题是属于uboot->kernel的交付阶段,在此阶段没有可用调试工具和设备,则采用黑盒和代码分析的方法,首先分析bootm的启动流程:
do_bootm |
bootm命令 |
do_bootm_states |
完成image和fdt的查找、解压、装载等动作 |
boot_selected_os |
选择从什么启动系统并设置回调函数 |
do_bootm_linux |
为启动image做准备,如关闭dcache等 |
armv8_switch_to_el2 |
选择启动模式(32 or 64)和级别(el2为系统级别) |
armv8_switch_to_el2_m |
实际启动内核 |
经上述流程分析发现,uboot在实际启动前做了级别切换,怀疑CPU在进入kernel前进入了某种模式,导致CPU卡死在uboot中?然后分析kernel启动代码,并在kernel中添加点亮led的方式确定CPU是否成功进入内核,代码如下:
经上述内核代码调试分析后发现,在上图(1)的位置CPU会抛出(synchronoud abort异常,led实则未点亮,看抛出的这个异常大致确定是寻址或译码上的问题,此处并未深究,但能够抛出异常也能确定是进入kernel中),而去掉图(1)在图(2)出则会卡死,分析问题点代码{
adr_l x0, __hyp_stub_vectors
msr vbar_el2, x0
},异常点代码是在设置异常向量表后卡死。经objdump分析判断CPU在uboot交付kernel后产生异常,进入异常处理(死循环),详见下图:
经上述分析,启动过程中是卡死在kernel阶段,并且是在设置异常向量表后出现的异常,所以排除是因uboot模式切换错误导致的卡死。因无法确定CPU是产生的哪种异常,所以启动流程暂停分析。
分析三:
结合分析一、分析二,在有问题的FIT的镜像使用FIT源文件用booti命令能够成功启动。则尝试在do_bootm_states镜像装载完成后,调用booti去启动内核,代码如下:
经尝试,在bootm镜像装载完成后,使用booti命令启动问题依然。继续分析booti和bootm启动流程的差异点,发现booti和bootm的启动流程基本相同,所不同的是,在booti在调用do_bootm_states前对装载的镜像做了偏移操作,如下:
经偏移操作后,kernel的FIT镜像中的Load地址为0x4380000,经偏移后实际使用地址为0x43880000,怀疑问题在kernel或fdt的load地址上。
分析四:
经分析三结论,尝试修改FIT镜像中的kernel和fdt的load地址,如下:
经多次尝试发现一个共同点,就是kernel的地址后面必须是0x80000(bootm并不会做对齐操作),并且fdt的load地址必须对齐(fdt的load地址在openwrt中默认是没有的,则bootm解析FIT后fdt的load地址为bootm装载的地址),结合分析三和linux-4.14.98/Documentation/arm64/booting.txt,以及查看kernel头部信息确认,头部信息中确实设置了相关位置,并且load的地址需要做偏移,如下:
- 结论
经问题分析测试后,确定问题有两点。
- kernel的load地址必须偏移0x80000,如基址是0x43800000则实际的load地址必须是0x43880000;
- 固定fdt的load地址。
因上述两点则会导致,进入kernel后CPU出现异常被挂起。
imx8mm偶现启动内核失败问题分析报告相关推荐
- 基于GLSurfaceView的视频播放器偶现无画面的问题分析
文章目录 一. 问题背景 二. 逐步排查 2.1 增加log,复现问题 2.2 查看ijkplayer源码 2.3 查看AOSP源码 三. 分析原因 3.1 Renderer回调onSurfaceCr ...
- Hi3520烧写flash失败问题分析
背景 CPU芯片型号:Hi3520 DRQCV300 CP3091820 1820-CHINA flash型号:MX25L12835FM2I-10G [spi nor flash] 工厂生产的样板回来 ...
- [转] 常见WinCE启动失败原因分析
*********************************************** 一般情况下,为设计中的IC开发SW方案,难免会碰到Bootloader/EBoot/OS启动失败的情况, ...
- S5P210-uboot源码分析-uboot如何启动内核
uboot如何启动内核 7.1.uboot和内核到底是什么? 1.uboot是一个裸机程序 (1)uboot的本质就是一个复杂点的裸机程序,和我们arm裸机中写的程序没有什么本质上的区别. (2)ub ...
- Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3.0 ARMv7) 【转】...
原文地址:Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3.0 ARMv7) 作者:tekkamanninja 转自:http://blog.chinauni ...
- 【Android 逆向】启动 DEX 字节码中的 Activity 组件 ( 使用 DexClassLoader 获取组件类失败 | 失败原因分析 | 自定义类加载器没有加载组件类的权限 )
文章目录 一.使用 DexClassLoader 获取组件类失败报错 二.失败原因分析 一.使用 DexClassLoader 获取组件类失败报错 在上一篇博客 [Android 逆向]启动 DEX ...
- Linux内核源码分析--内核启动之(4)Image内核启动(setup_arch函数)(Linux-3.0 ARMv7)【转】...
原文地址:Linux内核源码分析--内核启动之(4)Image内核启动(setup_arch函数)(Linux-3.0 ARMv7) 作者:tekkamanninja 转自:http://blog.c ...
- distcc 链接失败_distcc分布式编译时,icu host程序偶现编译失败原因分析
distcc分布式编译:将.c通过socket发送到其他电脑,其他电脑把.c编译成.o,然后再发送回来,在本地进行连接. icu:需要先编译host程序,然后使用host程序产生一些文件,再交叉编译出 ...
- U-boot启动流程(Linux内核)的分析(四)
在上一篇中分析到u-Boot启动Linux内核的函数do_bootm_linux,这一篇则着重分析,U-boot是如果一步一步启动内核的. 我们可以看到在,start_armboot()函数的最后,在 ...
- U-Boot启动流程(Linux内核)的分析
http://www.360doc.com/content/12/0816/10/7775902_230452499.shtml 前面一段时间一直在移植U-Boot,Linux内核和构建根文件 ...
最新文章
- 斯坦福大学报告称中国AI论文引用率首超美国!但李国杰院士也发文灵魂拷问!...
- macos终端快捷键
- 机器学习流程,以及实践应用
- Centos 6.8 搭建owncloud 私有云盘
- 解决idea导入项目后依赖报错问题
- 博客网站没落的两个原因
- 吴恩达 coursera ML 第十五课总结+作业答案
- 用Python轻松开发数据库取数下载工具
- 关于Android的应用程序的发布的学习(一)
- ThreadLocal 内存泄漏问题
- mysql s.`name`_MySQL的基础操作命令
- Java新职篇:类型提升的约定
- Mac使用VMware、Ubuntu安装配置虚拟机Linux
- soapui oracle groovy,SoapUI Groovy 使用实例
- 珠心算测验 C语言基础
- android 屏幕尺寸适配实现方案
- 解决TS中“Cannot find module ‘path‘ or its corresponding type declarations.”
- 好用的BUG、内存泄露捕捉工具 EurekaLog v6.0.3 Enterprise For D5-D2007
- Voldemort — 分布式 key-value 存储系统
- 巴菲特和盖茨的顶级对话:实现财富自由 没有那么难