免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 763 | 回复: 0
打印 上一主题 下一主题

移植U-boot-1.2.0到S3C2410 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-04-10 20:59 |只看该作者 |倒序浏览
前段时间移植了vivi-0.1.4,也对源代码进行了解析学习。原本的想法是给vivi增加tftp功能,那么就需要写cs8900a驱动(我用的网卡芯片是CS8900A-CQ3Z),然后呢实现tftp协议,最后添加到vivi支持的命令集中。这部分工作如果从头开发,没有必要,因为U-boot就提供了tftp功能,可以借鉴,把相关代码移植到vivi下,这样vivi就具备了tftp下载功能。所以,准备先移植uboot,学习一下。vivi和uboot互相利用,进行功能完善和理解的深入。

【备注: 2007年末就是专心研究bootloader相关技术,以vivi和U-boot进行对比研究,是一个很好的学习思路。两者可以同时进行,互相借鉴,有助于问题的解决。这仅仅是学习的方法,并不是工作开发的方法。毕竟工作中是没有太多的时间让你细致的研究相关的代码的。工作中就是要尽可能快的寻找一切可以有效利用的资源,然后整理吸收,在这个高度上完成自己的工作,绝对不能自大的一切从头做起。】

    下面只关注移植流程和解决方案,自己所作的工作量很少,结合的代码分析也比较少,主要解决出现的问题。后续的工作中,会结合uboot源代码分析学习。继续加深对bootloader技术的认识!

一、前言

    s3c2410在国内还是用的很广泛的,所以资料相对比较多。uboot对基于nand flash启动也提供了支持,相关的移植步骤和资料也比较多。我推荐的方法还是通过读patch来分析解决移植问题。这里主要提到几个参考资料:

1、openmoko

    网上原创性的解决方案,估计大多数源于openmoko。看看网上那些资料,所用的源代码和思路无一不是来自这里的patch,最多根据自己的开发板做了少许的改动。现在把openmoko的资源列表如下:

    wiki openmoko主页网址:
http://wiki.openmoko.org/wiki/Main_Page
    wiki openmoko bootloader:
http://wiki.openmoko.org/wiki/U-boot/zh_cn
    wiki openmoko uboot patches:
http://svn.openmoko.org/trunk/src/target/u-boot/patches/

    上面的资源非常丰富,只要有效的利用,能解决遇到大部分通常的问题。

2、嵌入式中国  
http://www.armchina.cn/default.asp

    北邮的hiboy在u-boot-1.2.0的移植上有不少独创性的工作。

3、lufuchong  
http://www.cnitblog.com/luofuchong/

    lufuchong也做了很多的工作,利用了hn的keety的补丁。不过我没有找到他的补丁,对其关于bootm的理解还是赞一个。

    其他的资料就不一一列出了,最有价值的就是上面三位的工作了。

    利用patch是很好的方法,当然我不是说直接打上补丁,而是阅读patch,通过patch把移植的思路和步骤理清理顺,然后形成自己的理解,最后可以深入源代码,增加自己的贡献。如果说我在s3c2410上做了些工作,那就是强调和利用patch,好的patch是最好的资源,即使没有详细的说明,有一定移植经验的人也很容易借鉴,并最终成功。如果对patch不了解,就先看一下我在去年暑假翻译的一篇文章:
http://blog.chinaunix.net/u/21948/showart_157145.html
《Linux下patch的制作和使用》。需要注意的是,在制作patch时,一定要用distclean清理一下源文件树,否则的话,制作的patch质量上可是不敢恭维。既然要做,就要做好一些。hiboy提供的patch中,就犯了这个错误,希望不是习惯问题。

二、准备工作

     1、选择版本

     版本虽然不是越新越好,但是新版本提供的特性较多,自己能够学习到的内容也比较多,所以还是选择最新版本。

[armlinux@lqm bootloader]$ ftp ftp.denx.de
Connected to
ftp.denx.de
.

    还是从pub/u-boot下载最新版本,现在正式发布版是u-boot-1.2.0。以后就以此版本进行学习和开发。解压等工作不必细说。

    为了制作patch的方便,解压之后的u-boot-1.2.0命名为u-boot-1.2.0.orig,然后复制做一个开发版u-boot-1.2.0。为了在命令行下操作方便,可以使用软链接。如下:

