Linux kernel IMX53外部中止
我正在IMX53 Sabre平板电脑上启动Android。android正常启动时串行端口上的最后几行如下所示:Linux kernel IMX53外部中止,linux-kernel,arm,abort,trust-zone,Linux Kernel,Arm,Abort,Trust Zone,我正在IMX53 Sabre平板电脑上启动Android。android正常启动时串行端口上的最后几行如下所示: warning: `rild' uses 32-bit capabilities (legacy support in use) pmem: request for physical address of pmem region from process 2262. request_suspend_state: on (3->0) at 12032459753 (2000-01
warning: `rild' uses 32-bit capabilities (legacy support in use)
pmem: request for physical address of pmem region from process 2262.
request_suspend_state: on (3->0) at 12032459753 (2000-01-03
01:08:28.336600001 U
TC)
Unhandled fault: external abort on non-linefetch (0x1018) at 0x40a85054
Unhandled fault: external abort on non-linefetch (0x1018) at 0x40a85054
.global tz_monitor
.align 5
tz_monitor:
@ Monitor
b _monitor_reset @ Reset
b _monitor_undef @ Undef
b smc_handler @ SMC
b _monitor_prefetch @ Prefetch
b _monitor_da @ Data abort
nop @ RESERVED
b _monitor_irq @IRQ
b _monitor_fiq @FIQ
ldr r0, =tz_monitor @ Get address of Monitors vector table
mcr p15, 0, r0, c12, c0, 1 @ Write Monitor Vector Address Register
注意,这些外部中止不会停止引导过程,Android会正常引导。现在我想使用这些外部中止来测试监视器中止处理程序代码。我希望能够捕获外部中止以进行监视
在安全监视器的初始化过程中,我执行以下操作:
mrc p15, 0, r4, c1, c1, 0
bic r4, #0x66 @ clear AW, IRQ, FIQ
orr r4, #0x19 @ set FW, EA, NS
//orr r4, #0x01 @ previously, just set NS
mcr p15, 0, r4, c1, c1, 0
我的监视器向量表如下所示:
warning: `rild' uses 32-bit capabilities (legacy support in use)
pmem: request for physical address of pmem region from process 2262.
request_suspend_state: on (3->0) at 12032459753 (2000-01-03
01:08:28.336600001 U
TC)
Unhandled fault: external abort on non-linefetch (0x1018) at 0x40a85054
Unhandled fault: external abort on non-linefetch (0x1018) at 0x40a85054
.global tz_monitor
.align 5
tz_monitor:
@ Monitor
b _monitor_reset @ Reset
b _monitor_undef @ Undef
b smc_handler @ SMC
b _monitor_prefetch @ Prefetch
b _monitor_da @ Data abort
nop @ RESERVED
b _monitor_irq @IRQ
b _monitor_fiq @FIQ
ldr r0, =tz_monitor @ Get address of Monitors vector table
mcr p15, 0, r0, c12, c0, 1 @ Write Monitor Vector Address Register
示例异常处理程序函数仅打印一条语句,如下所示:
在汇编中:
.global _monitor_prefetch
_monitor_prefetch:
push {lr}
bl monitor_prefetch
pop {lr}
movs pc, lr
在C中:
我在安全监视器的初始化中添加此向量表,如下所示:
warning: `rild' uses 32-bit capabilities (legacy support in use)
pmem: request for physical address of pmem region from process 2262.
request_suspend_state: on (3->0) at 12032459753 (2000-01-03
01:08:28.336600001 U
TC)
Unhandled fault: external abort on non-linefetch (0x1018) at 0x40a85054
Unhandled fault: external abort on non-linefetch (0x1018) at 0x40a85054
.global tz_monitor
.align 5
tz_monitor:
@ Monitor
b _monitor_reset @ Reset
b _monitor_undef @ Undef
b smc_handler @ SMC
b _monitor_prefetch @ Prefetch
b _monitor_da @ Data abort
nop @ RESERVED
b _monitor_irq @IRQ
b _monitor_fiq @FIQ
ldr r0, =tz_monitor @ Get address of Monitors vector table
mcr p15, 0, r0, c12, c0, 1 @ Write Monitor Vector Address Register
这些修改会带来变化,即内核在外部中止时崩溃。但是我在监视器处理程序中没有得到print语句。在启动Android时,我现在通过串行方式获得以下输出:
warning: `rild' uses 32-bit capabilities (legacy support in use)
pmem: request for physical address of pmem region from process 2262.
request_suspend_state: on (3->0) at 12005333628 (2000-01-03
00:38:52.322241626 UTC)
Bad mode in prefetch abort handler detected
Internal error: Oops - bad mode: 0 [#1] PREEMPT
last sysfs file: /sys/devices/platform/pwm-backlight.0/backlight/pwm-
backlight.0/brightness
Modules linked in:
CPU: 0 Not tainted (2.6.35.3-01265-g8f56f17 #6)
PC is at 0x77802570
LR is at 0xafd0bf6c
pc : [<77802570>] lr : [<afd0bf6c>] psr: 200001d6
sp : ce0e7fb0 ip : 8151c780 fp : 00000001
r10: 00000000 r9 : 40a85000 r8 : 00000002
r7 : 4090ae64 r6 : 8151c890 r5 : 00000018 r4 : 40207000
r3 : 40a85000 r2 : 00000001 r1 : 60000010 r0 : 00000000
Flags: nzCv IRQs off FIQs off Mode UK6_32 ISA ARM Segment user
Control: 10c5387d Table: 83668019 DAC: 00000015
Process Binder Thread # (pid: 2307, stack limit = 0xce0e62e8)
Stack: (0xce0e7fb0 to 0xce0e8000)
7fa0: 00000000 60000010 00000001
40a85000
7fc0: 40207000 00000018 8151c890 4090ae64 00000002 40a85000 00000000
00000001
7fe0: 8151c780 ce0e7fb0 afd0bf6c 77802570 200001d6 ffffffff ffc75a9a
dfd4eed7
Code: bad PC value
---[ end trace d8447dd37d1d45d8 ]---
Kernel panic - not syncing: Fatal exception
[<c003e58c>] (unwind_backtrace+0x0/0xf0) from [<c04862f0>]
(panic+0x6c/0xe0)
[<c04862f0>] (panic+0x6c/0xe0) from [<c003d420>] (die+0x2b4/0x304)
[<c003d420>] (die+0x2b4/0x304) from [<c003d4ac>] (bad_mode+0x3c/0x5c)
[<c003d4ac>] (bad_mode+0x3c/0x5c) from [<afd0bf6c>] (0xafd0bf6c)
好的,正如我所说的,您的
\u监视器\u预取
没有保存足够的寄存器。您需要保存所有寄存器;它们不在安全/正常世界之间存储。当发生“外部中止”时,您将随机损坏Linux寄存器。您正在与Linux共享资源。您尚未指定printf
的工作方式?使用轮询模式UART发送字符,并确保从监视器“刷新”。请注意,I/O配置和时钟也与Linux共享;这将如何影响UART?另外,当您返回Linux时,需要切换回“NS”。谢谢@artlessnoise。我编辑了这个问题。关于我在安全世界中拥有的内容:我在uboot imx的lib_arm/文件夹中添加/修改了这些文件。我只在编译此文件时更改uboot.bin。linux内核和Android映像我不会更改。U-boot还有其他printf-s,但我不清楚时钟/UART是如何在世界范围内共享的,如果有的话。我应该试试这样的吗?我将在处理程序中保存/还原寄存器,并在NS和NS之间切换。好的,U-boot的“引导linux”消息在哪里?与Linux控制台在同一序列上?他们会发生冲突。Linux将设置iomux(pinctrl)和时钟树,“setburg()”jazz依赖于该时钟树以获得有效的波特率。当我这样做时,我为TZ使用了一个单独的串行端口(没有对串行端口的LinuxDT引用),并编写了汇编程序轮询例程(如Linux中的早期控制台调试)。只需传递固定字符串(没有像printf
这样的格式),您就可以拥有一个printhex()
。。。这将最大限度地减少寄存器和内存以成功打印,最大限度地减少事情的正确性。检测到预回迁中止处理程序中的消息Bad mode(坏模式)意味着您没有在监视器条目上保存spsr
,并在返回正常世界时将其还原;因此,movspc,lr
似乎在printf
期间spsr发生了变化(可能是由于另一个例外)。通常,您将所有寄存器(包括spsr)保存在“世界上下文”中,并在返回时还原它们。为什么要使用R2
?这也与Linux共享。您需要设置SP_监视器。因此,在启动Linux之前,您需要在监视器模式下分配内存并将其分配给R13
。这就是监视器堆栈。将R2
更改为R13
或SP
。好的,正如我所说,您的\u监视器\u预取
没有保存足够的寄存器。您需要保存所有寄存器;它们不在安全/正常世界之间存储。当发生“外部中止”时,您将随机损坏Linux寄存器。您正在与Linux共享资源。您尚未指定printf
的工作方式?使用轮询模式UART发送字符,并确保从监视器“刷新”。请注意,I/O配置和时钟也与Linux共享;这将如何影响UART?另外,当您返回Linux时,需要切换回“NS”。谢谢@artlessnoise。我编辑了这个问题。关于我在安全世界中拥有的内容:我在uboot imx的lib_arm/文件夹中添加/修改了这些文件。我只在编译此文件时更改uboot.bin。linux内核和Android映像我不会更改。U-boot还有其他printf-s,但我不清楚时钟/UART是如何在世界范围内共享的,如果有的话。我应该试试这样的吗?我将在处理程序中保存/还原寄存器,并在NS和NS之间切换。好的,U-boot的“引导linux”消息在哪里?与Linux控制台在同一序列上?他们会发生冲突。Linux将设置iomux(pinctrl)和时钟树,“setburg()”jazz依赖于该时钟树以获得有效的波特率。当我这样做时,我为TZ使用了一个单独的串行端口(没有对串行端口的LinuxDT引用),并编写了汇编程序轮询例程(如Linux中的早期控制台调试)。只需传递固定字符串(没有像printf
这样的格式),您就可以拥有一个printhex()
。。。这将最大限度地减少寄存器和内存以成功打印,最大限度地减少事情的正确性。检测到预回迁中止处理程序中的消息Bad mode(坏模式)意味着您没有在监视器条目上保存spsr
,并在返回正常世界时将其还原;因此,movspc,lr
似乎在printf
期间spsr发生了变化(可能是由于另一个例外)。通常,您将所有寄存器(包括spsr)保存在“世界上下文”中,并在返回时还原它们。为什么要使用R2
?这也与Linux共享。您需要设置SP_监视器。因此,在启动Linux之前,您需要在监视器模式下分配内存并将其分配给R13
。这就是监视器堆栈。将R2
更改为R13
或SP
。