加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

uboot移植之启动过程--汇编过程start.s

发布时间:2020-12-15 06:49:04 所属栏目:百科 来源:网络整理
导读:uboot移植之启动过程--汇编过程start.s 说明:本文基于uboot-1.16,代码来源其中,代码版权归原作者所有。 代码版权:Copyright (C) 2001 - 2011 by Wolfgang Denk,DENX Software Engineering. ???????????????? Copyright (C) 2003 - 2011 by Detlev Zundel

uboot移植之启动过程--汇编过程start.s

说明:本文基于uboot-1.16,代码来源其中,代码版权归原作者所有。

代码版权:Copyright (C) 2001 - 2011 by Wolfgang Denk,DENX Software Engineering.

???????????????? Copyright (C) 2003 - 2011 by Detlev Zundel,DENX Software Engineering.

???????????????? Copyright (C) 2003 - 2011 by contributing authors

出处:http://blog.csdn.net/hail100

???????????????? uboot启动大致分2步: 第一步主要是完成关wacthdog、mmu,系统时钟的初始化,mem初始化,最后是uboot代码复制到RAM中,跳到c语言函数,这阶段主要用汇编在start.S,lowlevel_init.S中完成。第二步完成复杂设备的初始化,开启命令行,其主要由c语言完成。本文介绍smdk2410的start.S。

正文:

?????????????? smdk2410使用arm920T的内核,可以到arm官网上下载用户手册。http://infocenter.arm.com/help/index.jsp 。本文将结合用户手册和uboot代码介绍uboot启动第一阶段。主要代码在uboot-1.1.6/cpu/arm920t/start.S,注意是(.S)这文件在编译时要先经过预处理、有头文件的包含、宏定义的替代,(.s)不会预处理。

??/*
?*************************************************************************
?*
?* Jump vector table as in table 3.1 in [1]

?*?? arm 都是通过跳转向量完成启动、中断
?*
?*************************************************************************
?*/
.globl _start
_start:?? ?b?????? reset????????????????????????????????????? @? 重启 ??
?? ?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???????????????????????????????????????????? @ 快速中断

_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

?? ?.balignl 16,0xdeadbeef??????????? ====================================================================================================================================

/*

?* the actual reset code
?*/
@ 重启从这开始
reset:????????????????????????????????
?? ?/*
?? ? * set the cpu to SVC32 mode

?? ? */

@ uboot需要在管理模式中执行,msr和mrs 都是伪指令

@ 并禁止fiq 和irq

?? ?mrs?? ? r0,cpsr
?? ?bic?? ?? r0,r0,#0x1f
?? ?orr?? ?? r0,#0xd3
?? ?msr?? ?cpsr,r0
@ 关watchdog
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
?? ?ldr??????? r0,=pWTCON
?? ?mov???? r1,#0x0
?? ?str??????? r1,[r0]
@ 关中断
?? ?/*
?? ? * mask all IRQs by setting all bits in the INTMR - default
?? ? */
?? ?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 */
?? ?/* default FCLK is 120 MHz ! */
?? ?ldr?? ??? r0,? =CLKDIVN
?? ?mov?? ?r1,? #3
?? ?str?? ??? r1,? [r0]
#endif?? ?/* CONFIG_S3C2400 || CONFIG_S3C2410 */
@ cpu初始化, 后面分析
?? ?/*
?? ? * we do sys-critical inits only at reboot,
?? ? * not when booting from ram!
?? ? */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
?? ?bl?? ?? cpu_init_crit
#endif
@ 判断uboot是不是在RAM中启动
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate:?? ??? ??? ??? ?/* relocate U-Boot to RAM?? ???? */
?? ?adr?? r0,_start?? ??? ?/* r0 <- current position of code?? */
?? ?ldr?? ?r1,? _TEXT_BASE?? ??? ?/* test if we run from flash or RAM */
?? ?cmp r0,? r1????????????????? /* don't reloc during debug???????? */
?? ?beq? stack_setup

@ 可以在前面找到_armboot_start,_bss_start的定义

@ __bss_start 在u-boot.lds 里

@ 这是从nor flash启动时, 完成uboot到ram的复制

@nand flash 的复制要复杂的多,需要控制nand分块复制

?? ?ldr?? ?r2,_armboot_start
?? ?ldr?? ?r3,_bss_start
?? ?sub?? r2,r3,r2?? ??? ?/* r2 <- size of armboot??????????? */
?? ?add?? r2,r2?? ??? ?/* r2 <- source end address???????? */

