飞凌OK6410开发板之u-boot-2011.06-rc2移植之愚见

     最近,对UBOOT产生了点兴趣,以前一直用的都是飞凌官方自带的uboot1.16版本,记得当时的这个版本还不支持板载的DM9000网卡,后来就在其基础上学着去移植DM9000网卡驱动,虽然移植是成功了,但是说起来移植也是惭愧,完全是参照网上别人的教程,一条一条的去改相关文件的代码,完全就是依葫芦划瓢,哎,一点成就感也没有,为什么要去这么改,根本就不清楚,突然,就有种是被嵌入式在玩,而不是玩嵌入式的感觉,虽然我只是个嵌入式业余爱好者,刚开始接触是很困难,何况又是由S3C6410直接起步,但是我一直坚信,只要自己肯下功夫,肯用心,就没有学不好的东西,呵呵,废话感觉说的有点多了,还是切入正题吧!

     看到网上基于SAMSUNG-SOC-S3C6410的UBOOT移植文章很多,基本上都是基于6410开发板的讲解,但是基于飞凌OK6410开发板的很少,而且基于u-boot较新版本的移植的就更少,而且绝大多数都是在讲如何如何去操作,例如该CD哪个文件夹该MKDIR哪个文件夹,该RM哪些不要的东西,该CP哪些文件代码等等,没有一个很系统的讲解,总让人操作完后还是没有个啥概念,为此特地花了几天时间用自己手头上的OK6410开发板去移植了一下UBOOT,亲自实践后才整理出的这篇文章,当然我也只是个菜鸟,希望这篇文章对那些想学UBOOT移植的人有点帮助,网上看到也有些人对OK6410的UBOOT移植有困惑的,希望对你们有用。

     对于开发环境的搭建,在这我就不用多说了啊,毕竟网上多的去了,在这先贴出我的开发环境供参考。

    我的开发环境:

         1,笔记本主机系统WINDOWS XP SP3系统   

         2,虚拟机采用的是 VMware Workstation ACE版本

         3,虚拟机内采用的LINUX系统是UBUNTU10.10版本

         4,交叉编译工具是CROSS_COMPILE4.2.2版本

 

     要移植UBOOT,首先得下载一个版本,这里是uboot_DNEX团队的官方地址下载  ftp://ftp.denx.de/pub/u-boot/

     对于技术我是比较喜欢最新的,所以前几天就下载了最新的UBOOT版本u-boot-2011.06-rc2版本对其开工,当然在我写这篇文章的时候,前后就短短几天时间又更新到了UBOOT版本u-boot-2011.06-rc3,哎,看来这个更新真的是很快啊

     下载下来后就是u-boot-2011.06-rc2.tar.bz2,大约8.09M,但是解压后差不多80多M的样子。将这个下载下来的bz2文件放进linux系统的目录下,至于这个目录随便,我的是在UBUNTU下的/SHARE下,然后tar jxvf u-boot-2011.06-rc2.tar.bz2,对其解压缩,之后便得到了我们能够操作的的u-boot-2011.06-rc2,cd 进入u-boot-2011.06-rc2,然后就可以看到整个文件架构安排了,好了,移植工作也正式开始了。

 

 

   

 对于UBOOT移植,首先,脑袋里得有个总体概念,第一步该干嘛,然后几步又该如何去做,经过本人昨天晚上的OK6410运行情况,发现还是可行的,特地总结出来,以供大家参考。对于UBOOT移植,严格上来说,应该范围比较广,有CPU核架构级别的移植例如OK6410属于ARM1176架构的,CPU芯片级别的移植例如OK6410属于S3C6410SOC,还有基于板级移植的例如OK6410单板,而我们日常生活中大家说的移植,一般也都是这种板级移植,这种移植也是最简单的,所以大家搞UBOOT移植的时候就由板级——》CPU芯片级——》CPU核架构级去看,如果有相近的板级资源做参考,这样会事半功倍,由于本人能力有限,这里讲的也是基于板级移植的,希望大家勿喷,呵呵,所以当你拿到一个UBOOT源代码的时候,最好第一件事就是先进BOARD目录里面看看,看是否已经有你那款板子的或是相近板子的代码在里面,这样可以做到心里先有个数,如果有,那么你已经成功了一小半,呵呵。
    对于UBOOT的移植学习,我建议大家还是好好看看README这个文件,这里面写的好多东西都很用的,对于你移植代码很有帮助的,当然这个不在今天的重点里面。对于上图中的那些文件和文件夹以及递归的文件等等可能会使人觉得头晕,我已开始也是这种感觉,但是当你真正自己亲自独立移植成功之后,就会感觉一目了然了,好了,这里就以我的OK6410单板来说吧。
   第一步,我CD 进入u-boot-2011.06-rc2源代码根目录,然后进入BOARD/SAMSUNG
  
 发现了该版本自带SMDK6400,恩OK,基本成功了一小半了,这里我要给大家说明一点三星公司自家生产的开发板一般都是SMDK开头,例如SMDK2410,SMDK6400等等,既然板级资源已经找到,那么后面的CPU芯片级和核架构级得资源就肯定对路了,由于SMDK6400单板采用的是S3C6400SOC,与S3C6410SOC大部分资源差不多,就是在多媒体,省电方面,主频方面还有少数寄存器地址方面等等有点区别,绝大部分还是通用的,而且SMDK6400也是与OK6410最相近的一块板子了,毕竟采用的都是ARM1176的核,况且两款CPU也相近,那就拿SMDK6400开刀了。而且通过我看两2款芯片的DATASHEET比较,2者很相近,然后通过对比UBOOT1.16里面的CPU级别的初始化代码,发现绝大部分代码是通用的,所以,我有个大胆的猜测,直接将SMDK6400的u-boot-2011.06编译产生的U-BOOT.BIN通过DNW加载到OK6410的内存中,应该能够跑起来,呵呵,但是经过后来的实践验证,跑不起来
               
