arm-linux内核无法printk打印时的调试方法--内联汇编操作串口寄存器打印

很多情况下,我们在调试linux内核子系统或者内核驱动时,经常会用printk将调试信息打印到文件系统中或者串口终端。

但是在某些情况下,在linux系统刚启动时,或者某些场景下无法使用printk打印调试信息到文件系统,系统也无法起来,这个时候都无法查看堆栈信息。

这种情况下,如果板子上还有串口外设可以用,那我们就还有办法。
具体的办法就是通过在C语言代码中内联汇编操作串口寄存器打印,当然如果在汇编中,那就直接操作串口寄存器就好了。

同时这个方法不仅仅适用于linux内核,其他有串口的操作系统内核也可以操作,比如rtos这些。

一、arm32模式下内联汇编操作串口寄存器

假设当前板子上一路串口,寄存器基地址为0x30530000,同时已经配置好波特率还有时钟频率了,我们想让这路串口输出字符“1”,那应该如下操作:

__arm__ __volatile__(
    "ldr r0, #0x30530000\n\t"
    "ldr r1, #0x00000031\n\t"
    "str r1, [r0]\n\t"
);

1、"ldr r0, #0x30530000\n\t"

这里表示ldr将数值0x30530000加载到指定的通用寄存器r0中。

2、 "ldr r0, #0x00000031\n\t"
这里表示ldr将数值0x00000031,也就是字符“1”,加载到指定的通用寄存器r1中。

3、 "str r1, [r0]\n\t"
这里表示寄存器r1的数值写入寄存器r0的地址中,也就是直接写入数据。

二、arm64模式下内联汇编操作串口寄存器

假设当前板子上一路串口,寄存器基地址为0x30530000,同时已经配置好波特率还有时钟频率了,我们想让这路串口输出字符“1”,那应该如下操作:

__arm__ __volatile__(
    "ldr x0, #0x30530000\n\t"
    "ldr x1, #0x00000031\n\t"
    "str x1, [x0]\n\t"
);

1、"ldr x0, #0x30530000\n\t"

这里表示ldr将数值0x30530000加载到指定的通用寄存器x0中。

2、 "ldr x1, #0x00000031\n\t"
这里表示ldr将数值0x00000031,也就是字符“1”,加载到指定的通用寄存器x1中。

3、 "str x1, [x0]\n\t"
这里表示寄存器x1的数值写入寄存器x0的地址中,也就是直接写入数据。

三、arm32与arm64模式下汇编操作的注意细节

在arm32和arm64模式下的汇编其实有个地方是要注意的。

arm32模式下通用寄存器是用r0,arm64模式下通用寄存器是用x0。

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值