u-boot移植总结(一)start.S分析

发布者:快乐舞蹈最新更新时间:2024-07-25 来源: cnblogs关键字:u-boot  start 手机看文章 扫描二维码
随时随地手机看文章

本次移植u-boot-2010.09是基于S3C2440的FL440板子,板子自带NANDFLASH而没有NORFLASH,所以在U-BOOT启动的过程中必须实现从NANDFLASH到SDRAM的重定向。


其中最重要的就是在U-BOOT开始的start.S汇编代码,这段代码要完成工作:


1,异常中断向量表,复位后异常向量处理


2, 跳转到代码实际执行处start_code


3,关闭看门狗WATCHDOG


3,关闭所有中断INTERRUPT


4,设置时钟分频,主要设置寄存器CLKDVN,MPLLCON,UPLLCON


5,关闭MMU和CACHE,并调用lowlevel_init.S完成SDRAM和NANDFLASH的初始化,为代码的重定向做准备


6,设置堆栈,并且跳入第二阶段的C代码


7,异常向量处理代码


以下为start.S的分析:


1,异常中断向量表,复位后异常向量处理


//声明一个全局标量,在cpu/arm920t/u-boot.lds中有定义,即代码的入口地址,也是编译地址

_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


_undefined_instruction: .word undefined_instruction  //.word 定义一个32位的地址标识

_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//将地址偏移为16的整数倍,空余的内容填上0xdeadbeef,这个数即“Magic Number”,可用判断当前u-boot执行位置



_TEXT_BASE:

   .word   TEXT_BASE    //在config.mk中有定义,即u-boot自启时flash从定向到sdram的地址

.globl _armboot_start   //声明一个全局变量,之后要调用

_armboot_start:

   .word _start


/*

 * These are defined in the board-specific linker script.

 */


.globl _bss_start                   //连接脚本u-boot.lds中有定义

_bss_start:

   .word __bss_start


.globl _bss_end //连接脚本u-boot.lds中有定义

_bss_end:

  .word _end


#ifdef CONFIG_USE_IRQ           //堆栈设置

/* IRQ stack memory (calculated at run-time) */


.globl IRQ_STACK_START

IRQ_STACK_START:

  .word   0x0badc0de


/* IRQ stack memory (calculated at run-time) */


.globl FIQ_STACK_START

FIQ_STACK_START:

   .word 0x0badc0de


#endif

2, 跳转到代码实际执行处(设置管理模式=>关闭看门狗=>关闭所有中断=>设置时钟分频)


/*

 * the actual start code

 */


start_code:

    /*

     * set the cpu to SVC32 mode  

     */

                              //设置管理模式  31  30  29  28      7   6   4    3    2    1    0  

    mrs r0, cpsr              //    CPSR      N   Z   C   V       I   F   M4   M3   M2   M1   M0

    bic r0, r0, #0x1f         //                                          1    0    0    1    1

    orr r0, r0, #0xd3  

    msr cpsr, r0           // CPSR为状态寄存器,用于设置系统运行状态,只能用MSR MRS指令


#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK)   //系统中断重定向于RAM中,以便快速响应中断,搬运的代码为4*16bytes

/*  relocate exception table */

    ldr r0, =_start

    ldr r1, =0x0

    mov r2, #16

copyex: 

    subs r2, r2, #1

    ldr r3, [r0], #4 

    str r3, [r1], #4 

    bne copyex

#endif


//关闭看门狗

#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)

    /* 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 //查阅s3c2440的datesheet中指出寄存器地址

#define pWTCON    0x53000000 

#define INTMSK    0x4A000008  /* Interupt-Controller base addresses */

#define INTSUBMSK 0x4A00001C

#define CLKDIVN   0x4C000014  /* clock divisor register */

#endif


#define CLK_CTL_BASE 0x4C000000    //添加时钟分频寄存器地址,用于时钟分频设置

#define MDIV_405 0x7f<<12

#define PSDIV_405 0x21

#define MDIV_200 0xa1<<12

#define PSDIV_200 0x31

    ldr r0, =pWTCON

    mov r1, #0x0

    str r1, [r0] /*  mask all IRQs by setting all bits in the INTMR - default */

    mov r1, #0xffffffff                                //ARM920T有32个中断源,禁止所有中断,32位中断屏蔽寄存器置位 

    ldr r0, =INTMSK 

    str r1, [r0]

