APP下载

基于S3C2440的嵌入式Linux系统移植

2012-09-12王剑飞程耀瑜

电子测试 2012年11期
关键词:源码编译器开发板

王剑飞, 程耀瑜

(中北大学山西省现代无损检测工程技术研究中心, 山西太原 030051)

0 引言

嵌入式系统具有低功耗、实时性强和稳定性高等优点,在军事、工业和家用等领域得到广泛的应用。国内对嵌入式系统的一般定义是:以应用为中心,以计算机技术为基础,软硬件可裁剪,从而能够适应实际应用中对功能、可靠性、成本、体检、功耗等严格要求的专用计算机系统[1]。而操作系统的移植已成为嵌入式系统设计中的重要环节,具有可观的市场价值。

1 交叉编译环境

对于嵌入式系统的开发需要建立交叉编译环境,交叉编译环境就是在一个平台上生成可以在另一个平台上执行的代码的编译环境。Linux内核完全使用C和GNU形式的汇编完成因此嵌入式Linux的开发环境采用了GNU工具链的交叉开发平台。通过GNU提供的编译器cc/gcc、连接器ld/gld、汇编器as/gas和C函数库glibc以及精简的C库uClib,就可以建立完整的交叉开发环境来完成从开发GNU工具链针对不同的处理器提供了多种交叉开发平台[2]。

本次移植过程中使用的宿主机的操作系统是Ubuntu9.10。使用支持软浮点编译的交叉编译器arm-linux-gcc-3.4.5编译U-boot,而使用支持EABI技术的交叉编译器arm-linux-gcc-4.3.3编译Linux内核及根文件系统。使用PATH设置交叉编译路径[3]。将交叉编译器的源码包解压到宿主机/usr/local/目录下,然后修改环境变量:

# vi /etc/environment

PATH=/usr/local/4.3.3/bin

为了使新的环境变量生效,使用命令:source/etc/environment, 此 时,arm-linux-gcc-4.3.3交叉编译环境就建立了。

2 Bootloader引导程序

Bootloader的作用与PC上的BIOS类似,它在系统上电时执行,初始化硬件设备、准备好软件环境,最后调用操作系统的内核。Bootloader的实现非常依赖于具体的硬件,在嵌入式系统中硬件的配置千差万别,即使是相同的CPU,它的外设也可能不同,因此在嵌入式领域几乎不可能有统一的Bootloader支持所有的电路板。现在Bootloader种类繁多,比如x86上有LILO、GRUB等。不同的板级硬件,都需要进行U-Boot的移植工作[4]。对于ARM架构,有U-Boot、Vivi等。U-Boot支持大多数的CPU,具有较高的可靠性和稳定性。同时由于其开放源码,可以根据嵌入式Linux系统开发的需要增强U-Boot的功能。

2.1 U-Boot启动过程分析

U-Boot的启动过程可以分为两个阶段:第一阶段使用汇编来实现,完成同CPU体系结构相关的初始化,并调用第二阶段代码;第二阶段使用C语言实现,完成部分硬件的初始化及检测,最终启动内核[5]。

第一阶段主要内容包括:

(1)硬件设备初始化:调整CPU工作模式、设置CPU速度和时钟频率、关闭MMU等。

(2)为加载U-Boot的第二阶段代码准备RAM空间:调用lowlevel_init函数来设置存储控制器,初始化外接的SDRAM。

(3)复制U-Boot第二阶段的代码到RAM空间。

(4)设置堆栈。

(5)跳转到U-Boot第二阶段代码的C入口点:跳转之前,应清除BSS段。

第二阶段主要内容包括:

(1)初始化相关的硬件设备。

(2)检测系统内存映射。

(3)将内核和根文件映像复制到RAM空间。

(4)为内核设置启动参数。

(5)调用内核。

对于ARM架构的CPU,是通过do_bootm_linux函数来启动内核。这个函数中,设置标记列表,通过theKernel(0,bd->bi_arch_number,bd->bi_boot_params)调用内核。其中,theKernel指向内核存放的地址,bd->bi_arch_number就是在U-Boot中设置的机器类型ID,而bd->bi_boot_params就是标记列表的开始地址[6]。

2.2 U-Boot移植

从U-Boot的官方网站下载U-Boot-1.1.6.tar。bz2后解压可以得到全部源码。U-Boot的移植除了依赖CPU的体系结构外,还依赖于具体嵌入式开发板外设的配置情况。在获得U-Boot源码后,需要根据自己开发板的具体情况和嵌入式开发的相应需要修改部分源码。该版本的U-Boot不支持ARM微处理器S3C2440,但对同一系列的S3C2410有着完善的支持。由于两款微处理器在架构和使用上很接近,所以移植工作可以在对应的SMDK2410开发板的源码上做必要的修改,并且添加部分代码增强U-Boot的功能,以方便嵌入式系统的后期开发工作。

(1)进入U-Boot-1.1.6的源码目录,将board/smdk2410目录复制为wang2440目录。修改wang2440目录下smdk2410.c为wang2440.c。同时修改该目录下Makefile文件:COBJS:= wang 2440.o flash.o。 进入include/configs目录, 将smdk2410.h复制为wang2440.h 。

(2)在顶层Makefile中增加:Wang2440_config :unconfig@$(MKCONFIG) $(@:_config=)arm arm920t wang2440 NULL s3c24x0

各项的意思如下:

arm:CPU的架构(ARCH)

arm920t:CPU的类型(CPU),对应于CPU/arm920t子目录。

wang2440:开发板的型号(BOARD),对应于board/wang2440目录。

NULL:开发者或经销商(vender),此处NULL为没有。

S3c24x0:片上系统(SOC)。

(3)修改SDRAM配置和时钟设置,使其适应具体S3C2440开发板的配置。

(4)在cpu/arm920t/s3c24x0目录中增加NAND flash读取函数nand_flash.c。添加S3C2440 nand的驱动函数,同时修改nand_flash.c中的s3c24x0_init(void)函数,定义S3C2440 NAND flash的时钟和初始化NAND flash 。在board/wang2440目录下增加boot_init.c文件,让U-Boot支持从nand flash启动。

(5)U-Boot中没有提供对yaffs文件读写支持,可以通过增加nand write.yaffs命令实现对yaffs文件的读写支持。在commom/cmd_nand.c中增加处理函数do_nand.c实现对nand yaffs的支持。由于yaffs文件本身就包含了OOB区的数据(坏块标记、ECC校验码、其他yaffs相关信息),所以烧写时不需要再计算ECC值。

完成以上修改以后使用交叉编译工具armlinux-gcc-3.4.5编译U-Boot,在U-Boot目录输入:

make ARCH=arm CROSS_COMPILE=armlinux- wang2440_config

make ARCH=arm CROSS_COMPILE=armlinux- all

可以产生u-boot.bin文件。通过JTAG烧入开发板并复位,在SecureCRT终端输出如图1所示。

图1 u-boot运行结果

3 Linux内核移植

3.1 Linux内核启动过程

Linux的启动过程可以分为两部分:架构与开发板相关的引导过程、后续的启动过程。引导阶段通常使用汇编语言编写,首先检查内核是否支持当前架构的处理器,然后检查是否支持当前开发板。第二阶段使用C语言编写,进行内核初始化的工作,最后调用rest_init函数,创建第一个进程init。如图2中是ARM架构处理器上Linux内核的启动过程。

图2 Linux内核启动过程

3.2 Linux内核的移植

对Linux内核的移植是一个非常繁杂的过程,在对Linux内核深入了解的基础上,需要添加、修改相关的代码并对内核进行配置。Linux内核的确切能力取决于内核构建时所设定的配置。内核的配置可以让你移除非必要的支持或永远不会被用到的能力[7]。从官方网站可以下载Linux-2.6.30.4.tar.bz2,解压后可以得到Linux源码包。

修改Makefile文件,设置目标平台和指定交叉编译器。修改 Makefile中 ARCH=arm 和CROSS_COMPILE=arm-linux-,然后保存退出。修改平台时钟频率,修改内核源码arch/arm/mach-s3c2440/mach-smdk2440.c文件,通过函数s3c24xx_init_clocks(12000000)获得12M的外部时钟源输入。修改机器码,机器码在内核的arch/arm/mach-smdk2440.c文件中,确保机器码的值和U-boot中的一致。

设置分区信息,将NAND Flash划分为3个分区,修改内核源码arch/arm/plat-s3c24xx/common-smdk.c文件中结构体smdk_default_nand_part[]如下:

禁止ECC校验,修改drivers/mtd/nand/s3c2410.c文件,将chip->ecc.mode修改为chip->ecc.mode = NAND_ECC_NONE。

(3)配置内核,将arch/arm/configs/s3c2410_deconfig复制到.config文件,在默认配置单的基础上,通过make menuconfig命令 对内核进行必要的配置,把最终的配置结构保存为.config文件。

在内核源码目录下输入:make zImage,编译内核源码,编译完成后在arch/arm/boot目录下生成zImage镜像,将其烧入开发板中,可以得到内核启动时的分区信息如图3所示。

图3 MTD分区信息

3.3 根文件系统

Linux内核在系统启动期间所进行的最后操作就是挂载根文件系统,文件系统对系统中的文件和设备进行组织,为设备和用户提供统一接口[8]。Linux根文件系统的作用时存放各种工具、应用程序和必需的链接库等。使用Busybox可以简化制作嵌入式系统根文件系统的过程,因此,Busybox工具在嵌入式开发中广泛应用。从官方网站下载Busybox-1.15.2.tar.bz2,解压后可以得到源码。进入源码目录,修改Makefile文件,执行make menuconfig进行配置Busybox,根据实际需要添加或去除某些选项。配置完毕后,执行make、make install命令为新建的根文件系统添加/usr、/bin、/sbin等目录。

定制根文件系统的步骤如下:

(1)创建目录,在新建的根文件系统目录下,建立etc、dev、mnt等常见的Linux系统目录;

(2)创建设备节点;

(3)添加所需的库文件;

(4)配置系统文件;

(5)指定应用程序。

文件系统框架制作好后,使用mkyaffs2image工具,制作yaffs镜像。把可执行文件复制到/usr/bin目录下,制作文件系统镜像:mkyaffs2image root root.bin,将生成的root.bin文件烧入开发板,复位开发板后,在串口终端输入ls命令,结果如图4所示。

图4 根文件系统目录

4 结束语

本文系统介绍了以S3C2440的ARM9处理器为硬件平台的嵌入式Linux系统的移植过程。针对U-boot的源码进行了必要的修改,方便嵌入式Linux系统的后续开发工作。对嵌入式Linux内核的移植及根文件系统的创建方法进行总结。嵌入式Linux系统移植于嵌入式底层开发平台对嵌入式系统开发设计具有重要意义。移植后的Linux系统在ARM平台下稳定工作。

[1]徐英慧,马忠梅.ARM9嵌入式系统设计-基于S3C2410与Linux[M].北京:北京航空航天大学出版社,2010.

[2]刘文峰,李程远,李善平.嵌入式Linux操作系统的研究[J].浙江大学学报:工学版,2004,38(4).

[3]宋凯,严丽平.ARM Linux在S3C2410上的移植[J].计算机工程与设计,2008,29(16).

[4]邹颖婷,李绍荣.ARM9上的嵌入式Linux系统移植[J].自动化技术与应用,2009,28(6).

[5]师磊.U-Boot在S3C2440上的分析与移植[J].计算机系统应用,2010,19(4).

[6]韦东山.嵌入式Linux应用开发完全手册[M].北京:人民邮电出版社,2008.

[7]Karim Yaghmour, Jonathan Masters, Gilad Ben-Yossef.Building Embedded Linux Systems[M].O’Reilly,2003.

[8]师娟娟,彭迪.基于ARM9的嵌入式Linux移植[J].武汉理工大学学报,2008,30(2).

猜你喜欢

源码编译器开发板
面向数据可靠传输的高译码率带反馈的LT码
国内一站式工程设备租赁平台众能联合完成C2、C3两轮融资
浅谈开源操作系统的历史
企业如何保护源码
基于相异编译器的安全计算机平台交叉编译环境设计
浅析单片机开发板的设计与制作
Microchip为MPLAB XC系列专业版编译器推出低成本可续订包月许可证
ARM宣布mbed Enabled Freescale FRDM—K64F开发板通过微软认证
Mouser为您呈上开发关键之STMicroelectronics Nucleo开发板
Arduino和Atmel发布Arduino Zero开发板