U-boot移植笔记(一)
?
http://blog.ednchina.com/celer/1112959/Message.aspx 经过四天的苦战,今天终于将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,读读就知道怎么做了。 其实要做的也很简单,就是在设置链接脚本是将_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处理器比较常见的就是S3C2410和S3C2440,针对这两个开发板我们选择smdk2410开发板文件夹,因此我们可以复制一个到我们的开发板,这里我起名为UP-Star2410。 cp –rf smdk2410/ UP-Star2410 进入UP-Star2410,ls一下,看到有以下文件 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开发板配置了一个64M的SDRAM,地址范围在30000000~34000000,内核默认的运行地址是30008000,可选的ramdisk运行地址是30800000,uboot的默认运行地址是33F8000.但是我手中博创的开发板只有32M的SDRAM,并且接在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,#1n" ????????? "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,r1,c1,c0,0 n”???? /*read ctrl register*/ ???????????????????????????????????? ?“orr???????? r1,#0xc0000000 n” /* asynchronous */ ???????????????????????????????????? ?“mcr?????? p15,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; } ? /*参照S3C2410的datasheet,我们看到时钟频率设定的公式如下 * 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中被调用,这个文件是用来配置S3C2410的Memory 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位,而且由CPU的M0和M1引脚硬件决定*/ #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开发板上配置的是K4S561632A是16位数据宽度32M的SDRAM*/ #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 */ /*根据SDRAM的datasheet,我们需要改变这里的刷新频率*/ //#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,#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的,注意BANK6和BANK7的大小要相同 ???????? .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-Star是DM9000网卡 ?*等到用到的时候我们再来配置 ?*/ #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,#0x1f ?? 116????????? orr???? 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,#4 ?? 132????????? str???? r3,#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初始化,比如关闭MMUCache等 *注意:当我们再调试阶段时,也就是把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中),则不需要复制??? *如果不是出于调试阶段,这段搬移代码中的r0和r1肯定不相等的,*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,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,#CFG_MALLOC_LEN /* malloc area? */ ?? 206?? ???????sub???? r0,#CFG_GBL_DATA_SIZE /* bdinfo ??*/ ?? 207? #ifdef CONFIG_USE_IRQ ?? 208????????? sub???? r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) ?? 209? #endif ?? 210????????? sub???? sp,#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,#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,c7,0?? /* flush v3/v4 cache */ ?? 246????????? mcr???? p15,c8,0?? /* flush v4 TLB */ ?? 247 ?? 248????????? /* ?? 249?????????? * disable MMU stuff and caches ?? 250?????????? */ ?? 251????????? mrc???? p15,0 ?? 252????????? bic???? r0,#0x00002300???? @ clear bits 13,9:8 (--V- --RS) ?? 253????????? bic???? r0,#0x00000087???? @ clear bits 7,2:0 (B--- -CAM) ?? 254????????? orr???? r0,#0x00000002???? @ set bit 2 (A) Align ?? 255????????? orr???? r0,#0x00001000???? @ set bit 12 (I) I-Cache ?? 256????????? mcr???? p15,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的身份,呵呵。剩下的工作就留在下一篇博文吧。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |