文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>vivi汇编部分(stage1)分析

vivi汇编部分(stage1)分析

时间:2010-06-07  来源:charming2440

vivi的代码从head.S开始,也就是整个bootloader的stage1部分。这部分采用汇编语言来编写,从而达到高效,短小的目的。 首先我们需要注意的是head.S采用的是大写的后缀,而不是我们常规上面的小写。下面引用CalmArrow博客中的一段话来说明这个问题: "首先解决一个问题,就是为什么使用head.S而不是用head.s?有了GNU AS和GNU Gcc的基础,不难理解主要原因就是为了使用C预处理器的宏替换和文件包含功能(GNU AS的预处理无法完成此项功能)。可以参考前面的总结部分。这样的好处就是可以使用C预处理器的功能来提高ARM汇编的程序设计环境,更加方便。但是因为ARM汇编和C在宏替换的细节上有所不同,为了区分,引入了__ASSEMBLY__这个变量,这是通过Makefile中AFLAGS来引入的" 查看宏展开可以使用: GCC -E -D__ASSEMBLY__ -I./include /vivi/arch/s3c2440/head.S > charming.s

# 1 "arch/s3c2440/head.S"
# 1 "<built-in>"
# 1 "<鍛戒护琛?"
# 1 "arch/s3c2440/head.S"
# 35 "arch/s3c2440/head.S"
# 1 "./include/config.h" 1
# 14 "./include/config.h"
# 1 "./include/autoconf.h" 1
# 15 "./include/config.h" 2
# 36 "arch/s3c2440/head.S" 2
# 1 "./include/linkage.h" 1
# 37 "arch/s3c2440/head.S" 2
# 1 "./include/machine.h" 1



# 1 "./include/config.h" 1
# 5 "./include/machine.h" 2
# 22 "./include/machine.h"
# 1 "./include/platform/smdk2440.h" 1

# 1 "./include/s3c2440.h" 1
# 22 "./include/s3c2440.h"
# 1 "./include/hardware.h" 1
# 23 "./include/s3c2440.h" 2
# 1 "./include/bitfield.h" 1
# 24 "./include/s3c2440.h" 2
# 3 "./include/platform/smdk2440.h" 2




# 1 "./include/sizes.h" 1
# 8 "./include/platform/smdk2440.h" 2
# 74 "./include/platform/smdk2440.h"
# 1 "./include/architecture.h" 1
# 75 "./include/platform/smdk2440.h" 2
# 23 "./include/machine.h" 2
# 38 "arch/s3c2440/head.S" 2

@ Start of executable code

.globl _start; .align 0; _start:
.globl ResetEntryPoint; .align 0; ResetEntryPoint:

@
@ Exception vector table (physical address = 0x00000000)
@

@ 0x00: Reset
 b Reset

@ 0x04: Undefined instruction exception
UndefEntryPoint:
 b HandleUndef

@ 0x08: Software interrupt exception
SWIEntryPoint:
 b HandleSWI

@ 0x0c: Prefetch Abort (Instruction Fetch Memory Abort)
PrefetchAbortEnteryPoint:
 b HandlePrefetchAbort

@ 0x10: Data Access Memory Abort
DataAbortEntryPoint:
 b HandleDataAbort

@ 0x14: Not used
NotUsedEntryPoint:
 b HandleNotUsed

@ 0x18: IRQ(Interrupt Request) exception
IRQEntryPoint:
 b HandleIRQ

@ 0x1c: FIQ(Fast Interrupt Request) exception
FIQEntryPoint:
 b HandleFIQ

@
@ VIVI magics
@

@ 0x20: magic number so we can verify that we only put
 .long 0
@ 0x24:
 .long 0
@ 0x28: where this vivi was linked, so we can put it in memory in the right place
 .long _start
@ 0x2C: this contains the platform, cpu and machine id
 .long ((1 << 24) | (7 << 16) | 782)
@ 0x30: vivi capabilities
 .long 0
