原创 U-boot移植笔记(一)

2010-4-6 11:22 4453 2 3 分类: MCU/ 嵌入式

经过四天的苦战,今天终于将Uboot成功移植到博创的UP-Star2410上了。其实前几天就做好了,但是当时想通过原厂烧好的Uboot将我新移植的下载到SDRAM上运行,但是总是提示test:RC0,然后就停在原地了,只能重启。后来,我又将光盘里的U-boot 1.3.2重新配置编译好后发现仍然不能在RAM中运行,我就猜到了可能是在对RAM的配置上有些问题。还好我多了个心眼,又把编译好的通过sjf2410下载到NAND Flash上,结果一上电,哈,果然能够运行。看来还真是RAM在作怪。


今天终于发现问题了,原来时调试阶段是程序的链接和CPU的初始化有问题。偶然间看到一篇帖子上回复à直接在内存运行uboot就更简单了,只需要借助uboot自身把新编译的uboot先下载到内存,然后用go命令就行了,不过需要注意,调试uboot的时候,这个uboot链接位置千万不要和原来在运行的uboot链接地址一样,不能对SDRAM初始化,最好也不要对系统时钟再初始化。查查代码中这2个宏相关的代码CONFIG_SKIP_LOWLEVEL_INIT  CONFIG_SKIP_RELOCATE_UBOOT,读读就知道怎么做了。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


其实要做的也很简单,就是在设置链接脚本是将_TEXT_BASE=0x33f80000改为与当前运行的Uboot的地址不重合就行(之所以说不重合是指既不能相同,还要保证彼此不覆盖)。另外,在/cpu/arm920t下面的start.S中把包含lowlevel_init.S的语句跳过(即把#ifndef CONFIG_SKIP_LOWLEVEL_INIT改为#ifdef CONFIG_SKIP_LOWLEVEL_INIT)。然后 tftp 到内存里.直接从那go 就可以了


好了,闲话少说,下面把自己的移植过程跟大家分享一下,有不对的地方,恳请大家多多指正,让我能再上一个台阶。主要分以下几个步骤:


1.  下载源码


推荐官网ftp下载ftp://ftp.denx.de/pub/u-boot/,这里有最新最全的Uboot源码。但是利用校园网上网的同学需要麻烦一下,至少我们学校是这样,就得通过代理来下载了。至于怎么利用代理,我就不多叙述了,搞嵌入式这一行遇到问题就得是do {baidu; google;} while (~problem solved)


这里我下载的是U-boot-1.3.4,大家也可以下载其他的版本,至于区别这个我没有研究,等以后学习深入了再说吧。


2.  准备阶段。


下载到源码以后,解压到自己的工作目录,比如我的工作目录是/home/celer/u-boot,将源码拷贝到工作目录后解压,tar xjf u-boot-1.3.4.tar.bz2。网上已经有很多人介绍如何移植了,其实步骤都是很相似的。


解压好后,进入Uboot根目录,进入board目录,这里存放的是Uboot支持的所有开发板,所有为了让Uboot支持我们的开发板,我们也要新建一个,但是之所以称之为Uboot“移植”,我理解就是“修改”,我们要利用现有的代码来“搭建”成我们需要的代码。现在市面上主流的嵌入式ARM处理器比较常见的就是S3C2410S3C2440,针对这两个开发板我们选择smdk2410开发板文件夹,因此我们可以复制一个到我们的开发板,这里我起名为UP-Star2410


cp –rf smdk2410/ UP-Star2410


进入UP-Star2410ls一下,看到有以下文件


config.mk                   flash.c      lowlevel_init.S          Makefile  smdk2410.c   u-boot.lds


为了让大家能够更加明白为什么是这样或那样移植的,我们先来看看这几个文件的作用。(这里为了复制粘贴方便,我使用SSH来远程登录我虚拟机上的Linux。或者也可以使用UltraEdit,这个也是一个不错的工具,我所遇到的什么文件都能查看,真是厉害。大家不妨尝试一下)。


先来看看config.mk,只摘录比较关键的。(关于代码的改变,便于大家理解,注释部分我用蓝色来标记,需要改变的源代码我用紫色标记,改好后的代码我用红色标记,之所以选用红色,一是因为大家看起来方便,更主要的是大家如果发现错用可以及时指正)


# SMDK2410 has 1 bank of 64 MB DRAM


#


# 3000'0000 to 3400'0000


#


# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000


# optionally with a ramdisk at 3080'0000


#


# we load ourself to 33F8'0000


#


# download area is 3300'0000


#


TEXT_BASE = 0x33F80000


可以看出这个文件是对Uboot进行链接的,链接地址在0x33F80000。但是大家请注意注释里说到的,SMDK2410开发板配置了一个64MSDRAM,地址范围在30000000~34000000,内核默认的运行地址是30008000,可选的ramdisk运行地址是30800000uboot的默认运行地址是33F8000.但是我手中博创的开发板只有32MSDRAM,并且接在BANK6上,所以地址空间就变成30000000~32000000.这时我们程序的运行地址就需要相应的改变了,现在我们只讨论Uboot的移植,所有关于内核和ramdisk我们这里先不讨论。改好后的代码如下:


# UP-Star2410 has 1 bank of 32 MB DRAM


#


# 3000'0000 to 3200'0000


#


# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000


# optionally with a ramdisk at 3080'0000


#


# we load ourself to 31F8'0000


#


# download area is 3300'0000


#


TEXT_BASE = 0x31F80000


下面我们来看看smdk2410.c,这个文件主要是用来配置开发板的时钟分配以及SDARM的起始地址和大小的参数传递。


#include <common.h>


#include <s3c2410.h>


/*此全局变量指定用R8寄存器来存放其存储地址,所有在任意函数里面声明一下就可以使用同一个全局变量了,比如后面的gd*/


DECLARE_GLOBAL_DATA_PTR;


/*这部分是用来定义全局时钟和USB时钟的,但是可以看出默认的CPU主频是202.8MHz,而我们一般选择的是200MHz,所以这个地方我们需要修改一下*/


#define FCLK_SPEED 1


 


#if FCLK_SPEED==0               /* Fout = 203MHz, Fin = 12MHz for Audio */


#define M_MDIV  0xC3


#define M_PDIV  0x4


#define M_SDIV  0x1


#elif FCLK_SPEED==1             /* Fout = 202.8MHz */


#define M_MDIV  0xA1


#define M_PDIV  0x3


#define M_SDIV  0x1


#endif


 


#define USB_CLOCK 1


 


#if USB_CLOCK==0


#define U_M_MDIV        0xA1


#define U_M_PDIV        0x3


#define U_M_SDIV        0x1


#elif USB_CLOCK==1


#define U_M_MDIV        0x48


#define U_M_PDIV        0x3


#define U_M_SDIV        0x2


#endif


 


static inline void delay (unsigned long loops)


{


        __asm__ volatile ("1:\n"


          "subs %0, %1, #1\n"


          "bne 1b":"=r" (loops):"0" (loops));


}


 


/*


 * Miscellaneous platform dependent initialisations


 */


 


int board_init (void)


{


/* clk_power这个结构体指针指向的是一个S3C2410_CLOCK_POWER类型的结构体,里面封装了关于时钟以及电源配置的寄存器,这里我就不深究了,大家了解一下就行*/


S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();


        S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();


/*以下是开发板的时钟配置*/


                   /*我们先来配置一下时钟分频比例*/


                   clk_power->CLKDIVN = S3C2410_CLKDIV;


/*修改为异步总线模式这里我参考韦东山老师的代码,具体为什么我也没有深究,希望讨论的大家可以给我留言,我再仔细看看*/


                   __asm__(         “mrc       p15, 0, r1, c1, c0,0 \n”     /*read ctrl register*/


                                      “orr         r1, r1, #0xc0000000 \n” /* asynchronous */


                                      “mcr       p15, 0, r1, c1, c0, 0 \n” /*write ctrl register*/


                                     ::: “r1”


                                     );


        /* to reduce PLL lock time, adjust the LOCKTIME register */


        clk_power->LOCKTIME = 0xFFFFFF;


 


        /* configure MPLL */


        clk_power->MPLLCON = S3C2410_MPLL_200MHZ


 


        /* some delay between MPLL and UPLL */


        delay (4000);


 


        /* configure UPLL */


        clk_power->UPLLCON = S3C2410_UPLL_48MHZ;


 


        /* some delay between MPLL and UPLL */


        delay (8000);


 


        /* set up the I/O ports */


        gpio->GPACON = 0x007FFFFF;


        gpio->GPBCON = 0x00044555;


        gpio->GPBUP = 0x000007FF;


        gpio->GPCCON = 0xAAAAAAAA;


        gpio->GPCUP = 0x0000FFFF;


        gpio->GPDCON = 0xAAAAAAAA;


        gpio->GPDUP = 0x0000FFFF;


        gpio->GPECON = 0xAAAAAAAA;


        gpio->GPEUP = 0x0000FFFF;


        gpio->GPFCON = 0x000055AA;


        gpio->GPFUP = 0x000000FF;


        gpio->GPGCON = 0xFF95FFBA;


        gpio->GPGUP = 0x0000FFFF;


        gpio->GPHCON = 0x002AFAAA;


        gpio->GPHUP = 0x000007FF;


 


        /* arch number of SMDK2410-Board */


        gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;


 


        /* 这个是Uboot引导内核时传递参数的地址,这个要记住,因为我们以后移植内核时还要用到 */


        gd->bd->bi_boot_params = 0x30000100;


 


        icache_enable();


        dcache_enable();


 


  return 0;


}


/*这个是我们开发板上的SDRAM起始地址和空间大小,在include/configs/smdk2410.h中定义*/


int dram_init (void)


{


        gd->bd->bi_dram[0].start = PHYS_SDRAM_1;


        gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;


 


        return 0;


}


 


/*参照S3C2410datasheet,我们看到时钟频率设定的公式如下


* S3C2410: MPLL,UPLL=(m* Fin) / (p*2^s)


*m= MDIV (the value for divider M) + 8, p= PDIV (the value for divider) + 2, s="SDIV"


*虽然手册上有个表可以参考,不过没有我们想要的200MHz,所有还得我们自己来计算


*这里我就用大家常用的代入就可以了


*开发板的时钟为12MHz,在include/configs/smdk2410.h中的宏CONFIG_CLK_FREG中定义,*如果大家的时钟不同(不过我所见过的都是这个),可以修改


*/


#define     S3C2410_MPLL_200MHZ        ((0x5c<<12) | (0x04<<4) | (0x00))


#define     S3C2410_UPLL_48MHZ            ((0x28<<12) | (0x01<<4) | (0x02))


#define     S3C2410_CLKDIV                       0x03  /*FCLK:HCLK:PCLK=1:2:4*/


现在我们看出来,smdk2410.c就是我们开发板的时钟和RAM配置,那么我们的开发板既然是UP-Star2410,那么这个文件名也得改成UP-Star2410了。


我们再来看看u-boot.lds文件,这个文件我们不需要改动。


OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")


/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/


OUTPUT_ARCH(arm)


/*指明了Uboot程序的入口函数时_start,在cpu/arm920t/start.S中,后面会介绍*/


ENTRY(_start)


SECTIONS


{


      . = 0x00000000; /* 后记:这个链接起始地址实际上被-Ttest $(TEST_BASE)更新了*/


 


        . = ALIGN(4);


        .text      :          //程序段基址


        {


          cpu/arm920t/start.o   (.text)


          *(.text)


        }


 


        . = ALIGN(4);                       //只读数据段基址


        .rodata : { *(.rodata) }


 


        . = ALIGN(4);


        .data : { *(.data) }              //读写数据段基址


 


        . = ALIGN(4);


        .got : { *(.got) }


 


        . = .;


        __u_boot_cmd_start = .;


        .u_boot_cmd : { *(.u_boot_cmd) }


        __u_boot_cmd_end = .;


 


        . = ALIGN(4);


        __bss_start = .;                 //初始化为0或未定义变量的存储基址


        .bss (NOLOAD) : { *(.bss) }


        _end = .;


}


我们再来看看lowlevel_init.S文件,这个文件在Uboot启动后执行的第一个函数start.S中被调用,这个文件是用来配置S3C2410Memory Controller(比如我们需要添加网卡时也要配置这个文件)和SDRAM的设置。


#include <config.h>


#include <version.h>


 


 


/* some parameters for the board */


 


/*


 *


 * Taken from linux/arch/arm/boot/compressed/head-s3c2410.S


 *


 * Copyright (C) 2002 Samsung Electronics SW.LEE  <hitchcar@sec.samsung.com>


 *


 */


/*S3C2410特殊功能寄存器SFR的起始地址*/


#define BWSCON  0x48000000


 


/* BWSCON */


#define DW8                     (0x0)


#define DW16                    (0x1)


#define DW32                    (0x2)


#define WAIT                    (0x1<<2)


#define UBLB                    (0x1<<3)


/*定义每个BANK的数据总线带宽,注意BANK0的带宽只能是16位或32位,而且由CPUM0M1引脚硬件决定*/


#define B1_BWSCON               (DW32)


#define B2_BWSCON               (DW16)


#define B3_BWSCON               (DW16 + WAIT + UBLB)


#define B4_BWSCON               (DW16)


#define B5_BWSCON               (DW16)


//#define B6_BWSCON               (DW32)


//#define B7_BWSCON               (DW32)


/*UP-Star2410开发板上配置的是K4S561632A16位数据宽度32MSDRAM*/


#define B6_BWSCON               (DW16)


#define B7_BWSCON               (DW16)


 


/* BANK0CON */


#define B0_Tacs                 0x0     /*  0clk */


#define B0_Tcos                 0x0     /*  0clk */


#define B0_Tacc                 0x7     /* 14clk */


#define B0_Tcoh                 0x0     /*  0clk */


#define B0_Tah                  0x0     /*  0clk */


#define B0_Tacp                 0x0


#define B0_PMC                  0x0     /* normal */


 


/* BANK1CON */


#define B1_Tacs                 0x0     /*  0clk */


#define B1_Tcos                 0x0     /*  0clk */


#define B1_Tacc                 0x7     /* 14clk */


#define B1_Tcoh                 0x0     /*  0clk */


#define B1_Tah                  0x0     /*  0clk */


#define B1_Tacp                 0x0


#define B1_PMC                  0x0


 


#define B2_Tacs                 0x0


#define B2_Tcos                 0x0


#define B2_Tacc                 0x7


#define B2_Tcoh                 0x0


#define B2_Tah                  0x0


#define B2_Tacp                 0x0


#define B2_PMC                  0x0


 


#define B3_Tacs                 0x0     /*  0clk */


#define B3_Tcos                 0x3     /*  4clk */


#define B3_Tacc                 0x7     /* 14clk */


#define B3_Tcoh                 0x1     /*  1clk */


#define B3_Tah                  0x0     /*  0clk */


#define B3_Tacp                 0x3     /*  6clk */


#define B3_PMC                  0x0     /* normal */


 


#define B4_Tacs                 0x0     /*  0clk */


#define B4_Tcos                 0x0     /*  0clk */


#define B4_Tacc                 0x7     /* 14clk */


#define B4_Tcoh                 0x0     /*  0clk */


#define B4_Tah                  0x0     /*  0clk */


#define B4_Tacp                 0x0


#define B4_PMC                  0x0     /* normal */


 


#define B5_Tacs                 0x0     /*  0clk */


#define B5_Tcos                 0x0     /*  0clk */


#define B5_Tacc                 0x7     /* 14clk */


#define B5_Tcoh                 0x0     /*  0clk */


#define B5_Tah                  0x0     /*  0clk */


#define B5_Tacp                 0x0


#define B5_PMC                  0x0     /* normal */


 


#define B6_MT                   0x3     /* SDRAM */


#define B6_Trcd                 0x1


#define B6_SCAN                 0x1     /* 9bit */


 


#define B7_MT                   0x3     /* SDRAM */


#define B7_Trcd                 0x1     /* 3clk */


#define B7_SCAN                 0x1     /* 9bit */


 


/* REFRESH parameter */


#define REFEN                   0x1     /* Refresh enable */


#define TREFMD                 0x0     /* CBR(CAS before RAS)/Auto refresh */


#define Trp                     0x0     /* 2clk */


#define Trc                     0x3     /* 7clk */


#define Tchr                    0x2     /* 3clk */


/*根据SDRAMdatasheet,我们需要改变这里的刷新频率*/


//#define REFCNT           1113    /* period="15".6us, HCLK="60Mhz", (2048+1-15.6*60) */


#define REFCNT                            0x4f4   /*period=64ms/8192=7.8125us HCLK="100MHz"*/


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


 


_TEXT_BASE:


        .word   TEXT_BASE


 


.globl lowlevel_init


lowlevel_init:


        /* 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, r0, r1


        ldr     r1, =BWSCON     /* Bus Width Status Controller */


        add     r2, r0, #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 //这个地址用来存放BANKSIZE的,注意BANK6BANK7的大小要相同


         .word 0x30


    .word 0x30


    .word 0x30


我想看到这,大家可以都有些“乱了”,只是看到个文件便改,却不知道这个文件时怎么调用的,或是在什么时候用到。这样,flash.c文件我们就不看了,其实它是配置Nor Flash的。Uboot的源码只支持Nor flash操作,不支持Nand Flash的操作,所以如果我们将来的系统是想从Nand Flash启动的话,就得需要我们自己来增加nand flash的操作了。这留在后面再详细讲述。我们直接进入UP-Star2410开发板的Makefile来看看。


include $(TOPDIR)/config.mk


 


LIB     = $(obj)lib$(BOARD).a


 


#既然我们的文件名都改为UP-Star2410.c了,那么这里也要相应地修改


COBJS   := smdk2410.o flash.o


COBJS   := UP-Star2410.o flash.o


SOBJS   := lowlevel_init.o


 


SRCS    := $(SOBJS:.o=.S) $(COBJS:.o=.c)


OBJS    := $(addprefix $(obj),$(COBJS))


SOBJS   := $(addprefix $(obj),$(SOBJS))


 


$(LIB): $(obj).depend $(OBJS) $(SOBJS)


        $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)


 


clean:


        rm -f $(SOBJS) $(OBJS)


 


distclean:      clean


        rm -f $(LIB) core *.bak $(obj).depend


 


#########################################################################


 


# defines $(obj).depend target


include $(SRCTREE)/rules.mk


 


sinclude $(obj).depend


好了,到此我们关于UP-Star2410的开发板文件夹就配置完了。下面我们进入include/configs目录,里面有关于开发板配置的头文件,我们还是利用smdk2410.h来复制一个我们的UP-Star2410.h,我们进来看一看


#ifndef __CONFIG_H


#define __CONFIG_H


 


/*


 * High Level Configuration Options


* (easy to change)


 */


/*关于我们开发板的声明,至于具体的名字建议大家还是不要改,因为有很多地方会利用它们,如果修改了,一定要保证所有的都有替换*/


#define CONFIG_ARM920T          1       /* This is an ARM920T Core      */


#define CONFIG_S3C2410          1       /* in a SAMSUNG S3C2410 SoC     */


#define CONFIG_SMDK2410         1       /* on a SAMSUNG SMDK2410 Board  */


 


/* input clock of PLL


*这就是上面我提到的CPU输入时钟设置


*/


#define CONFIG_SYS_CLK_FREQ     12000000/* the SMDK2410 has 12MHz input clock */


 


 


