Davinci DM6446开发攻略――u-boot-1.3.4移植(1)

   

UBOOT 的版本更新速度比较快,截止今天,稳定正式的版本是 u-boot-2009.11-rc2 ,而 TI 最新的 EVM 开发包里的 UBOOT 1.2.0 版本,国内很多公司还一直使用 u-boot-1.1.4 u-boot-1.1.6 。其实,我们也没必要追风跟上最新版本,程序跑稳定才是最重要的。当然,有兴趣研究研究也不错,毕竟最新版本增加很多实用的功能。在移植之前,我们简单介绍 u-boot 这些版本架构的变化。从 u-boot-1.3.0 u-boot-1.3.2 基本上架构是一样的,而从 u-boot-1.3.3 u-boot-1.3.4 ,架构相对 u-boot-1.3.2 变化比较大。从 u-boot-2008.10 开始, nand flash 驱动变化非常大, u-boot-2009.03 增加强大的 lzma 压缩解压功能, fs 支持 yaffs2 u-boot-2009.06  nand flash 变化更大。到 u-boot-2009.11.1 增加 DM6467 DM365 的支持。
关于 u-boot-1.3.4 的移植,本人的博客也介绍在三星 s3c2440 上移植过,我们在这里主要针对 davinci 平台。由于 UBOOT 功能很多,要全部把移植的东西立刻写出来,对本人还是有难度,所以中间会先发布有关 montavista linux-2.6.18 的移植,如何把 DSP 程序先跑起来,等等。由于本人的主要工作是开发产品,卖卖 DM6446 核心板、 DM6437 核心板,及相关开发板,智能视频监控 IVR ,推推 DSP 方案,所以博客更新速度比较慢,其实写博客的目的,有很大的部分就是想和全国各地朋友交流技术。 同时这里要感谢 51CTO 的小松管理员,把本人的开发攻略改为推荐博文。 回到移植正题,我们一步一步把 UBOOT 跑起来,把内核也跑起来。鉴于学习的目的,本人这里不提供 patch
 
第一步:解压和简化 UBOOT
 
ftp.denx.de 下载 u-boot-1.3.4.tar.bz2 u-boot-1.3.4-rc2.tar.bz2 ,然后解压到你的工作目录,很多人解压完后, 就马上进入正题,修改makefile什么的,本人觉得不用那么急。首先删除和平台不相关的文件和文件夹,目的让UBOOT更简化,好理解,减少虚拟机的存储空间,便于备份(每次有进展的修改后,备份和修改记录很重要,这是良好习惯):
在顶层目录:把文件 avr32_config.mk blackfin_config.mk i386_config.mk m68k_config.mk microblaze_config.mk mips_config.mk nios2_config.mk nios_config.mk ppc_config.mk sh_config.mk sparc_config.mk 删除;文件夹 lib_avr32 lib_blackfin lib_i386 lib_m68k lib_microblaze lib_mips lib_nios lib_nios2 lib_ppc lib_sh lib_sparc nand_spl onenand_ipl ,其他就不要删了。
board 目录下:只保留 davinci 文件夹,其他平台板子全部干掉!男人就要狠一点。而 davinci 也只保留 TI 自己的 dv-evm 文件夹,这也是我们要修改的平台, schmoogie sffsdr sonata 是其他公司基于 davinci 上的板子,你可以删掉,也可以参考。当然,还是在 board\davinci 目录下,你可以 COPY dv-evm 并改成你公司的板子的名字,然后在顶层修改 makefile 支持你公司的板子,下一步再说。
cpu 的目录:只保留 arm926ejs ,其他 CPU 全部干掉。进入 arm926ejs 目录,同时把 at91sam9 omap versatile 文件夹删除,保留 davinci 和其他文件。
include 目录:把文件夹 asm-avr32 asm-blackfin asm-i386 asm-m68k asm-microblaze asm-mips asm-nios asm-nios2 asm-ppc asm-sh asm-sparc 删除掉。进入 configs 目录,只保留 davinci_dvevm.h ,其他 *.h 文件全部删除调!
做完以上的工作后, UBOOT 相当简洁,其实还有一些文件和文件可以再删,不过已经没必要,我们删除的对象是其他不相关的平台。备份一下这个源版本,便于日后自己修改的 UBOOT 和这个源版本比较。
 
第二步:链接交叉编译环境
 
如果你已经看过本人有关《 DAVINCI DM6446 开发攻略——环境搭建篇》,按里边描述的方法,对交叉编译环境进行搭建,那么下面编译工作就好进行了。
修改顶层makefile
144行:把CROSS_COMPILE = arm-linux-改为CROSS_COMPILE = arm_v5t_le-
 
