移植u-boot-2012.04.01到JZ2440

发布时间:2024-06-17  

开发环境:Ubuntu 12.04

开发板:JZ2440  256M NandFlash  64M SDRAM

交叉编译器:arm-linux-gcc-4.3.2

u-boot:u-boot-2012.04.01 

分析uboot中 make xxx_config过程  http://www.linuxidc.com/Linux/2017-06/145292.htm

U-Boot源代码下载地址 http://www.linuxidc.com/Linux/2011-07/38897.htm

  最近在学习BootLoader,移植u-boot-2012.04.01到JZ2440开发板,现在把移植过程记录下来,一来梳理思路,二来方便以后更进一步学习。

一、  u-boot分析过程

    a、 初始化硬件:关看门狗、设置时钟、设置SDRAM、初始化NAND FLASH

    b、如果bootloader比较大,要把它重定位到SDRAM

    c、把内核从NAND FLASH读到SDRAM

    d、设置"要传给内核的参数"

    e、跳转执行内核

具体代码分析

1、set the cpu to SVC32 mode

2、turn off the watchdog

3、mask all IRQs by setting all bits in the INTMR

4、设置时钟比例

5、设置内存控制器

6、设置栈,调用C函数board_init_f

7、调用函数数组init_sequence里的各个函数

    7.1 board_early_init_f : 设置系统时钟、设置GPIO

......................................

8、重定位代码

    8.1 从NOR FLASH把代码复制到SDRAM

    8.2 程序的链接地址是0,访问全局变量、静态变量、调用函数时是使"基于0地址编译得到的地址",现在把程序复制到了SDRAM,需要修改代码,把"基于0地址编译得到的地址"改为新地址。

    8.3 程序里有些地址在链接时不能确定,要到运行前才能确定:fixabs

9、clear_bss

10、调用C函数board_init_r:第2阶段的代码

 

二、初始编译

 1、  解压 u-boot-2012.04.01.tar.bz2


tar xjf u-boot-2012.04.01.tar.bz2

进入解压后文件目录

cd u-boot-2012.04.01

2、在解压后文件目录下根据靠近的单板,配置

make smdk2410_config
make

这个时候编译完成后是不能在JZ2440上正常运行

三、建立自己的单板,定制适合自己单板的bootloader

1、新建一个单板

    cd board/samsung/
    cp smdk2410 smdk2440 -rf
    cd ../../include/configs/
    cp smdk2410.h smdk2440.h

修改boards.cfg

仿照2410,添加2440


smdk2410                    arm        arm920t    -                  samsung        s3c24x0

添加

smdk2440                    arm        arm920t    -                  samsung        s3c24x0

make , 烧写调试

2、根据需求进一步配置

make menuconfig 

3、修改Makefile ,开头指定架构和编译器

 ARCH=arm
 CROSS_COMPILE=arm-linux-

4、修改uboot代码,适合单板

  uboot里先以60MHZ的时钟计算参数来设置内存控制器,但是MPLL还未设置

  处理措施: 把MPLL的设置放到start.S里,取消board_early_init_f里对MPLL的设置

a、设置PLL的时钟的函数在_main中的board_init_f中初始化函数列表中的  boad_early_init_f 中,设置MPLL倍频值。它应该要在设置分频系数和初始化内存控制器之前来设置。

做如下修改: 在smdk2410.c文件中找到设置MPLL部分的代码,注释掉。

 


    /* to reduce PLL lock time, adjust the LOCKTIME register */
        //writel(0xFFFFFF, &clk_power->locktime);

      /* configure MPLL */
        //writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV,
          //    &clk_power->mpllcon);

然后在start.S中再设置MPLL

#define S3C2440_MPLL_400MHZ    ((0x5c<<12)|(0x01<<4)|(0x01))
#if 0
    /* FCLK:HCLK:PCLK = 1:2:4 */
    /* default FCLK is 120 MHz ! */
    ldr    r0, =CLKDIVN
    mov    r1, #3
    str    r1, [r0]
  #else
        /* 2. 设置时钟 400MHz */
        ldr r0, =0x4c000014
        //  mov r1, #0x03;            // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1
        mov r1, #0x05;            // FCLK:HCLK:PCLK=1:4:8
        str r1, [r0]
        /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */
        mrc p15, 0, r1, c1, c0, 0      /* 读出控制寄存器 */
        orr r1, r1, #0xc0000000        /* 设置为“asynchronous bus mode” */
        mcr p15, 0, r1, c1, c0, 0      /* 写入控制寄存器 */
   
        #define S3C2440_MPLL_400MHZ    ((0x5c<<12)|(0x01<<4)|(0x01))
        /* MPLLCON = S3C2440_MPLL_200MHZ */
        ldr r0, =0x4c000004
        ldr r1, =S3C2440_MPLL_400MHZ
        str r1, [r0]
 
        /* 启动ICACHE */
        mrc p15, 0, r0, c1, c0, 0  @ read control reg
        orr r0, r0, #(1<<12)
        mcr p15, 0, r0, c1, c0, 0  @ write it back
  #endif