#define USE_920T_MMU            1


#undef CONFIG_USE_IRQ                   /* we don't need IRQ/FIQ stuff */


 


/*


 * Size of malloc() pool


 */


#define CFG_MALLOC_LEN          (CFG_ENV_SIZE + 128*1024)


#define CFG_GBL_DATA_SIZE       128     /* size in bytes reserved for initial data */


 


/*


 * Hardware drivers


 *网卡声明,SMDK2410开发板自带的是CS8900网卡,而我们的UP-StarDM9000网卡


 *等到用到的时候我们再来配置


 */


#define CONFIG_DRIVER_CS8900    1       /* we have a CS8900 on-board */


#define CS8900_BASE             0x19000300


#define CS8900_BUS16            1 /* the Linux driver does accesses as shorts */


 


/*


 * select serial console configuration


 */


#define CONFIG_SERIAL1          1       /* we use SERIAL 1 on SMDK2410 */


 


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


 * RTC


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


#define CONFIG_RTC_S3C24X0      1


 


/* allow to overwrite serial and ethaddr */


#define CONFIG_ENV_OVERWRITE


 


#define CONFIG_BAUDRATE         115200


 


 


/*


 * BOOTP options


 */


#define CONFIG_BOOTP_BOOTFILESIZE


#define CONFIG_BOOTP_BOOTPATH


#define CONFIG_BOOTP_GATEWAY


#define CONFIG_BOOTP_HOSTNAME


 


 


/*


 * Command line configuration.


 *Uboot提供的命令行,非常有用,无论是在调试还是下载都是大有帮助的


 *但是初始时提供的命令很少,需要我们自己来添加,这个也放在后面再说


 */


#include <config_cmd_default.h>


 


#define CONFIG_CMD_CACHE


#define CONFIG_CMD_DATE


#define CONFIG_CMD_ELF


 


/*系统自启动时间设定,这个可以根据自己的需要来设定,我把它改为5s*/


//#define CONFIG_BOOTDELAY        3


#define CONFIG_BOOTDELAY        5


/*下面几个宏定义是用来设置网络的,等以后我们用到网络再来改*/


/*#define CONFIG_BOOTARGS       "root=ramfs devfs="mount" console="ttySA0",9600" */


/*#define CONFIG_ETHADDR        08:00:3e:26:0a:5b */


#define CONFIG_NETMASK          255.255.255.0


#define CONFIG_IPADDR           10.0.0.110


#define CONFIG_SERVERIP         10.0.0.1


/*#define CONFIG_BOOTFILE       "elinos-lart" */


/*#define CONFIG_BOOTCOMMAND    "tftp; bootm" */


 


#if defined(CONFIG_CMD_KGDB)


#define CONFIG_KGDB_BAUDRATE    115200          /* speed to run kgdb serial port */


/* what's this ? it's not used anywhere */


#define CONFIG_KGDB_SER_INDEX   1               /* which serial port to use */


#endif


 


/*


 * Miscellaneous configurable options


 */


#define CFG_LONGHELP                            /* undef to save memory         */


/*用来设定命令行的名字,这里我改成我自己设置的开发板的名字UP-Star2410*/


//#define CFG_PROMPT       "SMDK2410 # "   /* Monitor Command Prompt       */


#define CFG_PROMPT         "UP-Star2410 # "   /* Monitor Command Prompt       */


#define CFG_CBSIZE              256             /* Console I/O Buffer Size      */


#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */


#define CFG_MAXARGS             16              /* max number of command args   */


#define CFG_BARGSIZE            CFG_CBSIZE      /* Boot Argument Buffer Size    */


/*设置RAM的工作范围*/


#define CFG_MEMTEST_START       0x30000000      /* memtest works on     */


//#define CFG_MEMTEST_END         0x33F00000      /* 63 MB in DRAM     */


#define CFG_MEMTEST_END         0x31F00000      /* 32 MB in DRAM     */


 


#undef  CFG_CLKS_IN_HZ          /* everything, incl board info, in Hz */


