UART在Linux内核启动时突然不打印的问题

ops/2024/10/11 7:23:34/

国庆前一天收到的任务,在一颗比较成熟的芯片的SDK基础上,移植一个新内核,让它能够在bitfile下跑在FPGA上。
看了芯片设计那边给的文档,对比过去的那颗,感觉也就改改寄存器,中断号,时钟,内存布局,这活儿也就搞完了,两天解决。
谁曾想一搞就是十天[em]e105[/em]

最气人的是第二天就已经进内核了,串口打印停在busybox,init进程被唤起之前的位置,一度以为是文件系统打包的问题,学了一波buildroot打包方式,追内核解包代码。。。途中,还替换了原先rootfs的打包方法,效果是一致的,串口停在同一个位置。无奈,就开始在最后一行log附近,加打印,最后发现内核start_kernel都跑完了,init也被do_exec了,返回值还是正确的,真邪乎!

串口不打印了,有可能是串口本身有问题,或是init进程运行失败了,也有可能二者叠加。设计给的bitfile也只引出一个串口,这怎么调试?

我开始对我新拉的分支上的代码不信任了,找出过去能在evb上正常跑的代码,在此基础上做最小修改让它在FPGA上能跑起来,结果是这两套内核对齐到最后只有串口时钟源不一致(FPGA固定20M),其他配置都一致,在FPGA上依然卡主。

这么一对比,感觉FPGA上串口有问题啊,可我没有证据!无非就是基地址,中断号,时钟这仨有一个出错了。

基地址不用看,因为内核早期启动打印正常,但是它不用中断,所以感觉中断号有问题,去看手册吧,核实了我设备树配置得一样。时钟如果有问题,也只是乱码而已,不会停住不输出。

到这里怀疑范围可以进一步缩小了,最有可能的依然是中断,遂换个思路,改evb代码,故意改错他注册的中断号,跑起来后发现效果和FPGA一致,停在了同一个地方!!!

这时我就开始想怼设计,拉着他看现象了,后来静下来一想,我证据还是不足啊:busybox里还会进一步对串口进行配置,做重定向,是不是我busybox得问题呢?我在看了一眼busybox代码,头疼。。。一想到又要在它里边儿加打印,追执行路径,重新编译。。。
算了,换个方法,能否直接沿用早期的bootconsole?不在启动时把它关闭?似乎只要在设备树里不去加串口的设备节点就好了(听说),后来证明不行,我也是后来才知道除了删掉节点还要改一个flag,否则依然会用启动后期新注册的串口。

怀疑中断问题,但不好调试证明,此时我已经开始请救兵了,大佬推荐我在串口的中断处理函数里加gloabl cnt,在System.map找到这个全局变量地址,Attach仿真器上去看这个地址上的值(仿真器加符号表加调用堆栈,无敌的调试方式)

结果证明串口的中断就是没有进,但此时我依然坚信串口中断号配置是对的,因为我的同事已经做过裸区验证,串口的中断收发是pass的,同一个bitfile,同一个中断号,没理由是效果不同。(很矛盾)

为了证明串口是错误的,我开始修改串口驱动,中断模式改为poll模式,再启动,发现FPGA上也可以跑的更远了,这次跑到了inittab里(排除了init进程调用失败),停在了配置getty与console绑定的这一行(也是通过在rcS里加打印)来确认了。还是停住了,依然没进login,很苦恼,临门一脚了。我已经没有路数了。

后来还是一个同事提醒我,你都能在rcS加打印了,你为什么不多加点,cat 一下内核中断计数啊?
好吧,追了这么多天,脑子糊涂了。如下图,加入了getty权限显示,tty绑定关系显示,中断号显示。可以看到ttyS0也就是我的UART0上是没有计数的,与此同时arch timer居然也没有计数,6啊这玩意都没有计数那指定是有问题了,还是它们老大的问题,GIC控制器。

先看下evb和fpga的差异,我先dump了EVB板子上的GIC控制器所有寄存器,然后用仿真器dump我卡死的FPGA Linux的GIC控制器,然后dump裸驱工程执行时GIC的寄存器。(dump这仨用的是同一个基地址,因为设计给的手册上市同一个值)
我发现evb上gic配置正确,但是后两者dump出来都是0!!。fpga linux的gic没配置我能理解,它中断没计数嘛。裸驱工程怎么也没配置,它串口的中断模式不是验证了吗?保持怀疑,自己找个工程跑一次case,结果确实市通的。说实在的,我还没看过裸驱里怎么配置的GIC,那就跟一下它的代码,我发现它是通过汇编配置的,虽然代码里用宏定义配置了它的基地址,但是没人引用这个宏,且它的基地址是从CP15协处理器读出来的!!!我用仿真器读图二的r0寄存器,好家伙,地址是一个陌生的值 0xf0611000。
我囿于串口,init进程,rootfs近十天,在他们仨之间打转,这个陌生的值鬼使神差得推着我将它填入Linux的设备树(图三),编译过程中就想着了这次绝对能过。
效果如图四。爽了。
最后还留了一个问题,为啥poll模式进不到login位置,中断模式可以?

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


http://www.ppmy.cn/ops/123859.html

相关文章

网站开发基础:HTML、CSS

前端开发主要使用的技术如 HTML、CSS 和 JavaScript 等。 简单制作一个网页 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>柒毓同学网站的首页</title><style>.c1{border: solid 1px g…

【uniapp小程序】使用cheerio去除字符串中的HTML标签并获取纯文本内容

【uniapp小程序】使用cheerio去除字符串中的HTML标签并获取纯文本内容 参考资料安装引入使用 参考资料 【博主&#xff1a;AIpoem】uniapp小程序 使用cheerio处理网络请求拿到的dom数据 cheerio文档&#xff1a;https://github.com/cheeriojs/cheerio/wiki/Chinese-README 安…

JAVA开发中的常用通讯协议

在JAVA开发中&#xff0c;通讯协议是实现不同系统或组件之间数据交换的基础。随着分布式系统和微服务架构的流行&#xff0c;掌握常用的通讯协议对于JAVA开发者来说至关重要。本文将介绍在JAVA开发中常用的几种通讯协议&#xff0c;以及它们的特点和应用场景。 1. HTTP/HTTPS …

kotlin 委托

一、类委托 interface DB{fun insert() } class SqliteDB : DB {override fun insert() {println(" SqliteDB insert")} }class MySql : DB{override fun insert() {println(" MySql insert")} }class OracleDB : DB{override fun insert() {println(&quo…

情绪识别数据集(包含25w张图片) yolo格式类别:八种训练数据已划分, 识别精度:90%

情绪识别数据集(包含25w张图片) yolo格式 类别&#xff1a;Anger、Contempt、Disgust、Fear、Happy、Neutral、Sad、Surprise 八种 训练数据已划分&#xff0c;配置文件稍做路径改动即可训练。 训练集&#xff1a;171010 验证集&#xff1a;54060 测试集&#xff1a;27550 共计…

Codeforces Round 977 (Div. 2)E1 Digital Village (Easy Version)(Floyd,贪心)

题目链接 Codeforces Round 977 (Div. 2&#xff09;E1 Digital Village (Easy Version) 思路 首先&#xff0c;我们注意到 n n n的最大值只有 400 400 400。 因此&#xff0c;我们可以先用 F l o y d Floyd Floyd算法预处理出任意两座城市之间的最大延迟时间。 之后&…

strstr

strstr函数原型&#xff1a; char *strstr&#xff08;conset char *s, conset char *s2&#xff09;; 功能&#xff1a;在字符串s中查找字符串s2出现的位置 返回值&#xff1a; 成功&#xff1a;返回第一次出现的s2的地址 失败&#xff1a;NULL

springboot第75集:kafka,线程,进程,容器化服务,线程池

消息中间件在异步通信中⽤的最多&#xff0c;很多业务流程中&#xff0c;如果所有步骤都同步进⾏可能会导致核⼼流程耗时⾮常⻓&#xff0c;更重 要的是所有步骤都同步进⾏⼀旦⾮核⼼步骤失败会导致核⼼流程整体失败&#xff0c;因此在很多业务流程中Kafka就充当了异步 通信⻆⾊…