这是大四的时候做的,附上移植文档,供大家参考,当时也查了很多网上的东东,呵呵
Uboot移植
Uboot十分强大,支持多种嵌入式系统体系架构,但是尽管硬件体系结构一样而不同的开发板也需要对uboot进行移植,因为可能各个“出板商”外设的地址空间映射是不同的,所以需要修改,而修改最开始最需要修改的两个初始化重要的汇编文件就是
①cpu/arm920t/start.S
②/board/<myboard>/lowlevel_init.S
详细移植步骤 NO.1:
1.到网站ftp://ftp.denx.de/pub/u-boot/下载u-boot-2008.10.tar.bz2,到相应网站下载编译器版本arm-linux-gcc-4.1.0.tar.gz
2.解压文件
相关命令:tar xjvf u-boot-2008.10.tar.bz2
3.进入uboot主目录,创建自己的开发板目录,拷贝相应体系架构相关文件到该目录。
相关命令:cd u-boot-2008.10
mkdir board/mini2440
cp board/smdk2410/* board/mini2440/
mv board/mini2440/smdk2410.c board/mini2440/mini2440.c
cp include/configs/smdk2410.h include/configs/mini2440.h(宏配置头文件)
4.修改顶层文件Makefile以及board/mini2440/,修改如下:
5.至此初步对自己的开发板修改框架完成,但是不能支持nor flash启动,主要原因是因为在uboot启动第一阶段初始化sdram时候(在lowlevel_init.S中完成),这与具体开发板外设连接相关,需要修改,然而大家也可以make一下看编译出错否?在这之前请自行配置好PATH环境变量!
编译命令: make mini2440_config
make ARCH=arm
No.2:
1.修改两个文件start.S和lowlevel_init.S,如何修改呢?请大家先看看这两个文件,看看具体的作用是什么,再想想怎么修改?
具体修改参考如下:
......
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) ||defined(CONFIG_S3C2440)
/* turn off the watchdog */思考:那么CONFIG_S3C2440在哪里定义呢?
#if defined(CONFIG_S3C2400)
#define pWTCON 0x15300000
#define INTMSK 0x14400008 /* Interupt-Controller base addresses */
#define CLKDIVN 0x14800014 /* clock divisor register */
#else //Q1:这里为什么不再分开defined 2440和2410呢?请查阅datasheet
#define pWTCON 0x53000000
#define INTMSK 0x4A000008 /* Interupt-Controller base addresses */
#define INTSUBMSK 0x4A00001C
#define CLKDIVN 0x4C000014 /* clock divisor register */
#endif
//Q2:以下宏的作用??请查阅datasheet
#define CLK_CTL_BASE 0x4C000000
#define MDIV_405 0x7F<<12
#define PSDIV_405 0x21
#define UPLL_MDIV_48 0x38<<12
#define UPLL_PSDIV_48 0x22
#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
ldr r0, =INTMSK
str r1, [r0]
#if defined(CONFIG_S3C2410)
ldr r1, =0x7ff
ldr r0, =INTSUBMSK
str r1, [r0]
#endif
#if defined(CONFIG_S3C2440)
ldr r1, =0x7ff
ldr r0, =INTSUBMSK
str r1, [r0]
# endif
#if defined(CONFIG_S3C2440)
/*FCLK:HCLK:PCLK=1:4:8*/
ldr r0,=CLKDIVN
mov r1,#5
str r1,[r0]
/*MMU_SetAsyncBusMode*/
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,#UPLL_MDIV_48
add r2,r2,#UPLL_PSDIV_48
str r2,[r1,#0x08]
mov r2,#MDIV_405
add r2,r2,#PSDIV_405
str r2,[r1,#0x04]
#else
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
/* 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 ||CONFIG_S3C2440 */
A1:查阅以下寄存器的地址2410和2440是一样的,所以没有必要再分开了
A2:请自行研究datasheet中clock一章
2.对汇编文件lowlevel_init.S的修改:请根据外设连接来设置,想查看datasheet第五章存储映射图,看看mini2440外设是如何和各个bank对应的?也请先看看该文件,看看具体做了些什么工作?
参考修改:
#define B4_BWSCON (DW16 + WAIT + UBLB)
/*by jacke_wang,--------------*/
//#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 B4_Tacs 0x0 /* 0clk */
#define B4_Tcos 0x3 /* 4clk */
#define B4_Tacc 0x7 /* 14clk */
#define B4_Tcoh 0x1 /* 1clk */
#define B4_Tah 0x3 /* 4clk */
#define B4_Tacp 0x6
#define B4_PMC 0x0 /* normal */
修改原因:参考数据手册和原理图,bank4映射的什么外设?
/* 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 */
//#define REFCNT 1113 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
/**************************************/
#if defined(CONFIG_S3C2440) 找到这个宏在哪里定义了吗?
#define Trp 0x2 /*4clk*/
#define REFCNT 1012 /**/
#else
#define Trp 0x0
#define REFCNT 0x0459
#endif
Tips:两个汇编初始化文件完成后,进入c语言第一个入口函数是start_armboot.,在/lib_arm/board.c中定义.
3.在最重要的mini2440.h文件中添加相关配置宏
参考配置:
/*
* High Level Configuration Options
* (easy to change)
*/
#define CONFIG_ARM920T 1 /* This is an ARM920T Core */
#define CONFIG_S3C2440 1 /* in a SAMSUNG S3C2440 SoC */
#define CONFIG_MINI2440 1 /* on a SAMSUNG MINI2440 Board */
/*原来CONFIG_S3C2440在这里定义的*/
/*
* Hardware drivers
*/
//#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 */
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_USE_16BIT 1
#define CONFIG_DM9000_BASE 0x20000300(为什么是这个地址?请参考原理图)
#define DM9000_IO 0x20000300
#define DM9000_DATA 0x20000304
/*添加一些配置命令*/
#define CONFIG_CMD_CACHE
#define CONFIG_CMD_DATE
#define CONFIG_CMD_ELF
#define CONFIG_CMD_PING
#define CONFIG_CMD_FLASH
#define CONFIG_CMD_ENV
/*这几个宏表示bootloader可以向内核传递启动参数,是需要的*/
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_INITRD_TAG
#define CONFIG_CMDLINE_TAG
/*mini2440中nor flash 芯片为 SST39vf1601,所以还需要注释掉LV400和LV800
*相关的宏定义,请自行修改,对于nor flash芯片的擦写,我们需要还修改文件
*/board/mini2440/flash.c
*/
#define CONFIG_SST_39VF1601 1
#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
#ifdef CONFIG_SST_39VF1601
#define PHYS_FLASH_SIZE 0x200000 /*2MB*/
#define CFG_MAX_FLASH_SECT (512)
#define CONFIG_ENV_ADDR ((CFG_FLASH_BASE + 0x40000))
#define SST_MANUTACT 0x00BF00BF
#define SST_ID_xF1601 0x234B234B
#endif
/*env set*/
#define CONFIG_ENV_IS_IN_FLASH 1
#define CONFIG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
#define FLASH_SECTOR_SIZE 0x1000
#define CONFIG_ENV_OFFSET 0x40000
4.修改/board/mini2440/flash.c,以便查看nor芯片ID信息时输出对应信息!(这里没有修改读写函数)
........
#if defined(CONFIG_AMD_LV400)
(AMD_MANUFACT & FLASH_VENDMASK) |
(AMD_ID_LV400B & FLASH_TYPEMASK);
#endif
/**add by jacke_wang*/
#if defined(CONFIG_SST_39VF1601)
(SST_MANUTACT & FLASH_VENDMASK) |
(SST_ID_xF1601 & FLASH_TYPEMASK);
/*------------------*/
#endif
#if defined(CONFIG_AMD_LV800)
(AMD_MANUFACT & FLASH_VENDMASK) |
(AMD_ID_LV800B & FLASH_TYPEMASK);
#endif
.............
case (AMD_ID_LV800B & FLASH_TYPEMASK):
printf ("1x Amd29LV800BB (8Mbit)\n");
break;
case (SST_ID_xF1601 & FLASH_TYPEMASK):
printf("1x SST39VF1601 (16MBIT) ^_^ \n");
break;
default:
printf ("Unknown Chip Type\n");
goto Done;
break;
5.添加上CONFIG_S3C2440宏和CONFIG_MINI2440后,有些相应文件由于本身代码就有宏定义的规范,所以现在会报错,因为找不到相关代码了。所以我们必须在相应由CONFIG_S3C2410和CONFIG_SMDK2410的地方再添加上CONFIG_S3C2440和CONFIG_MINI2440使得某些函数原型代码得以编译。
① 执行完前三步的修改后,出现的第一个错误是说找不到gpio中的各种成员,大家想想怎么解决呢?用source insight 搜索该结构后,找到定义的地方,发现了什么没有?
修改/include/s3c24x0.h中的412行,大家看看怎么修改?
本文件还要注意添加一个东西:
#if defined(CONFIG_S3C2440)
S3C24X0_REG32 CAMDIVN;
后面计算PLLCLK,HCLK要用到,2440才有,2410没有,查阅数据手册
② 依次修改以下文件中相关宏定义
/include/common.h /cpu/arm920t/s3c24x0/I2c.c
/cpu/arm920t/s3c24x0/interrupts.c
/cpu/arm920t/s3c24x0/serial.c
/cpu/arm920t/s3c24x0/speed.c
/driver/usb/usb_ohci.c
/cpu/arm920t/s3c24x0/usb.c
/cpu/arm920t/s3c24x0/usb_ohci.c
/board/mini2440/mini2440.c(请自行修改)
其中speed.c中的
get_pllclk函数中:
S3C24X0_CLOCK_POWER
* constclk_power = S3C24X0_GetBase_CLOCK_POWER();
#if defined(CONFIG_S3C2440)
if(pllreg==MPLL)
return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s));
else if(pllreg==UPLL)
return((CONFIG_SYS_CLK_FREQ * m) / (p << s));
#endif
get_hclk函数中:
#if defined(CONFIG_S3C2440)
if(clk_power->CLKDIVN & 0x6)
{
if((clk_power->CLKDIVN & 0x6)==2)
return(get_FCLK()/2);
if((clk_power->CLKDIVN & 0x6)==6)
return((clk_power->CAMDIVN & 0x100)?get_FCLK()/6:get_FCLK()/3);
if((clk_power->CLKDIVN & 0x6)==4)
return((clk_power->CAMDIVN & 0x200)?get_FCLK()/8:get_FCLK()/4);
return(get_FCLK());
}
else
return(get_FCLK());
#else
return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
#endif
具体参考datasheet中clock一章中的计算方法
其中mini2440.c中的宏修改与2410也有所不同,所以参考修改如下:
#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 */
#if defined(CONFIG_S3C2410)
#define M_MDIV 0xA1
#define M_PDIV 0x3
#define M_SDIV 0x1
#endif
#if defined(CONFIG_S3C2440)
#define M_MDIV 0x7f
#define M_PDIV 0x2
#define M_SDIV 0x1
#endif
#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
#if defined(CONFIG_S3C2410)
#define U_M_MDIV 0x48
#define U_M_PDIV 0x3
#define U_M_SDIV 0x2
#endif
#if defined(CONFIG_S3C2440)
#define U_M_MDIV 0x38
#define U_M_PDIV 0x2
#define U_M_SDIV 0x2
#endif
#endif
到此结束,请大家重新make 编译。
No 3.
到此针对nor的移植基本完成,带有网络功能,大家可以用H-JTAG烧写看看效果如何呢?
未完成:由于没有修改flash的读写擦出函数,不能使用saveenv命令(大家可以思考怎么修改?欢迎联系:(QQ)736992499)
注意的问题:由于本uboot启动的内核是友善自带的2.6.29内核,对应的MINI2440的ID号是1999,所以在uboot中传递的ID号也应该是1999,在文件/board/mini2440/mini2440.c中修改
/* arch number of MINI2440-Board */
gd->bd->bi_arch_number = MACH_TYPE_MINI2440; //1999,宏定义在include/asm-arm/mach- types.h中 请自行定义好!
输出效果如下:

|