关闭看门狗、关中断

#define S3C2440_MPLL_400MHZ    ((0x5c<<12)|(0x01<<4)|(0x01))
#if 0
    /* FCLK:HCLK:PCLK = 1:2:4 */
    /* default FCLK is 120 MHz ! */
    ldr    r0, =CLKDIVN
    mov    r1, #3
    str    r1, [r0]
  #else
        /* 2. 设置时钟 400MHz */
        ldr r0, =0x4c000014
        //  mov r1, #0x03;            // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1
        mov r1, #0x05;            // FCLK:HCLK:PCLK=1:4:8
        str r1, [r0]
        /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */
        mrc p15, 0, r1, c1, c0, 0      /* 读出控制寄存器 */
        orr r1, r1, #0xc0000000        /* 设置为“asynchronous bus mode” */
        mcr p15, 0, r1, c1, c0, 0      /* 写入控制寄存器 */
   
        #define S3C2440_MPLL_400MHZ    ((0x5c<<12)|(0x01<<4)|(0x01))
        /* MPLLCON = S3C2440_MPLL_200MHZ */
        ldr r0, =0x4c000004
        ldr r1, =S3C2440_MPLL_400MHZ
        str r1, [r0]
 
        /* 启动ICACHE */
        mrc p15, 0, r0, c1, c0, 0  @ read control reg
        orr r0, r0, #(1<<12)
        mcr p15, 0, r0, c1, c0, 0  @ write it back
  #endif
关闭看门狗、关中断

#ifdef CONFIG_S3C24X0
    /* turn off the watchdog */

# if defined(CONFIG_S3C2400)
#  define pWTCON    0x15300000
#  define INTMSK    0x14400008    /* Interrupt-Controller base addresses */
#  define CLKDIVN    0x14800014    /* clock divisor register */
#else
#  define pWTCON    0x53000000
#  define INTMSK    0x4A000008    /* Interrupt-Controller base addresses */
#  define INTSUBMSK    0x4A00001C
#  define CLKDIVN    0x4C000014    /* clock divisor register */
# endif

    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
#endif

b、内存控制器的设置值改为如下

在/board/samsung/smdk2410/lowlevel_init.S文件中做一下修改

SMRDATA:
#if 0
    .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
#else

  .long 0x22011110    //BWSCON
  .long 0x00000700    //BANKCON0
  .long 0x00000700    //BANKCON1
  .long 0x00000700    //BANKCON2
  .long 0x00000700    //BANKCON3
  .long 0x00000700    //BANKCON4
  .long 0x00000700    //BANKCON5
  .long 0x00018005    //BANKCON6
  .long 0x00018005    //BANKCON7
  .long 0x008C04F4    //REFRESH
  .long 0x000000B1    //BANKSIZE
  .long 0x00000030    //MRSRB6
  .long 0x00000030    //MRSRB7

 #endif

c、设置串口波特率(get_HCLK函数),乱码,查看串口波特率的设置,发现在get_HCLK里没有定义CONFIG_S3C2440宏

处理措施:在include/configs/smdk2440.h中


//#define CONFIG_S3C2410        /* specifically a SAMSUNG S3C2410 SoC */
//#define CONFIG_SMDK2410        /* on a SAMSUNG SMDK2410 Board */
#define CONFIG_S3C2440        /* specifically a SAMSUNG S3C2440 SoC */
#define CONFIG_SMDK2440        /* on a SAMSUNG SMDK2440 Board */

d、修改UBOOT支持NAND启动,原来的代码在链接时加了"-pie"选项, 使得u-boot.bin里多了"*(.rel*)", "*(.dynsym)"

    使得程序非常大,不利于从NAND启动(重定位之前的启动代码应该少于4K)


arch/arm/config.mk:75:LDFLAGS_u-boot += -pie 去掉这行

把init.c放入board/samsung/smdk2440目录,修改Makefile,使init.c编译进去

修改smdk2440.h ,修改CONFIG_SYS_TEXT_BASE为0x33f80000


#define CONFIG_SYS_TEXT_BASE    0x33f00000

init.c

/* NAND FLASH控制器 */
#define NFCONF (*((volatile unsigned long *)0x4E000000))
#define NFCONT (*((volatile unsigned long *)0x4E000004))
#define NFCMMD (*((volatile unsigned char *)0x4E000008))
#define NFADDR (*((volatile unsigned char *)0x4E00000C))
#define NFDATA (*((volatile unsigned char *)0x4E000010))
#define NFSTAT (*((volatile unsigned char *)0x4E000020))

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>