一、编写目的
本文档用于记录移植U-BOOT-2.14.07到MICRO 2440开发板的过程。方便日后工作、学习中查阅/参考相关设置方法。
U-BOOT移植部分参考“u-boot-2014.04移植手册(TQ2440)”。
二、U-BOOT移植
所有版本的u-boot源代码压缩包都可以在ftp://ftp.denx.de/pub/u-boot/下载。关于u-boot源代码的信息,看http://www.denx.de/wiki/U-Boot/SourceCode。本文档使用的u-boot源码为当前最新版本u-boot-2014.07.tar.bz2(网盘:http://pan.baidu.com/s/1gdJ0u3p)。
1. 解压源码
为了适应更多的CPU,U-BOOT的源码目录结构会越来越复杂,本文档只针对MICRO 2440开发板进行开发,该开发板使用的CPU为三星的S3C2440(arm920t)。
解压U-BOOT源码到工作目录
# tar -xvf /media/sf_ShareDIR/MICRO2440/source/u-boot-2014.07.tar.bz2 -C ./
# cd ./u-boot-2014.07/
2. 建立MICR02440开发板配置
a) 建立board下的micro2440目录
#cp ./board/samsung/smdk2410/ ./board/samsung/micro2440 -rf
#mv ./board/samsung/micro2440/smdk2410.c ./board/samsung/micro2440/micro2440.c
b) 修改micro2440下的Makefile文件
# vim ./board/samsung/micro2440/Makefile
c) 建立include/configs下的micro2440配置文件
# cp include/configs/smdk2410.h include/configs/micro2440.h
d) 修改U-BOOT配置文件
# vim include/configs/micro2440.h
#define CONFIG_SYS_PROMPT "MICRO2440 # "
e) 修改顶层vim boards.cfg,增加开发板配置(旧版本UBOOT在MAKEFILE配置)
# vim boards.cfg
3. 时钟初始化
a) 修改start.S中时钟初始化代码
# vim ./arch/arm/cpu/arm920t/start.S
# if defined(CONFIG_S3C2410) ldr r1, =0x3ff ldr r0, =INTSUBMSK str r1, [r0] # endif
#if defined(CONFIG_S3C2440) ldr r1, =0x7fff ldr r0, =INTSUBMSK str r1, [r0] #endif /*CONFIG_S3C2440*/
#if defined(CONFIG_S3C2440) #define MPLLCON 0x4C000004 #define UPLLCON 0x4C000008 #define CAMDIVN 0x4C000018 ldr r0, =CAMDIVN mov r1, #0 str r1, [r0] ldr r0, =CLKDIVN mov r1, #0x05 str r1, [r0] mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #0xc0000000 mcr p15, 0, r0, c1, c0, 0 ldr r0, =UPLLCON ldr r1, =0x38022 str r1, [r0] /* ** When you set MPLL&UPLL values,you have to set the UPLL ** value first and then the MPLL value.(Needs intervals ** approximately 7 NOP) */ nop nop nop nop nop nop nop ldr r0, =MPLLCON ldr r1, =0x5c011 str r1, [r0] #else /* FCLK:HCLK:PCLK = 1:2:4 */ /* default FCLK is 120 MHz ! */ ldr r0, =CLKDIVN mov r1, #3 str r1, [r0] #endif /* CONFIG_S3C2440 */
#endif /* CONFIG_S3C24X0 */ |
b) 屏蔽micro2440.c时钟初始化代码
在上一步中修改start.S的时候,已经增加了时钟初始化的代码。因此需要屏蔽掉micro2440.c文件下的时钟初始化代码。
# vim board/samsung/micro2440/micro2440.c
int board_early_init_f(void) { // struct s3c24x0_clock_power * const clk_power = // s3c24x0_get_base_clock_power(); struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
#if 0 /* 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);
/* some delay between MPLL and UPLL */ pll_delay(4000);
/* configure UPLL */ writel((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV, &clk_power->upllcon);
/* some delay between MPLL and UPLL */ pll_delay(8000); #endif
/* set up the I/O ports */ writel(0x007FFFFF, &gpio->gpacon); writel(0x00044555, &gpio->gpbcon); |
4. 编译并下载至于RAM运行
a) 由于需要通过DNW(参考MICRO2440用户手册)下载UBOOT到SDRAM上运行,因此需要先去掉底层初始化相关的代码,如SDRAM、NAND初始化的代码,通过定义CONFIG_SKIP_LOWLEVEL_INIT宏即可。另外需要设置CONFIG_SYS_TEXT_BASE为0x32000000,通过DNW下载BIN文件到这个地址运行。
# vim include/configs/micro2440.h
#define CONFIG_SYS_TEXT_BASE 0x32000000
#define CONFIG_SKIP_LOWLEVEL_INIT
b) 屏蔽U-BOOT中暂时未用到的功能(如果不屏蔽,将编译不过)
# vim include/configs/micro2440.h
(1) #if 0 #define CONFIG_CS8900 /* we have a CS8900 on-board */ #define CONFIG_CS8900_BASE 0x19000300 #define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as shorts */ #endif
(2) #if 0 #define CONFIG_USB_OHCI #define CONFIG_USB_OHCI_S3C24XX #define CONFIG_USB_KEYBOARD #define CONFIG_USB_STORAGE #define CONFIG_DOS_PARTITION #endif
(3) #if 0 #define CONFIG_CMD_DHCP #define CONFIG_CMD_ELF #define CONFIG_CMD_NAND #define CONFIG_CMD_PING #define CONFIG_CMD_REGINFO #define CONFIG_CMD_USB #endif
(4) #if 0 #define CONFIG_CMD_FAT #define CONFIG_CMD_EXT2 #define CONFIG_CMD_UBI #define CONFIG_CMD_UBIFS #define CONFIG_CMD_MTDPARTS #define CONFIG_MTD_DEVICE #define CONFIG_MTD_PARTITIONS #define CONFIG_YAFFS2 #define CONFIG_RBTREE #endif |
c) 编译
# make micro2440_config
# make ARCH=arm CROSS_COMPILE=arm-linux-
d) 运行
设置开发板从NOR启动,使用友善之臂提供的DNW(FriendlyARM BIOS 2.0 for 2440的d选项)下载生成的u-boot.bin文件至RAM中运行。运行结果如下图所示,可以正常输出,但无法初始化FLASH,是因为还没移植好NOR FLASH的驱动。
5. 移植NOR FLASH
MICRO 2440开发板使用的NOR FLASH型号为SST39VF1601。因此需要为U-BOOT增加对NOR的支持。在u-boot中添加对Nor flash的支持比较简单,大多数Nor flash都支持CFI接口,而u-boot有对cfi flash的驱动支持。对于SSTVF1601,并不支持标准的CFI接口,所以得使用JEDEC接口。但jedec_flash.c中并没有SSTVF1601的配置信息,所以得手动添加上。
a) 修改jedec_table结构体,增加对SST39VF1601的支持
#ifdef CONFIG_SYS_FLASH_LEGACY_1024Kx16 { /* MICRO2440 SST39VF1601 */ .mfr_id = (u16)SST_MANUFACT, .dev_id = SST39VF1601, .name = "SST39VF1601", .uaddr = { [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */ }, .DevSize = SIZE_2MiB, .CmdSet = P_ID_AMD_STD, .NumEraseRegions= 4, .regions = { ERASEINFO(0x1000,96), ERASEINFO(0x1000,160), ERASEINFO(0x1000,240), ERASEINFO(0x1000,16), } } #endif |
# vim ./drivers/mtd/jedec_flash.c
b) 修改开发板的NOR配置为CONFIG_SYS_FLASH_LEGACY_1024Kx16
# vim include/configs/micro2440.h
#define CONFIG_SYS_FLASH_LEGACY_1024Kx16
#define CONFIG_SYS_MAX_FLASH_SECT (512)
c) 重新编译并下载至RAM中运行
如下图所示,已经可以正常识别NOR FLASH。
d) 测试FLASH读写命令
Ø 解锁FLASH
# protect off all
Ø 格式化FLASH
# erase 0 +200000
Ø 复制数据至FLASH中
# cp.b 32000000 0 200000
Ø 比较数据
# cmp.b 0 32000000 200000
注意:经过上面几个测试后,FLASH的数据已经是混乱的,因此已无法通过NOR启动SUPERVIVI了,需要使用J-LINK重新烧写SUPERVIVI-128MB。
6. 移植DM9000网卡
a) 屏蔽原有网卡配置,这一步在前面已经修改过的
# vim include/configs/micro2440.h
#if 0 #define CONFIG_CS8900 /* we have a CS8900 on-board */ #define CONFIG_CS8900_BASE 0x19000300 #define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as shorts */ #endif |
b) 增加DM9000网卡配置
# vim include/configs/micro2440.h
#define CONFIG_DRIVER_DM9000 #define CONFIG_DM9000_BASE 0x20000300 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE + 4) #define CONFIG_DM9000_USE_16BIT |
c) 根据实际网络设置网络参数
# vim include/configs/micro2440.h
#define CONFIG_NETMASK 255.255.255.0 #define CONFIG_IPADDR 192.168.2.123 #define CONFIG_SERVERIP 192.168.2.222 #define CONFIG_ETHADDR 10:23:45:67:89:AB |
d) 修改网卡初始化函数
# vim ./board/samsung/micro2440/micro2440.c
int board_eth_init(bd_t *bis) { int rc = 0; #ifdef CONFIG_CS8900 rc = cs8900_initialize(0, CONFIG_CS8900_BASE); #endifi
#ifdef CONFIG_DRIVER_DM9000 rc = dm9000_initialize(bis); #endif return rc; } |
e) 打开PING命令,用于测试网络
# vim include/configs/micro2440.h
#define CONFIG_CMD_PING
f) 测试网络
重新编译后下载至RAM中运行,使用PING命令测试网络,测试结果如下图所示。
7. 移植NAND FLASH
MICRO 2440开发板使用的NAND FLASH为K9F2G08U0B,该FLASH为256MB大小,详细参数可参考相关DATASHEET。
a) 打开NAND命令(之前的步骤中屏蔽过)
# vim include/configs/micro2440.h
#define CONFIG_CMD_NAND
b) 增加S3C2440的NAND驱动文件
# cp drivers/mtd/nand/s3c2410_nand.c drivers/mtd/nand/s3c2440_nand.c
c) 将s3c2440_nand.c内所有的2410改成2440
# vim drivers/mtd/nand/s3c2440_nand.c
# 按esc键
# :%s/2410/2440/g
d) 修改Makefile,增加编译选项
# vim drivers/mtd/nand/Makefile
obj-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o
e) 修改配置文件
# vim include/configs/micro2440.h
/* * NAND configuration */ #ifdef CONFIG_CMD_NAND #ifdef CONFIG_S3C2440 #define CONFIG_NAND_S3C2440 #define CONFIG_SYS_S3C2440_NAND_HWECC #else #define CONFIG_NAND_S3C2410 #define CONFIG_SYS_S3C2410_NAND_HWECC #endif #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_SYS_NAND_BASE 0x4E000000 #endif |
f) 修改NAND驱动文件
# vim drivers/mtd/nand/s3c2440_nand.c
(1) #define S3C2440_NFCONF_nFCE (1<<1) #define S3C2440_NFCONF_TACLS(x) ((x)<<12) #define S3C2440_NFCONF_TWRPH0(x) ((x)<<8) #define S3C2440_NFCONF_TWRPH1(x) ((x)<<4)
#define S3C2440_ADDR_NALE 8 #define S3C2440_ADDR_NCLE 0xC
(2) twrph1 = CONFIG_S3C24XX_TWRPH1; #else tacls = 0; twrph0 = 1; twrph1 = 0; #endif
//cfg = S3C2440_NFCONF_EN; cfg |= S3C2440_NFCONF_TACLS(tacls); cfg |= S3C2440_NFCONF_TWRPH0(twrph0); cfg |= S3C2440_NFCONF_TWRPH1(twrph1); writel(cfg, &nand_reg->nfconf); writel((1<<4)|(1<<1)|(1<<0), &nand_reg->nfcont);
/* initialize nand_chip data structure */
(3) if (ctrl & NAND_CTRL_CHANGE) { ulong IO_ADDR_W = (ulong)nand;
if (!(ctrl & NAND_CLE)) IO_ADDR_W |= S3C2440_ADDR_NCLE; if (!(ctrl & NAND_ALE)) IO_ADDR_W |= S3C2440_ADDR_NALE; if (cmd == NAND_CMD_NONE) IO_ADDR_W= &nand->nfdata;
chip->IO_ADDR_W = (void *)IO_ADDR_W;
if (ctrl & NAND_NCE) writel(readl(&nand->nfcont) & ~(1 << 1), &nand->nfcont); else writel(readl(&nand->nfcont) | (1 << 1), &nand->nfcont); } |
g) 修改nand_base.c文件
# vim drivers/mtd/nand/nand_base.c
static void nand_select_chip(struct mtd_info *mtd, int chipnr) { struct nand_chip *chip = mtd->priv;
switch (chipnr) { case -1: chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE); break; case 0: chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_CTRL_CLE | NAND_CTRL_CHANGE); break; |
h) 测试NAND驱动
重新编译后下载至RAM中运行,使用PING命令测试网络,测试结果如下图所示。可以识别到NAND为256MB。
i) 测试NAND读写命令
Ø 格式化NAND
# nand erase.chip
Ø 将SDRAM的0x32000000地址的0xff字节数据写到NAND的0地址
# nand write 32000000 0 ff
Ø 从NAND的0 地址读0xff字节数据到SDRAM的0x31000000 地址
# nand read 31000000 0 ff
Ø 比较
# cmp.b 31000000 32000000 ff
8. 保存过程代码
目前U-BOOT已经可以通过FriendlyARM BIOS 2.0 for 2440下载到SDRAM运行,并可以对NOR、NAND、网络等进行操作,接下来需要增加支持NOR、NAND启动等功能。保存目前所有修改过的代码,并上传到网盘,方便接下来的修改进行。
# cd ..
# tar -jcvf 201407230222_u-boot-2014.07.tar.bz2 u-boot-2014.07/
网盘:http://pan.baidu.com/s/1bnxnQsn
9. NOR启动支持
a) 修改启动地址
# vim include/configs/micro2440.h
#define CONFIG_SYS_TEXT_BASE 0x00000000 |
b) 打开底层初始化(之前的步骤中屏蔽了)
# vim include/configs/micro2440.h
//#define CONFIG_SKIP_LOWLEVEL_INIT |
c) 修改内在初始化代码
根据HCLK设置SDRAM的刷新参数,主要是REFCNT寄存器,将其改为0x4f4。
# vim board/samsung/micro2440/lowlevel_init.S
#define REFCNT 0x4F4 |
d) 重新编译下载BIN文件至NOR中并启动
Ø 复制BIN文件到TFTP目录
# cp u-boot.bin /opt/TFTP_DIR/MICRO2440/
Ø 使用之前制作的U-BOOT将支持NOR启动的U-BOOT下载至NOR
通过FriendlyARM BIOS 2.0 for 2440下载之前的U-BOOT到SDRAM运行
Ø 通过FLASH操作命令将新的U-BOOT镜像下载至NOR FLASH中
# protect off all
# erase 0 +40000
# tftp 0x32000000 /MICRO2440/u-boot.bin
# cp.b 0x32000000 0x0 0x40000
Ø 重新上电,如下图所示,能正常从NOR中启动U-BOOT
10. 保存参数至NADN
a) 修改配置,设置参数保存位置
# vim include/configs/micro2440.h
#define CONFIG_SYS_MAX_FLASH_BANKS 1 #define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE } #define CONFIG_SYS_MAX_FLASH_SECT (512)
#if 0 #define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x070000) #define CONFIG_ENV_IS_IN_FLASH #define CONFIG_ENV_SIZE 0x10000 #endif
#define CONFIG_ENV_IS_IN_NAND #define CONFIG_ENV_OFFSET 0x40000 // 256K for u-boot #define CONFIG_ENV_SIZE 0x20000 // 128K for environment
/* allow to overwrite serial and ethaddr */ #define CONFIG_ENV_OVERWRITE |
b) 重新编译并测试
目前NOR上已经有了支持NOR启动的U-BOOT了,使用U-BOOT的命令可以将新编译的U-BOOT烧写至NOR中,接下来烧写U-BOOT都使用这种方法,不再使用SDRAM运行的方法。同时也可以使用J-LINK将U-BOOT烧写至NOR中。
Ø 编译
# make ARCH=arm CROSS_COMPILE=arm-linux-
# cp u-boot.bin /opt/TFTP_DIR/MICRO2440/
Ø 下载
# protect off all
# erase 0 +40000
# tftp 0x32000000 /MICRO2440/u-boot.bin
# cp.b 0x32000000 0x0 0x40000
Ø 重新上电,并使用setenv、saveenv指令测试
11. 保存过程代码
目前U-BOOT已经可以在NOR上运行,并将参数存储于NAND中,接下来需要增加支持NAND启动等功能。保存目前所有修改过的代码,并上传到网盘,方便接下来的修改进行。
# cd ..
# tar -jcvf 201407231832_u-boot-2014.07.tar.bz2 u-boot-2014.07/
网盘:http://pan.baidu.com/s/1c0q0lTu
12. 建立NAND分区
13. 支持NAND FLASH启动