282行:把ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND) $(U_BOOT_ONENAND),改为ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND) $(U_BOOT_ONENAND) u-boot.img,就是后面添加u-boot.img
 
308行:./tools/mkimage -A $(ARCH) -T firmware -C none \后面,添加和注销以下代码:
    -a 0x$(shell grep "T _start" $(TOPDIR)/System.map | awk '{ printf "%s", $$1 }') \
    -e 0x$(shell grep "T _start" $(TOPDIR)/System.map | awk '{ printf "%s", $$1 }') \
    -n 'u-boot image' -d $< $@
#       -a $(TEXT_BASE) -e 0 \
#       -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
#          sed -e 's/"[  ]*$$/ for $(BOARD) board"/') \
#       -d $< $@
(注意要加tab键)
这里这样做的目的,生成的u-boot.img可以被上篇介绍的UBLBOOT起来,而u-boot.bin可以被TI提供的uart_load.exe uartapp.bin 软件方式(soft boot)启动起来,便于生产和测试。
 
在源makefile文件2416行:就是davinci_dvevm_config :    unconfig
    @$(MKCONFIG) $(@:_config=) arm arm926ejs dv-evm davinci davinci
根据这一行,你可以参考TI 这个做法定义自己的板子,添加自己板子的config,比如加入:
davinci_dm6446_config : unconfig
    @$(MKCONFIG) $(@:_config=) arm arm926ejs dm6446 davinci davinci
然后在board\davinci目录下, 使用
mkdir dm6446
cp –f dv-evm/* dm6446/
同时进入include/configs/目录,使用cp –f davinci_dvevm.h davinci_dm6446.h
注:其实直接在TI  dv-evm上移植也可以,没必要定义自己的板子和配置。这里只不过给大家举个例子。
编译工作:
$make distclean
$make davinci_dm6446_config
$make
看是否编译全部通过,是否生成u-boot.binu-boot.img等文件,同时检查你的交叉编译环境是否建立好,没问题继续往下进行。
 
第三步:移植板子驱动和配置
1、  修改davinci_dm6446.h
首先说说本人板子的信息:DDR2 —— 256M-Byte NAND —— 128M-Byte —— 2K Page 通用网口 PHY 芯片,没有 NOR FLASH ATA
/*=======*/
/* Board */
/*=======*/
#define DV_EVM
#define CFG_USE_NAND (支持NAND
#define CFG_NAND_LARGEPAGE (支持2K Page NAND
//#define CFG_NAND_SMALLPAGE (表示支持 512 字节 Page
//#define CFG_USE_NOR (表示支持 NOR FLASH
 
。。。。。。。
/*===================*/
/* SoC Configuration */
/*===================*/
#define CONFIG_ARM926EJS                   /* arm926ejs CPU core */
#define CONFIG_SYS_CLK_FREQ     297000000     /* Arm Clock frequency */
#define CFG_TIMERBASE          0x01c21400    /* use timer 0 */
#define CFG_HZ_CLOCK            27000000       /* Timer Input clock freq */
#define CFG_HZ                   1000
#define CONFIG_SOC_DM644X   SOC DM644X
 
/*====================================================*/
/* EEPROM definitions for Atmel 24C256BN SEEPROM chip */
/* on Sonata/DV_EVM board. No EEPROM on schmoogie.    */
/*====================================================*/
//#define CFG_I2C_EEPROM_ADDR_LEN            2
//#define CFG_I2C_EEPROM_ADDR              0x50
//#define CFG_EEPROM_PAGE_WRITE_BITS      6
//#define CFG_EEPROM_PAGE_WRITE_DELAY_MS  20
(如果你的板子没有 I2C 接口的 EEPROM ,把上面的代码注释掉)
 
/*=============*/
/* Memory Info */
/*=============*/
#define CFG_MALLOC_LEN              (0x10000 + 128*1024)  /* malloc() len */
#define CFG_GBL_DATA_SIZE    128         /* reserved for initial data */
#define CFG_MEMTEST_START  0x80000000    /* memtest start address */
#define CFG_MEMTEST_END            0x81000000    /* 16MB RAM test */
#define CONFIG_NR_DRAM_BANKS 1            /* we have 1 bank of DRAM */
#define CONFIG_STACKSIZE     (256*1024)     /* regular stack */
#define PHYS_SDRAM_1           0x80000000    /* DDR Start */
#define PHYS_SDRAM_1_SIZE 0x10000000    /* DDR size 256MB */
#define DDR_8BANKS                      /* 8-bank DDR2 (256MB) */
有关 DDR Memory 这里不需要修改,因为本人的板子是 256M 的。除非你的板子是 128M 才改为: SIZE     0x08000000 DDR_4BANKS
 