这个是DNW的加载UBOOT的截图,校验和OK之后就没反应了,看来我的猜测还是有BUG啊,呵呵,但是我的猜测大部分应该是对的,只不过可能离成功还差那么一点,那么看来是相关代码需要更改了,既然需要改代码,所以建议大家还是另起炉灶,切忌不要在SMDK6400代码里面乱改一通,然后放到自己的开发板上,咦,可以跑起来了,移植OK,这样是个很不好的习惯,因为这样你就破坏了别个的代码,我们既然借鉴了别人的劳动成果,就不应该再去破坏别人的代码,况且,这样你的代码估计也会很乱。
  第二步,刚才看到了既然有SMDK6400,那么我们可以先将这个编译一遍,看是否可以编译成功,为以后的移植做好准备。在根目下使用命令 make smdk6400_config,然后使用make,如果不出意外,7到8分钟就可以编译成功,然后在根目下就会产生u-boot.bin,当然对于编译SMDK6400来说,几乎都是编译不通过的,总是出现._end未定义,但是SMDK2410很顺利,呵呵,这是为什么呢?其实这个应该是UBOOT的一个BUG吧,不用担心,你只用在/u-boot-2011.06-rc2/board/samsung/smdk6400/u-boot-nand.lds文件里.bss __rel_dyn_start (OVERLAY) : {前面加上_end = .;就行了,这个是必须的哦,呵呵,参考/u-boot-2011.06-rc2/nand_spl/board/samsung/smdk6400/u-boot.lds,加完后保存,然后再编译一遍,这次OK。
  第三步,刚刚第一步已经说了,这样编译的代码是无法加载到OK6410的板载内存里面运行的,因此需要修改相应的代码,为了避免破坏他人的劳动成果,还是另起炉灶,那就开始吧,在这之前,先介绍下几个移植需要重点关注的文件夹,一个是/u-boot-2011.06-rc2/board/文件夹,它代表板级相关代码资源,一个是/u-boot-2011.06-rc2/arch/文件夹,它代表CPU架构级资源,还有一个就是/u-boot-2011.06-rc2/nand_spl/文件夹,那就以我的OK6410为例来说明吧:
   1,在/u-boot-2011.06-rc2/board/下新建文件夹:mkdir feilin/ok6410(飞凌)
   2,将/u-boot-2011.06-rc2/board/samsung/smdk6400/所有文件复制到/u-boot-2011.06-rc2/board/feilin/ok6410下,cp  ../../samsung/smdk6400/* ./
   3,将smdk6400.c改名为ok6410.c ,mv smdk6400.c ok6410.c
将smdk6400_nand_spl.c改名为ok6410_nand_spl.c  mv smdk6400_nand_spl.c   ok6410_nand_spl.c  将Makefile 打开,用vi 或是gedit都行,更改COBJS-y := ok6410.o,
  4,在/u-boot-2011.06-rc2/nand_spl/board/下新建文件夹:mkdir feilin/ok6410
  5,将/u-boot-2011.06-rc2/nand_spl/board/samsung/smdk6400/所有文件复制到/u-boot-2011.06-rc2/nand_spl/board/feilin/ok6410/, cp ../../samsung/smdk6400/* ./ ,并更改Makefile内与板级有关的部分,截图为
 
 6,将u-boot-2011.06-rc2/include/configs/smdk6400.h 复制一份并更名为ok6410.h,mv smdk6400.h ok6410.h这个是必需的哦,要不然无法完成编译,这上面全是板级配置资源,现在不必修改
7,将u-boot-2011.06-rc2/arch/arm/include/asm/arch-s3c64xx/s3c6400.h复制一份,并更名为s3c6410.h   mv s3c6400.h  s3c6410.h,可能有人会问干嘛复制这个文件呢,其实这个文件代表的就是CPU_S3C6410的资源代码,必定会与CPU_S3C6400有所不同,方便以后修改,不破坏SMDK6400的,所以在这里就需要将3条里面的ok6410.c里面用用到的头文件换成s3c6410.h,凡事遇到s3c6400.h的地方都换成s3c6410.h
8,也是这一步中的最后一个环节了,就是修改u-boot-2011.06-rc2/根目录下的Makefile文件,这个是主导make文件,资源配置都是靠它的,修改截图1
并在其后添加
CROSS_COMPILE = /usr/local/arm/4.2.2-eabi/usr/bin/arm-linux-
export CROSS_COMPILE ,也就是指定自己的交叉编译器,最后就是找到arm1176systems
smdk6400_noUSB_config /
smdk6400_config : unconfig
 @mkdir -p $(obj)include $(obj)board/samsung/smdk6400
 @mkdir -p $(obj)nand_spl/board/samsung/smdk6400
 @echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h
 @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
 @if [ -z "$(findstring smdk6400_noUSB_config,$@)" ]; then   /
  echo "RAM_TEXT = 0x57e00000" >> $(obj)board/samsung/smdk6400/config.tmp;/
 else          /
  echo "RAM_TEXT = 0xc7e00000" >> $(obj)board/samsung/smdk6400/config.tmp;/
 fi
 @$(MKCONFIG) smdk6400 arm arm1176 smdk6400 samsung s3c64xx
 @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
修改为
ok6410_noUSB_config /
ok6410_config : unconfig
 @mkdir -p $(obj)include $(obj)board/feilin/ok6410
 @mkdir -p $(obj)nand_spl/board/feilin/ok6410
 @echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h
 @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
 @if [ -z "$(findstring ok6410_noUSB_config,$@)" ]; then   /
  echo "RAM_TEXT = 0x57e00000" >> $(obj)board/feilin/ok6410/config.tmp;/
 else          /
  echo "RAM_TEXT = 0xc7e00000" >> $(obj)board/feilin/ok6410/config.tmp;/
 fi
 @$(MKCONFIG) ok6410 arm arm1176 ok6410 feilin s3c64xx
 @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
    以上第三步看起来步骤很多,其实则不然,归根到底就是COPY,将SMDK6400的板载资源代码复制一份到自己建的OK6410中,看是OK6410,其实用的还是SMDK6400的代码,呵呵,只不过现在改动就不要紧了,相当于是在一份副本上修改了,对吧,所以到目前为止,我们做的工作还是停留在COPY阶段,当然,这个时候最好先make ok6410_config 然后在make ,如果编译无问题,那恭喜你,已经离成功很近了,当然了,其实这个时候你编译的代码U-BOOT.BIN其实还是SMDK6400的,所以和你第二步编译的是一个代码,仍无法在OK6410上跑起来。好了,既然我们已经有了SMDK6400的副本了,就该为它做点啥子修改了,要不然可就对不住自己前面的那一番折腾啊,对吧。
     第四步:先来说说我到这一步当时的想法吧,由于手头没有啥子SDRAM内程序调试工具,就只有个串口,也只能借助串口来调试了,关键是现在串口根本就没有输出,不知道是UBOOT没跑起来,还是OK6410板子上的串口没有初始化,网上找了好久也没找出个问题所在,关键还是要靠自己啊 ,没办法,只好去参考哈UBOOT1.16内的代码了,但是那么多的东西,该看啥呢,呵呵,对了,这个也是需要好好琢磨的,所以多看哈子源代码会很有用的,通过代码大致翻阅最终被我锁定在了/u-boot-2011.06-rc2/board/feilin/ok6410/lowlevel_init.S这个文件上,其实这个文件就是板载资源底层初始化,发现其内缺少UBOOT内存搬运代码以及串口初始化部分的代码有点问题,毕竟这个是SMDK6400的板载代码,现在是OK6410,所以需要修改,于是参考UBOOT1.16内的部分代码:第一处
第二处
 
在其后加上
//<-add by hwq
 ldr r1, =0x2222
 str    r1, [r0, #GPBCON_OFFSET]
 ldr r0, =ELFIN_UART_CONSOLE_BASE  @0x7F005000
 mov r1, #0x0
 str r1, [r0, #UFCON_OFFSET]
 str r1, [r0, #UMCON_OFFSET]
 mov r1, #0x3                 @was 0.
 str r1, [r0, #ULCON_OFFSET]
#if defined(CONFIG_CLKSRC_CLKUART)
 ldr r1, =0xe45   /* UARTCLK SRC = 11 => EXT_UCLK1*/
#else
 ldr r1, =0x245   /* UARTCLK SRC = x0 => PCLK */
#endif
 str r1, [r0, #UCON_OFFSET]
#if defined(CONFIG_UART_50)
 ldr r1, =0x1A
#elif defined(CONFIG_UART_66)
 ldr r1, =0x22
#else
 ldr r1, =0x1A
#endif
 str r1, [r0, #UBRDIV_OFFSET]
#if defined(CONFIG_UART_50)
 ldr r1, =0x3
#elif defined(CONFIG_UART_66)
 ldr r1, =0x1FFF
#else
 ldr r1, =0x3
#endif
 str r1, [r0, #UDIVSLOT_OFFSET]
 ldr r1, =0x4f4f4f4f
 str r1, [r0, #UTXH_OFFSET]  @'O'
//->
,通过修改后,再次编译,成功,然后将其u-boot.bin再一次通过DNW加载进OK6410的SDRAM内运行,奇迹出现了,呵呵,截图如下:
截图显示FLASH 失败,其实是由于还没有移植FLASH驱动的缘故,基本这个移植版本还是雏形,啥子也做不了,因为驱动都还没搞定,但是说明UBOOT可以跑了毕竟看上面的时间还是我昨晚1点43分才测试好的,呵呵,哎写这篇文章又花了不少时间,觉得既然有心得体会,还是写出来供大家交流,后面有时间会逐步去完善的,当然了后期的工作量估计会更大啊,呵呵。

你可能感兴趣的:(嵌入式LINUX之UBOOT)