嵌入式Linux在SH4架构下的移植技术研究

时间:2022-09-19 11:11:19

嵌入式Linux在SH4架构下的移植技术研究

摘 要:SuperH系列微处理器是Renesas公司(原Hitachi)开发的采用了RISC系统指令集的32位系列微处理器。详细介绍SH4系列交叉编译平台在新版本编译器下的配置过程,提出一种适用于SuperH系列微处理器的通用的内核移植的方法并研究Linux 2.6内核在SH4系列微处理器SH7751上的移植方案。实验证明该方法可行,移植过程也对其他平台有借鉴作用。

关键词:SuperH;Linux2.6;嵌入式系统;内核移植

中图分类号:TN21;TP311文献标识码:A

文章编号:1004-373X(2008)24-058-03

Research of Porting Embedded linux Based on sh4

WANG Ruo,GUAN Shengxiao,DIAO Zhihua

(USTC-Renesas Joint Library,University of Science and Technology of China,Hefei,230026,China)

Abstract: SuperH is a series of 32bit RISC MPU production of Renesas Company.The paper provides a method of porting embedded Linux kernel 2.6 to SH7751 and introduces the way of establishing crosstool in SH4 series MPU.The result proves it viable and helpful to other architecture of MPUs.And the migration process is also helpful to the other platform.The paper presents a common core transplant method applicable to series of SuperH microprocessor.

Keywords:SuperH;Linux2.6;embedded system;core transplant

1 引 言

Renesas公司的SuperH系列微处理器是由原Hitachi公司设计开发,由SuperH公司提供CPU技术支持。SH7751属于微处理器SH4系列,有着较高的工作频率和处理性能(430 MIPS/ 240 MHz)。Linux 2.6内核相对于先前版本的内核在可配置性方面有了较大的改进,内核的可抢占和响应时间的改进使其在应用软件性能上更加优异。由于支持高档的电源管理APM,就为各种手持设备和对电源管理比较严格的嵌入式系统提供了良好的平台支持,越来越多的嵌入式系统陆续将Linux2.6作为开发的基础平台。因此将新内核移植并建立开发环境成为进行嵌入式系统开发首先要进行的工作。一般对内核移植的具体工作可以分为3个步骤:建立交叉编译工具链(Toolchain);内核的配置和剪裁;建立根文件系统并配置bootloader。

SH系列微处理器进行嵌入式Linux移植也是按照上述3个步骤进行,但在新版本编译器环境下移植Linux2.6过程与先前版本的配置有较大差。

2 交叉编译环境的建立

2.1 交叉编译源文件和工具的选取

交叉编译是指在宿主机器(Host)上生成针对特定平台代码(Target)的过程。实验中使用的是x86平台下的debian4.0的宿主机对SH4系列平台代码进行交叉编译,从而生成在SH4系列MPU上可运行的代码。进行交叉编译的一系列工具即称为交叉编译工具链。

交叉编译工具主要由binutils,gcc 和 glibc组成。由于SH4系列微处理器应用较少,一些著名的交叉编译工具如CLFS,crosstool均未提供对SH4系列环境的支持。有较多的SH系列微处理器开发板厂商提供了对Linux的开发工具包,但提供的大都是2.4版本的内核,并且无法及时得到社区的技术支持。实验中使用Renesas公司的EDOSK7751R开发平台,移植中选取负责SH架构Linux内核团队2007年5月的内核稳定版本linux-sh-2.6.20。

在选取C库过程中由于稳定性考虑选取标准库glibc,glibc-sh中INSTALL文件指明了binutils和gcc的最低版本和推荐版本,实验中选取的binutils版本为2.17。

与内核的选取不同,gcc的选取并不建议选用最新的版本,这是因为可能在选用的其他工具软件进行具体调试中很多陈旧代码可能在新编译器下编译链接错误较难解决。在实验中选择的是gcc4.1.1及gcc的Sh4补丁。实验中使用的源文件和补丁如下:

binutils-2.17.50.tar.gz

binutils-2.17.50-sh4-linux.tar.gz

gcc4.1.1.tar.gz

gcc4.1.1-sh4-linux.tar.gz

glibc-2.5.3.tar.gz

glibc-2.5.3-sh4-linux.tar.gz

glibc-linuxthreads-2.5.3.tar.gz

glibc-headers-2.5.3.tar.gz

glibc-headers-2.5-3.sh4.tar.gz

linux-sh-2.6.20.10.tar.gz

2.2 内核头文件的生成。

首先建立工作目录和一些环境外部变量:

$export PREFIX=/home/ruo

$export PATH=${PREFIX}/usr/bin:${PATH}

内核头文件是交叉编译的基础文件,在较早版本的Linux(如2.4)中交叉编译中一般通过对内核的配置生成。在Linux2.6环境下配置完内核后,版本头文件version.h要单独建立,否则后期glibc无法安装。解压linux-sh-2.6.20.10.tar.gz并运行指令:

$tar Cxzf linux-sh-2.6.20.10.tar.gz

$cd linux-2.6.20

$make ARCH=sh CROSS_COMPILE=sh4-linux- menuconfig

$make include/linux/version.h

$install -dv ${PREFIX}/usr/include/{asm,asm-generic,linux,rdma,mtd,sound,video}

配置“Processor selection”选择“support SH7751 processor”,另外根据SH7751系列不同型号CPU的用户手册配置其他内核选项。配置完成保存退出后,建立版本头文件。运行后可查看/include/linux/文件夹中是否生成autoconf.h和version.h是否生成而判定内核头文件是否创建成功。

将生成的头文件中asm,asm-generic,linux,rdma,mtd, sound,video七个目录拷贝到工作目录${PREFIX}/usr/include中。

2.3 建立引导编译器(bootstrap gcc)

binutils是一组二进制工具集合,将binutils-2.17和补丁解压后,打完全部补丁,然后即可安装生成交叉编译的二进制工具集合。将libiberty.h文件拷入内核头文件库中,编译后期gcc使用。命令参数如下:

$cd binutils-2.17-sh4-linux

$patch -p1 < ../binutils-2.17-sh4-linux.patch

$patch ....(省略)

$cd ..

$../binutils-2.17/configure --prefix=${PREFIX}/tools --target=sh4-linux

--disable-nls --enable-shared --disable-multilib

$make

$make install

$cp -v include/libiberty.h ${PREFIX}/usr/include

与先前版本不同,gcc3.2后版本安装引导编译器必须要获得glibc的支持。而glibc库又依靠gcc交叉编译。为解决这个问题,glibc提供了头文件供gcc初始编译器使用。在编译引导编译器前,首先要安装glibc-headers。注意此过程并非交叉编译glibc,因为没有gcc引导编译器是无法进行的。与binutils设置不同,安装中参数“--host”必须设定为目标平台架构“sh4-linux”,这样才能告诉gcc编译出符合目标系统的信息。在对glibc-headers解压和补丁处理后,安装并在工作目录中建立假文件stubs.h。拷贝pthreadtypes.h文件到内核头文件中提供本地POSIX线程库支持,以便后期编译glibc。命令参数如下:

$CC=gcc ../glibc-2.4/configure --prefix=${PREFIX}/tools

--host=sh4-linux --with-headers=${PREFIX}/usr/include

$make install-headers

$install -dv ${PREFIX}/usr/include/bits

$touch ${PREFIX}/usr/include/gnu/stubs.h

$cp -v nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h

${PREFIX}/usr/include/bits

当glibc头文件安装完毕,即可安装引导交叉编译器。引导编译器仅是一个C语言的编译器,作用是对glibc进行交叉编译,然后使用编译后的glibc生成完整的支持C++的gcc完整交叉编译器(full gcc)。解压并打好补丁后修改对可能使用的某些共享库的搜索目录,以便在后期建立完整交叉工具链能直接找到共享库。在/gcc/config/sh/linux.h文件第46行后添加:

#undef LIB_SPEC

#define LIB_SPEC

“%{!static:

%{!m4:-rpath-link /usr/sh4-linux/lib}

%{m4:-rpath-link /usr/sh4-linux/lib/m4}}”

然后进行配置安装:

$../gcc-4.1.1/configure --prefix=${PREFIX}/tools

--target= sh4-linux --build= i686-linux

--disable-multilib --disable-nls --disable-shared

--enable-languages=c

$make all-gcc

$make install-gcc

2.4 建立完整的交叉编译工具链(full gcc)

在bootstrap gcc的安装完成后,就可以完整地交叉编译glibc了。解压glibc-2.53和glibc-linuxthreads-2.5.3(提供基于POSIX标准的核心线程库)及补丁文件,即可配置安装,“--enable-kernel=2.6.0”表示kernel选用2.6.x,并不需要指明详细版本。配置参数如下:

$CC=sh4-linux-gcc AR=sh4-linux-ar

../glibc-2.5.3/configure --prefix=/home/ruo/tools

--libexecdir=/usr/lib/glibc

--host=sh4-linux --disable-profile --enable-add-ons

--with-tls --enable-kernel=2.6.0 --with-__thread

--with-binutils=${PREFIX}/tools/bin

--with-headers=${PREFIX}/usr/include

完成对gcc的安装,配置参数如下:

$../gcc-4.1.1/configure --prefix=${PREFIX}/tools

--target=sh4-linux --build= i686-linux

--disable-multilib --disable-nls --enable-shared

--enable-languages=c,c++ --enable-__cxa_atexit

--enable-c99 --enable-long-long --enable-threads=posix

完成后工作目录下/tools/bin下会生成以一系列“sh4-linux-”为前缀的交叉编译二进制工具。这样交叉编译工具链即建立完成。

3 内核的配置和剪裁

与前期建立交叉编译内核头文件不同,对内核的配置由于完整的Linux内核对于嵌入式系统来说过于庞大,需经过剪裁非必要的部分达到减小内核镜像的目的。运行指令:

make ARCH=sh CROSS_COMPILE=sh4-linux- menuconfig