/*====================*/
/* Serial Driver info */
/*====================*/
串口驱动不用改。
 
/*===================*/
/* I2C Configuration */
/*===================*/
I2C 驱动可以不用改。也可以注释掉,如果你不想在 UBOOT 操作任何 I2C 的动作。
 
/*==================================*/
/* Network & Ethernet Configuration */
/*==================================*/
网络配置也不需要修改
 
/*=====================*/
/* Flash & Environment */
/*=====================*/
由于最开始我们已经定义好 CFG_USE_NAND CFG_NAND_LARGEPAGE 的信息,所以这里也不需要修改;
 
/*==============================*/
/* U-Boot general configuration */
/*==============================*/
这里主要定义 UBOOT 的一些操作,比如命令行显示字符串, delay 等待时间的长短,这些根据个人要求修改,不改也可以。
 
/*===================*/
/* Linux Information */
/*===================*/
UBOOT 要把一些参数信息传给内核 linux 使用, linux 内核运行的时候需要这些配置信息,内核能够识别这些字符串信息。先把以下两个定义注释掉,
//#define CONFIG_BOOTARGS           xxxxxxxxxxxxxx
//#define CONFIG_BOOTCOMMAND     xxxxxxxxxxxxxxx
如果你要从 NAND FLASH 启动:
#define CONFIG_BOOTARGS “mem=120M console=ttyS0,115200n8 noinitrd ip=off root=/dev/mtdblock3” mtdblock3 表示文件系统放在 LINUX 内核分区)
#define CONFIG_BOOTCOMMAND   " nboot 0x80008000 0x700000" (把 linux 内核从 FLASH BOOT 起来,下面会介绍 UBOOT 的命令)
如果你还在调试阶段,建议你使用 NFS 文件系统:
#define CONFIG_BOOTARGS “mem=120M console=ttyS0,115200n8 noinitrd rw ip=dhcp root=/dev/nfs nfsroot=192.168.1.251:/home/<useraccount>/nfs/tirootfs,nolock”
#define CONFIG_BOOTCOMMAND   " nboot 0x80008000 0x700000"
 
本人的 redhat linux 的主机地址是: 192.168.1.251 ,即 SERVER IP=192.168.1.251
板子的 IP 是: 192.168.1.188
如果你没有路由器给你分配 IP 地址,参数行里使用: ip=off
mem=120M :本人定义前 128M linux 系统 , 128M DSP 和图像缓冲区等;
nboot 0x80008000 0x700000:讲明本人把内核放在nand 地址为0x700000,通过nand boot的命令把内核从nand 0x700000地址导入DDR 0x80008000地址
 
/*=================*/
/* U-Boot commands */
/*=================*/
这里有很多功能的定义,包括 #include <config_cmd_default.h> 里边定义的,不需要的功能可以使用 #undef ,从而减小 UBOOT 生成 BIN 文件的尺寸。比如
#undef CONFIG_CMD_DHCP
#undef CONFIG_CMD_DIAG
#undef CONFIG_CMD_EEPROM
#undef CONFIG_CMD_LOADB   /* loadb */
#undef CONFIG_CMD_LOADS    /* loads */
 
2、  修改board/davinci/dv-evm/dv_board.c里的有关自己板子的配置
int board_init(void)函数里,因为本人的板子使用/EM_CS2作为NAND FLASH的片选信号,故在PINMUX0寄存器里,有关AEAW必须关掉。
/* Enable EMAC and AEMIF pins */
//REG(PINMUX0) = 0x80000c1f;
REG(PINMUX0) = 0x80000000; 只使用 EMAC
否则UBOOT 启动不起来。
 
