s3c2410 u-boot源码分析start.S

http://blogold.chinaunix.net/u3/93782/showart.php?id=2067190

根据board/samsumg/smdk2410下的u-boot.lds这个链接脚本知道u-boot启动的第一阶段函数是在cpu/arm920t/start.S。完成的功能主要包括

1:cpu自身的初始化:包括MMU,catch,时钟系统,SDRAM控制系统的初始话。

2:重定位:把自己从flash中搬到SDRAM 中

3:分配堆栈空间,设置堆栈指针

4:清零BSS数据段

5:跳转到第二阶段入口函数。

具体分析如下:

.globl _start

@设置异常向量表,其中_start是GNU 汇编的默认入口标签。注意ldr r0,0x1234是把0X1234中的内容写到R0中,ldr r0,=0x1234,是将1234这个值写到R0中,以及ADR 是用来加载地址。
_start: b       start_code 
        ldr     pc, _undefined_instruction
        ldr     pc, _software_interrupt
        ldr     pc, _prefetch_abort
        ldr     pc, _data_abort
        ldr     pc, _not_used
        ldr     pc, _irq
        ldr     pc, _fiq

@.word为GUN 汇编分配一段字内存单元,下面几句话相当于是C语言中的变量名和变量值。
_undefined_instruction: .word undefined_instruction
_software_interrupt:    .word software_interrupt
_prefetch_abort:        .word prefetch_abort
_data_abort:            .word data_abort
_not_used:              .word not_used
_irq:                   .word irq
_fiq:                   .word fiq

@全局符号定义

_TEXT_BASE:
        .word   TEXT_BASE@在board/samsumg/smdk2410中定义为3ff80000..即UBOOT映像文件所在地址
.globl _armboot_start
_armboot_start:
        .word _start
@下面主要在u-boot.lds链接脚本中定义
.globl _bss_start
_bss_start:
        .word __bss_start

.globl _bss_end
_bss_end:
        .word _end

@下面主要为start_code 的实现

start_code:
        @设置当前状态为SVC32模式
        mrs     r0,cpsr   
        bic     r0,r0,#0x1f   @相应位置清零
        orr     r0,r0,#0xd3  @相应位置1,同时关闭IRQ,FIQ。
        msr     cpsr,r0   

@关闭看门狗,关中断,设置时钟分频控制寄存器。pWTCON是看门狗控制寄存器,INTMSK是中断屏蔽寄存器,INTSUBMSK是中断子屏蔽寄存器,CLKDIVN是clock divisor register,用来设置FCLK,HCLK,PCLK三者的比例。

         #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
        /* turn off the watchdog */

# if defined(CONFIG_S3C2400)
#  define pWTCON                0x15300000
#  define INTMSK                0x14400008      /* Interupt-Controller base addresses */
#  define CLKDIVN       0x14800014      /* clock divisor register */
#else
#  define pWTCON                0x53000000
#  define INTMSK                0x4A000008      /* Interupt-Controller base addresses */
#  define INTSUBMSK     0x4A00001C
#  define CLKDIVN       0x4C000014      /* clock divisor register */
# endif
       @关看门狗
        ldr     r0, =pWTCON
        mov     r1, #0x0
        str     r1, [r0]

         @关闭主中断屏蔽寄存器
         mov     r1, #0xffffffff
        ldr     r0, =INTMSK
        str     r1, [r0]
       # if defined(CONFIG_S3C2410)

      @关闭副中断屏蔽寄存器

        ldr     r1, =0x3ff
        ldr     r0, =INTSUBMSK
        str     r1, [r0]
# endif

     @设置时钟分频控制寄存器。
 /* FCLK:HCLK:PCLK = 1:2:4 */FCLK为核心提供时钟,HCLK为AHB(ARM920T,内存控制器,中断控制器,LCD控制器,DMA和主USB模块)提供时钟,PCLK为APB(看门狗、IIS、I2C、PWM、MMC、ADC、UART、GPIO、RTC、SPI)提供时钟
        /* default FCLK is 120 MHz ! */


        ldr     r0, =CLKDIVN
        mov     r1, #3
        str     r1, [r0]
