Linux kernel IMX53外部中止

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

我正在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-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