基于S3C6410的Uboot分析与移植
2013-10-17冯林琳耿恒山
冯林琳,耿恒山
(河北工业大学计算机科学与软件学院,天津 300401)
1 移植环境和BootLoader介绍
1.1 移植Uboot的软硬件环境
本文采用的S3C6410芯片是基于ARM11架构的16/32位RISC微处理器。它采用ARMv6指令集,支持从 SD Card、NOR Flash、NAND Flash 和 One-NAND Flash中引导系统,是一个低成本、低功耗、高性能的应用处理器解决方案。开发板主要硬件资源见表1。
表1 开发板主要硬件资源
本文使用 Kubuntu 12.04作为编译系统,采用arm-linux-gcc-4.7.0工具链作为编译器。开发板与目标机通过串口和网口链接,并使用Jlink V8仿真器进行调试和下载。
1.2 BootLoader介绍
BootLoader是嵌入式设备上电后执行的第一段程序,负责初始化硬件设备、建立内存空间映射图,引导嵌入式操作系统内核,其功能同X86体系结构中BIOS基本相同。BootLoader通常使用SD Card、NOR Flash和NAND Flash启动。目前,常用的BootLoader主要为vivi和Uboot,其中Uboot又占据了绝大部分份额。
2 Uboot结构与启动流程分析
2.1 Uboot结构分析
Uboot为德国DENX小组开发的嵌入式通用BootLoader。它支持 ARM、MIPS、XScale等多种体系结构,并支持引导Linux、VxWorks、NETBSD等多种操作系统。本文采用Uboot-2012-4版本。
Uboot共有18个目录,按层次和调用关系如图1所示。
图1 UBoot源代码层次和调用关系
Uboot新版本相对之前的旧版本,层次结构和调用关系更加清晰,对于移植新平台非常有利,降低了移植的难度和时间。
2.2 Uboot启动流程分析
Uboot的启动分为两个阶段。第一阶段主要为汇编代码,涉及 cpu/arm1176/start.s,board/开发板目录/lowlevel_init.S 和 arch/arm/lib/board.c 中的 borad_init_f函数。完成如下工作:
(1)设置CPU为SVC模式,关中断,关看门狗,关MMU;
(2)设置时钟,初始化各硬件控制器;
(3)设置堆栈;
(4)复制(重定位)Uboot到内存中;
(5)跳转到第二阶段代码入口。
第一阶段流程图如图2所示。
图2 第一阶段流程图
因为在第一阶段已经设置好堆栈,所以从第二阶段开始使用C语言实现。在arch/arm/lib/board.c的borad_init_r函数中uboot继续初始化各硬件资源,如串口、网卡、NAND Flash等。然后跳转至死循环common/main.c中的main_loop函数,启动Linux内核或等待用户输入命令。
3 Uboot移植
针对本文采用的开发板,使用与其硬件资源相近并且Uboot已经支持的SMDK6400开发板实现移植。本开发板没有配置NOR Flash,因此要实现从NAND Flash中启动UBoot。
3.1 创建工程目录
(1)在boardsamsung下,新建文件夹S3C6410。将SMDK6400目录下所有文件拷贝到S3C6410中,重命名 smdk6400.c和 smdk6400_nand_spl.c为s3c6410.c和 s3c6410_nand_spl.c,修改 Makefile 中COBJS-y:=smdk6400.o 为 COBJS-y:=s3c6410.o。
(2)在nand_sploardsamsung下,新建文件夹s3c6410,拷贝smdk6400目录下所有文件到s3c6410中。重命名smdk6400_nand_spl.c为s3c6410_nand_spl.c,修改 makefile中 smdk6400 字段为 s3c6410。
(3)在includeconfigs目录下,拷贝 smdk6400.h并重命名为s3c6410.h。
(4)修改根目录下的makefile,依据smdk6400添加s3c6410编译规则。
3.2 实现NAND Flash启动Uboot
ARM体系结构的微处理器上电后从地址0x0开始执行第一条代码。随着时代的发展,NAND Flash凭借容量大、速度快、价格低等优点逐渐取代NOR Flash。许多嵌入式平台上已经不再配备NOR Flash。
NOR Flash可以按地址读取,NAND Flash只能按页读取,因此不能直接从NAND Flash中启动Uboot。当S3C6410芯片配置成从NAND Flash启动模式时,系统上电后通过NAND Flash控制器自动读取NAND Flash中前4k内容到S3C6410芯片内部的stepping stone中,并将其映射到地址0x0开始执行。所以,如果S3C6410要从NAND Flash中启动,就必须在程序前4k代码中将完整的Uboot从NAND Flash中复制到内存,然后跳转到内存中相应继续执行,完成启动过程。
从NAND Flash启动的Uboot由两部分组成:前4k uboot_nand_spl文件和正常Uboot文件。它们顺序相接,中间没有空隙。宏 CONFIG_NAND_SPL是uboot_nand_spl的编译开关。当编译uboot_nand_spl时,第一阶段将由s3c6410_nand_spl.c中board_init_f函数替换board.c中的 board_init_f函数。此处的board_init_f不设置堆栈直接跳转回start.S,然后再从start.s跳转至 nand_spl and_boot.c 中的 nand_boot函数。nand_boot函数负责将NAND Flash中4k之后正常的Uboot复制到内存中,并跳转到内存中相应位置继续执行。
nand_boot函数用C语言实现,但第一阶段的board_init_f没有设置堆栈,所以这里使用的堆栈应该是s3c6410内部的IRAM(地址为0x0c00_0000~0x0fff_ffff,实际使用只有4k)。
将 start.s中的
此时sp指向S3C6410内部的IRAM。
3.3 添加DM9000A网卡
在uboot-2012-4版本中,已经实现对DM9000A网卡的支持,在此只需正确配置网卡信息,即可完成网卡驱动的移植。
开发板的所有硬件资源配置信息在include/configs/s3c6410.h中。本开发板使用的DM9000A网卡连接至S3c6410芯片的Bank0,地址为0x18000300,DM9000A。修改 s3c6410.h,添加以下 DM9000A网卡配置信息:
删除以下cs8900网卡配置信息:
本文使用的开发板为256MB内存,需修改内存配置信息:
3.4 编译并烧写到NAND Flash
在Uboot根目录下执行make s3c6410_config,生成编译配置文件,再执行make编译Uboot镜像。根目录生成的u-boot.bin镜像可在内存和NOR Flash中启动,u-boot-nand.bin镜像可在NAND Flash中启动。
NAND Flash无法直接使用Jlink烧写,本文通过Uboot自身功能实现NAND Flash的烧写。
使用Jlink把u-boot.bin和 u-boot-nand.bin下载到开发板内存中0x50000000和0x50100000处,运行u-boot.bin。此时 Uboot由内存中启动。执行 Uboot的nand erase 0x0 64000擦除NAND Flash最前面400kB空间,执行 nand write 0x50100000 0x0 64000将u-boot-nand.bin烧写到NAND Flash。复位开发板实现从NAND Flash中启动Uboot。
4 结束语
BootLoader是嵌入式开发极其重要的一环,本文在分析Uboot原理后,结合最新Uboot源代码和编译环境,在 S3C6410开发板上移植成功,并实现了NAND Flash启动和网络通信等功能。本方法为S3C6410后续开发奠定了基础,并对其它开发板的Uboot移植工作提供了一定的参考价值。
[1]田泽.嵌入式系统开发与应用[M].北京:北京航空航天大学出版社,2005:134-349.
[2]陈文智,王总辉.嵌入式系统原理与设计[M].北京:清华大学出版社,2011:53-178.
[3]陈赜.ARM嵌入式技术原理与应用[M].北京:北京航空航天大学出版社,2011:127-183.
[4]Sumsuang Electronics.S3C6410x User’s Manual[Z].Sumsuang Electronics,2008:60-245.
[5]Sumsuang Electronics.K9F2G08UXA Datasheet[Z].Sumsuang Electronics,2007:2-44
[6]Davicom Semiconductor.DM9000A Datasheet[Z].Davicom Semiconductor,2006:6-52.
[7]Sumsuang Electronics.S3C6410x Application Note(Internal ROM Booting)[Z].Sumsuang Electronics,2008:5-19.
[8]广州友善之臂计算机科技有限公司.Tiny6410硬件说明手册[Z].广州友善之臂计算机科技有限公司,2011:5-26.
[9][美]Daniel W Levis.嵌入式软件基础—C语言与汇编的整合[M].陈宗斌译.北京:高等教育出版社,2005:182-194.
[10]刘凯.ARM嵌入式接口技术应用[M].北京:清华大学出版社,2009:78-157.
[11]刘峰.ARM汇编语言[M].成都:电子科技大学出版社,2010:10-63.
[12]DENX.U-Boot Source Code[DB/OL].http://www.denx.de/wiki/U-Boot/SourceCode,2012-08-15
[13]DENX.The DENX U-Boot and Linux Guide(DULG)for canyonlands[DB/OL]. http://www.denx.de/wiki/DULG/Manual,2012-08-15.
[14]DENX.The Universal Boot Loader(“Das U-Boot”)[DB/OL].http://www.denx.de/wiki/U-Bootdoc/Presentation,2012-08-15.