#endif  /* CONFIG_S3C2400 || CONFIG_S3C2410 */

@执行CPU初始话。

176 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
178       bl      cpu_init_crit @如果没有定义CONFIG_SKIP_LOELEVEL_INIT,则执行cpu_init_crit.见236-268下
179  #endif

@重新定位u-boot到SDRAM中

#ifndef CONFIG_SKIP_RELOCATE_UBOOT
181 relocate:                               /* relocate U-Boot to RAM           */
182         adr     r0, _start             @通过adr指令得到当前代码的地址信息:如果U-boot是从RAM开始运行,则从adr,r0,_start得到的地址信息为r0=_start=_TEXT_BASE=TEXT_BASE=0x3ff80000;如果U-boot从Flash开始运行,即从处理器对应的地址运行,则r0=0x0000,这时将会执行copy_loop标识的那段代码了
183         ldr     r1, _TEXT_BASE          /* test if we run from flash or RAM */
184         cmp     r0, r1                  /* don't reloc during debug         */
185         beq     stack_setup   @如果r0等于r1,跳过重定位代码
186
187         ldr     r2, _armboot_start@_start的内容写入r2
188         ldr     r3, _bss_start  @_bss_start的内容写入r3
189         sub     r2, r3, r2          @计算armboot所占字节大小
190         add     r2, r0, r2             @armboot结束地址
191 @实现从flash中拷贝到_TEXT_BASE(0x3ff80000)所在的地址中去
192 copy_loop:
193         ldmia   r0!, {r3-r10}           /* copy from source address [r0]    */
194         stmia   r1!, {r3-r10}           /* copy to   target address [r1]    */
195         cmp     r0, r2                  /* until source end addreee [r2]    */
196         ble     copy_loop
197 #endif  /* CONFIG_SKIP_RELOCATE_UBOOT */
198
199   @初始化堆栈                                                */
200 stack_setup:
201         ldr     r0, _TEXT_BASE      @3ff80000 
202         sub     r0, r0, #CONFIG_SYS_MALLOC_LEN  @ 向下内存分配,为malloc预留分配空间
203         sub     r0, r0, #CONFIG_SYS_GBL_DATA_SIZE@ 全局数据结构空间
204 #ifdef CONFIG_USE_IRQ
205         sub     r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)@ 为IRQ,FIQ分配空间
206 #endif
207         sub     sp, r0, #12           @为abort异常预留12字节的空间,并将当前的地址赋给sp,这样就为内存栈设置好了,之后如果在u-boot中运行程序时需要使用栈的时候就从这里开始。
208 @清空数据段

209 clear_bss:
210         ldr     r0, _bss_start          /* find start of bss segment        */
211         ldr     r1, _bss_end            /* stop here                        */
212         mov     r2, #0x00000000         /* clear                            */
213
214 clbss_l:str     r2, [r0]                /* clear loop...                    */
215         add     r0, r0, #4
216         cmp     r0, r1
217         ble     clbss_l
219         ldr     pc, _start_armboot@跳转到_start_armboot,也就是函数 start_armboot,此函数存放在u-boot-2009.03/lib_arm/board.c,这样就到了u-boot的第二阶段了。
220
221 _start_armboot: .word start_armboot

uboot存储映像

@执行cpu_init_crit.

236 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
237 cpu_init_crit:
238         /*
239          * flush v4 I/D caches
240          */
241         mov     r0, #0
242         mcr     p15, 0, r0, c7, c7, 0   @使Icaches和Dcaches无效
243         mcr     p15, 0, r0, c8, c7, 0   @使TLB失效
244
245      关闭mmu和cache,这里249行,将13,9,8bit清零(13—异常向量表基地址:0x0, 9—DisableSystem Protection, 8—Disable ROM Protection),250行,将7,2,1,0bit清零(7—为0的时候表示小端字节序,2-- Data Cache Disabled,1-- Alignment Fault checkingdisabled,0—为0的话MMU disabled),251行,将bit 1 设置为1表示Fault checkingenabled,252行,将bit 12设置为1表示使能 I-Cache。

@MRC指令的格式为:
@MRC{条件} 协处理器编码,协处理器操作码1,目的寄存器,源寄存器1,源寄存器2,协处理器操作码2。
@MRC指令用于将协处理器寄存器中的数据传送到ARM处理器寄存器中,若协处理器不能成功完成操作,则产生未定义指令异常。其中协处理器操作码1和协处理器操作码2为协处理器将要执行的操作,目的寄存器为ARM处理器的寄存器,源寄存器1和源寄存器2均为协处理器的寄存器。  指令示例: MRC  P3,3,R0,C4,C5,6    ;该指令将协处理器P3的寄存器中的数据传送到ARM处理器寄存器中。

248         mrc     p15, 0, r0, c1, c0, 0
249         bic    r0, r0, #0x00002300     @ clearbits 13, 9:8 (--V- --RS)
250         bic    r0, r0, #0x00000087     @ clearbits 7, 2:0 (B--- -CAM)
251         orr    r0, r0, #0x00000002     @ set bit2 (A) Align
252         orr    r0, r0, #0x00001000     @ set bit12 (I) I-Cache
253         mcr     p15, 0, r0, c1, c0, 0
254       

260         mov     ip, lr @保存当前链接寄存器中的值
261
262         bl      lowlevel_init @ @u-boot-2009.03/board/samsung/smdk2410/lowlevel_init.S ,主要是初始话存储控制器件,共13个。只需要设置BWSCON和BANKCONx(x为0-5),而BANK6,BANK7接SDRAM,除了设置BWSCON和BANKCONx(x为6,7),还需要设置其他四个寄存器,而这13个寄存器的地址是连续的,BWSCON是第一个寄存器
263

264         mov     lr, ip
265         mov     pc, lr @返回执行relocate。

266 #endif /* CONFIG_SKIP_LOWLEVEL_INIT */

@以下就是各种中断的处理。

 @.macro伪操作符标识宏定义的开始,.endm标识宏定义的结束。二者包含的一段代码,称为宏定义体,这样在程序中就可通过宏指令多次调用该代码段。格式:
.macro macroname {parameter{,parameter}...}
  ...
 .endm
宏的参数可直接使用斜线“\字符”来引用,如下“\reg”所示。

  @略过     

这里重声一下ldr和b的区别:

b跳转指令是个相对跳转指令直接向PC寄存器赋值,依赖当前PC的值,这使得B指令不依赖代码存储的位置,被称为位置无关码