#if defined(CONFIG_S3C2440)||defined(CONFIG_S3C2410) /* add by zhou */ 

    ldr r1, =0x7ff //屏蔽所有的中断源,S3C2440中寄存器只有前15位有效,故0x7ff置位INTSUNMSK 

    ldr r0, =INTSUBMSK 

    str r1, [r0]

#endif

//设置时钟频率

#if defined(CONFIG_S3C2440)

    mov  r1, #5

    str  r1, [r0]


    mrc  p15, 0, r1, c1, c0, 0 

    orr  r1, r1, #0xc0000000

    mcr  p15, 0, r1, c1, c0, 0 


    mov  r1, #CLK_CTL_BASE //S3C2440系统主频为405MHZ,USB为48MHZ,要求MPLLCON = (0x7f<<12) | (0x02<<4) | (0x01) = 0x7f021

    mov  r2, #MDIV_405

    add  r2, r2, #PSDIV_405

    str  r2, [r1, #0x04]   

#else


    /* FCLK:HCLK:PCLK = 1:2:4 */

    /* default FCLK is 120 MHz ! */

    ldr r0, =CLKDIVN

    mov r1, #3

    str r1, [r0]


    mrc p15, 0, r1, c1, c0, 0

    orr r1, r1, #0xc0000000

    mcr p15, 0, r1, c1, c0, 0



    mov r1, #CLK_CTL_BASE

    mov r2, #MDIV_200

    add r2, r2,#PSDIV_200

    str r2, [r1,#0x04]


#endif

#endif /* (CONFIG_S3C2400) || (CONFIG_S3C2410) || (CONFIG_S3C2440) */


3,关闭MMU和CACHE,并调用lowlevel_init.S完成SDRAM和NANDFLASH的初始化,为代码的重定向做准备

   /*******************************************

     * we do sys-critical inits only at reboot,

     * not when booting from ram!

     ******************************************/


#ifndef CONFIG_SKIP_LOWLEVEL_INIT

    bl  cpu_init_crit  //关闭MMU和CACHE,并调用lowlevel_init.S完成SDRAM和NANDFLASH的初始化

#endif

...........

...........

...........

/*

 *************************************************************************

 *

 * CPU_init_critical registers

 *

 * setup important registers

 * setup memory timing

 *

 *************************************************************************

 */


#ifndef CONFIG_SKIP_LOWLEVEL_INIT

cpu_init_crit:

    /*

     * flush v4 I/D caches

     */

    mov r0, #0       //具体设置看下图,详细参考CP15指令:http://blog.csdn.net/gooogleman/article/details/3635238

    mcr p15, 0, r0, c7, c7, 0 //向c7写入0将使ICache与DCache 无效flush v3/v4 cache 

    mcr p15, 0, r0, c8, c7, 0  //向c8写入0将使TLB失效 flush v4 TLB 


    /*

     * disable MMU stuff and caches     //协处理器CP15的C1处理器可以设置MMU和caches,具体参考下图

     */

    mrc p15, 0, r0, c1, c0, 0  

    bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)

    bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)

    orr r0, r0, #0x00000002 @ set bit 2 (A) Align

    orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache

    mcr p15, 0, r0, c1, c0, 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       //由于有两层调用,需要把lr保存到ip,以防止破坏


    bl  lowlevel_init //调用c函数,初始化FLASH和SDRAM,为代码重定向做准备


    mov lr, ip 

    mov pc, lr      //返回

#endif /* CONFIG_SKIP_LOWLEVEL_INIT */

代码重定向基本思路:


1.内存运行与否,是则设置堆栈,跳入c函数阶段


2.若不在内存运行,判断是在norflash还在nandflash运行


//代码重定向部分

/***************CHECK_CODE_POSITION******************************/


    adr r0, _start      /* r0 <- current position of code   */   //检查代码是否在已经SDRAM中运行,是则设置堆栈,并跳入c代码部分

    ldr r1, _TEXT_BASE      /* test if we run from flash or RAM */  //_start为u-boot的真正运行地址,_TEXT_BASE为FLASH加载到SDRAM的地址,在config.mk中定义为0x33f80000

    cmp r0, r1          /* don't reloc during debug         */      //若相等,说明已经在SDRAM中运行,设置堆栈,并且调转到第二阶段的C函数

    beq stack_setup //若不相等,则要判断是从NORFLASF或NANDFLASH启动


/***************CHECK_CODE_POSITION******************************/


/***************CHECK_BOOT_FLASH********************************/


    ldr r1, =((4<<28)|(3<<4)|(3<<2))  /*address in 4000003c*/

    mov r0, #0     //NANDFLASH的启动原理,启动时4K SRAM,即Stepping Stone,会映射到nGCS0,0x0000 0000地址,同时它还是会被映射到0x4000 0000地址 

    str r0,[r1]    //而NORFLASH支持片上运行,并会被一直挂载到nGCS0,0x0000 0000,具体可以参照NANDFLASH启动原理


    mov r1, #0x3c   /*address in 0x3c*/ //NANDFLASH启动时,因为地址为16倍数对齐,此时0x0000 003c 和 0x4000 003c都为唯一确定的0xdeadbeef,即'Magic Mumber'

    ldr r0, [r1]    //当0x4000 003c清零,若0x0000 003c读出也是零,则u-boot代码从NANDFLASH启动,否则从NORFLASH

    cmp r0, #0

    bne relocate



    /*recover 0x4000003c */

    ldr r0, =(0xdeadbeef)     //若在NANDFLASH启动,必须保证代码和前4K拷贝到SRAM一致,否则会进入死循环

    ldr r1, =((4<<28)|(3<<4)|(3<<2))

[1] [2]
关键字:u-boot  start 引用地址:u-boot移植总结(一)start.S分析

上一篇:u-boot中nandflash初始化流程分析
下一篇:S3C2440之存储控制器学习记录

推荐阅读最新更新时间:2026-03-25 15:20