/*串口默认的下载地址,这里我改成0x30008000*/


//#define CFG_LOAD_ADDR           0x33000000  /* default load address */


#define CFG_LOAD_ADDR           0x30008000  /* default load address */


 


/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */


/* it to wrap 100 times (total 1562500) to get 1 sec. */


#define CFG_HZ                  1562500


 


/* valid baudrates */


#define CFG_BAUDRATE_TABLE      { 9600, 19200, 38400, 57600, 115200 }


 


/*-----------------------------------------------------------------------


 * Stack sizes


 *


 * The stack sizes are set up in start.S using the settings below


 */


#define CONFIG_STACKSIZE        (128*1024)      /* regular stack */


#ifdef CONFIG_USE_IRQ


#define CONFIG_STACKSIZE_IRQ    (4*1024)        /* IRQ stack */


#define CONFIG_STACKSIZE_FIQ    (4*1024)        /* FIQ stack */


#endif


 


/*-----------------------------------------------------------------------


 * Physical Memory Map


 *这就是我们再UP-Star2410.c里面最好两行用来设置SDRAM的宏定义


 */


#define CONFIG_NR_DRAM_BANKS    1          /* we have 1 bank of DRAM */


#define PHYS_SDRAM_1            0x30000000 /* SDRAM Bank #1 */


//#define PHYS_SDRAM_1_SIZE       0x04000000 /* 64 MB */


#define PHYS_SDRAM_1_SIZE       0x02000000 /* 32 MB */


 


 


#define PHYS_FLASH_1            0x00000000 /* Flash Bank #1 */


 


#define CFG_FLASH_BASE          PHYS_FLASH_1


 


/*-----------------------------------------------------------------------


 * FLASH and environment organization


 *下面是Flash的配置,等我们用到的时候再说


 */


 


#define CONFIG_AMD_LV400        1       /* uncomment this if you have a LV400 flash */


#if 0


#define CONFIG_AMD_LV800        1       /* uncomment this if you have a LV800 flash */


#endif


 


#define CFG_MAX_FLASH_BANKS     1       /* max number of memory banks */


#ifdef CONFIG_AMD_LV800


#define PHYS_FLASH_SIZE         0x00100000 /* 1MB */


#define CFG_MAX_FLASH_SECT      (19)    /* max number of sectors on one chip */


#define CFG_ENV_ADDR            (CFG_FLASH_BASE + 0x0F0000) /* addr of environment */


#endif


#ifdef CONFIG_AMD_LV400


#define PHYS_FLASH_SIZE         0x00080000 /* 512KB */


#define CFG_MAX_FLASH_SECT      (11)    /* max number of sectors on one chip */


#define CFG_ENV_ADDR            (CFG_FLASH_BASE + 0x070000) /* addr of environment */


#endif


 


/* timeout values are in ticks */


#define CFG_FLASH_ERASE_TOUT    (5*CFG_HZ) /* Timeout for Flash Erase */


#define CFG_FLASH_WRITE_TOUT    (5*CFG_HZ) /* Timeout for Flash Write */


 


#define CFG_ENV_IS_IN_FLASH     1


#define CFG_ENV_SIZE            0x10000 /* Total Size of Environment Sector */


 


#endif  /* __CONFIG_H */


最后,我们再来进入cpu/arm920t/start.S里面看看,这个才是Uboot启动后执行的第一个文件,不过全是用汇编来写的,大家要做好心理准备。


28  #include <config.h>


    29  #include <version.h>


    30  #include <status_led.h>


    31


    32  /*


    33   *************************************************************************


    34   *


    35   * Jump vector table as in table 3.1 in [1]


    36   *


    37   *************************************************************************


    38   */


    39


    40


    41  .globl _start


    42  _start:   b       start_code                       @执行的第一条语句,在110


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


    64   *


    65   * Startup Code (called from the ARM reset exception vector)


    66   *


    67   * do important init only if we don't start from memory!


    68   * relocate armboot to ram


    69   * setup stack


    70   * jump to second stage


    71   *


    72   *************************************************************************


    78  .globl _armboot_start              @第二阶段C语言的入口函数


    79  _armboot_start:


    80          .word _start


   106  /*


   107   * the actual start code


   108   */


   109


   110  start_code:


   111          /*


   112           * set the cpu to SVC32 mode


   113           */


   114          mrs     r0,cpsr


   115          bic     r0,r0,#0x1f


   116          orr     r0,r0,#0xd3


   117          msr     cpsr,r0


   118


   119  //        bl coloured_LED_init              @SMDK开发板上的LED,后面我们用自己的


   120  //        bl red_LED_on


   121   /* 下面的#if…#endif之间的内容我们去掉,对我们代码的执行没有作用*/


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


   122  #if     defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK) || defined(CONFIG_AT91RM9200DF)


   123          /*


   124           * relocate exception table


   125           */


   126          ldr     r0, =_start


   127          ldr     r1, =0x0


   128          mov     r2, #16


   129  copyex:


   130          subs    r2, r2, #1


   131          ldr     r3, [r0], #4


   132          str     r3, [r1], #4


   133          bne     copyex


   134  #endif


   135************************************************************************/


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


   137          /* turn off the watchdog */


   138


   139  # if defined(CONFIG_S3C2400)


   140  #  define pWTCON                0x15300000


   141  #  define INTMSK                0x14400008      /* Interupt-Controller base addresses */


   142  #  define CLKDIVN       0x14800014      /* clock divisor register */


   143  #else


   144  #  define pWTCON                0x53000000


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


   146  #  define INTSUBMSK     0x4A00001C


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


   148  # endif


   149


   150          ldr     r0, =pWTCON


   151          mov     r1, #0x0


   152          str     r1, [r0]


   153


   154          /*


   155           * mask all IRQs by setting all bits in the INTMR - default


   156           */


   157          mov     r1, #0xffffffff


   158          ldr     r0, =INTMSK


   159          str     r1, [r0]


   160  # if defined(CONFIG_S3C2410)


   161          ldr     r1, =0x3ff


   162          ldr     r0, =INTSUBMSK


 163          str     r1, [r0]


   164  # endif


   165


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


   167          /* default FCLK is 120 MHz ! */


   168          ldr     r0, =CLKDIVN


   169          mov     r1, #3


   170          str     r1, [r0]


   171  #endif  /* CONFIG_S3C2400 || CONFIG_S3C2410 */


   172 /*第一步设置完成,点亮一下我们的LED1,我这里接的是GPC5/6/7*/


#if 1


         ldr    r6, =0x5400


         ldr    r7, =0x56000020


         str    r6, [r7]


 


         ldr    r6, =0xc0


         ldr    r7, =0x56000024


         str    r6, [r7]


#endif


   173/*


   174 * we do sys-critical inits only at reboot,


   175* not when booting from ram!


           *用来设置CPU初始化,比如关闭MMU\Cache


*注意:当我们再调试阶段时,也就是把UBoot装载到RAM中运行时,我们一定能


*能再初始化CPU


   176 */


   177  #ifndef CONFIG_SKIP_LOWLEVEL_INIT


   178          bl      cpu_init_crit


   179  #endif


   180/*这个#ifdef#endif也去掉*/


 


   181 // #ifndef CONFIG_AT91RM9200


   182


   183  #ifndef CONFIG_SKIP_RELOCATE_UBOOT


   184  relocate:                              /* relocate U-Boot to RAM*/


   185          adr     r0, _start               /* r0:当前代码的开始地址*/


   186          ldr      r1, _TEXT_BASE         /* r1:代码段链接地址,即运行地址*/ 


 187          cmp     r0, r1               /* test if we run from flash or RAM */


 188          beq     stack_setup                        /* don't reloc during debug   */


   189/*如果已经在RAM中(调试时直接下载到RAM中),则不需要复制   


*如果不是出于调试阶段,这段搬移代码中的r0r1肯定不相等的,*r0=#0,r1=#TEXT_BASE: 0x33F80000(./board/smdk2410/config.mk),所以执行代码*的自身拷贝与搬移


*如果是调试阶段,则_start地址就是串口或网卡下载的默认地址,比如30008000


*/


   190          ldr     r2, _armboot_start


   191          ldr     r3, _bss_start


   192          sub     r2, r3, r2              /* r2 <- size of armboot            */


   193          add     r2, r0, r2              /* r2 <- source end address         */


   194


   195  copy_loop:


   196          ldmia   r0!, {r3-r10}           /* copy from source address [r0]    */


   197          stmia   r1!, {r3-r10}           /* copy to   target address [r1]    */


   198          cmp     r0, r2                  /* until source end addreee [r2]    */


   199          ble     copy_loop


   200 // #endif  /* CONFIG_SKIP_RELOCATE_UBOOT */


   201 #endif


   202 /* Set up the stack   */


   203  stack_setup:


   204          ldr     r0, _TEXT_BASE          /* upper 128 KiB: relocated uboot   */


   205          sub     r0, r0, #CFG_MALLOC_LEN /* malloc area  */


   206          sub     r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo   */


   207  #ifdef CONFIG_USE_IRQ


   208          sub     r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)


   209  #endif


   210          sub     sp, r0, #12             /* leave 3 words for abort-stack    */


   211/*堆栈设置完成,准备调用第二阶段的C语言,我们再来点亮一个LED2*/


 #if 1


                     ldr    r6, =0x5400


                     ldr    r7, =0x56000020


                     str    r6, [r7]


 


                     ldr    r6, =0xa0


                     ldr    r7, =0x56000024


                     str    r6, [r7]


#endif


   212  clear_bss:


   213          ldr     r0, _bss_start          /* find start of bss segment        */


   214          ldr     r1, _bss_end          /* stop here   */


   215          mov     r2, #0x00000000         /* clear    */


   216


   217  clbss_l:str     r2, [r0]                /* clear loop...   */


   218          add     r0, r0, #4


   219          cmp     r0, r1


   220          ble     clbss_l


   221 /*在进入C语言前,我们再来点亮一下LED3*/


#if 1


                                     ldr    r6, =0x5400


                                     ldr    r7, =0x56000020


                                     str    r6, [r7]


 


                                     ldr    r6, =0x80


                                     ldr    r7, =0x56000024


                                     str    r6, [r7]


#endif


   222          ldr     pc, _start_armboot


   223


   224  _start_armboot: .word start_armboot


   225


   226


   227  /*


   228   *************************************************************************


   229   *


   230   * CPU_init_critical registers


   231   *


   232   * setup important registers


   233   * setup memory timing


   234   *


   235   *************************************************************************


   236   */


   237


   238


   239  #ifndef CONFIG_SKIP_LOWLEVEL_INIT


   240  cpu_init_crit:


   241          /*


   242           * flush v4 I/D caches


   243           */


   244          mov     r0, #0


   245          mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */


   246          mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */


   247


   248          /*


   249           * disable MMU stuff and caches


   250           */


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


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


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


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


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


   256          mcr     p15, 0, r0, c1, c0, 0


   257


   258          /*


   259           * before relocating, we have to setup RAM timing


   260           * because memory timing is board-dependend, you will


   261           * find a lowlevel_init.S in your board directory.


   262           */


   263          mov     ip, lr


                   /*再次去掉#if#else#endif*/


   264  //#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK) || defined(CONFIG_AT91RM9200DF)


   265


   266  //#else


   267          bl      lowlevel_init


   268  ///#endif


   269          mov     lr, ip


   270          mov     pc, lr


   271  #endif /* CONFIG_SKIP_LOWLEVEL_INIT */


现在我们再回到根目录,修改Makefile。关于根目录的Makefile的介绍,大家可以参考其他相关的资料,这里我就不再赘述了,如果有问题欢迎给我留言,我尽量帮大家来解答。


Makefile中有关于CPU分类的开发板配置文件,我们在其中第2494行找到smdk2410对应的配置项


smdk2410_config    :        unconfig


         @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0


修改如下                 


UP-Star2410_config         :        unconfig


         @$(MKCONFIG) $(@:_config=) arm arm920t UP-Star2410 NULL s3c24x0


现在,我们的Uboot就可以编译了,目前具备的功能只有串口,而且还只能在RAM上运行。总结一下我们之前做过的配置,首先我们要建立一个自己的开发板目录,然后先针对CPU进行一下修改,这里我们用的是S3C2410,正是Uboot的默认配置,所以不需要修改,如果是S3C2440或者是其他CPU就需要修改了。然后就是配置开发板的时钟、SDRAM的配置,另外,如果是从Nor Flash上启动,好需要配置一下Nor Flash(由于我的板子上没有,所有没有写,需要的话也欢迎讨论)。经过以上的一些配置,正常情况一个最基本的Uboot就移植完成,但是功能太过简单,有失Uboot的身份,呵呵。剩下的工作就留在下一篇博文吧。


 


 P.S没想到一下写了这么多,连上传都得分好几次等10分钟~

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户1664007 2010-4-11 11:39

期待你的下一篇博文,能把你改后的Uboot的源码发我一份吗?我的邮箱zgwcome1@163.com,谢谢了
相关推荐阅读
用户178555 2010-04-06 09:18
写在arm入门前--转载
“ARM怎么入门”。我不是高手,仍然是菜鸟。       但是回想起自己当时的迷茫,特意写了这篇东西,当作给和我一样的兄弟姐妹的帮助吧。问这个问题的人多半不是已经工作的工程师,而是和我一样是学生,所以...
用户178555 2010-04-01 13:21
永远忠于年轻时的梦想(转载特权's blog)
本来我也不知道最后的两课该以怎样的方式来讲,也不是很确定什么时候能够静下心来录。最近遇到了很多事,开心的不开心的,其实也无所谓开心和不开心,因为我的心情还是很平静的,不论是哪一方面。但是今天我算是闲下...
用户178555 2010-03-11 21:41
Linux下程序开发流程
Linux下程序开发流程首先说明一下我的开发环境:Windows XP SP3+VMwork station 7.0+Redhat Linux 9.0编译工具为arm-linux-gcc 3.4.51...
EE直播间
更多
我要评论
1
2
关闭 站长推荐上一条 /3 下一条