ldr是从内存中的某个位置读出数据,并给PC赋值这个位置的地址是当前PC寄存器的值加上偏移值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
linuxdriver_code_tool |-- 03 | `-- 2.6内核升级工具 | |-- device-mapper-1.00.19-2.i386.rpm | |-- lvm2-2.00.25-1.01.i386.rpm | |-- mkinitrd-4.2.0.3.tar.tar | |-- module-init-tools-3.2.2.tar.bz2 | `-- modutils-2.4.5-1.src.rpm |-- 04 | |-- 内核模块参数范例 | | `-- book.c | |-- 内核模块导出符号 | | `-- export_symb.c | `-- 最简单的内核模块 | `-- hello.c |-- 05 | `-- udev源代码 | `-- udev-114.tar.gz |-- 06 | |-- globalmem驱动 | | `-- globalmem.c | `-- 包含2个globalmem设备的驱动 | `-- globalmem_two.c |-- 07 | `-- 含并发控制的globalmem驱动 | `-- globalmem_lock.c |-- 08 | |-- globalfifo驱动 | | `-- globalfifo.c | `-- poll应用程序范例 | `-- pollmonitor.c |-- 09 | |-- 异步通知应用程序范例 | | `-- asyncmonitor.c | `-- 支持异步通知的globalfifo | `-- globalfifo_async.c |-- 10 | |-- S3C2410实时钟驱动 | | `-- s3c2410-rtc.c | `-- 秒设备驱动与应用程序 | |-- second.c | `-- second_test.c |-- 11 | |-- DMA范例 | | |-- 3c505.c | | |-- 3c505.h | | `-- dma.h | `-- 静态映射范例 | `-- mach-smdk2440.c |-- 12 | |-- NVRAM驱动 | | `-- generic_nvram.c | |-- 触摸屏驱动 | | |-- 作为input设备 | | | |-- s3c2410_ts.c | | | `-- s3c2410_ts.h | | `-- 作为普通字符设备 | | `-- s3c2410-ts.c | |-- 看门狗驱动 | | `-- s3c2410_wdt.c | `-- 平台设备 | `-- devs.c |-- 13 | |-- IDE驱动 | | |-- ide-disk.c | | `-- ide-h8300.c | `-- RAMDISK驱动 | `-- rd.c |-- 14 | |-- S3C2410串口驱动 | | |-- regs-gpio.h | | |-- regs-serial.h | | `-- s3c2410.c | `-- 串口核心层 | |-- serial_core.c | `-- serial_core.h |-- 15 | |-- S3C2410 I2C主机驱动 | | |-- i2c-s3c2410.c | | |-- iic.h | | |-- regs-gpio.h | | `-- regs-iic.h | `-- SAA711x I2C设备驱动 | `-- saa711x.c |-- 16 | `-- CS8900以太网设备驱动 | |-- cs89x0.c | `-- cs89x0.h |-- 17 | |-- ALSA工具及库 | | |-- alsa-driver-1.0.15.tar.bz2 | | |-- alsa-firmware-1.0.15.tar.bz2 | | |-- alsa-lib-1.0.15.tar.bz2 | | |-- alsa-oss-1.0.15.tar.bz2 | | |-- alsa-tools-1.0.15.tar.bz2 | | |-- alsa-utils-1.0.13.tar.bz2 | | `-- pyalsa-1.0.15.tar.bz2 | |-- ALSA驱动范例 | | |-- sa11xx-uda1341.c | | `-- uda1341.h | |-- ALSA应用程序范例 | | |-- pcm.c | | `-- pcm_min.c | |-- OSS驱动范例 | | `-- s3c2410-uda1341.c | `-- OSS应用程序范例 | |-- mixer.c | `-- sound.c |-- 18 | |-- FRAMEBUFFER应用程序范例 | | `-- fb_display | | |-- fb_display.c | | |-- fb_display.h | | |-- Makefile | | |-- README | | `-- test.c | `-- S3C2410 LCD驱动 | |-- s3c2410fb.c | `-- s3c2410fb.h |-- 19 | |-- busybox源代码 | | `-- busybox-1.2.1.tar.bz2 | |-- MTD工具 | | `-- mtd-utils-1.0.0.tar.gz | |-- nand驱动范例 | | `-- s3c2410.c | |-- nor驱动范例 | | `-- s3c2410nor.c | `-- yaffs&yaffs2源代码 | |-- yaffs.tar.gz | `-- yaffs2.tar.gz |-- 20 | |-- USB串口驱动 | | |-- usb-serial.c | | `-- usb-serial.h | |-- USB工具 | | `-- usbview-1.0.tar.tar | |-- USB骨架程序 | | `-- usb-skeleton.c | |-- USB键盘驱动 | | |-- input.h | | |-- usb_input.h | | `-- usbkbd.c | `-- usb主机控制器驱动范例 | |-- ohci-s3c2410.c | `-- usb-control.h |-- 21 | |-- PCI骨架程序 | | `-- pci-skeleton.c | `-- PCI驱动范例 | `-- i810_audio.c `-- 22 |-- 范例代码 | |-- oops范例 | | |-- oops_example.asm | | `-- oops_example.c | `-- proc范例 | `-- sim_proc.c `-- 内核调试工具 |-- ddd-3.3.11.tar.gz |-- gdbmod-2.4.bz2 |-- kdb-v4.4-2.6.15-rc5-common-1.bz2 |-- kdb-v4.4-2.6.15-rc5-common-2.bz2 |-- kdb-v4.4-2.6.15-rc5-i386-1.bz2 `-- linux-2.6.15.5-kgdb-2.4.tar.tar 73 directories, 91 files

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值