u-boot之ARM920T的start.S分析
cpu/arm920t/start.S程序步骤大致有以下几个 1、设置中断向量表 2、设置CPU模式为SVC32 mode并且关闭IRQ与FIQ中断 3、关闭看门狗 4、屏蔽所有中断 5、判断程序是否在RAM中运行如果不是的话则先关闭MMU再则需要初始化RAM。 6、设置堆栈准备在C函数中运行了 7、 跳转到C函数clock_init初始化系统时钟 8、跳转到C函数CopyCode2Ram将代码拷贝到RAM中 9、清零BSS段 10、跳转到_start_armboot运行,此时代码已经在RAM中运行了 11、IRQ中断与FIQ中断发生后的上下文处理 1、cpu/arm920t/sta
[单片机]
<font color='red'>u-boot</font>之ARM920T的<font color='red'>start</font>.<font color='red'>S</font>分析
u-boot移植总结(一)start.S分析
本次移植u-boot-2010.09是基于S3C2440的FL440板子,板子自带NANDFLASH而没有NORFLASH,所以在U-BOOT启动的过程中必须实现从NANDFLASH到SDRAM的重定向。 其中最重要的就是在U-BOOT开始的start.S汇编代码,这段代码要完成工作: 1,异常中断向量表,复位后异常向量处理 2, 跳转到代码实际执行处start_code 3,关闭看门狗WATCHDOG 3,关闭所有中断INTERRUPT 4,设置时钟分频,主要设置寄存器CLKDVN,MPLLCON,UPLLCON 5,关闭MMU和CACHE,并调用lowlevel_init.S完成SDRAM和NAND
[单片机]
<font color='red'>u-boot</font><font color='red'>移植</font>总结(一)<font color='red'>start</font>.<font color='red'>S</font>分析
u-boot 移植 --->3、S5PV210启动序列
S5PV210_iROM_ApplicationNote_Preliminary_20091126.pdf,了解到S5PVS10这款芯片的复位过程启动序列。芯片在出厂时就在内部固化了一段程序internal ROM简称iROM,这段代码在芯片复位一后会自动运行,他主要负责初始化系统的时钟等具体如下: 1. Disable the Watch-Dog Timer \关闭看门狗 2. Initialize the instruction cache \关闭指定cache 3. Initialize the stack region (see “memory map” on chap 2.5) \设置不同模式的栈指针 4. Init
[单片机]
深度解读S3C2410A的嵌入式系统的U-Boot移植
0 引 言 ARM嵌入式处理器已被广泛应用于消费电子产品、无线通信、网络通信和工业控制等领域。其中,ARM9的芯片更是以其低价格、低功耗、高性能在手持设备中占据着重要市场。在嵌入式操作系统中,Linux,Vxworks,WinCE三足鼎立,其中Linux由于其开源性、稳定性、安全性、可裁减性更是一支独放。在嵌入式系统中,如何实现在ARM9平台下Linux操作系统的引导工作是嵌入式技术开发的重要环节。 1 嵌入式系统的软件组成 1.1 系统的软件组成 嵌入式的软件系统主要由Bootloader、操作系统、文件系统、应用程序等组成。其中,Bootloader是介于硬件和操作系统之间的一层,其作用就好像PC机中的BIOS。系统加电运
[单片机]
深度解读<font color='red'>S</font>3C2410A的嵌入式系统的<font color='red'>U-Boot</font><font color='red'>移植</font>
U-bootS3C2440上的移植详解(五)
一、移植环境 主 机:VMWare--Fedora 9 开发板:Mini2440--64MB Nand,Kernel:2.6.30.4 编译器:arm-linux-gcc-4.3.2.tgz u-boot:u-boot-2009.08.tar.bz2 二、移植步骤 9)实现u-boot对yaffs/yaffs2文件系统下载的支持。 注意:此篇对Nand的操作是基于MTD架构方式,在“u-boot-2009.08在2440上的移植详解(三)”中讲到过。 通常一个Nnad Flash存储设备由若干块组成,1个块由若干页组成。一般128MB以下容量的Nand Flash芯片,一页大小为528B,被依次分为2
[单片机]
<font color='red'>U-boot</font>在<font color='red'>S</font>3C2440上的<font color='red'>移植</font>详解(五)
U-boot 在 mini2440-S3C2440 上的移植(3)-第一阶段:探索启动代码
1.本文以mini2440开发板为例: u-boot属于两阶段的Bootloader,第一阶段文件为CPU/arm920t/start.S和board/mini2440/lowlevel_init.S,前者是平台相关的,后者是开发板相关的; U-boot第一阶段代码: 1.硬件设备初始化 该部分完成:将CPU的工作模式设置为管理模式;关闭WATCHDOG; 设置FCLK;HCLK;PCLK的比例,关闭MMU;CACHE 参考代码:cpu/arm920t/start.S 2.为加载Bootloader的第二阶段代码准备RAM空间;所谓准备RAM空间,就是初始化内存芯片,参考代码start.S中调用的lowlevel_init.S函数
[单片机]
04-S3C2440u-boot学习之u-boot分析(5)_uboot启动内核
参考《韦东山1期视频》第09课第5节 u-boot分析_uboot启动内核.WMV (1)启动内核主要命令: s = getenv ( bootcmd ); debug ( ### main_loop: bootcmd= %s n , s ? s : UNDEFINED ); if (bootdelay = 0 && s && !abortboot (bootdelay)) { # ifdef CONFIG_AUTOBOOT_KEYED int prev = disable_ctrlc(1); /* disable Control C checking */ # endif # ifndef CFG_
[单片机]
04-<font color='red'>S</font>3C2440u-boot学习之<font color='red'>u-boot</font>分析(5)_uboot启动内核
使用J-Link烧写一U-boot的烧写+裸板程序烧写(JZ2440-S3C2440)
一、使用J-Link 烧写NOR Flash 注意:J-Link 只支持NOR Flash,不支持NAND Flash。 1、安装J-link 驱动(在Windows 下) 在JZ2440 开发板JLINK 使用手册(JZ2440开发板JLINK使用手册jlink安装驱动程序目录)中,驱动名为:Setup_JLinkARM_V436e.exe。 双击即可进行安装,安装完成后,桌面上显示两个图标J-Flash和J-Link: 2、使用JLINK 烧写Uboot 到NOR Flash (1)开发板设置为NOR (将NAND/NOR 开关打到NOR一侧)启动,接好J-Link 后,最后启动上电。 (2)启动上电。打开J-Flas
[单片机]
使用J-Link烧写一<font color='red'>U-boot</font>的烧写+裸板程序烧写(JZ2440-<font color='red'>S</font>3C2440)
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved