startup callout中的一些疑问,先谢谢各位了!

以下是sa1100 startup.s文件中的一段代码,本人刚开始学习QNX,其中有很多不理解,请教大家了。先

谢谢了!
-------------------------------
CALLOUT_START(interrupt_id_sa1111db, 0, patch_irr)
mov r0, #0x000000ff // IRR base (patched)
orr r0, r0, #0x0000ff00
orr r0, r0, #0x00ff0000
orr r0, r0, #0xff000000

ldr r1, [r0]
mov r4, #0
eor r1, r1, #3
tst r1, #1 // Ethernet
moveq r4, #1
tsteq r1, #2 // USAR
moveq r4, #2
tsteq r1, #4 // SA1111
mvneq r4, #0
CALLOUT_END(interrupt_id_sa1111db)

……

patch_irr:
stmdb sp!,{r4,lr}
add r4, r0, r2 // address of callout routine

ldr r1, LIIR_BASE
mov r0, #4 // size of interrupt registers
bl callout_io_map
CALLOUT_PATCH r4, r0, r1, r2, ip

ldmia sp!,{r4,pc}

LIIR_BASE: .word 0x10000024 // base address of board IIR register
----------------------------
1:看了帮助文档现在还是不清楚callout的最终作用,请大虾们解释一下吧!
2:patch_irr是在interrupt_id_sa1111db执行完才被调用的吗?
3:callout_io_map在这个汇编文件中没有地方标注的,但是在别的文件中函数,是不是直接调用?

callout是跟硬件紧密相关,又必须放在内核里的代码.因为QNX的内核为通用内核,没有任何与硬件有关的东西,而这些代码又是必不可少的,所以这部分代码必须由startup将其拷贝到内核空间的某个地方以便内核调用.
由于内核不能访问物理地址,所以必须由startup将物理地址map到内核可以访问的虚拟地址,这个工作一般由patcher来作.当然patcher也可以用来作别的用途.
patcher是在startup中被调用的,而且只存在startup中,不会被拷到内核中.具体到你的例子,patch_irr在startup中调用,interrupt_id_sa1111db是在内核运行中CPU接受到中断后才被调用.


很感谢!