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方案,所以博客更新速度比较慢,其实写博客的目的,有很大的部分就是想和全国各地朋友交流技术。<b>同时这里要感谢</b><b>51cto</b><b>的小松管理员,把本人的开发攻略改为推荐博文。</b>回到移植正题,我们一步一步把uboot跑起来,把内核也跑起来。鉴于学习的目的,本人这里不提供patch。
<b>第一步:解压和简化</b><b>uboot</b>
<b>第二步:链接交叉编译环境</b><b></b>
如果你已经看过本人有关《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) <b>u-boot.img</b>,就是后面添加u-boot.img 在308行:./tools/mkimage -a $(arch) -t firmware -c none \后面,添加和注销以下代码: <b> -a 0x$(shell grep "t _start" $(topdir)/system.map | awk '{ printf "%s", $$1 }') \</b> <b> -e 0x$(shell grep "t _start" $(topdir)/system.map | awk '{ printf "%s", $$1 }') \</b> <b> -n 'u-boot image' -d $< $@</b> <b># -a $(text_base) -e 0 \</b> <b># -n $(shell sed -n -e 's/.*u_boot_version//p' $(version_file) | \</b> <b># sed -e 's/"[ ]*$$/ for $(board) board"/') \</b> <b># -d $< $@</b> (注意要加tab键) 这里这样做的目的,生成的u-boot.img可以被上篇介绍的ubl给boot起来,而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 <b>注:其实直接在ti dv-evm上移植也可以,没必要定义自己的板子和配置。这里只不过给大家举个例子。</b> 编译工作: $make distclean $make davinci_dm6446_config $make 看是否编译全部通过,是否生成u-boot.bin和u-boot.img等文件,同时检查你的交叉编译环境是否建立好,没问题继续往下进行。
<b>第三步:移植板子驱动和配置</b>
1、 修改davinci_dm6446.h
首先说说本人板子的信息:ddr2——256m-byte,nand——128m-byte——2k page; 通用网口phy芯片,没有nor flash和ata。 /*=======*/ /* board */ /*=======*/ #define dv_evm <b>#define cfg_use_nand</b><b>(支持nand</b><b>)</b> <b>#define cfg_nand_largepage </b><b>(支持2k page</b><b>的nand</b><b>)</b> //#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 <b>#define config_soc_dm644x </b><b>(soc</b><b>为dm644x</b><b>)</b> /*====================================================*/ /* eeprom definitions for atmel 24c256bn seeprom chip */ /* on sonata/dv_evm board. no eeprom on schmoogie. */ /*====================================================*/ <b>//#define cfg_i2c_eeprom_addr_len 2</b> <b>//#define cfg_i2c_eeprom_addr 0x50</b> <b>//#define cfg_eeprom_page_write_bits 6</b> <b>//#define cfg_eeprom_page_write_delay_ms 20</b> (如果你的板子没有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 */ <b>#define phys_sdram_1 0x80000000 /* ddr start */</b> <b>#define phys_sdram_1_size 0x10000000 /* ddr size 256mb */</b> <b>#define ddr_8banks /* 8-bank ddr2 (256mb) */</b> 有关ddr memory这里不需要修改,因为本人的板子是256m的。除非你的板子是128m才改为:<b>size 0x08000000 ddr_4banks</b><b>。</b> /*====================*/ /* 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;
<b>reg(pinmux0) = 0x80000000;</b><b>只使用</b>emac<b></b>
否则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-就可以编译了。
补充有关dm6446 boot的一点知识:如果板子没有任何程序,rbl会通过串口0发送bootme命令上来,运行uart_load.exe,会接到rbl的命令,然后握手通信,下载uart.bin到板子上,并运行起来,uart.bin程序就是小小的boot,通过串口0和pc通信,下载u-boot.bin,并把u-boot.bin给运行起来。所以uboot移植到上面的步骤,可以进入linux 内核移植的工作了。
<a>wuyunzdh、xi2008、tsin</a>
5人
了这篇文章
<a></a>
2010-03-11 15:59:39 不错!学习了
呵呵 很有难度的东西啊
2010-03-11 23:25:22 几个月前自己也装过一个“有奔头”玩了一下,感觉还可以。
2010-03-12 09:19:20 uboot在开源嵌入产品设计中,地位越来越重要,功能越来越丰富。
2010-04-12 11:00:06 你好,我也是做dm6446,我们公司买的板子是ti原厂的,就是那个dvevm,我现在想移植下u-boot-1.3.4,就把根目录下的那个makefile的cross_compile=arm_v5t_le-,然后就直接make distclean;make davinci_dvevm_config;make
这样也生成了u-boot.bin以后,用dvflasher下载到板子上了,发现uboot启动不了,打印信息如下:
ti ubl version: 1.12, flash type: nand
booting psp boot loader
pspbootmode = nand
starting nand copy...
initializing nand flash...
valid magicnum found.
nand boot success.
done
然后就停止了,请问下为什么???谢谢了,我的qq是451686458,谢谢了
2010-04-13 18:23:07 这个原因有很多,你要跟踪是否运行到board.c里的start_armboot()函数,等等。你可以参考人家给你的uboot是如何编译出u-boot.bin还是其他加有头信息的二进制文件
2010-05-12 12:15:12 你好,我的dvflasher不能运行。
2010-05-12 15:29:20 抱歉,没用过dvflasher,我们肯定不用这个dvflasher。
2010-09-16 09:51:08 下载uboot之前有个flashwrite到什么地方能够下载源码?这个文件时通用的还是根据硬件决定
2010-09-16 10:56:13 这个估计是ti的dsp out文件,我们不关心这个。
2011-01-03 18:27:12 你好,我的的uboot用老的环境是可以编译通过的并可以正常使用,最近从新装了一个编译环境,也是编译过去的,但是,下载到norflash中美任何反应,但是可以用软件可以启动启动起来!!!
请问这是什么原因引起来的!!
2011-01-04 16:54:43 我们没有测试过nor flash的应用。你的新编译环境.bashrc文件是否设置:
path="/opt/mv_pro_5.0.0/montavista/pro/devkit/arm/v5t_le/bin:
/opt/mv_pro_5.0.0/montavista/pro/bin:
/opt/mv_pro_5.0.0/montavista/common/bin:$path"
的路径
2011-01-06 11:18:09 谢谢你的回复,
路径肯定个配置了,在.bash_profile不然应该也编译不过去呀,是不是?
这是我新环境的:
cat /root/.bash_profile
# .bash_profile
# get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# user specific environment and startup programs
path=$path:$home/bin
path=/opt/montavista/pro/devkit/arm/v5t_le/bin:/opt/montavista/pro/bin:/opt/montavista/common/bin:/opt/3.4.1/bin:/opt/arm-920t-3.4.4/bin:$path
export path
unset username
下面是我老环境的:
[root@myhost ~]# cat /root/.bash_profile
alias rm='rm -i'
alias ll='ls -l --color'
alias cp='cp -i'
alias mv='mv -i'
path="${path}":/usr/local/arm/3.4.1/bin:/usr/local/920t_le/bin:/usr/local/bin:/opt/mv_pro_4.0/montavista/pro/devkit/arm/v5t_le/bin:/opt/mv_pro_4.0/montavista/common/bin:/opt/mv_pro_4.0/montavista/pro/bin:/opt/hisilicon/toolchains/arm-uclibc-linux-soft/bin:/opt/uclinux/bfin-uclinux/bin://opt/uclinux/bfin-linux-uclibc/bin
. $home/.bashrc
2011-01-06 16:06:43 谢谢你的回复,肯定设置了,不然也编译不过去,我的是放在.bash_profile中的。
新的编译环境见下:
[root@localhost bin]# cat /root/.bash_profile
老的编译环境是: