ARM linux解析之压缩内核zImage的启动过程
下面以arch/arm/boot/compressed/head.s为主线进行启动过程解析。
1.head.s的debug宏定义部分
最开始的一段都是head.s的debug宏定义部分,这部分可以方便我们调试时使用。
如下:
#ifdefDEBUG
#if defined(CONFIG_DEBUG_ICEDCC)
#if defined(CONFIG_CPU_V6) defined(CONFIG_CPU_V6K) defined(CONFIG_CPU_V7)
.macro loadsp, rb, tmp
.endm
.macro writeb, ch, rb
mcrp14, 0, \ch, c0, c5, 0
.endm
#elif defined(CONFIG_CPU_XSCALE)
.macro loadsp, rb, tmp
.endm
.macro writeb, ch, rb
mcrp14, 0, \ch, c8, c0, 0
.endm
#else
.macro loadsp, rb, tmp
.endm
.macro writeb, ch, rb
mcrp14, 0, \ch, c1, c0, 0
.endm
#endif
#else
#include
.macro writeb, ch, rb
senduart \ch, \rb
.endm
#if defined(CONFIG_ARCH_SA1100)
.macro loadsp, rb, tmp
mov\rb, #0x80@ physical base address
#ifdef CONFIG_DEBUG_LL_SER3
add \rb, \rb, #0x50 @ Ser3
#else
add \rb, \rb, #0x10 @ Ser1
#endif
.endm
#elif defined(CONFIG_ARCH_S3C2410)
.macro loadsp, rb, tmp
mov\rb, #0x50
add \rb, \rb, #0x4 * CONFIG_S3C_LOWLEVEL_UART_PORT
.endm
#else
.macro loadsp, rb, tmp
addruart \rb, \tmp
.endm
#endif
#endif
#endif
如果开启DEBUGging宏的话,这部分代码分两段CONFIG_DEBUG_ICEDCC是用ARMv6以上的加构支持的ICEDCC技术进行调试,DCC(Debug Communications Channel)是ARM的一个调试通信通道,在串口无法使用的时候可以使用这个通道进行数据的通信,具体的技术参前ARM公司文档《ARM Architecture Reference Manual》。
第二部分首先#include
#include
#include
.macroaddruart, rp, rv
ldr \rp, =ARM_EVB_UART0_BASE@ System peripherals (phys address)
ldr \rv, =(IO_BASE+ ARM_EVB _UART0_BASE)@ System peripherals (virt address)
.endm
.macrosenduart,rd,rx
strb\rd, [\rx, #(0x00)]@ Write to Transmitter Holding Register
.endm
.macrowaituart,rd,rx
1001:ldr \rd, [\rx, #(0x18)]@ Read Status Register
tst \rd, #0x20@when TX FIFOFull, then wait
bne 1001b
.endm
.macrobusyuart,rd,rx
1001:ldr \rd, [\rx, #(0x18)]@ Read Status Register
tst \rd, #0x08@ when uart is busy then wait
bne 1001b
.endm
主要实现addruart,senduart,waituart,busyuart这四个函数的具体实施。这个是调试函数打印的基础。
下面是调试打印用到的kputc和kphex
.macrokputc,val
movr0, \val
blputc
.endm
.macrokphex,val,len
movr0, \val
movr1, #\len
blphex
.endm
它所调用的putc和phex是在head.s最后的一段定义的,如下
#ifdef DEBUG
.align2
.typephexbuf,#object
phexbuf:.space12
.sizephexbuf, . - phexbuf
上面是分配打印hex的buffer,下面是具体的实现:
@ phex corrupts {r0, r1, r2, r3}
phex:adr r3, phexbuf
movr2, #0
strbr2, [r3, r1]
1:subsr1, r1, #1
movmi r0, r3
bmiputs
and r2, r0, #15
movr0, r0, lsr #4
cmpr2, #10
addger2, r2, #7
add r2, r2, #0
strbr2, [r3, r1]
b1b
@ puts corrupts {r0, r1, r2, r3}
puts:loadspr3, r1
1:ldrbr2, [r0], #1
teq r2, #0
moveqpc, lr
2:writebr2, r3
movr1, #0x20
3:subsr1, r1, #1
bne 3b
teq r2, #\n
moveqr2, #\r
beq 2b
teq r0, #0
bne 1b
movpc, lr
@ putc corrupts {r0, r1, r2, r3}
putc:
movr2, r0
movr0, #0
loadspr3, r1
b2b
@ memdump corrupts {r0, r1, r2, r3, r10, r11, r12, lr}
memdump:movr12, r0
movr10, lr
movr11, #0
2:movr0, r11, lsl #2
add r0, r0, r12
movr1, #8
blphex
movr0, #:
blputc
1:movr0, #
blputc
ldrr0, [r12, r11, lsl #2]
movr1, #8
blphex
and r0, r11, #7
teq r0, #3
moveqr0, #
bleqputc
and r0, r11, #7
add r11, r11, #1
teq r0, #7
bne 1b
movr0, #\n
blputc
cmpr11, #64
blt2b
movpc, r10
#endif
嘿嘿,还有memdump这个函数可以用,不错。
好了
ARMlinux解析压缩内核zImage启动过 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)