int misc_init_r (void)函数里,因为本人没有使用I2C EEPROM存储MAC 地址,所以要注释掉
#if 0
/* Set Ethernet MAC address from EEPROM */
if (i2c_read(CFG_I2C_EEPROM_ADDR, 0x7f00, CFG_I2C_EEPROM_ADDR_LEN, buf, 6)) {
     printf("\nEEPROM @ 0x%02x read FAILED!!!\n", CFG_I2C_EEPROM_ADDR);
}
else
    {
     tmp[0] = 0xff;
     for (i = 0; i < 6; i++)
         tmp[0] &= buf[i];
 
     if ((tmp[0] != 0xff) && (getenv("ethaddr") == NULL)) {
         sprintf((char *)&tmp[0], "%02x:%02x:%02x:%02x:%02x:%02x",
             buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
         setenv("ethaddr", (char *)&tmp[0]);
     }
}
#endif
一般MAC地址保存到NAND,降低成本。
………
#if 0
i2c_read (0x39, 0x00, 1, (u_int8_t *)&i, 1);
setenv ("videostd", ((i  & 0x80) ? "pal" : "ntsc"));
#endif
如果你的板子没有 TI 的视频采集芯片 TVP5146 之类的,上面的功能最好去掉。
 
3、  网口驱动移植:Cpu/arm926ejs/davinci/ ether.c
因为 DM6446 芯片上集成 EMAC MDIO ,所以直接使用 PHY 芯片就可以了,驱动就使用 UBOOT-1.3.4 TI 默认的驱动,而不是 TI EVM 使用的 PHY_LXT972 。直接使用 GENERIC PHY ,有个地方需要修改,否则网口工作不起来,本人也是从一个网友那里查到类似的信息,在 static int dm644x_eth_phy_detect(void) 函数里,改成:
#if 0
for (i = 0; i < 32; i++) {
        if (phy_act_state & (1 << i)) {
               if (phy_act_state & ~(1 << i))
                      return(0);              /* More than one PHY */
               else {
                      active_phy_addr = i;
                      return(1);
               }
        }
}
 
return(0);       /* Just to make GCC happy */
#else
active_phy_addr = 1;
return(1);
#endif
由于本人的开发板使用 GPIO PHY 芯片进行复位,所以在 static int dm644x_eth_hw_init(void) 函数里,加入 GPIO 复位的支持,同时文件头部加入 #include <asm/arch/hardware.h>
可以说, UBOOT 移植到这里,基本上可以跑起网络了, TFTP 应该没问题了,但是有关如何烧写 UBL ,烧写 UBOOT LINUX 内核等文件,以后再慢慢聊吧,一步一步来,《 UBOOT 移植( 2 )》以后会推出来,下一篇直接到 MonaVista linux-2.6.18 的移植( 1 ),先让系统通过网络和串口跑起来,由简单到复杂。
继续 make 一下,生成 u-boot.bin u-boot.img COPY u-boot.bin WINDOWS 底下,使用 uart_load.exe 和配套 uart.bin 文件,就可以把 u-boot.bin 给跑起来。如果有 linux 内核编译出来并使用 UBOOT tool 目录下的 mkimage 工具生成 uImage ,在 UBOOT 命令行下:
U-Boot > tftp 80008000 uImage
#######################################
U-Boot > bootm 80008000
## Booting kernel from Legacy Image at 80008000 ...
   Image Name:   linux-2.6.18
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    1509948 Bytes =  1.4 MB
   Load Address: 80008000
   Entry Point:  80008040
   Verifying Checksum ... OK
   XIP Kernel Image ... OK
OK
 
Starting kernel ...
 
Uncompressing Linux...................................................................................................... done, booting the kernel.
Linux version 2.6.18_pro500-davinci_evm-arm_v5t_le ([email protected]) (gcc version 4.2.0 (MontaVista 4.2.0-16.0.32.0801914 2008-08-30)) #1 PREEMPT Sun Mar 7 01:07:16 CST 2010
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
Machine: DaVinci EVM
……………………………………………………………
当出现上面的信息后,说明以上u-boot-1.3.4 的移植是成功的。有兴趣的朋友可以参考以上做法移植u-boot-2009.11-rc2,也可以跑起来,只不过CROSS_COMPILE ?= arm-linux-不是放在顶层makefile了,而是放在lib_arm/config.mk里,改成CROSS_COMPILE = arm_v5t_le-就可以编译了。  
 

 

Davinci DM6446开发攻略――u-boot-1.3.4移植(1)_第1张图片

 

 

补充有关 DM6446 BOOT 的一点知识:如果板子没有任何程序, RBL 会通过串口 0 发送 BOOTME 命令上来,运行 uart_load.exe ,会接到 RBL 的命令,然后握手通信,下载 uart.bin 到板子上,并运行起来, uart.bin 程序就是小小的 BOOT ,通过串口 0 PC 通信,下载 u-boot.bin ,并把 u-boot.bin 给运行起来。所以 UBOOT 移植到上面的步骤,可以进入 linux 内核移植的工作了。

你可能感兴趣的:(开发,休闲,攻略,Davinci,U-boot移植)