再次进入menuconfig界面,主要配置板级支持,对块设备RAMdisk、设备驱动及文件系统的支持。可将与内核其他部分关系较远且不经常使用的功能代码编译成为可加载模块,以有效地减小内核的大小,还可减小内核消耗的内存。当配置完成后即可编译内核生成内核映像。内核映像可以选择压缩或者非压缩格式,在实际嵌入式系统中一般选择压缩内核,这样能够有效地减小内核占用体积,编译压缩内核映像:

make ARCH=sh CROSS_COMPILE=sh4-linux- zImage

4 根文件系统的建立与配置bootloader

4.1 根文件系统的建立

Linux在启动期间需要安装根文件系统,根文件系统也是所有Unix系统所必须的组件。其中常用必需的目录有:/bin,/dev,/etc,/lib等。bin目录下放置必要的用户命令(二进制文件),dev目录下放置了设备文件,etc目录下是系统配置文件和启动文件,lib目录下放置系统运行库的文件等。嵌入式Linux一般通过内存来虚拟设备文件,将根文件系统的压缩镜像解压到其中并挂载而创建。建立创建一个名为initrd临时用于挂载根文件系统的设备点,挂载并建立/bin,/dev,/etc等文件夹:

# mkdir -p /mnt/initrd

# dd if=/dev/zero of=/initrd bs=1k count=6144

# mke2fs -F -m 0 initrd

# mount -o loop /initrd /mnt/initrd

# mkdir dev proc etc etc/rc.d sbin bin lib usr

将配置文件及库文件拷贝到相关目录。对于用户命令的二进制文件可以使用BusyBox来创建。BusyBox 包含了近百种 Linux 上标准的工具程序,仅需要几百kb空间,在嵌入式系统上非常适合使用以减少根目录文件大小。可以在下载到busybox-1.2.0-3.sh4.tar.gz,注意在交叉编译BusyBox时需要glibc的支持,需要将其所需要的库文件链接到其lib目录中。

另外内核应该对根文件系统的大小进行配置,在选项“Block Devices”中 “Default RAM disk size”进行大小设置,以便在后期启动时能够指示根文件系统目录的大小。实验中生成的内核大致在 6 MB左右,所以在先前创建initrd时参数“bs=1k count=6144”指明文件每块大小1 kB,共6 144块。

在根文件系统创建并配置完成后,即可压缩镜像文件了。可用gzip压缩镜像:

# gzip -c -9 initrd.img > initrd.bin

4.2 bootloader的配置

bootloader是在操作系统内核运行之前的一段程序,通过这段程序初始化硬件设备,建立内存空间的映射表,从而建立适当的系统软硬件环境,为调用操作系统内核做好准备。由于bootloader是基于特定硬件平台的,所以不同架构有着不同的bootloader。SH系列微处理器的标准专用bootloader是Renesas公司的sh-boot,EDOSK7751R开发板中提供了工具包。

SH4系列微处理器加电复位后从A000 0000处取得第一条指令。修改sh-boot中/FLASH/FLASHboot.c文件以确定FLASH和RAM的位置和大小,以映射到相映的位置。修改/machine/syshsh4.mem文件确定启动镜像文件的大小,设置堆栈指针。/config/config.h文件设置CONFIG_BOOT_LOADER1 用来启动方式(从FLASH启动或网络启动)。如果设置从FLASH启动,需修改Makefile文件中的LINUX_ROM_ADDRESS和INITRD_ROM_ADDRESS确定Linux压缩内核和根文件系统镜像在FLASH中的位置,其他启动方式如tftp等设置可参阅Renesas提供的sh-boot技术文档。设置完毕后make,即可得到bootloader的启动镜像。

5 结 语

本文针对国内应用较少的SuperH平台,介绍嵌入式Linux2.6在7751上的移植技术。重点针对SH4系列在较新版本编译器和内核环境下交叉编译环境的建立和内核的配置进行详细阐述。实验结果表明,在EDOSK7751R开发板上系统运行可靠,是SH4架构移植的一般性方法,对以后开发SH系列微处理器嵌入式系统有着指导意义。

参考文献

[1]Karim Yagbmour.构建嵌入式Linux系统[M].北京:中国电力出版社,2004.

[2]Anon SHLinux Quick Start Guide.Renesas Technology Europe Limited,2003.

[3]Bill Gatliff.Running Linux on the Sega Dreamcast[EB/OL].,2005.

[4]张晓林,崔迎炜.嵌入式系统设计与实践[M].北京:北京航空航天大学出版社,2006.

[5]袁太生,张素琴.嵌入式环境下Linux 移植问题的探讨[J].计算机应用研究,2003(11):61-63.

[6]张艺濒,谢金晶.通用安全Linux操作系统设计分析.现代电子技术,2007,30(6):102-104.

作者简介 王 若 男,1982年出生,硕士研究生。研究方向为模式识别与智能系统。

关胜晓 男,1964年出生。副教授。研究方向为嵌入式系统,智能机器人等。

刁智华 男,1982年出生,博士研究生。研究方向为图像处理、嵌入式系统。

上一篇:基于DMFT的LFM信号参数估计 下一篇:基于SDIO接口的通用RFID读写器的开发