copy_loop:
?? ?ldmia?? ?r0!,{r3-r10}?? ??? ?/* copy from source address [r0]??? */
?? ?stmia?? ?r1!,{r3-r10}?? ??? ?/* copy to?? target address [r1]??? */
?? ?cmp?? ? ? r0,r2?? ??? ??? ?/* until source end addreee [r2]??? */
?? ?ble?? ?copy_loop
#endif?? ?/* CONFIG_SKIP_RELOCATE_UBOOT */
@ 设置堆栈指针
?? ?/* Set up the stack?? ??? ??? ??? ??? ??? ???? */
stack_setup:
?? ?ldr?? ?? r0,_TEXT_BASE?? ??? ?/* upper 128 KiB: relocated uboot?? */
?? ?sub?? ?r0,#CFG_MALLOC_LEN?? ?/* malloc area????????????????????? */
?? ?sub?? ?r0,#CFG_GBL_DATA_SIZE /* bdinfo??????????????????????? */
#ifdef CONFIG_USE_IRQ
?? ?sub?? ?r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
?? ?sub?? ?sp,#12?? ??? ?/* leave 3 words for abort-stack??? */
@ 清零bss区
clear_bss:
?? ?ldr?? ???? r0,_bss_start?? ??? ?/* find start of bss segment??????? */
?? ?ldr?? ???? r1,_bss_end?? ??? ?/* stop here??????????????????????? */
?? ?mov ?? ?r2,#0x00000000?? ??? ?/* clear??????????????????????????? */

clbss_l:

????? str?? ?r2,[r0]?? ??? ?/* clear loop...??????????????????? */

?? ?add?? ?r0,#4
?? ?cmp?? ?r0,r1
?? ?ble?? ?clbss_l
@ 从这开始跳到c语言入口
?? ?ldr?? ?pc,_start_armboot

_start_armboot:?? ?.word start_armboot

====================================================================================================================================

cache和mmu的操作都是在协处理器中完成的,协处理器 p15的操作可以看arm920t用户手册。

cpu_init_crit:

@ 刷新cache
?? ?/*
?? ? * flush v4 I/D caches
?? ? */
?? ?mov?? ?r0,#0
?? ?mcr?? ?p15,c7,0?? ?/* flush v3/v4 cache */
?? ?mcr?? ?p15,c8,0?? ?/* flush v4 TLB */
@ 禁止MMU 和 caches,这是cp15中的c1寄存器控制的
?? ?/*
?? ? * disable MMU stuff and caches
?? ? */
?? ?mrc?? ?p15,c1,c0,0
?? ?bic?? ? r0,#0x00002300?? ?@ clear bits 13,9:8 (--V- --RS)
?? ?bic?? ? r0,#0x00000087?? ?@ clear bits 7,2:0 (B--- -CAM)
?? ?orr?? ? r0,#0x00000002?? ?@ set bit 2 (A) Align
?? ?orr?? ? r0,#0x00001000?? ?@ set bit 12 (I) I-Cache
?? ?mcr?? ?p15,0

?? ?/*
?? ? * before relocating,we have to setup RAM timing
?? ? * because memory timing is board-dependend,you will
?? ? * find a lowlevel_init.S in your board directory.
?? ? */
?? ?mov?? ?ip,lr

@ 跳到?lowlevel_init.S中,完成RAM时序配置

??? bl?? ?lowlevel_init
?? ?mov?? ?lr,ip
?? ?mov?? ?pc,lr

====================================================================================================================================

在u-boot-1.1.6/board/smdk2410/lowlevel_init.S中完成RAM时序的配置,这需要看系统频率和所用RAM工作时序,来配置smdk2410的RAM控制器。

_TEXT_BASE:
?? ?.word?? ?TEXT_BASE

.globl lowlevel_init
lowlevel_init:

@对于sdram的控制,主要是设置其控制器。其中有时序的配置,

@需要看ram的手册查询,要配置好系统时钟,计算出是多个ram控制器时钟

@还有就是看soc手册讲解的控制器配置流程

??? /* memory control configuration */
?? ?/* make r0 relative the current location so that it */
?? ?/* reads SMRDATA out of FLASH rather than memory ! */
?? ?ldr???? r0,=SMRDATA
?? ?ldr?? ?r1,_TEXT_BASE
?? ?sub?? ?r0,r1
?? ?ldr?? ?r1,=BWSCON?? ?/* Bus Width Status Controller */
?? ?add???? r2,#13*4
0:
?? ?ldr???? r3,[r0],#4
?? ?str???? r3,[r1],#4
?? ?cmp???? r2,r0
?? ?bne???? 0b

?? ?/* everything is fine now */
?? ?mov?? ?pc,lr

?? ?.ltorg
/* the literal pools origin */

SMRDATA:
??? .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
??? .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
??? .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
??? .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
??? .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
??? .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
??? .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
??? .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
??? .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
??? .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
??? .word 0x32
??? .word 0x30
??? .word 0x30

====================================================================================================================================

start.S最后中断的入口,中断的宏完成现场保存,跳到中断处理函数。do_xxx 都在 interrupt.c中处理。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读