# 103 "arch/s3c2440/head.S"
@
@ Start VIVI head
@
Reset:
 @ disable watch dog timer
 mov r1, #0x53000000
 mov r2, #0x0
 str r2, [r1]

 @ disable all interrupts
 mov r1, #0x4A000000
 mov r2, #0xffffffff
 str r2, [r1, #0x08]
 ldr r2, =0x7ff
 str r2, [r1, #0x1C]

 @ initialise system clocks
 mov r1, #0x4C000000
 mvn r2, #0xff000000
 str r2, [r1, #0x00]

 mov r1, #0x4C000000
 ldr r2, clkdivn_value
 str r2, [r1, #0x14]

 mrc p15, 0, r1, c1, c0, 0 @ read ctrl register
 orr r1, r1, #0xc0000000 @ Asynchronous
 mcr p15, 0, r1, c1, c0, 0 @ write ctrl register

 mov r1, #0x4C000000
 @ldr r2, mpll_value @ clock default
 ldr r2, =0x7f021 @mpll_value_USER @ clock user set
 str r2, [r1, #0x04]
 bl memsetup
# 147 "arch/s3c2440/head.S"
 @ All LED on
 mov r1, #0x56000000
 add r1, r1, #0x50
 ldr r2,=0x55aa
 str r2, [r1, #0x0]
 mov r2, #0xff
 str r2, [r1, #0x8]
 mov r2, #0x00
 str r2, [r1, #0x4]
# 165 "arch/s3c2440/head.S"
 @ set GPIO for UART

 mov r1, #0x56000000
 add r1, r1, #0x70
 ldr r2, gpio_con_uart @0x16faaa
 str r2, [r1, #0x0]
 ldr r2, gpio_up_uart        @0x7ff,enable the up resistence
 str r2, [r1, #0x8]

 bl InitUART
# 190 "arch/s3c2440/head.S"
 bl copy_myself


 mov r1, #0x56000000
 add r1, r1, #0x50
 mov r2, #0x00
 str r2, [r1, #0x4]


 @ jump to ram
 ldr r1, =on_the_ram
 add pc, r1, #0
 nop
 nop
1: b 1b @ infinite loop

on_the_ram:
# 217 "arch/s3c2440/head.S"
@ get read to call C functions
@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@0x33defffc, there are 32k bytes stack in the vivi,the base address of the stack @is 0x33de8000
@and there are many parameter in the vivi from the base address of 0x33df0000
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 ldr sp, DW_STACK_START @ setup stack pointer
 mov fp, #0 @ no previous frame, so fp=0
 mov a2, #0 @ set argv to NULL

 bl main @ call main

 mov pc, #0x00000000 @ otherwise, reboot

@
@ End VIVI head
@





@
@ Wake-up codes
@
# 303 "arch/s3c2440/head.S"
.globl memsetup; .align 0; memsetup:
 @ initialise the static memory

 @ set memory control registers
 mov r1, #0x48000000
 adrl r2, mem_cfg_val
 add r3, r1, #52
1: ldr r4, [r2], #4
 str r4, [r1], #4
 cmp r1, r3
 bne 1b
 mov pc, lr



@
@ copy_myself: copy vivi to ram
@
copy_myself:
 mov r10, lr

 @ reset NAND
 mov r1, #0x4E000000
 ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )
 str r2, [r1, #0x00]
 ldr r2, [r1, #0x00]

 ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control
 str r2, [r1, #0x04]
 ldr r2, [r1, #0x04]

 ldr r2, =(0x6) @ RnB Clear
 str r2, [r1, #0x20]
 ldr r2, [r1, #0x20]

 mov r2, #0xff @ RESET command
 strb r2, [r1, #0x08]
 mov r3, #0 @ wait
1: add r3, r3, #0x1
 cmp r3, #0xa
 blt 1b
2: ldr r2, [r1, #0x20] @ wait ready
 tst r2, #0x4
 beq 2b

 ldr r2, [r1, #0x04]
 orr r2, r2, #0x2 @ Flash Memory Chip Disable
 str r2, [r1, #0x04]

 @ get read to call C functions (for nand_read())
 ldr sp, DW_STACK_START @ setup stack pointer
 mov fp, #0 @ no previous frame, so fp=0

 mov r1, #0x56000000
 add r1, r1, #0x50
 mov r2, #0xe0
 str r2, [r1, #0x4]


 @ copy vivi to RAM
 ldr r0, =(0x30000000 + 0x04000000 - 0x00100000)
 mov r1, #0x0
 mov r2, #0x20000
 bl nand_read_ll


 mov r1, #0x56000000
 add r1, r1, #0x50
 mov r2, #0xb0
 str r2, [r1, #0x4]



 tst r0, #0x0
 beq ok_nand_read
# 386 "arch/s3c2440/head.S"
ok_nand_read:


@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@if there is any mistake while reading the nand flash,jump to the bad_nand_read
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
bad_nand_read:
    ldr r0, STR_FAIL
    ldr r1, SerBase
    bl PrintWord
1:
    b 1b        @infinite loop

ok_nand_read:
    ldr r0, STR_OK
    ldr r1, SerBase
    bl PrintWord

    @verrify

    mov r0, #0
    ldr r1, =0x33f00000
    mov r2,#0x400 @ 4 bytes * 1024 = 4k-bytes
go_next:
    ldr r3, [r0], #4
    ldr r4, [r1], #4
    teq r3,r4
    bne notmatch
    subs r2,r2,#4
    beq done_nand_read
    bne go_next
notmatch:
    sub r0, r0, #4
    ldr r1, SerBase
    bl PrintHexWord
    ldr r0, STR_FAIL
    ldr r1, SerBase
    pl PrintWord
1:
    b 1b

done_nand_read:
    mov r1, #GPIO_CTL_BASE
    add r1, r1, #oGPIO_F
    mov r2, #0x70
    str r2, [r1, #oGPIO_DAT]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
PrintChar:
TXBusy:
    ldr r2, [r1, #oUTRSTAT]
    and r2, r2, #UTRSTAT_TX_EMPTY
    tst r2,#UTRSTAT_EX_EMPTY
    beq TXBusy
    str r0,[r1, #oTUXHL]
    mov pc lr

PrintWord:
    mov r3, r0
    mov r4, lr
    bl PrintChar

    mov r0, r3, LSR #8
    bl PrintChar

    mov r0, r3, LSR #16
    bl PrintChar

    mov r0, r3, LSR #24
    bl PrintChar

    mov r0, #'\r'
    bl PrintChar

    mov r0, #'\n'
    bl PrintChar

    mov pc, r4

PrintHexNibble:
    adr r2, HEX_TO_ASCII_TABLE
    and r0, r0, #0xf
    ldr r0, [r2, r0]
    b PrintChar

PrintHexWord:
    mov r4, lr
    mov r3, r0
    mov r0, r3, LSR #28
    bl PrintHexNibble
    mov r0, r3, LSR #24
    bl PrintHexNibble
    mov r0, r3, LSR #20
    bl PrintHexNibble
    mov r0, r3, LSR #16
    bl PrintHexNibble
    mov r0, r3, LSR #12
    bl PrintHexNibble
    mov r0, r3, LSR #8
    bl PrintHexNibble
    mov r0, r3, LSR #4
    bl PrintHexNibble
    mov r0, r3
    bl PrintHexNibble

    mov r0, #'\r'
    bl PrintChar
    mov r0, #'\n'
    bl PrintChar

    mov pc, r4
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@



 mov pc, r10

@ clear memory
@ r0: start address
@ r1: length
mem_clear:
 mov r2, #0
 mov r3, r2
 mov r4, r2
 mov r5, r2
 mov r6, r2
 mov r7, r2
 mov r8, r2
 mov r9, r2

clear_loop:
 stmia {r2-r9}
 subs r1, r1, #(8 * 4)
 bne clear_loop

 mov pc, lr

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@end of nand_flash_read;in this function there are something you have to do
@first: initialize the nand_flash
@1:    set the NFCONF register(NFCONF = 0X7770)
@2:    set the NFCONT register(NFCONT = 0x11)
@3:    clear the RnB bit in the NFSTAT register
@ (NFSTAT = 0X60?but i think it should be set to 0x40)
@4:    reset the nand flash {MOV R1,#0XFF
@                         STRB R1, [NFCMD]}
@5:    wait ready{2:
@             LDR R2, =NFSTAT
@                 TST R2, #0X04
@                 beq 2b}
@6:    disable_chip(NFCONT &= (~(1 << 1)))
@7:    jump to the function of nand_read_ll
@second: copy the code from the nand flash to sdram(nand_read_ll)
@third: check the data you have copyed(check if the data in the nand flash is
@        equal to the data you have copy to the sdram)
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


@ Initialize UART
@
@ r0 = number of UART port
InitUART:
 ldr r1, SerBase
 mov r2, #0x0
 str r2, [r1, #0x08] @Disable the FIFO control register
 str r2, [r1, #0x0C] @Disable the MODULE control register        
 mov r2, #0x3
 str r2, [r1, #0x00] @normal,no parity,1 bit stop per frame,8 bits transfer
 ldr r2, =0x245
 str r2, [r1, #0x04]

 mov r2, #((50000000 / (115200 * 16)) - 1)        @0x26
 str r2, [r1, #0x28]

@
@ Wait a little while
@
 mov r3, #100
 mov r2, #0x0
1: sub r3, r3, #0x1
 tst r2, r3
 bne 1b
# 496 "arch/s3c2440/head.S"
 mov pc, lr
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@UART register:
@ULCON0 0X50000000
@ULCON1 0X50004000
@ULCON2 0X50008000
@UCONn +0X04
@UFCONn +0X08
@UMCONn +0X0C
@UTRSTAT +0X10
@UBRDIV +0X28
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@
@ Exception handling functions
@
HandleUndef:







1: b 1b @ infinite loop

HandleSWI:







1: b 1b @ infinite loop

HandlePrefetchAbort:







1: b 1b @ infinite loop

HandleDataAbort:







1: b 1b @ infinite loop

HandleIRQ:







1: b 1b @ infinite loop

HandleFIQ:







1: b 1b @ infinite loop

HandleNotUsed:







1: b 1b @ infinite loop


@
@ Low Level Debug
@
# 681 "arch/s3c2440/head.S"
@
@ Data Area
@
@ Memory configuration values
.align 4
mem_cfg_val:
 .long 0x22111110
 .long 0x00000700
 .long 0x00000700
 .long 0x00000700
 .long 0x00000700
 .long 0x00000700
 .long 0x00000700
 .long 0x00018009
 .long 0x00018009
 .long 0x008e04eb
 .long 0xB2
 .long 0x30
 .long 0x30


@ Processor clock values
.align 4
clock_locktime:
 .long 0x00ffffff
@mpll_value:
@ .long vMPLLCON_NOW
mpll_value_USER:
 .long ((0x5c << 12) | (0x1 << 4) | (0x0))
clkdivn_value:
 .long 0x5

@ initial values for serial
uart_ulcon:
 .long 0x3
uart_ucon:
 .long 0x245
uart_ufcon:
 .long 0x0
uart_umcon:
 .long 0x0
@ inital values for GPIO
gpio_con_uart:
 .long 0x0016faaa
gpio_up_uart:
 .long 0x000007ff

 .align 2
DW_STACK_START:
 .word (((((0x30000000 + 0x04000000 - 0x00100000) - 0x00100000) - 0x00004000) - (0x00004000 + 0x00004000 + 0x00004000)) - 0x00008000)+0x00008000 -4

@ =0x33DEFFFC
# 761 "arch/s3c2440/head.S"
.align 4
SerBase:

 .long 0x50000000

以上部分就是stage1的代码,我做了一些解释。这部分主要是与硬件打交道,所以主要是熟悉各种寄存器的功能和相关的配置,剩下的工作就是根据需求设置寄存器即可。其实现的功能主要是设备的初始化,和搬运工作。 做完相应的工作以后跳转到main函数的入口。
相关阅读 更多 +
排行榜 更多 +
宝宝情商养成宝宝巴士

宝宝情商养成宝宝巴士

休闲益智 下载
燥热手机版

燥热手机版

飞行射击 下载
巨人狙击手安卓版

巨人狙击手安卓版

飞行射击 下载