[armlinux@lqm bootloader]$ cp -rf u-boot-1.2.0.orig/ u-boot-1.2.0
[armlinux@lqm bootloader]$ ln -s u-boot-1.2.0.orig/ orig
[armlinux@lqm bootloader]$ ln -s u-boot-1.2.0 develop

     这样,使用TAB键就方便多了。关于要删除这些链接文件,可能会遇到一个小的bug。看一下我的解决方案:
http://blog.chinaunix.net/u/21948/showart_385132.html


    2、交叉编译工具链

    u-boot-1.2.0的版本还是比较高的,去年暑假自己做过交叉编译工具链,耗费工作量太大。兴趣也不在那里,所以还是选择已有的质量较高的工具链。还是到ARM的官方网站上找,可以找到CODESOURCERY公司提供高质量的GNU Toolchain,你可以从这里下载:
http://www.codesourcery.com/gnu_toolchains/arm/download.html
。最新版已经是arm-2007q1。我把交叉编译工具都放到/usr/local/arm/下面了,现在只有两个:

[armlinux@lqm arm]$ tree -L 1
.
|-- 2.95.3
`-- arm-2007q1
2 directories, 0 files

    大多数非最新版使用2.95.3可以解决了,新版本基本采用arm-2007q1。这两个工具都是比较成熟好用的,可以避免出现不少问题。

    3、硬件配置说明

    实验箱还是深圳Embest的EDUKIT-III,资源如下:

    ·SoC  : S3C2410A
    ·SDRAM: 两片HY57V561620CT-H(共64M)
    ·NOR Flash : AM29LV160DB-90EC(2M)
    ·NAND Flash: K9F5608UOC(32M)
    ·网络芯片: CS8900A-CQ3Z(接在nGCS3,也就是bank3,由此对应的基地址为0x19000300)

    可见大部分是smdk2410的标配,所以移植的工作量是很小的。只是在流程上弄清楚,在分析完源代码后,可以考虑增加或者改进功能。现在的想法是暂时不使用nor flash,直接使用nand flash,跟前面vivi的开发保持一致。

(备注:
    从U-boot-1.2.0可以看出,U-boot的开发已经不仅仅满足于作为一个bootloader,现在正在逐步在下面几个方面深入和完善:增加下载手段和对文件系统的支持度、增加内核调试功能(集成debugger)、完善对多architecture多硬件平台的支持。从这个角度上看,U-boot已经身兼bootloader、monitor、debugger多重功能,支持的力度也越来越广泛。这是bootloader技术发展的一个趋势,慢慢的庞大起来,如同Linux内核一样,不再小巧。与此同时,我们可以从中学习和认识的东西也在不断增多。
    我想现在bootloader的设计分成三种趋势。第一种是只要求具备基本的bootloader功能,对性能大小要求非常高,这样需要专门编写。归结为“微型化”。第二种是利用现成的通用的bootloader,移植到自己的开发板上,比如U-boot就是一个很好的选择。在这方面,U-boot已经从bootloader的基本功能向可能扩展的各个方向延伸,可归结为“大型化”。第三种,就是SoC厂商为了推广自己的产品,在推出时,可能会开发专用的bootloader,功能比较完善,但是对其他平台的支持并不好,如vivi、blob都在此范围内。它介于上述两者之间。


三、移植工作

(一)首先就是让U-boot能跑起来

    这部分的工作比较少,参考的主要是openmoko的uboot-s3c2410-nand.patch,通过读这个patch理顺移植的思路。因为前面做at91rm9200的时候用过uboot1.1.2,所以对uboot的整个结构和移植的思路还有一定了解的。假定我们的开发板命名为myboard,与smdk2410基本类似。往常我的做法也是修改uboot,使之支持myboard,而针对smdk2410是没有变化的。现在为了使patch更容易阅读,与源代码的修改更加明确,就默认smdk2410就是myboard,直接在上面动手术。这样,通过patch可以把修改的步骤看的一清二楚。

主要的步骤有这么几个:

    ·修改顶层Makefile,更改CROSS_COMPILE为你的交叉编译工具的路径。

    这步工作并非必须,你也可以在命令行中指定。不过那样就麻烦了些。

    ·修改board/{your board}/

    这是主要的工作量,board目录下是平台依赖,存放电路板相关的文件。重点是内存初始化和flash驱动、开发板初始化。

    ·修改cpu/arm920t/

    这里存放的是cpu相关的目录文件,启动的入口地址就是在start.S中。需要做适当的修改。

    ·修改include/configs下相关配置文件

    这里是修改配置文件,对smdk2410来说,就是smdk2410.h。主要是根据自己需要的功能进行定制customize,也可以称之为裁减。

    当然上面是基本的步骤,也仅仅能够完成基本的工作。真正原创性的移植工作需要完成大量的驱动编写工作,在我看来,那才是真正的移植,那样的人也是最为缺乏的人才。我现在只是在别人移植好的基础上进行二次移植,类似于二次开发,难度和工作量要小的多。不管怎么样,先按照这个基本的思路展开。关于uboot各个文件夹的存放内容,详细部分参考我移植到at91rm9200时的笔记
http://blog.chinaunix.net/u/21948/showart_153570.html
。就整体的架构而言,目录可以分为三种类型:

    1、与处理器架构或开发板硬件相关
    2、一些通用的函数或者驱动程序
    3、uboot的应用程序、工具或者文档

    下面开始移植。

    第一步工作,修改顶层目录下的Makefile。

    这里的基本工作就是修改CROSS_COMPILE,比较简单。网上通常的流程(以smdk2410为例)为:

make smdk2410_config
make

    为什么要这样做,还有什么可以执行的make命令。在这里还是简单的阅读一下Makefile,对整体规划有了初步的了解。其中第一条命令源于(以smdk2410为例),属于指定目标编译:

smdk2410_config : unconfig
        @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0

    其中依赖部分unconfig的作用是清理一下垃圾文件。

unconfig:
        @rm -f $(obj)include/config.h $(obj)include/config.mk \
                $(obj)board/*/config.tmp $(obj)board/*/*/config.tmp

    而MKCONFIG是一个脚本文件,可以从下看出:

MKCONFIG := $(SRCTREE)/mkconfig

    继续向上追SRCTREE:

SRCTREE := $(CURDIR)

    到此就是终结了。CURDIR这个变量是Makefile提供的,代表了make当前的工作路径。也就是说在顶层目录下有一个mkconfig脚本文件。如果不清楚变量到底是什么,提供的调试手段就是在Makefile的底部加入调试单元,比如:

#
# make debug
#
debug:
        @echo "CRUDIR: $(CURDIR)"
        @echo "SRCTREE: $(SRCTREE)"
        @echo "OBJTREE: $(OBJTREE)"

    这样就可以清楚的看到每个变量代表的内容了。追查到这里,就很清楚了,如果你的第一步工作是make smdk2410_config,那么所进行的工作就是清理一下临时文件,然后执行mkcofig这个shell脚本。脚本的内容就不具体分析了,比较简单,其实就是通过你的配置部分完成include/config.mk的生成,里面有四个宏,这是根据你的配置来的。例如:

ARCH = arm
CPU = arm920t
BOARD = smdk2410
SOC = s3c24x0

    具体的含义很明显了。这样第二步的工作是make,其实按照make的执行规则就是执行make all。如果你前面指定了CROSS_COMPILE,那么第二步工作只需要执行make就可以了,不需要在命令行指定ARCH=arm,也不需要在Makefile中指定ARCH。这些工作mkconfig会替你去做。你需要做的只是完成配置命令部分。

    为了是测试流程自动化,借鉴vivi的Makefile,我增加了一个make命令,这样只需要执行make smdk2410,就可以完成三步工作:一是make distclean,二是make smdk2410_config,三是make。第一部分patch如下:

[armlinux@lqm bootloader]$ cat uboot_topdir_makefile.patch
diff -urN u-boot-1.2.0.orig/Makefile u-boot-1.2.0/Makefile
--- u-boot-1.2.0.orig/Makefile 2007-01-07 07:13:11.000000000 +0800
+++ u-boot-1.2.0/Makefile 2007-09-19 12:09:20.000000000 +0800
@@ -125,7 +125,7 @@
CROSS_COMPILE = powerpc-linux-
endif
ifeq ($(ARCH),arm)
-CROSS_COMPILE = arm-linux-
+CROSS_COMPILE = /usr/local/arm/arm-2007q1/bin/arm-none-linux-gnueabi-
endif
ifeq ($(ARCH),i386)
ifeq ($(HOSTARCH),i386)
@@ -2350,3 +2350,10 @@
        gtar --force-local -zcvf `date "+$$F-%Y-%m-%d-%T.tar.gz"` $$F

#########################################################################
+
+#
+# make {your board}
+#
+
+%: distclean %_config
+ $(MAKE) && echo "^_^ Succeed!"

    第二步工作:修改board的相关文件

    一是修改lowlevel_init.S,就是完成13个内存寄存器的配置。前面在vivi的基础实验中也做过了。这里最为关键的部分其实是BWSCON,要配置好BANK3的总线时序。如果此处的总线时序配置不好,那么CS8900A是无法正常工作的。因为EDUKIT-III完全按照smdk2410的配置,片选为nGCS3,也就是BANK3,基地址仍然为0x19000300。基本不需要修改,如果是其他的网络芯片,一定要注意设置此处的总线位宽和总线时序,否则,网络芯片无法正常工作。我在这里的工作是调整了sdram的刷新频率,具体为:

#define REFCNT 1268 /* period=7.8125us, HCLK=100Mhz, (2048+1-7.8125*100) */

    但是,这样的前提是HCLK必须为100MHz。这就需要修改smdk2410.c了,同时还要根据蜂鸣器等等,设置合适的GPIO的数值。可以参考patch。

    因为是从nand flash启动,需要用到nand read,可以直接把vivi中的nand_read.c复制过来,增加一个配置选项CONFIG_S3C2410_NAND_BOOT。按照uboot的配置参数的命名原则,CONFIG_和CFG_是不同的。需要注意一下。

    完成这些,修改一下Makefile就可以了。这里面最为困难的就是要配置好内存寄存器,设置好总线时序。网卡驱动的关键性工作也在这个地方,软硬件都理解才能顺利解决。


文件:
uboot_board_s3c2410.patch.gz
大小:
1KB
下载:
下载

    第三步工作:修改cpu/arm920t相关文件

    主要就是修改start.S。而start.S的核心工作就是增加copy_myself。这个可以借鉴vivi的部分,不过需要根据uboot的一些特点做一些修改。也不用多说。补丁如下:

   

文件:
uboot_cpu_s3c2410.patch.gz
大小:
3KB
下载:
下载

    第四步工作:修改配置文件

   

文件:
uboot_include_s3c2410.patch.gz
大小:
3KB
下载:
下载

    注意,上述的每个补丁都包含前面所做的工作。也就是说,最后的补丁uboot_include_s3c2410.patch.gz是完成基本工作后的补丁。

    编译得到u-boot.bin,利用JTAG工具烧写nand flash,上电后从nand flash启动:


U-Boot 1.2.0 (Sep 19 2007 - 12:43:31)
DRAM: 64 MB
Flash: 512 kB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
U-boot # printenv
bootdelay=3
baudrate=115200
ethaddr=08:00:3e:26:0a:5b
ipaddr=192.168.1.110
serverip=192.168.1.216
netmask=255.255.255.0
stdin=serial
stdout=serial
stderr=serial
Environment size: 161/65532 bytes
U-boot # ping 192.168.1.216
host 192.168.1.216 is alive

    测试了一下printenv命令和ping命令,都正常。然后又测试了date命令,如下,也正常:

U-boot # date 091916122007
Date: 2007-09-19 (Wednesday) Time: 16:12:00
U-boot # date
Date: 2007-09-19 (Wednesday) Time: 16:12:03

    但是不能读写nand flash。这是需要改进的地方。tftp是正常的,要想利用bootm来启动内核,需要在zImage来增加头信息。这个详细部分可以参考lufuchong的文章,写的简明准确:
http://www.cnitblog.com/luofuchong/archive/2007/01/12/21834.html
,我制作了一个uImage,测试如下:

U-boot # tftp 0x31000000 uImage
TFTP from server 192.168.1.216; our IP address is 192.168.1.110
Filename 'uImage'.
Load address: 0x31000000
Loading: #################################################################
         #################################################################
done
Bytes transferred = 662340 (a1b44 hex)
U-boot # bootm 0x31000000
## Booting image at 31000000 ...
   Image Name: linux-2.4.18
   Created: 2007-09-18 5:01:45 UTC
   Image Type: ARM Linux Kernel Image (uncompressed)
   Data Size: 662276 Bytes = 646.8 kB
   Load Address: 30008000
   Entry Point: 30008000
   Verifying Checksum ... OK
OK
Starting kernel ...
Uncompressing Linux................................................ done, booting the kernel.
Linux version 2.4.18-rmk7-pxa1 (armlinux@lqm) (gcc version 2.95.3 20010315 (release)) #1 Tue Sep 18 12:59:07 CST 2007
//下面省略

    看来是成功的。

    注意到一个问题,原来用uboot1.1.2的时候,会打印U-Boot code: ,但是现在没有。使用source insight查看lib_arm中的board.c的init_sequence数组,经过查找,应该在display_banner里面:

/*
* To match the U-Boot user interface on ARM platforms to the U-Boot
* standard (as on PPC platforms), some messages with debug character
* are removed from the default U-Boot build.
*
* Define DEBUG here if you want additional info as shown below
* printed upon startup:
*
* U-Boot code: 00F00000 -> 00F3C774 BSS: -> 00FC3274
* IRQ Stack: 00ebff7c
* FIQ Stack: 00ebef7c
*/

    通过debug可以知道,uboot取消了额外的调试信息,追查到【include/common.h】中,看看这个部分的定义:

#ifdef DEBUG
#define debug(fmt,args...) printf (fmt ,##args)
#define debugX(level,fmt,args...) if (DEBUG>=level) printf(fmt,##args);
#else
#define debug(fmt,args...)
#define debugX(level,fmt,args...)
#endif /* DEBUG */

    也就是说,你只要在这里定义一下DEBUG,把开关打开就可以看到调试信息了,上面的注释解释的也非常明确。我想打印调试信息,所以增加了DEBUG,并且修正了patch(当然你也可以不要这个debug信息)。注意,要在include 前增加DEBUG的定义,原因很简单。于是现在的补丁如下:


文件:
uboot-s3c2410-nand.patch.gz
大小:
3KB
下载:
下载

    uboot.bin下载后,上电启动打印信息如下:

U-Boot 1.2.0 (Sep 19 2007 - 13:07:41)
U-Boot code: 33F80000 -> 33F96C74 BSS: -> 33F9B3A4
RAM Configuration:
Bank #0: 30000000 64 MB
Flash: 512 kB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
U-boot #

    比较好用了。

(二)下面的工作就是去掉flash配置部分,然后增加nand读写部分。这里需要参考hiboy的patch和openmoko的default-env.patch,另外需要关注的就是uboot自带的文档,在doc中,关于nand部分有两篇有价值的参考。


文件:
uboot-s3c2410-nand.patch.gz
大小:
6KB
下载:
下载

    先给出patch,明天再总结吧。主要就是关于legacy的使用方法、nand的底层驱动、default env的修正三个方面。现在的启动信息如下:

U-Boot 1.2.0 (Sep 19 2007 - 13:54:19)
U-Boot code: 33F80000 -> 33F97950 BSS: -> 33F9C200
RAM Configuration:
Bank #0: 30000000 64 MB
NAND: 32 MB
In: serial
Out: serial
Err: serial
U-boot #

    测试了nand部分,效果还可以,一切正常。用bootm引导内核也没有问题,还不能挂载文件系统。如果把文件系统挂载弄好,那bootloader就算是彻底移植好了。争取把tftp部分移植到vivi上面。

U-boot # nand info
Device 0: Samsung KM29U256T at 0x4e000000 (32 MB, 16 kB sector)
U-boot # printenv
baudrate=115200
ethaddr=08:00:3e:26:0a:5b
netmask=255.255.255.0
ipaddr=192.168.1.110
serverip=192.168.1.216
bootargs=noinitrd root=/dev/bon/2 console=ttyS0
bootdelay=5
stdin=serial
stdout=serial
stderr=serial
Environment size: 209/131068 bytes
U-boot # setenv bootargs 6
U-boot # saveenv
Saving Environment to NAND...
Erasing Nand...Writing to Nand... done
?boot # reset
U-Boot 1.2.0 (Sep 19 2007 - 13:54:19)
U-Boot code: 33F80000 -> 33F97950 BSS: -> 33F9C200
RAM Configuration:
Bank #0: 30000000 64 MB
NAND: 32 MB
In: serial
Out: serial
Err: serial
U-boot # printenv
baudrate=115200
ethaddr=08:00:3e:26:0a:5b
netmask=255.255.255.0
ipaddr=192.168.1.110
serverip=192.168.1.216
bootdelay=5
bootargs=6
stdin=serial
stdout=serial
stderr=serial
Environment size: 172/131068 bytes
U-boot #


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/66039/showart_526105.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP